mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop
This commit is contained in:
@@ -2,7 +2,6 @@ import {
|
||||
patchState,
|
||||
signalStore,
|
||||
withComputed,
|
||||
withHooks,
|
||||
withMethods,
|
||||
withProps,
|
||||
withState,
|
||||
@@ -99,9 +98,12 @@ export const RemissionStore = signalStore(
|
||||
* @see {@link https://angular.dev/guide/signals/resource} Angular Resource API documentation
|
||||
*/
|
||||
_receiptResource: resource({
|
||||
loader: async ({ abortSignal }) => {
|
||||
const receiptId = store.receiptId();
|
||||
const returnId = store.returnId();
|
||||
params: () => ({
|
||||
returnId: store.returnId(),
|
||||
receiptId: store.receiptId(),
|
||||
}),
|
||||
loader: async ({ params, abortSignal }) => {
|
||||
const { receiptId, returnId } = params;
|
||||
|
||||
if (!receiptId || !returnId) {
|
||||
return undefined;
|
||||
|
||||
@@ -53,7 +53,7 @@ export class MyComponent {
|
||||
The library supports several filter input types:
|
||||
|
||||
- **Text Filters** (`InputType.Text`): For search queries and text-based filtering
|
||||
- **Checkbox Filters** (`InputType.Checkbox`): For multi-select options
|
||||
- **Checkbox Filters** (`InputType.Checkbox`): For multi-select options with optional selection limits
|
||||
- **Date Range Filters** (`InputType.DateRange`): For time-based filtering
|
||||
|
||||
### Query Settings
|
||||
@@ -73,9 +73,12 @@ const settings: QuerySettings = {
|
||||
label: 'Category',
|
||||
type: InputType.Checkbox,
|
||||
options: {
|
||||
max: 3, // Optional: Limit selection to 3 items
|
||||
values: [
|
||||
{ label: 'Electronics', value: 'electronics' },
|
||||
{ label: 'Clothing', value: 'clothing' },
|
||||
{ label: 'Books', value: 'books' },
|
||||
{ label: 'Sports', value: 'sports' },
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -114,7 +117,7 @@ The `OrderByToolbarComponent` allows users to sort data based on different crite
|
||||
|
||||
The library includes specialized components for different input types:
|
||||
|
||||
- `CheckboxInputComponent`: For multi-select options
|
||||
- `CheckboxInputComponent`: For multi-select options with optional selection limits
|
||||
- `DatepickerRangeInputComponent`: For date range selection
|
||||
- `SearchBarInputComponent`: For text-based search
|
||||
|
||||
@@ -146,9 +149,11 @@ const settings: QuerySettings = {
|
||||
label: 'Status',
|
||||
type: InputType.Checkbox,
|
||||
options: {
|
||||
max: 2, // Allow up to 2 status selections
|
||||
values: [
|
||||
{ label: 'Active', value: 'active' },
|
||||
{ label: 'Inactive', value: 'inactive' },
|
||||
{ label: 'Pending', value: 'pending' },
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -193,6 +198,52 @@ export class ProductListComponent {
|
||||
|
||||
onApplyFilters() {
|
||||
// Trigger data refresh or update
|
||||
this.filterService.commit();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Maximum Options for Checkbox Filters
|
||||
|
||||
Checkbox filters support an optional `max` property to limit the number of selections users can make:
|
||||
|
||||
```typescript
|
||||
// Configuration with maximum options
|
||||
{
|
||||
key: 'tags',
|
||||
label: 'Tags',
|
||||
type: InputType.Checkbox,
|
||||
options: {
|
||||
max: 5, // Users can select up to 5 tags
|
||||
values: [
|
||||
{ label: 'JavaScript', value: 'js' },
|
||||
{ label: 'TypeScript', value: 'ts' },
|
||||
{ label: 'Angular', value: 'angular' },
|
||||
{ label: 'React', value: 'react' },
|
||||
{ label: 'Vue', value: 'vue' },
|
||||
{ label: 'Node.js', value: 'node' },
|
||||
{ label: 'Python', value: 'python' },
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Behavior with Maximum Options:**
|
||||
|
||||
- **FIFO Strategy**: When the limit is exceeded, the oldest selections are automatically removed
|
||||
- **UI Enhancement**: The "Select All" control is hidden when `max` is configured to prevent user confusion
|
||||
- **Automatic Enforcement**: The filter service handles limit enforcement transparently
|
||||
|
||||
**Example with FIFO Behavior:**
|
||||
```typescript
|
||||
// Starting state: [] (empty)
|
||||
// User selects: ['js']
|
||||
// User selects: ['js', 'ts']
|
||||
// User selects: ['js', 'ts', 'angular']
|
||||
// User selects: ['js', 'ts', 'angular', 'react']
|
||||
// User selects: ['js', 'ts', 'angular', 'react', 'vue']
|
||||
// User selects 'node' -> ['ts', 'angular', 'react', 'vue', 'node'] (oldest 'js' removed)
|
||||
```
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -228,7 +279,7 @@ The Filter library is organized into several key modules:
|
||||
|
||||
### Inputs Module
|
||||
|
||||
- **CheckboxInput**: Multi-select options component
|
||||
- **CheckboxInput**: Multi-select options component with configurable selection limits
|
||||
- **DatepickerRangeInput**: Date range selection component
|
||||
- **SearchBarInput**: Text-based search component
|
||||
- **InputRenderer**: Dynamic component renderer
|
||||
|
||||
@@ -113,10 +113,29 @@ export class FilterService {
|
||||
/**
|
||||
* Sets the selected values for a checkbox input with the specified key.
|
||||
*
|
||||
* This method directly sets the selected values for a checkbox input. Unlike
|
||||
* `setInputCheckboxOptionSelected`, this method does not handle hierarchical
|
||||
* parent-child relationships or enforce maximum options limits. It directly
|
||||
* replaces the entire selection array with the provided values.
|
||||
*
|
||||
* @param key - The key of the checkbox input to update
|
||||
* @param selected - Array of selected values
|
||||
* @param selected - Array of selected values to set (replaces current selection entirely)
|
||||
* @param options - Optional parameters
|
||||
* @param options.commit - If true, commits the changes immediately
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Set specific selected values
|
||||
* filterService.setInputCheckboxValue('categories', ['electronics', 'books'], { commit: true });
|
||||
*
|
||||
* // Clear all selections
|
||||
* filterService.setInputCheckboxValue('categories', []);
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* This method bypasses the maximum options enforcement and hierarchical logic.
|
||||
* Use `setInputCheckboxOptionSelected` for individual option management with
|
||||
* proper limit enforcement and parent-child relationship handling.
|
||||
*/
|
||||
setInputCheckboxValue(
|
||||
key: string,
|
||||
@@ -147,12 +166,13 @@ export class FilterService {
|
||||
* Sets the selection state of a specific checkbox option within a hierarchical structure.
|
||||
*
|
||||
* This method handles the selection/deselection of checkbox options with automatic
|
||||
* parent-child relationship management:
|
||||
* parent-child relationship management and maximum options enforcement:
|
||||
* - When selecting a parent option, all child options are implicitly selected
|
||||
* - When deselecting a parent option, all child options are also deselected
|
||||
* - Child options can be individually selected/deselected
|
||||
* - If `maxOptions` is configured and selection would exceed the limit, oldest selections are removed (FIFO)
|
||||
*
|
||||
* @param path - Array representing the hierarchical path to the option [group, groupKey, ...optionKeys]
|
||||
* @param checkboxOption - The checkbox option object containing the hierarchical path and metadata
|
||||
* @param selected - Whether to select (true) or deselect (false) the option
|
||||
* @param options - Optional parameters
|
||||
* @param options.commit - If true, commits the changes immediately
|
||||
@@ -161,17 +181,26 @@ export class FilterService {
|
||||
* ```typescript
|
||||
* // Select a specific option
|
||||
* filterService.setInputCheckboxOptionSelected(
|
||||
* ['category', 'products', 'electronics', 'phones'],
|
||||
* checkboxOption,
|
||||
* true
|
||||
* );
|
||||
*
|
||||
* // Deselect a parent option (also deselects all children)
|
||||
* filterService.setInputCheckboxOptionSelected(
|
||||
* ['category', 'products', 'electronics'],
|
||||
* parentCheckboxOption,
|
||||
* false,
|
||||
* { commit: true }
|
||||
* );
|
||||
*
|
||||
* // When maxOptions is set to 3 and selecting would exceed the limit:
|
||||
* // If currently selected: ['option1', 'option2', 'option3']
|
||||
* // Selecting 'option4' results in: ['option2', 'option3', 'option4']
|
||||
* // (oldest selection 'option1' is automatically removed)
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* The maximum options enforcement only applies when selecting options. Deselection is not affected by the limit.
|
||||
* The FIFO (First In, First Out) strategy ensures the most recently selected options are preserved when the limit is exceeded.
|
||||
*/
|
||||
setInputCheckboxOptionSelected(
|
||||
checkboxOption: CheckboxFilterInputOption,
|
||||
@@ -210,7 +239,14 @@ export class FilterService {
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
const newSelected = [...input.selected, ...keys];
|
||||
const maxOptions = input.maxOptions;
|
||||
|
||||
let newSelected = [...input.selected, ...keys];
|
||||
|
||||
if (maxOptions && newSelected.length > maxOptions) {
|
||||
const excessCount = newSelected.length - maxOptions;
|
||||
newSelected = newSelected.slice(excessCount);
|
||||
}
|
||||
|
||||
return {
|
||||
...input,
|
||||
|
||||
@@ -6,15 +6,16 @@ import { checkboxOptionMapping } from './checkbox-option.mapping';
|
||||
* Maps an Input object to a CheckboxFilterInput object with support for hierarchical options.
|
||||
*
|
||||
* This function transforms a generic Input object into a strongly-typed CheckboxFilterInput,
|
||||
* handling nested checkbox options and tracking selection states. The mapping process:
|
||||
* handling nested checkbox options, selection limits, and tracking selection states. The mapping process:
|
||||
* - Validates the input against the CheckboxFilterInputSchema
|
||||
* - Maps the maximum options limit from `input.options?.max` to `maxOptions` property
|
||||
* - Recursively maps nested options with proper path tracking
|
||||
* - Extracts selected values from the option tree
|
||||
*
|
||||
* @param group - The group identifier that this input belongs to
|
||||
* @param input - The source input object containing checkbox configuration
|
||||
* @returns A validated CheckboxFilterInput object with hierarchical options
|
||||
*
|
||||
* @returns A validated CheckboxFilterInput object with hierarchical options and optional selection limits
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const checkboxInput = checkboxFilterInputMapping('filters', {
|
||||
@@ -22,6 +23,7 @@ import { checkboxOptionMapping } from './checkbox-option.mapping';
|
||||
* label: 'Product Category',
|
||||
* type: 'checkbox',
|
||||
* options: {
|
||||
* max: 3, // Maps to maxOptions: 3
|
||||
* values: [
|
||||
* { value: 'electronics', label: 'Electronics', selected: true },
|
||||
* { value: 'clothing', label: 'Clothing' }
|
||||
|
||||
@@ -8,9 +8,25 @@ import { CheckboxFilterInputOptionSchema } from './checkbox-filter-input-option.
|
||||
* Extends the BaseFilterInputSchema with checkbox-specific properties.
|
||||
*
|
||||
* @property type - Must be InputType.Checkbox
|
||||
* @property maxOptions - Optional limit on how many options can be selected
|
||||
* @property maxOptions - Optional limit on how many options can be selected simultaneously.
|
||||
* When set, the filter service enforces this limit using a FIFO (First In, First Out) strategy,
|
||||
* automatically removing the oldest selections when new selections would exceed the limit.
|
||||
* When configured, the "Select All" control is hidden to prevent user confusion.
|
||||
* @property options - Array of selectable checkbox options
|
||||
* @property selected - Array of string values representing the currently selected options
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Checkbox input with maximum of 3 selections
|
||||
* const checkboxInput: CheckboxFilterInput = {
|
||||
* type: InputType.Checkbox,
|
||||
* key: 'categories',
|
||||
* label: 'Categories',
|
||||
* maxOptions: 3, // Users can select up to 3 categories
|
||||
* options: [...],
|
||||
* selected: ['electronics', 'books']
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export const CheckboxFilterInputSchema = BaseFilterInputSchema.extend({
|
||||
type: z
|
||||
@@ -22,7 +38,9 @@ export const CheckboxFilterInputSchema = BaseFilterInputSchema.extend({
|
||||
.number()
|
||||
.optional()
|
||||
.describe(
|
||||
'Optional maximum number of options that can be selected simultaneously. If not provided, all options can be selected.',
|
||||
'Optional maximum number of options that can be selected simultaneously. ' +
|
||||
'When exceeded, the oldest selections are automatically removed (FIFO strategy). ' +
|
||||
'Setting this value also hides the "Select All" control to prevent user confusion.',
|
||||
),
|
||||
options: z
|
||||
.array(CheckboxFilterInputOptionSchema)
|
||||
|
||||
@@ -24,18 +24,20 @@
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<label
|
||||
class="w-full flex items-center gap-4 cursor-pointer isa-text-body-2-bold"
|
||||
>
|
||||
<ui-checkbox>
|
||||
<input
|
||||
(click)="toggleSelection()"
|
||||
[checked]="allChecked()"
|
||||
type="checkbox"
|
||||
/>
|
||||
</ui-checkbox>
|
||||
<span> Alle aus/abwählen</span>
|
||||
</label>
|
||||
@if (!hasMaxOptions()) {
|
||||
<label
|
||||
class="w-full flex items-center gap-4 cursor-pointer isa-text-body-2-bold"
|
||||
>
|
||||
<ui-checkbox>
|
||||
<input
|
||||
(click)="toggleSelection()"
|
||||
[checked]="allChecked()"
|
||||
type="checkbox"
|
||||
/>
|
||||
</ui-checkbox>
|
||||
<span> Alle aus/abwählen</span>
|
||||
</label>
|
||||
}
|
||||
|
||||
@for (option of options(); track option.key; let i = $index) {
|
||||
<filter-checkbox-input-control
|
||||
|
||||
@@ -54,6 +54,29 @@ export class CheckboxInputComponent {
|
||||
) as CheckboxFilterInput;
|
||||
});
|
||||
|
||||
/**
|
||||
* Computed property that determines if the checkbox input has a maximum options limit configured.
|
||||
*
|
||||
* This property is used to conditionally show/hide the "Select All" control in the template.
|
||||
* When a maximum limit is set, the "Select All" functionality is disabled to prevent
|
||||
* users from selecting more items than allowed, which would result in automatic deselection
|
||||
* due to the FIFO enforcement in the filter service.
|
||||
*
|
||||
* @returns True if the input has a maximum options limit greater than 0, false otherwise
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // In template:
|
||||
* // @if (!hasMaxOptions()) {
|
||||
* // <label>Select All</label>
|
||||
* // }
|
||||
* ```
|
||||
*/
|
||||
hasMaxOptions = computed(() => {
|
||||
const input = this.input();
|
||||
return input.maxOptions && input.maxOptions > 0;
|
||||
});
|
||||
|
||||
options = computed(() => {
|
||||
const input = this.input();
|
||||
const options = input?.options || [];
|
||||
|
||||
Reference in New Issue
Block a user