@valtimo/layout 13.16.0 → 13.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,19 +7,20 @@ import { CommonModule, DOCUMENT } from '@angular/common';
7
7
  import * as i2$1 from '@ngx-translate/core';
8
8
  import { TranslateModule, TranslatePipe } from '@ngx-translate/core';
9
9
  import * as i1 from '@valtimo/components';
10
- import { ViewType, CarbonListModule, EllipsisPipe, MdiIconViewerComponent, FormIoModule, CARBON_THEME, CurrentCarbonTheme, runAfterCarbonModalClosed, AutoKeyInputComponent, CARBON_CONSTANTS, ValuePathSelectorPrefix, CarbonMultiInputModule, InputLabelModule, ConfirmationModalModule, JsonEditorComponent, ValuePathSelectorComponent, SelectModule, MdiIconSelectorComponent, ValuePathType, MenuRoutingModule, TopbarModule, LeftSidebarModule, RightSidebarModule, PageHeaderModule, AlertModule, PromptModule, MultiInputFormModule, RenderInPageHeaderDirective } from '@valtimo/components';
10
+ import { ViewType, CarbonListModule, EllipsisPipe, MdiIconViewerComponent, FormIoModule, CARBON_THEME, CurrentCarbonTheme, InputLabelModule, InputModule as InputModule$1, FormModule, SelectModule, ParagraphModule, DateTimePickerComponent, runAfterCarbonModalClosed, AutoKeyInputComponent, CARBON_CONSTANTS, ValuePathSelectorPrefix, CarbonMultiInputModule, ConfirmationModalModule, JsonEditorComponent, ValuePathSelectorComponent, MdiIconSelectorComponent, ValuePathType, MenuRoutingModule, TopbarModule, LeftSidebarModule, RightSidebarModule, PageHeaderModule, AlertModule, PromptModule, MultiInputFormModule, RenderInPageHeaderDirective } from '@valtimo/components';
11
11
  import * as i3 from 'carbon-components-angular';
12
- import { ButtonModule, InputModule, LayerModule, SkeletonModule, PaginationModel, PaginationModule, TilesModule, IconModule, DialogModule, MenuButtonModule, ContextMenuModule, LoadingModule, ModalModule, TooltipModule, ComboBoxModule, DropdownModule, StructuredListModule, ToggleModule, AccordionModule, ProgressIndicatorModule, TabsModule, CheckboxModule, TagModule, Tab, SelectModule as SelectModule$1, PlaceholderModule } from 'carbon-components-angular';
12
+ import { ButtonModule, InputModule, LayerModule, SkeletonModule, PaginationModel, PaginationModule, TilesModule, IconModule, TimePickerModule, DialogModule, MenuButtonModule, ContextMenuModule, LoadingModule, ModalModule, TooltipModule, ComboBoxModule, DropdownModule, StructuredListModule, ToggleModule, AccordionModule, ProgressIndicatorModule, TabsModule, CheckboxModule, TagModule, Tab, SelectModule as SelectModule$1, PlaceholderModule } from 'carbon-components-angular';
13
13
  import { Subscription, BehaviorSubject, combineLatest, map, tap, switchMap, take, filter as filter$1, Subject, debounceTime, of, startWith, merge, delay } from 'rxjs';
14
14
  import { TrashCan16, Filter16, Link16, Edit16, ArrowUp16, ArrowDown16, DragVertical16 } from '@carbon/icons';
15
15
  import * as i2 from '@angular/router';
16
16
  import { NavigationEnd, RouterModule } from '@angular/router';
17
- import { filter } from 'rxjs/operators';
17
+ import { filter, catchError } from 'rxjs/operators';
18
18
  import * as i1$1 from '@valtimo/shared';
19
19
  import { getCaseManagementRouteParams, GlobalNotificationComponent, ROLE_ADMIN } from '@valtimo/shared';
20
20
  import { isEqual, cloneDeep } from 'lodash';
21
21
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
22
22
  import * as i1$2 from '@valtimo/form';
23
+ import * as i2$3 from '@angular/common/http';
23
24
  import { HttpParams } from '@angular/common/http';
24
25
  import * as i2$2 from '@valtimo/document';
25
26
  import * as i3$1 from '@valtimo/access-control';
@@ -91,6 +92,11 @@ var MoveRowDirection;
91
92
  MoveRowDirection["UP"] = "UP";
92
93
  MoveRowDirection["DOWN"] = "DOWN";
93
94
  })(MoveRowDirection || (MoveRowDirection = {}));
95
+ var FilterDropdownDataProvider;
96
+ (function (FilterDropdownDataProvider) {
97
+ FilterDropdownDataProvider["DATABASE"] = "dropdownDatabaseDataProvider";
98
+ FilterDropdownDataProvider["JSON"] = "dropdownJsonFileDataProvider";
99
+ })(FilterDropdownDataProvider || (FilterDropdownDataProvider = {}));
94
100
 
95
101
  /*
96
102
  * Copyright 2015-2025 Ritense BV, the Netherlands.
@@ -1384,23 +1390,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1384
1390
  class WidgetInteractiveTableSearchComponent {
1385
1391
  set initSearchRequest(value) {
1386
1392
  this._initSearchRequest = value ?? {};
1387
- this.setInitialForm();
1388
1393
  }
1389
1394
  set filters(value) {
1390
1395
  this._filters = value ?? [];
1391
- this.buildFiltersFormControls();
1392
- this.setInitialForm();
1396
+ this.rebuildFormControlsPreservingValues();
1397
+ this.loadDropdownItems();
1398
+ this.setInitialForm(this._initSearchRequest ?? {});
1393
1399
  }
1394
1400
  get filters() {
1395
1401
  return this._filters;
1396
1402
  }
1397
- get filtersFormGroup() {
1398
- return this.formGroup.get('filters');
1399
- }
1400
- constructor(cdsThemeService, fb, iconService) {
1403
+ constructor(cdsThemeService, fb, iconService, translateService) {
1401
1404
  this.cdsThemeService = cdsThemeService;
1402
1405
  this.fb = fb;
1403
1406
  this.iconService = iconService;
1407
+ this.translateService = translateService;
1404
1408
  this._initSearchRequest = {};
1405
1409
  this._filters = [];
1406
1410
  this.searchSubmitEvent = new EventEmitter();
@@ -1408,58 +1412,228 @@ class WidgetInteractiveTableSearchComponent {
1408
1412
  this.formGroup = this.fb.group({
1409
1413
  filters: this.fb.group({}),
1410
1414
  });
1415
+ this.dropdownSelectItemsMap = {};
1416
+ this.clear$ = new Subject();
1411
1417
  this._subscriptions = new Subscription();
1418
+ this.BOOLEAN_POSITIVE = 'booleanPositive';
1419
+ this.BOOLEAN_NEGATIVE = 'booleanNegative';
1420
+ this.booleanItems$ = this.translateService
1421
+ .stream([`searchFields.${this.BOOLEAN_POSITIVE}`, `searchFields.${this.BOOLEAN_NEGATIVE}`])
1422
+ .pipe(map(() => [
1423
+ { id: this.BOOLEAN_POSITIVE, text: this.translateService.instant(`searchFields.${this.BOOLEAN_POSITIVE}`) },
1424
+ { id: this.BOOLEAN_NEGATIVE, text: this.translateService.instant(`searchFields.${this.BOOLEAN_NEGATIVE}`) },
1425
+ ]));
1412
1426
  this.iconService.register(TrashCan16);
1413
1427
  }
1414
1428
  ngOnInit() {
1415
- this.buildFiltersFormControls();
1416
- this.setInitialForm();
1429
+ this.rebuildFormControlsPreservingValues();
1430
+ this.setInitialForm(this._initSearchRequest ?? {});
1417
1431
  this._subscriptions.add(this.filtersFormGroup.valueChanges.pipe(debounceTime(500)).subscribe(() => {
1418
- this.searchSubmitEvent.emit(this.mapFormValueToWidgetInteractiveTableSearch());
1432
+ const req = this.mapFormValueToWidgetInteractiveTableSearch();
1433
+ this.searchSubmitEvent.emit(req);
1419
1434
  }));
1435
+ const initialReq = this.mapFormValueToWidgetInteractiveTableSearch();
1436
+ this.searchSubmitEvent.emit(initialReq);
1420
1437
  }
1421
1438
  ngOnDestroy() {
1422
1439
  this._subscriptions.unsubscribe();
1423
1440
  }
1441
+ ngOnChanges(changes) {
1442
+ if (changes['initSearchRequest'] && !changes['initSearchRequest'].firstChange) {
1443
+ this.setInitialForm(this._initSearchRequest ?? {});
1444
+ }
1445
+ }
1446
+ get filtersFormGroup() {
1447
+ return this.formGroup.get('filters');
1448
+ }
1424
1449
  onClearFilter() {
1425
1450
  this.filtersFormGroup.reset(this.getDefaultFilterValues());
1451
+ this.clear$.next();
1452
+ this.searchSubmitEvent.emit({});
1426
1453
  }
1427
- buildFiltersFormControls() {
1454
+ singleValueChange(controlKey, value) {
1455
+ const control = this.filtersFormGroup.get(controlKey);
1456
+ if (!control)
1457
+ return;
1458
+ control.setValue(value);
1459
+ }
1460
+ rangeValueChange(filterKey, value) {
1461
+ this.filtersFormGroup.patchValue({
1462
+ [`${filterKey}_start`]: value?.start ?? '',
1463
+ [`${filterKey}_end`]: value?.end ?? '',
1464
+ }, { emitEvent: true });
1465
+ }
1466
+ rebuildFormControlsPreservingValues() {
1467
+ const snapshot = (this.filtersFormGroup.getRawValue() ?? {});
1468
+ const expectedKeys = new Set();
1428
1469
  this.filters.forEach((filter) => {
1429
- if (!this.filtersFormGroup.get(filter.key)) {
1430
- this.filtersFormGroup.addControl(filter.key, this.fb.control(''));
1470
+ if (filter.fieldType === 'range') {
1471
+ expectedKeys.add(`${filter.key}_start`);
1472
+ expectedKeys.add(`${filter.key}_end`);
1473
+ return;
1474
+ }
1475
+ expectedKeys.add(filter.key);
1476
+ });
1477
+ Object.keys(this.filtersFormGroup.controls).forEach(controlKey => {
1478
+ if (!expectedKeys.has(controlKey)) {
1479
+ this.filtersFormGroup.removeControl(controlKey);
1431
1480
  }
1432
1481
  });
1482
+ this.filters.forEach((filter) => {
1483
+ if (filter.fieldType === 'range') {
1484
+ this.ensureControl(`${filter.key}_start`, '');
1485
+ this.ensureControl(`${filter.key}_end`, '');
1486
+ return;
1487
+ }
1488
+ if (this.isDropdownField(filter) || filter.dataType === 'boolean') {
1489
+ const initialValue = filter.fieldType === 'multi-select-dropdown' ? [] : '';
1490
+ this.ensureControl(filter.key, initialValue);
1491
+ return;
1492
+ }
1493
+ this.ensureControl(filter.key, '');
1494
+ });
1495
+ const toRestore = {};
1496
+ expectedKeys.forEach(k => {
1497
+ if (snapshot[k] !== undefined)
1498
+ toRestore[k] = snapshot[k];
1499
+ });
1500
+ if (Object.keys(toRestore).length) {
1501
+ this.filtersFormGroup.patchValue(toRestore, { emitEvent: false });
1502
+ }
1503
+ }
1504
+ ensureControl(key, initialValue = '') {
1505
+ if (!this.filtersFormGroup.get(key)) {
1506
+ this.filtersFormGroup.addControl(key, this.fb.control(initialValue));
1507
+ }
1433
1508
  }
1434
1509
  getDefaultFilterValues() {
1435
- return Object.fromEntries(this.filters.map(filter => [filter.key, '']));
1510
+ const defaults = {};
1511
+ this.filters.forEach(filter => {
1512
+ if (filter.fieldType === 'range') {
1513
+ defaults[`${filter.key}_start`] = '';
1514
+ defaults[`${filter.key}_end`] = '';
1515
+ return;
1516
+ }
1517
+ if (this.isDropdownField(filter) || filter.dataType === 'boolean') {
1518
+ defaults[filter.key] = filter.fieldType === 'multi-select-dropdown' ? [] : '';
1519
+ return;
1520
+ }
1521
+ defaults[filter.key] = '';
1522
+ });
1523
+ return defaults;
1524
+ }
1525
+ setInitialForm(searchRequest) {
1526
+ const mapped = this.mapSearchRequestToFormValue(searchRequest);
1527
+ this.filtersFormGroup.reset(this.getDefaultFilterValues(), { emitEvent: false });
1528
+ if (mapped.filters) {
1529
+ this.filtersFormGroup.patchValue(mapped.filters, { emitEvent: false });
1530
+ }
1436
1531
  }
1437
1532
  mapFormValueToWidgetInteractiveTableSearch() {
1438
- const formValue = this.formGroup.getRawValue();
1533
+ const rawFilters = (this.formGroup.getRawValue().filters ?? {});
1439
1534
  const filters = {};
1440
- for (const key in formValue.filters) {
1441
- if (formValue.filters[key]) {
1442
- filters[key] = formValue.filters[key];
1535
+ for (const filter of this.filters) {
1536
+ if (filter.fieldType === 'range') {
1537
+ const start = rawFilters[`${filter.key}_start`];
1538
+ const end = rawFilters[`${filter.key}_end`];
1539
+ const hasStart = this.hasValue(start);
1540
+ const hasEnd = this.hasValue(end);
1541
+ if (hasStart || hasEnd) {
1542
+ filters[filter.key] = JSON.stringify({
1543
+ rangeFrom: hasStart ? this.normalizeValue(start, filter.dataType) : null,
1544
+ rangeTo: hasEnd ? this.normalizeValue(end, filter.dataType) : null,
1545
+ });
1546
+ }
1547
+ continue;
1443
1548
  }
1549
+ const value = rawFilters[filter.key];
1550
+ if (!this.hasValue(value))
1551
+ continue;
1552
+ filters[filter.key] = this.normalizeValue(value, filter.dataType);
1444
1553
  }
1445
1554
  return {
1446
1555
  ...(Object.keys(filters).length && { filters }),
1447
1556
  };
1448
1557
  }
1449
1558
  mapSearchRequestToFormValue(searchRequest) {
1450
- return {
1451
- ...(searchRequest.filters && { filters: searchRequest.filters }),
1452
- };
1559
+ const result = {};
1560
+ const search = (searchRequest.filters ?? {});
1561
+ for (const filter of this.filters) {
1562
+ if (filter.fieldType === 'range') {
1563
+ const raw = search[filter.key];
1564
+ if (typeof raw === 'string') {
1565
+ try {
1566
+ const parsed = JSON.parse(raw);
1567
+ result[`${filter.key}_start`] = parsed?.rangeFrom ?? '';
1568
+ result[`${filter.key}_end`] = parsed?.rangeTo ?? '';
1569
+ }
1570
+ catch {
1571
+ result[`${filter.key}_start`] = '';
1572
+ result[`${filter.key}_end`] = '';
1573
+ }
1574
+ }
1575
+ continue;
1576
+ }
1577
+ const raw = search[filter.key];
1578
+ if (raw === undefined)
1579
+ continue;
1580
+ if (filter.dataType === 'boolean') {
1581
+ if (raw === true || raw === 'true')
1582
+ result[filter.key] = this.BOOLEAN_POSITIVE;
1583
+ else if (raw === false || raw === 'false')
1584
+ result[filter.key] = this.BOOLEAN_NEGATIVE;
1585
+ else if (raw === this.BOOLEAN_POSITIVE || raw === this.BOOLEAN_NEGATIVE)
1586
+ result[filter.key] = raw;
1587
+ else
1588
+ result[filter.key] = '';
1589
+ continue;
1590
+ }
1591
+ result[filter.key] = raw;
1592
+ }
1593
+ return Object.keys(result).length ? { filters: result } : {};
1453
1594
  }
1454
- setInitialForm() {
1455
- const mappedFormValue = this.mapSearchRequestToFormValue(this._initSearchRequest);
1456
- this.filtersFormGroup.reset(this.getDefaultFilterValues(), { emitEvent: false });
1457
- if (mappedFormValue.filters) {
1458
- this.filtersFormGroup.patchValue(this.mapSearchRequestToFormValue(this._initSearchRequest).filters, { emitEvent: false });
1595
+ normalizeValue(value, dataType) {
1596
+ if (Array.isArray(value)) {
1597
+ return value
1598
+ .map(entry => this.normalizeValue(entry, dataType))
1599
+ .filter(entry => entry !== null && entry !== undefined);
1600
+ }
1601
+ if (value && typeof value === 'object' && 'id' in value) {
1602
+ value = value.id;
1603
+ }
1604
+ if (dataType === 'boolean') {
1605
+ if (value === this.BOOLEAN_POSITIVE)
1606
+ return true;
1607
+ if (value === this.BOOLEAN_NEGATIVE)
1608
+ return false;
1609
+ if (value === true || value === false)
1610
+ return value;
1611
+ return null;
1459
1612
  }
1613
+ return value;
1614
+ }
1615
+ hasValue(value) {
1616
+ if (value === null || value === undefined)
1617
+ return false;
1618
+ if (typeof value === 'string')
1619
+ return value.trim().length > 0;
1620
+ if (Array.isArray(value))
1621
+ return value.length > 0;
1622
+ return true;
1623
+ }
1624
+ isDropdownField(filter) {
1625
+ return ['single-select-dropdown', 'multi-select-dropdown'].includes(filter.fieldType);
1626
+ }
1627
+ loadDropdownItems() {
1628
+ this.filters
1629
+ .filter(f => this.isDropdownField(f) && !!f.dropdownDataProvider && !!f.key)
1630
+ .forEach(filter => {
1631
+ const dropdownEntries = Object.entries(filter.dropdownValues ?? {});
1632
+ this.dropdownSelectItemsMap[filter.key] = dropdownEntries.map(([id, text]) => ({ id, text }));
1633
+ });
1460
1634
  }
1461
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableSearchComponent, deps: [{ token: i1.CdsThemeService }, { token: i1$3.FormBuilder }, { token: i3.IconService }], target: i0.ɵɵFactoryTarget.Component }); }
1462
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetInteractiveTableSearchComponent, isStandalone: true, selector: "valtimo-widget-interactive-table-search", inputs: { initSearchRequest: "initSearchRequest", filters: "filters" }, outputs: { searchSubmitEvent: "searchSubmitEvent" }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n<form\n *ngIf=\"theme$ | async as theme\"\n class=\"valtimo-widget-interactive-table-search\"\n [formGroup]=\"formGroup\"\n (click)=\"$event.stopImmediatePropagation()\"\n>\n <section class=\"valtimo-widget-interactive-table-search__fields\" formGroupName=\"filters\">\n @for (filter of filters; track filter.key) {\n <cds-text-label class=\"valtimo-widget-interactive-table-search__filter-field\">\n {{ filter.title }}\n\n <input\n cdsText\n [attr.data-carbon-theme]=\"theme\"\n [formControlName]=\"filter.key\"\n [placeholder]=\"filter.title\"\n />\n </cds-text-label>\n }\n </section>\n\n <button cdsButton=\"tertiary\" type=\"button\" (click)=\"onClearFilter()\">\n {{ 'interface.clear' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n</form>\n", styles: [".valtimo-widget-interactive-table-search{display:flex;flex-direction:column;width:360px;padding:16px}.valtimo-widget-interactive-table-search__fields{display:grid;grid-template-columns:repeat(2,1fr);align-items:flex-end;margin-bottom:16px;gap:16px}.valtimo-widget-interactive-table-search__filter-field{width:100%;display:flex;flex-direction:column}.valtimo-widget-interactive-table-search__label{font-size:var(--cds-label-01-font-size);color:var(--widget-text-color, var(--cds-text-secondary))}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: InputModule }, { kind: "component", type: i3.TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid"] }, { kind: "directive", type: i3.TextInput, selector: "[cdsText], [ibmText]", inputs: ["theme", "size", "invalid", "warn", "skeleton"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1635
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableSearchComponent, deps: [{ token: i1.CdsThemeService }, { token: i1$3.FormBuilder }, { token: i3.IconService }, { token: i2$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
1636
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetInteractiveTableSearchComponent, isStandalone: true, selector: "valtimo-widget-interactive-table-search", inputs: { initSearchRequest: "initSearchRequest", filters: "filters" }, outputs: { searchSubmitEvent: "searchSubmitEvent" }, usesOnChanges: true, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n<form\n *ngIf=\"theme$ | async as theme\"\n class=\"valtimo-widget-interactive-table-search\"\n [formGroup]=\"formGroup\"\n (click)=\"$event.stopPropagation()\"\n>\n <section class=\"valtimo-widget-interactive-table-search__fields\" formGroupName=\"filters\">\n @for (filter of filters; track filter.key) {\n <cds-text-label\n class=\"valtimo-widget-interactive-table-search__filter-field\"\n [ngClass]=\"{\n 'valtimo-widget-interactive-table-search__filter-field--range': filter.fieldType === 'range'\n }\"\n >\n <v-input-label *ngIf=\"filter.title\" [title]=\"filter.title\"></v-input-label>\n\n @if (filter.dataType === 'text' && filter.fieldType === 'single') {\n <v-input\n [dataTestId]=\"'widget-interactive-table-filter-' + filter.key\"\n [name]=\"filter.key\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [defaultValue]=\"filtersFormGroup.get(filter.key)?.value\"\n [fullWidth]=\"true\"\n [carbonTheme]=\"'g100'\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></v-input>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'range') {\n <v-form className=\"multiple-search-fields\" (valueChange)=\"rangeValueChange(filter.key, $event)\">\n <v-input\n name=\"start\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_start')?.value\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <v-input\n name=\"end\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_end')?.value\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n </v-form>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'single-select-dropdown') {\n <v-select\n [items]=\"dropdownSelectItemsMap[filter.key]\"\n [formControlName]=\"filter.key\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [appendInline]=\"true\"\n ></v-select>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'multi-select-dropdown') {\n <v-select\n [items]=\"dropdownSelectItemsMap[filter.key]\"\n [formControlName]=\"filter.key\"\n [multiple]=\"true\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [appendInline]=\"true\"\n ></v-select>\n }\n @else if (filter.dataType === 'number' && filter.fieldType === 'single') {\n <v-input\n type=\"number\"\n [hideNumberSpinBox]=\"true\"\n [name]=\"filter.key\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [defaultValue]=\"filtersFormGroup.get(filter.key)?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></v-input>\n }\n @else if (filter.dataType === 'number' && filter.fieldType === 'range') {\n <v-form className=\"multiple-search-fields\" (valueChange)=\"rangeValueChange(filter.key, $event)\">\n <v-input\n type=\"number\"\n name=\"start\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_start')?.value\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <v-input\n type=\"number\"\n name=\"end\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_end')?.value\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n </v-form>\n }\n @else if (filter.dataType === 'boolean' && filter.fieldType === 'single') {\n <v-select\n *ngIf=\"booleanItems$ | async as booleanItems\"\n [items]=\"booleanItems\"\n [formControlName]=\"filter.key\"\n [clearSelectionSubject$]=\"clear$\"\n ></v-select>\n }\n @else if (filter.dataType === 'time' && filter.fieldType === 'single') {\n <cds-timepicker\n [placeholder]=\"'searchFields.timePlaceholder' | translate\"\n [formControlName]=\"filter.key\"\n ></cds-timepicker>\n }\n @else if (filter.dataType === 'time' && filter.fieldType === 'range') {\n <cds-timepicker [formControlName]=\"filter.key + '_start'\"></cds-timepicker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <cds-timepicker [formControlName]=\"filter.key + '_end'\"></cds-timepicker>\n }\n @else if (filter.dataType === 'date' && filter.fieldType === 'single') {\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key)?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></valtimo-date-time-picker>\n }\n @else if (filter.dataType === 'date' && filter.fieldType === 'range') {\n <div class=\"multiple-search-fields\">\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_start')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_start', $event)\"\n ></valtimo-date-time-picker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_end')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_end', $event)\"\n ></valtimo-date-time-picker>\n </div>\n }\n @else if (filter.dataType === 'datetime' && filter.fieldType === 'single') {\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key)?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></valtimo-date-time-picker>\n }\n @else if (filter.dataType === 'datetime' && filter.fieldType === 'range') {\n <div class=\"multiple-search-fields multiple-search-fields--stacked\">\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_start')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_start', $event)\"\n ></valtimo-date-time-picker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_end')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_end', $event)\"\n ></valtimo-date-time-picker>\n </div>\n }\n </cds-text-label>\n }\n </section>\n\n <button cdsButton=\"tertiary\" type=\"button\" (click)=\"onClearFilter()\">\n {{ 'interface.clear' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n</form>\n", styles: [".valtimo-widget-interactive-table-search{display:flex;flex-direction:column;gap:16px;padding:16px;max-width:420px;max-height:300px;overflow-y:scroll}.valtimo-widget-interactive-table-search__fields{display:grid;gap:16px;grid-template-columns:repeat(2,1fr);align-items:flex-end}.valtimo-widget-interactive-table-search__datetime{align-items:flex-end}.valtimo-widget-interactive-table-search__filter-field{width:100%;display:flex;flex-direction:column;min-width:0}.valtimo-widget-interactive-table-search__filter-field--range{grid-column:1/-1}.valtimo-widget-interactive-table-search__label{font-size:var(--cds-label-01-font-size);color:var(--widget-text-color, var(--cds-text-secondary))}::ng-deep .multiple-search-fields{display:flex!important;flex-direction:row!important;align-items:center!important}.to-text{margin-inline-start:8px;margin-inline-end:8px}::ng-deep .cds--date-picker.cds--date-picker--single .cds--date-picker__input{inline-size:unset!important;width:180px!important}::ng-deep v-input input{background-color:var(--cds-layer-02)!important}::ng-deep v-select input{background-color:var(--cds-layer-02)!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important;max-height:max-content!important;height:max-content!important}::ng-deep .multiple-search-fields--stacked{flex-direction:column!important;align-items:stretch!important;gap:8px!important}.to-text--stacked{margin-inline-start:0;margin-inline-end:0}::ng-deep .cds--list-box__field{background-color:var(--cds-layer-02)!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: InputModule }, { kind: "component", type: i3.TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: InputLabelModule }, { kind: "component", type: i1.InputLabelComponent, selector: "v-input-label", inputs: ["name", "tooltip", "tooltipTranslationKey", "largeMargin", "small", "noMargin", "title", "titleTranslationKey", "required", "disabled", "carbonTheme"] }, { kind: "ngmodule", type: TimePickerModule }, { kind: "component", type: i3.TimePicker, selector: "cds-timepicker, ibm-timepicker", inputs: ["invalid", "invalidText", "label", "hideLabel", "placeholder", "pattern", "id", "disabled", "value", "maxLength", "skeleton", "theme", "size"], outputs: ["valueChange"] }, { kind: "ngmodule", type: InputModule$1 }, { kind: "component", type: i1.InputComponent, selector: "v-input", inputs: ["name", "type", "title", "titleTranslationKey", "defaultValue", "widthPx", "fullWidth", "margin", "smallMargin", "disabled", "step", "min", "maxLength", "tooltip", "required", "hideNumberSpinBox", "smallLabel", "rows", "clear$", "carbonTheme", "placeholder", "dataTestId", "trim", "presetsTitle", "presetOptions"], outputs: ["valueChange"] }, { kind: "ngmodule", type: FormModule }, { kind: "component", type: i1.FormComponent, selector: "v-form", inputs: ["className"], outputs: ["valueChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i1.SelectComponent, selector: "v-select", inputs: ["items", "defaultSelection", "defaultSelectionId", "defaultSelectionIds", "disabled", "dropUp", "invalid", "multiple", "margin", "widthInPx", "notFoundText", "clearAllText", "clearText", "clearable", "name", "title", "titleTranslationKey", "clearSelectionSubject$", "tooltip", "required", "loading", "loadingText", "placeholder", "smallMargin", "carbonTheme", "appendInline", "warn", "warnText", "dataTestId"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: ParagraphModule }, { kind: "component", type: i1.ParagraphComponent, selector: "v-paragraph", inputs: ["center", "fullWidth", "margin", "italic", "loading", "dataTestId"] }, { kind: "component", type: DateTimePickerComponent, selector: "valtimo-date-time-picker", inputs: ["fullWidth", "margin", "name", "title", "placeholder", "titleTranslationKey", "disabled", "tooltip", "required", "smallLabel", "enableTime", "carbonTheme", "dateFormat", "showFieldLabel", "datePlaceholder", "timePlaceholder", "labelText", "defaultDate", "defaultDateIsToday", "clear$"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1463
1637
  }
1464
1638
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableSearchComponent, decorators: [{
1465
1639
  type: Component,
@@ -1471,8 +1645,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1471
1645
  InputModule,
1472
1646
  ReactiveFormsModule,
1473
1647
  FormsModule,
1474
- ], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n<form\n *ngIf=\"theme$ | async as theme\"\n class=\"valtimo-widget-interactive-table-search\"\n [formGroup]=\"formGroup\"\n (click)=\"$event.stopImmediatePropagation()\"\n>\n <section class=\"valtimo-widget-interactive-table-search__fields\" formGroupName=\"filters\">\n @for (filter of filters; track filter.key) {\n <cds-text-label class=\"valtimo-widget-interactive-table-search__filter-field\">\n {{ filter.title }}\n\n <input\n cdsText\n [attr.data-carbon-theme]=\"theme\"\n [formControlName]=\"filter.key\"\n [placeholder]=\"filter.title\"\n />\n </cds-text-label>\n }\n </section>\n\n <button cdsButton=\"tertiary\" type=\"button\" (click)=\"onClearFilter()\">\n {{ 'interface.clear' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n</form>\n", styles: [".valtimo-widget-interactive-table-search{display:flex;flex-direction:column;width:360px;padding:16px}.valtimo-widget-interactive-table-search__fields{display:grid;grid-template-columns:repeat(2,1fr);align-items:flex-end;margin-bottom:16px;gap:16px}.valtimo-widget-interactive-table-search__filter-field{width:100%;display:flex;flex-direction:column}.valtimo-widget-interactive-table-search__label{font-size:var(--cds-label-01-font-size);color:var(--widget-text-color, var(--cds-text-secondary))}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
1475
- }], ctorParameters: () => [{ type: i1.CdsThemeService }, { type: i1$3.FormBuilder }, { type: i3.IconService }], propDecorators: { initSearchRequest: [{
1648
+ InputLabelModule,
1649
+ TimePickerModule,
1650
+ InputModule$1,
1651
+ FormModule,
1652
+ SelectModule,
1653
+ ParagraphModule,
1654
+ DateTimePickerComponent,
1655
+ ], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n<form\n *ngIf=\"theme$ | async as theme\"\n class=\"valtimo-widget-interactive-table-search\"\n [formGroup]=\"formGroup\"\n (click)=\"$event.stopPropagation()\"\n>\n <section class=\"valtimo-widget-interactive-table-search__fields\" formGroupName=\"filters\">\n @for (filter of filters; track filter.key) {\n <cds-text-label\n class=\"valtimo-widget-interactive-table-search__filter-field\"\n [ngClass]=\"{\n 'valtimo-widget-interactive-table-search__filter-field--range': filter.fieldType === 'range'\n }\"\n >\n <v-input-label *ngIf=\"filter.title\" [title]=\"filter.title\"></v-input-label>\n\n @if (filter.dataType === 'text' && filter.fieldType === 'single') {\n <v-input\n [dataTestId]=\"'widget-interactive-table-filter-' + filter.key\"\n [name]=\"filter.key\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [defaultValue]=\"filtersFormGroup.get(filter.key)?.value\"\n [fullWidth]=\"true\"\n [carbonTheme]=\"'g100'\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></v-input>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'range') {\n <v-form className=\"multiple-search-fields\" (valueChange)=\"rangeValueChange(filter.key, $event)\">\n <v-input\n name=\"start\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_start')?.value\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <v-input\n name=\"end\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_end')?.value\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n </v-form>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'single-select-dropdown') {\n <v-select\n [items]=\"dropdownSelectItemsMap[filter.key]\"\n [formControlName]=\"filter.key\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [appendInline]=\"true\"\n ></v-select>\n }\n @else if (filter.dataType === 'text' && filter.fieldType === 'multi-select-dropdown') {\n <v-select\n [items]=\"dropdownSelectItemsMap[filter.key]\"\n [formControlName]=\"filter.key\"\n [multiple]=\"true\"\n [placeholder]=\"'searchFields.textPlaceholder' | translate\"\n [appendInline]=\"true\"\n ></v-select>\n }\n @else if (filter.dataType === 'number' && filter.fieldType === 'single') {\n <v-input\n type=\"number\"\n [hideNumberSpinBox]=\"true\"\n [name]=\"filter.key\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [defaultValue]=\"filtersFormGroup.get(filter.key)?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></v-input>\n }\n @else if (filter.dataType === 'number' && filter.fieldType === 'range') {\n <v-form className=\"multiple-search-fields\" (valueChange)=\"rangeValueChange(filter.key, $event)\">\n <v-input\n type=\"number\"\n name=\"start\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_start')?.value\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <v-input\n type=\"number\"\n name=\"end\"\n [defaultValue]=\"filtersFormGroup.get(filter.key + '_end')?.value\"\n [placeholder]=\"'searchFields.numberPlaceholder' | translate\"\n [fullWidth]=\"true\"\n ></v-input>\n </v-form>\n }\n @else if (filter.dataType === 'boolean' && filter.fieldType === 'single') {\n <v-select\n *ngIf=\"booleanItems$ | async as booleanItems\"\n [items]=\"booleanItems\"\n [formControlName]=\"filter.key\"\n [clearSelectionSubject$]=\"clear$\"\n ></v-select>\n }\n @else if (filter.dataType === 'time' && filter.fieldType === 'single') {\n <cds-timepicker\n [placeholder]=\"'searchFields.timePlaceholder' | translate\"\n [formControlName]=\"filter.key\"\n ></cds-timepicker>\n }\n @else if (filter.dataType === 'time' && filter.fieldType === 'range') {\n <cds-timepicker [formControlName]=\"filter.key + '_start'\"></cds-timepicker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <cds-timepicker [formControlName]=\"filter.key + '_end'\"></cds-timepicker>\n }\n @else if (filter.dataType === 'date' && filter.fieldType === 'single') {\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key)?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></valtimo-date-time-picker>\n }\n @else if (filter.dataType === 'date' && filter.fieldType === 'range') {\n <div class=\"multiple-search-fields\">\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_start')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_start', $event)\"\n ></valtimo-date-time-picker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_end')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"false\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_end', $event)\"\n ></valtimo-date-time-picker>\n </div>\n }\n @else if (filter.dataType === 'datetime' && filter.fieldType === 'single') {\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key)?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key, $event)\"\n ></valtimo-date-time-picker>\n }\n @else if (filter.dataType === 'datetime' && filter.fieldType === 'range') {\n <div class=\"multiple-search-fields multiple-search-fields--stacked\">\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_start')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_start', $event)\"\n ></valtimo-date-time-picker>\n\n <div class=\"to-text\">\n <v-paragraph>{{ 'searchFields.to' | translate }}</v-paragraph>\n </div>\n\n <valtimo-date-time-picker\n [defaultDate]=\"filtersFormGroup.get(filter.key + '_end')?.value ?? ''\"\n [clear$]=\"clear$\"\n [enableTime]=\"true\"\n [showFieldLabel]=\"false\"\n (valueChange)=\"singleValueChange(filter.key + '_end', $event)\"\n ></valtimo-date-time-picker>\n </div>\n }\n </cds-text-label>\n }\n </section>\n\n <button cdsButton=\"tertiary\" type=\"button\" (click)=\"onClearFilter()\">\n {{ 'interface.clear' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n</form>\n", styles: [".valtimo-widget-interactive-table-search{display:flex;flex-direction:column;gap:16px;padding:16px;max-width:420px;max-height:300px;overflow-y:scroll}.valtimo-widget-interactive-table-search__fields{display:grid;gap:16px;grid-template-columns:repeat(2,1fr);align-items:flex-end}.valtimo-widget-interactive-table-search__datetime{align-items:flex-end}.valtimo-widget-interactive-table-search__filter-field{width:100%;display:flex;flex-direction:column;min-width:0}.valtimo-widget-interactive-table-search__filter-field--range{grid-column:1/-1}.valtimo-widget-interactive-table-search__label{font-size:var(--cds-label-01-font-size);color:var(--widget-text-color, var(--cds-text-secondary))}::ng-deep .multiple-search-fields{display:flex!important;flex-direction:row!important;align-items:center!important}.to-text{margin-inline-start:8px;margin-inline-end:8px}::ng-deep .cds--date-picker.cds--date-picker--single .cds--date-picker__input{inline-size:unset!important;width:180px!important}::ng-deep v-input input{background-color:var(--cds-layer-02)!important}::ng-deep v-select input{background-color:var(--cds-layer-02)!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important;max-height:max-content!important;height:max-content!important}::ng-deep .multiple-search-fields--stacked{flex-direction:column!important;align-items:stretch!important;gap:8px!important}.to-text--stacked{margin-inline-start:0;margin-inline-end:0}::ng-deep .cds--list-box__field{background-color:var(--cds-layer-02)!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
1656
+ }], ctorParameters: () => [{ type: i1.CdsThemeService }, { type: i1$3.FormBuilder }, { type: i3.IconService }, { type: i2$1.TranslateService }], propDecorators: { initSearchRequest: [{
1476
1657
  type: Input
1477
1658
  }], filters: [{
1478
1659
  type: Input
@@ -1481,7 +1662,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1481
1662
  }] } });
1482
1663
 
1483
1664
  /*
1484
- * Copyright 2015-2025 Ritense BV, the Netherlands.
1665
+ * Copyright 2015-2026 Ritense BV, the Netherlands.
1485
1666
  *
1486
1667
  * Licensed under EUPL, Version 1.2 (the "License");
1487
1668
  * you may not use this file except in compliance with the License.
@@ -1675,7 +1856,7 @@ class WidgetInteractiveTableComponent {
1675
1856
  this.searchSubmitEvent.emit(searchRequest);
1676
1857
  }
1677
1858
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i2$2.DocumentService }, { token: i3.IconService }], target: i0.ɵɵFactoryTarget.Component }); }
1678
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetInteractiveTableComponent, isStandalone: true, selector: "valtimo-widget-interactive-table", inputs: { widgetConfiguration: "widgetConfiguration", widgetData: "widgetData", searchRequest: "searchRequest" }, outputs: { paginationEvent: "paginationEvent", rowClickEvent: "rowClickEvent", actionEvent: "actionEvent", caseStartEvent: "caseStartEvent", queryParamsEvent: "queryParamsEvent", searchSubmitEvent: "searchSubmitEvent" }, host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<ng-container\n *ngIf=\"{\n fields: fields$ | async,\n widgetData: widgetData$ | async,\n caseDefinitions: caseDefinitions$ | async,\n filters: filters$ | async,\n } as obs\"\n>\n <div class=\"valtimo-widget-interactive-table__title-container\">\n <valtimo-mdi-icon-viewer\n *ngIf=\"widgetConfiguration?.icon\"\n [mdiIcon]=\"widgetConfiguration.icon\"\n ></valtimo-mdi-icon-viewer>\n\n <span class=\"widget-title\">{{ widgetConfiguration?.title }}</span>\n </div>\n\n <valtimo-carbon-list\n [header]=\"false\"\n [fields]=\"obs.fields\"\n [items]=\"obs.widgetData || []\"\n [initialSortState]=\"$initialSortState()\"\n [loading]=\"obs.widgetData === null\"\n [skeletonRowCount]=\"widgetConfiguration?.properties?.defaultPageSize || 5\"\n [pagination]=\"$paginationModel()\"\n [paginatorConfig]=\"$paginatorConfig()\"\n (paginationClicked)=\"onPaginationClicked($event)\"\n (paginationSet)=\"onPaginationSet($event)\"\n (sortChanged)=\"onSortChanged($event)\"\n (rowClicked)=\"rowClick($event)\"\n >\n <section class=\"valtimo-widget-interactive-table__header\" carbonToolbarContent>\n <button\n *ngIf=\"!!obs.filters.length\"\n carbonToolbarContent\n [cdsOverflowMenu]=\"widgetInteractiveTableSearch\"\n [customPane]=\"true\"\n [iconOnly]=\"true\"\n [flip]=\"true\"\n [offset]=\"{x: 0, y: 47}\"\n placement=\"bottom\"\n cdsButton=\"ghost\"\n >\n <svg cdsIcon=\"filter\" size=\"16\"></svg>\n </button>\n\n <cds-overflow-menu\n *ngIf=\"!!widgetConfiguration?.actions?.length\"\n [customTrigger]=\"externalLinkTrigger\"\n placement=\"bottom\"\n flip=\"true\"\n [offset]=\"{x: 4, y: 44}\"\n >\n @for (action of widgetConfiguration?.actions; track action.name) {\n <cds-overflow-menu-option (click)=\"onActionClick(action)\">\n {{ action.name }}\n </cds-overflow-menu-option>\n }\n </cds-overflow-menu>\n\n <cds-menu-button\n *ngIf=\"widgetConfiguration?.properties?.canStartCase\"\n [label]=\"'Start Case' | translate\"\n >\n @for (definition of obs.caseDefinitions; track definition.caseDefinitionKey) {\n <cds-menu-item\n [label]=\"definition.name\"\n (click)=\"onCaseStart(definition)\"\n ></cds-menu-item>\n }\n </cds-menu-button>\n </section>\n\n <valtimo-no-results\n *ngIf=\"obs.widgetData !== null\"\n [collapseVertically]=\"true\"\n [description]=\"'widgets.noData' | translate\"\n [smallPadding]=\"true\"\n ></valtimo-no-results>\n </valtimo-carbon-list>\n\n <ng-template #widgetInteractiveTableSearch>\n <valtimo-widget-interactive-table-search\n [filters]=\"obs.filters\"\n [initSearchRequest]=\"searchRequest\"\n (searchSubmitEvent)=\"onSearchSubmit($event)\"\n ></valtimo-widget-interactive-table-search>\n </ng-template>\n\n <ng-template #externalLinkTrigger>\n <button cdsButton=\"ghost\" iconOnly=\"true\">\n <svg cdsIcon=\"link\" size=\"16\"></svg>\n </button>\n </ng-template>\n</ng-container>\n", styles: [".valtimo-widget-interactive-table{display:flex;flex-direction:column;height:100%}.valtimo-widget-interactive-table__header{display:flex;align-items:center;justify-content:flex-end;width:100%}.valtimo-widget-interactive-table__title-container{display:flex;align-items:center;gap:8px;padding:12px 0 0 16px}.valtimo-widget-interactive-table__content{display:flex;align-items:center;flex-direction:column}.valtimo-widget-interactive-table valtimo-carbon-list,.valtimo-widget-interactive-table cds-table-container{width:100%;height:100%}.valtimo-widget-interactive-table cds-table{height:calc(100% - 88px)}.valtimo-widget-interactive-table .widget-title{color:var(--widget-text-color, var(--cds-text-primary));font-weight:600;font-size:16px;line-height:24px}.cds--menu-item__label{overflow:unset!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: CarbonListModule }, { kind: "component", type: i1.CarbonListComponent, selector: "valtimo-carbon-list", inputs: ["items", "fields", "tableTranslations", "paginatorConfig", "pagination", "loading", "skeletonRowCount", "actions", "actionItems", "showActionItems", "header", "hideColumnHeader", "initialSortState", "sortState", "isSearchable", "enableSingleSelection", "lastColumnTemplate", "paginationIdentifier", "showSelectionColumn", "striped", "hideToolbar", "lockedTooltipTranslationKey", "movingRowsEnabled", "dragAndDrop", "dragAndDropDisabled"], outputs: ["rowClicked", "paginationClicked", "paginationSet", "search", "sortChanged", "moveRow", "itemsReordered"] }, { kind: "component", type: i1.CarbonNoResultsComponent, selector: "valtimo-no-results", inputs: ["action", "description", "illustration", "title", "smallPadding", "collapseVertically", "alwaysRenderVertically"] }, { kind: "ngmodule", type: PaginationModule }, { kind: "ngmodule", type: TilesModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.OverflowMenu, selector: "cds-overflow-menu, ibm-overflow-menu", inputs: ["buttonLabel", "description", "flip", "placement", "open", "customTrigger", "offset", "wrapperClass", "triggerClass"], outputs: ["openChange"] }, { kind: "directive", type: i3.OverflowMenuDirective, selector: "[cdsOverflowMenu], [ibmOverflowMenu]", inputs: ["ibmOverflowMenu", "cdsOverflowMenu", "flip", "offset", "wrapperClass", "customPane"], exportAs: ["overflowMenu"] }, { kind: "component", type: i3.OverflowMenuOption, selector: "cds-overflow-menu-option, ibm-overflow-menu-option", inputs: ["divider", "type", "disabled", "href", "target", "innerClass"], outputs: ["selected"] }, { kind: "ngmodule", type: MenuButtonModule }, { kind: "component", type: i3.MenuButtonComponent, selector: "cds-menu-button", inputs: ["menuId", "kind", "size", "menuAlignment", "buttonTabIndex", "disabled", "open", "label"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i3.ContextMenuItemComponent, selector: "cds-menu-item, cds-context-menu-item, ibm-context-menu-item", inputs: ["disabled", "danger", "label", "info", "type", "checked", "icon", "value"], outputs: ["checkedChange", "itemClick"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: MdiIconViewerComponent, selector: "valtimo-mdi-icon-viewer", inputs: ["mdiIcon"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: WidgetInteractiveTableSearchComponent, selector: "valtimo-widget-interactive-table-search", inputs: ["initSearchRequest", "filters"], outputs: ["searchSubmitEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1859
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetInteractiveTableComponent, isStandalone: true, selector: "valtimo-widget-interactive-table", inputs: { widgetConfiguration: "widgetConfiguration", widgetData: "widgetData", searchRequest: "searchRequest" }, outputs: { paginationEvent: "paginationEvent", rowClickEvent: "rowClickEvent", actionEvent: "actionEvent", caseStartEvent: "caseStartEvent", queryParamsEvent: "queryParamsEvent", searchSubmitEvent: "searchSubmitEvent" }, host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2026 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<ng-container\n *ngIf=\"{\n fields: fields$ | async,\n widgetData: widgetData$ | async,\n caseDefinitions: caseDefinitions$ | async,\n filters: filters$ | async,\n } as obs\"\n>\n <div class=\"valtimo-widget-interactive-table__title-container\">\n <valtimo-mdi-icon-viewer\n *ngIf=\"widgetConfiguration?.icon\"\n [mdiIcon]=\"widgetConfiguration.icon\"\n ></valtimo-mdi-icon-viewer>\n\n <span class=\"widget-title\">{{ widgetConfiguration?.title }}</span>\n </div>\n\n <valtimo-carbon-list\n [header]=\"false\"\n [fields]=\"obs.fields\"\n [items]=\"obs.widgetData || []\"\n [initialSortState]=\"$initialSortState()\"\n [loading]=\"obs.widgetData === null\"\n [skeletonRowCount]=\"widgetConfiguration?.properties?.defaultPageSize || 5\"\n [pagination]=\"$paginationModel()\"\n [paginatorConfig]=\"$paginatorConfig()\"\n (paginationClicked)=\"onPaginationClicked($event)\"\n (paginationSet)=\"onPaginationSet($event)\"\n (sortChanged)=\"onSortChanged($event)\"\n (rowClicked)=\"rowClick($event)\"\n >\n <section class=\"valtimo-widget-interactive-table__header\" carbonToolbarContent>\n <button\n *ngIf=\"!!obs.filters.length\"\n carbonToolbarContent\n [cdsOverflowMenu]=\"widgetInteractiveTableSearch\"\n [customPane]=\"true\"\n [iconOnly]=\"true\"\n [flip]=\"true\"\n [offset]=\"{x: 0, y: 47}\"\n placement=\"bottom\"\n cdsButton=\"ghost\"\n >\n <svg cdsIcon=\"filter\" size=\"16\"></svg>\n </button>\n\n <cds-overflow-menu\n *ngIf=\"!!widgetConfiguration?.actions?.length\"\n [customTrigger]=\"externalLinkTrigger\"\n placement=\"bottom\"\n flip=\"true\"\n [offset]=\"{x: 4, y: 44}\"\n >\n @for (action of widgetConfiguration?.actions; track action.name) {\n <cds-overflow-menu-option (click)=\"onActionClick(action)\">\n {{ action.name }}\n </cds-overflow-menu-option>\n }\n </cds-overflow-menu>\n\n <cds-menu-button\n *ngIf=\"widgetConfiguration?.properties?.canStartCase\"\n [label]=\"'Start Case' | translate\"\n >\n @for (definition of obs.caseDefinitions; track definition.caseDefinitionKey) {\n <cds-menu-item\n [label]=\"definition.name\"\n (click)=\"onCaseStart(definition)\"\n ></cds-menu-item>\n }\n </cds-menu-button>\n </section>\n\n <valtimo-no-results\n *ngIf=\"obs.widgetData !== null\"\n [collapseVertically]=\"true\"\n [description]=\"'widgets.noData' | translate\"\n [smallPadding]=\"true\"\n ></valtimo-no-results>\n </valtimo-carbon-list>\n\n <ng-template #widgetInteractiveTableSearch>\n <valtimo-widget-interactive-table-search\n [filters]=\"obs.filters\"\n [initSearchRequest]=\"searchRequest\"\n (searchSubmitEvent)=\"onSearchSubmit($event)\"\n ></valtimo-widget-interactive-table-search>\n </ng-template>\n\n <ng-template #externalLinkTrigger>\n <button cdsButton=\"ghost\" iconOnly=\"true\">\n <svg cdsIcon=\"link\" size=\"16\"></svg>\n </button>\n </ng-template>\n</ng-container>\n", styles: [".valtimo-widget-interactive-table{display:flex;flex-direction:column;height:100%}.valtimo-widget-interactive-table__header{display:flex;align-items:center;justify-content:flex-end;width:100%}.valtimo-widget-interactive-table__title-container{display:flex;align-items:center;gap:8px;padding:12px 0 0 16px}.valtimo-widget-interactive-table__content{display:flex;align-items:center;flex-direction:column}.valtimo-widget-interactive-table valtimo-carbon-list,.valtimo-widget-interactive-table cds-table-container{width:100%;height:100%}.valtimo-widget-interactive-table cds-table{height:calc(100% - 88px)}.valtimo-widget-interactive-table .widget-title{color:var(--widget-text-color, var(--cds-text-primary));font-weight:600;font-size:16px;line-height:24px}.cds--menu-item__label{overflow:unset!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{width:min(50vw,420px)!important;max-width:min(50vw,420px)!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "ngmodule", type: CarbonListModule }, { kind: "component", type: i1.CarbonListComponent, selector: "valtimo-carbon-list", inputs: ["items", "fields", "tableTranslations", "paginatorConfig", "pagination", "loading", "skeletonRowCount", "actions", "actionItems", "showActionItems", "header", "hideColumnHeader", "initialSortState", "sortState", "isSearchable", "enableSingleSelection", "lastColumnTemplate", "paginationIdentifier", "showSelectionColumn", "striped", "hideToolbar", "lockedTooltipTranslationKey", "movingRowsEnabled", "dragAndDrop", "dragAndDropDisabled"], outputs: ["rowClicked", "paginationClicked", "paginationSet", "search", "sortChanged", "moveRow", "itemsReordered"] }, { kind: "component", type: i1.CarbonNoResultsComponent, selector: "valtimo-no-results", inputs: ["action", "description", "illustration", "title", "smallPadding", "collapseVertically", "alwaysRenderVertically"] }, { kind: "ngmodule", type: PaginationModule }, { kind: "ngmodule", type: TilesModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.OverflowMenu, selector: "cds-overflow-menu, ibm-overflow-menu", inputs: ["buttonLabel", "description", "flip", "placement", "open", "customTrigger", "offset", "wrapperClass", "triggerClass"], outputs: ["openChange"] }, { kind: "directive", type: i3.OverflowMenuDirective, selector: "[cdsOverflowMenu], [ibmOverflowMenu]", inputs: ["ibmOverflowMenu", "cdsOverflowMenu", "flip", "offset", "wrapperClass", "customPane"], exportAs: ["overflowMenu"] }, { kind: "component", type: i3.OverflowMenuOption, selector: "cds-overflow-menu-option, ibm-overflow-menu-option", inputs: ["divider", "type", "disabled", "href", "target", "innerClass"], outputs: ["selected"] }, { kind: "ngmodule", type: MenuButtonModule }, { kind: "component", type: i3.MenuButtonComponent, selector: "cds-menu-button", inputs: ["menuId", "kind", "size", "menuAlignment", "buttonTabIndex", "disabled", "open", "label"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i3.ContextMenuItemComponent, selector: "cds-menu-item, cds-context-menu-item, ibm-context-menu-item", inputs: ["disabled", "danger", "label", "info", "type", "checked", "icon", "value"], outputs: ["checkedChange", "itemClick"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: MdiIconViewerComponent, selector: "valtimo-mdi-icon-viewer", inputs: ["mdiIcon"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: WidgetInteractiveTableSearchComponent, selector: "valtimo-widget-interactive-table-search", inputs: ["initSearchRequest", "filters"], outputs: ["searchSubmitEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1679
1860
  }
1680
1861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableComponent, decorators: [{
1681
1862
  type: Component,
@@ -1693,7 +1874,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
1693
1874
  MdiIconViewerComponent,
1694
1875
  SkeletonModule,
1695
1876
  WidgetInteractiveTableSearchComponent,
1696
- ], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<ng-container\n *ngIf=\"{\n fields: fields$ | async,\n widgetData: widgetData$ | async,\n caseDefinitions: caseDefinitions$ | async,\n filters: filters$ | async,\n } as obs\"\n>\n <div class=\"valtimo-widget-interactive-table__title-container\">\n <valtimo-mdi-icon-viewer\n *ngIf=\"widgetConfiguration?.icon\"\n [mdiIcon]=\"widgetConfiguration.icon\"\n ></valtimo-mdi-icon-viewer>\n\n <span class=\"widget-title\">{{ widgetConfiguration?.title }}</span>\n </div>\n\n <valtimo-carbon-list\n [header]=\"false\"\n [fields]=\"obs.fields\"\n [items]=\"obs.widgetData || []\"\n [initialSortState]=\"$initialSortState()\"\n [loading]=\"obs.widgetData === null\"\n [skeletonRowCount]=\"widgetConfiguration?.properties?.defaultPageSize || 5\"\n [pagination]=\"$paginationModel()\"\n [paginatorConfig]=\"$paginatorConfig()\"\n (paginationClicked)=\"onPaginationClicked($event)\"\n (paginationSet)=\"onPaginationSet($event)\"\n (sortChanged)=\"onSortChanged($event)\"\n (rowClicked)=\"rowClick($event)\"\n >\n <section class=\"valtimo-widget-interactive-table__header\" carbonToolbarContent>\n <button\n *ngIf=\"!!obs.filters.length\"\n carbonToolbarContent\n [cdsOverflowMenu]=\"widgetInteractiveTableSearch\"\n [customPane]=\"true\"\n [iconOnly]=\"true\"\n [flip]=\"true\"\n [offset]=\"{x: 0, y: 47}\"\n placement=\"bottom\"\n cdsButton=\"ghost\"\n >\n <svg cdsIcon=\"filter\" size=\"16\"></svg>\n </button>\n\n <cds-overflow-menu\n *ngIf=\"!!widgetConfiguration?.actions?.length\"\n [customTrigger]=\"externalLinkTrigger\"\n placement=\"bottom\"\n flip=\"true\"\n [offset]=\"{x: 4, y: 44}\"\n >\n @for (action of widgetConfiguration?.actions; track action.name) {\n <cds-overflow-menu-option (click)=\"onActionClick(action)\">\n {{ action.name }}\n </cds-overflow-menu-option>\n }\n </cds-overflow-menu>\n\n <cds-menu-button\n *ngIf=\"widgetConfiguration?.properties?.canStartCase\"\n [label]=\"'Start Case' | translate\"\n >\n @for (definition of obs.caseDefinitions; track definition.caseDefinitionKey) {\n <cds-menu-item\n [label]=\"definition.name\"\n (click)=\"onCaseStart(definition)\"\n ></cds-menu-item>\n }\n </cds-menu-button>\n </section>\n\n <valtimo-no-results\n *ngIf=\"obs.widgetData !== null\"\n [collapseVertically]=\"true\"\n [description]=\"'widgets.noData' | translate\"\n [smallPadding]=\"true\"\n ></valtimo-no-results>\n </valtimo-carbon-list>\n\n <ng-template #widgetInteractiveTableSearch>\n <valtimo-widget-interactive-table-search\n [filters]=\"obs.filters\"\n [initSearchRequest]=\"searchRequest\"\n (searchSubmitEvent)=\"onSearchSubmit($event)\"\n ></valtimo-widget-interactive-table-search>\n </ng-template>\n\n <ng-template #externalLinkTrigger>\n <button cdsButton=\"ghost\" iconOnly=\"true\">\n <svg cdsIcon=\"link\" size=\"16\"></svg>\n </button>\n </ng-template>\n</ng-container>\n", styles: [".valtimo-widget-interactive-table{display:flex;flex-direction:column;height:100%}.valtimo-widget-interactive-table__header{display:flex;align-items:center;justify-content:flex-end;width:100%}.valtimo-widget-interactive-table__title-container{display:flex;align-items:center;gap:8px;padding:12px 0 0 16px}.valtimo-widget-interactive-table__content{display:flex;align-items:center;flex-direction:column}.valtimo-widget-interactive-table valtimo-carbon-list,.valtimo-widget-interactive-table cds-table-container{width:100%;height:100%}.valtimo-widget-interactive-table cds-table{height:calc(100% - 88px)}.valtimo-widget-interactive-table .widget-title{color:var(--widget-text-color, var(--cds-text-primary));font-weight:600;font-size:16px;line-height:24px}.cds--menu-item__label{overflow:unset!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{max-width:max-content!important;width:max-content!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
1877
+ ], template: "<!--\n ~ Copyright 2015-2026 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<ng-container\n *ngIf=\"{\n fields: fields$ | async,\n widgetData: widgetData$ | async,\n caseDefinitions: caseDefinitions$ | async,\n filters: filters$ | async,\n } as obs\"\n>\n <div class=\"valtimo-widget-interactive-table__title-container\">\n <valtimo-mdi-icon-viewer\n *ngIf=\"widgetConfiguration?.icon\"\n [mdiIcon]=\"widgetConfiguration.icon\"\n ></valtimo-mdi-icon-viewer>\n\n <span class=\"widget-title\">{{ widgetConfiguration?.title }}</span>\n </div>\n\n <valtimo-carbon-list\n [header]=\"false\"\n [fields]=\"obs.fields\"\n [items]=\"obs.widgetData || []\"\n [initialSortState]=\"$initialSortState()\"\n [loading]=\"obs.widgetData === null\"\n [skeletonRowCount]=\"widgetConfiguration?.properties?.defaultPageSize || 5\"\n [pagination]=\"$paginationModel()\"\n [paginatorConfig]=\"$paginatorConfig()\"\n (paginationClicked)=\"onPaginationClicked($event)\"\n (paginationSet)=\"onPaginationSet($event)\"\n (sortChanged)=\"onSortChanged($event)\"\n (rowClicked)=\"rowClick($event)\"\n >\n <section class=\"valtimo-widget-interactive-table__header\" carbonToolbarContent>\n <button\n *ngIf=\"!!obs.filters.length\"\n carbonToolbarContent\n [cdsOverflowMenu]=\"widgetInteractiveTableSearch\"\n [customPane]=\"true\"\n [iconOnly]=\"true\"\n [flip]=\"true\"\n [offset]=\"{x: 0, y: 47}\"\n placement=\"bottom\"\n cdsButton=\"ghost\"\n >\n <svg cdsIcon=\"filter\" size=\"16\"></svg>\n </button>\n\n <cds-overflow-menu\n *ngIf=\"!!widgetConfiguration?.actions?.length\"\n [customTrigger]=\"externalLinkTrigger\"\n placement=\"bottom\"\n flip=\"true\"\n [offset]=\"{x: 4, y: 44}\"\n >\n @for (action of widgetConfiguration?.actions; track action.name) {\n <cds-overflow-menu-option (click)=\"onActionClick(action)\">\n {{ action.name }}\n </cds-overflow-menu-option>\n }\n </cds-overflow-menu>\n\n <cds-menu-button\n *ngIf=\"widgetConfiguration?.properties?.canStartCase\"\n [label]=\"'Start Case' | translate\"\n >\n @for (definition of obs.caseDefinitions; track definition.caseDefinitionKey) {\n <cds-menu-item\n [label]=\"definition.name\"\n (click)=\"onCaseStart(definition)\"\n ></cds-menu-item>\n }\n </cds-menu-button>\n </section>\n\n <valtimo-no-results\n *ngIf=\"obs.widgetData !== null\"\n [collapseVertically]=\"true\"\n [description]=\"'widgets.noData' | translate\"\n [smallPadding]=\"true\"\n ></valtimo-no-results>\n </valtimo-carbon-list>\n\n <ng-template #widgetInteractiveTableSearch>\n <valtimo-widget-interactive-table-search\n [filters]=\"obs.filters\"\n [initSearchRequest]=\"searchRequest\"\n (searchSubmitEvent)=\"onSearchSubmit($event)\"\n ></valtimo-widget-interactive-table-search>\n </ng-template>\n\n <ng-template #externalLinkTrigger>\n <button cdsButton=\"ghost\" iconOnly=\"true\">\n <svg cdsIcon=\"link\" size=\"16\"></svg>\n </button>\n </ng-template>\n</ng-container>\n", styles: [".valtimo-widget-interactive-table{display:flex;flex-direction:column;height:100%}.valtimo-widget-interactive-table__header{display:flex;align-items:center;justify-content:flex-end;width:100%}.valtimo-widget-interactive-table__title-container{display:flex;align-items:center;gap:8px;padding:12px 0 0 16px}.valtimo-widget-interactive-table__content{display:flex;align-items:center;flex-direction:column}.valtimo-widget-interactive-table valtimo-carbon-list,.valtimo-widget-interactive-table cds-table-container{width:100%;height:100%}.valtimo-widget-interactive-table cds-table{height:calc(100% - 88px)}.valtimo-widget-interactive-table .widget-title{color:var(--widget-text-color, var(--cds-text-primary));font-weight:600;font-size:16px;line-height:24px}.cds--menu-item__label{overflow:unset!important}::ng-deep .cds--overflow-menu-options.cds--overflow-menu-options--open{width:min(50vw,420px)!important;max-width:min(50vw,420px)!important}\n/*!\n * Copyright 2015-2026 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
1697
1878
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i2$2.DocumentService }, { type: i3.IconService }], propDecorators: { class: [{
1698
1879
  type: HostBinding,
1699
1880
  args: ['class']
@@ -2920,6 +3101,26 @@ class WidgetWizardFiltersStepComponent {
2920
3101
  content: this.translateService.instant('searchFields.text'),
2921
3102
  selected: false,
2922
3103
  },
3104
+ {
3105
+ id: 'number',
3106
+ content: this.translateService.instant('searchFields.number'),
3107
+ selected: false,
3108
+ },
3109
+ {
3110
+ id: 'date',
3111
+ content: this.translateService.instant('searchFields.date'),
3112
+ selected: false,
3113
+ },
3114
+ {
3115
+ id: 'datetime',
3116
+ content: this.translateService.instant('searchFields.datetime'),
3117
+ selected: false,
3118
+ },
3119
+ {
3120
+ id: 'boolean',
3121
+ content: this.translateService.instant('searchFields.boolean'),
3122
+ selected: false,
3123
+ },
2923
3124
  ];
2924
3125
  this.FIELD_TYPE_ITEMS = [
2925
3126
  {
@@ -2927,6 +3128,40 @@ class WidgetWizardFiltersStepComponent {
2927
3128
  content: this.translateService.instant('searchFieldsOverview.single'),
2928
3129
  selected: false,
2929
3130
  },
3131
+ {
3132
+ id: 'range',
3133
+ content: this.translateService.instant('searchFieldsOverview.range'),
3134
+ selected: false,
3135
+ },
3136
+ {
3137
+ id: 'single-select-dropdown',
3138
+ content: this.translateService.instant('searchFieldsOverview.single-select-dropdown'),
3139
+ selected: false,
3140
+ },
3141
+ {
3142
+ id: 'multi-select-dropdown',
3143
+ content: this.translateService.instant('searchFieldsOverview.multi-select-dropdown'),
3144
+ selected: false,
3145
+ },
3146
+ ];
3147
+ this.MATCH_TYPE_ITEMS = [
3148
+ {
3149
+ id: 'exact',
3150
+ content: this.translateService.instant('searchFieldsOverview.exact'),
3151
+ selected: false,
3152
+ },
3153
+ {
3154
+ id: 'like',
3155
+ content: this.translateService.instant('searchFieldsOverview.like'),
3156
+ selected: false,
3157
+ },
3158
+ ];
3159
+ this.DROPDOWN_PROVIDER_ITEMS = [
3160
+ {
3161
+ id: 'dropdownDatabaseDataProvider',
3162
+ content: this.translateService.instant('searchFieldsOverview.dropdownDatabaseDataProvider'),
3163
+ selected: false,
3164
+ },
2930
3165
  ];
2931
3166
  this.iconService.registerAll([TrashCan16, ArrowUp16, ArrowDown16]);
2932
3167
  }
@@ -2971,14 +3206,24 @@ class WidgetWizardFiltersStepComponent {
2971
3206
  return;
2972
3207
  this.reorderFilters(data.index, data.index + 1);
2973
3208
  }
3209
+ selectItem(items, id) {
3210
+ const selectedItem = items.find(item => item.id === id);
3211
+ return selectedItem ? { ...selectedItem, selected: true } : null;
3212
+ }
2974
3213
  createFilterFormGroup(filter) {
2975
- return this.fb.group({
3214
+ const formGroup = this.fb.group({
2976
3215
  title: this.fb.control(filter?.title ?? '', Validators.required),
2977
3216
  key: this.fb.control(filter?.key ?? '', Validators.required),
2978
- dataType: this.fb.control(this.getDataTypeControlValue(), Validators.required),
2979
- fieldType: this.fb.control(this.getFieldTypeControlValue(), Validators.required),
2980
- matchType: this.fb.control(filter?.matchType ?? null),
3217
+ dataType: this.fb.control(this.selectItem(this.DATA_TYPE_ITEMS, filter?.dataType), Validators.required),
3218
+ fieldType: this.fb.control(this.selectItem(this.FIELD_TYPE_ITEMS, filter?.fieldType), Validators.required),
3219
+ matchType: this.fb.control(this.selectItem(this.MATCH_TYPE_ITEMS, filter?.matchType)),
3220
+ dropdownDataProvider: this.fb.control(this.selectItem(this.DROPDOWN_PROVIDER_ITEMS, filter?.dropdownDataProvider)),
3221
+ dropdownValues: this.fb.array([]),
2981
3222
  });
3223
+ if (filter?.dropdownValues) {
3224
+ Object.entries(filter.dropdownValues).forEach(([k, v]) => this.addDropdownValue(formGroup, { key: k, value: v }));
3225
+ }
3226
+ return formGroup;
2982
3227
  }
2983
3228
  initForm() {
2984
3229
  const filters = this.widgetWizardService.$widgetContent()?.filters ?? [];
@@ -2993,12 +3238,39 @@ class WidgetWizardFiltersStepComponent {
2993
3238
  }
2994
3239
  openFormSubscription() {
2995
3240
  this._subscriptions.add(this.formGroup.valueChanges.pipe(debounceTime(100)).subscribe(({ filters }) => {
3241
+ (filters ?? []).forEach((_, index) => {
3242
+ const form = this.filters.at(index);
3243
+ const dataTypeId = form.get('dataType')?.value?.id;
3244
+ const fieldTypeId = form.get('fieldType')?.value?.id;
3245
+ const isDropdown = dataTypeId === 'text' &&
3246
+ (fieldTypeId === 'single-select-dropdown' || fieldTypeId === 'multi-select-dropdown');
3247
+ if (isDropdown && !form.get('dropdownDataProvider')?.value) {
3248
+ form
3249
+ .get('dropdownDataProvider')
3250
+ ?.setValue({ ...this.DROPDOWN_PROVIDER_ITEMS[0], selected: true }, { emitEvent: false });
3251
+ }
3252
+ if (isDropdown) {
3253
+ const providerId = form.get('dropdownDataProvider')?.value?.id;
3254
+ if (providerId === 'dropdownDatabaseDataProvider') {
3255
+ const arr = this.getDropdownValuesArray(form);
3256
+ if (arr.length === 0) {
3257
+ this.addDropdownValue(form);
3258
+ }
3259
+ }
3260
+ }
3261
+ if (!isDropdown && form.get('dropdownDataProvider')?.value) {
3262
+ form.get('dropdownDataProvider')?.setValue(null, { emitEvent: false });
3263
+ this.getDropdownValuesArray(form).clear();
3264
+ }
3265
+ });
2996
3266
  const mappedFilters = (filters ?? []).map(filter => ({
2997
3267
  title: filter.title,
2998
3268
  key: filter.key,
2999
- dataType: this.getListItemId(filter.dataType) ?? 'text',
3000
- fieldType: this.getListItemId(filter.fieldType) ?? 'single',
3001
- matchType: filter.matchType,
3269
+ dataType: this.getListItemId(filter.dataType) ?? null,
3270
+ fieldType: this.getListItemId(filter.fieldType) ?? null,
3271
+ matchType: this.getListItemId(filter.matchType) ?? null,
3272
+ dropdownDataProvider: this.getListItemId(filter.dropdownDataProvider) ?? null,
3273
+ dropdownValues: this.mapDropdownValues(filter.dropdownValues) ?? null,
3002
3274
  }));
3003
3275
  this.widgetWizardService.$widgetContent.update((content) => ({
3004
3276
  ...content,
@@ -3007,28 +3279,63 @@ class WidgetWizardFiltersStepComponent {
3007
3279
  this.widgetWizardService.$widgetFiltersValid.set(this.formGroup.valid);
3008
3280
  }));
3009
3281
  }
3282
+ getDropdownValuesArray(formGroup) {
3283
+ return formGroup.get('dropdownValues');
3284
+ }
3010
3285
  getDataTypeDropdownItems(filterRow) {
3011
- const selectedId = this.getListItemId(filterRow.get('dataType')?.value) ?? 'text';
3012
- return this.selectItem(this.DATA_TYPE_ITEMS, selectedId);
3286
+ const selectedId = filterRow.get('dataType')?.value?.id ?? null;
3287
+ return this.DATA_TYPE_ITEMS.map(item => ({ ...item, selected: item.id === selectedId }));
3013
3288
  }
3014
3289
  getFieldTypeDropdownItems(filterRow) {
3015
- const selectedId = this.getListItemId(filterRow.get('fieldType')?.value) ?? 'single';
3016
- return this.selectItem(this.FIELD_TYPE_ITEMS, selectedId);
3290
+ const selectedId = filterRow.get('fieldType')?.value?.id ?? null;
3291
+ const dataTypeId = filterRow.get('dataType')?.value?.id ?? null;
3292
+ const isText = dataTypeId === 'text';
3293
+ const isBoolean = dataTypeId === 'boolean';
3294
+ const items = this.FIELD_TYPE_ITEMS.filter(item => {
3295
+ if (isText)
3296
+ return true;
3297
+ if (isBoolean)
3298
+ return item.id === 'single';
3299
+ return item.id !== 'single-select-dropdown' && item.id !== 'multi-select-dropdown';
3300
+ });
3301
+ return items.map(item => ({
3302
+ ...item,
3303
+ selected: item.id === selectedId,
3304
+ }));
3305
+ }
3306
+ getMatchTypeDropdownItems(filterRow) {
3307
+ const selectedId = filterRow.get('matchType')?.value?.id ?? null;
3308
+ return this.MATCH_TYPE_ITEMS.map(item => ({ ...item, selected: item.id === selectedId }));
3309
+ }
3310
+ getDropdownDataProviderItems(filterRow) {
3311
+ const selectedId = filterRow.get('dropdownDataProvider')?.value?.id ?? null;
3312
+ return this.DROPDOWN_PROVIDER_ITEMS.map(item => ({ ...item, selected: item.id === selectedId }));
3313
+ }
3314
+ shouldShowDropdownValues(filterRow) {
3315
+ const dataTypeId = filterRow.get('dataType')?.value?.id ?? null;
3316
+ const fieldTypeId = filterRow.get('fieldType')?.value?.id ?? null;
3317
+ const providerId = filterRow.get('dropdownDataProvider')?.value?.id ?? null;
3318
+ const hasValues = (filterRow.get('dropdownValues')?.value?.length ?? 0) > 0;
3319
+ const isDropdownField = dataTypeId === 'text' &&
3320
+ (fieldTypeId === 'single-select-dropdown' || fieldTypeId === 'multi-select-dropdown');
3321
+ return isDropdownField && (providerId === 'dropdownDatabaseDataProvider' || hasValues);
3322
+ }
3323
+ addDropdownValue(filterRow, prefill) {
3324
+ const arr = this.getDropdownValuesArray(filterRow);
3325
+ arr.push(this.fb.group({
3326
+ key: this.fb.control(prefill?.key ?? '', Validators.required),
3327
+ value: this.fb.control(prefill?.value ?? '', Validators.required),
3328
+ }));
3329
+ }
3330
+ removeDropdownValue(filterRow, index) {
3331
+ const arr = this.getDropdownValuesArray(filterRow);
3332
+ arr.removeAt(index);
3017
3333
  }
3018
3334
  onFilterAccordionSelection(expanded, index) {
3019
3335
  this.expandedFilterIndex = expanded ? index : -1;
3020
3336
  }
3021
3337
  getListItemId(value) {
3022
- if (!value) {
3023
- return null;
3024
- }
3025
- return value.id;
3026
- }
3027
- getDataTypeControlValue() {
3028
- return { ...this.DATA_TYPE_ITEMS[0], selected: true };
3029
- }
3030
- getFieldTypeControlValue() {
3031
- return { ...this.FIELD_TYPE_ITEMS[0], selected: true };
3338
+ return value?.id ?? null;
3032
3339
  }
3033
3340
  reorderFilters(fromIndex, toIndex) {
3034
3341
  const reorderedControls = this.swapItems(this.filters.controls, fromIndex, toIndex);
@@ -3045,20 +3352,24 @@ class WidgetWizardFiltersStepComponent {
3045
3352
  this.expandedFilterIndex = fromIndex;
3046
3353
  }
3047
3354
  }
3048
- selectItem(items, selectedId) {
3049
- return items.map(item => ({
3050
- ...item,
3051
- selected: item.id === selectedId,
3052
- }));
3053
- }
3054
3355
  swapItems(items, index1, index2) {
3055
3356
  const itemToInsert = items[index1];
3056
3357
  const filteredItems = items.filter((_, index) => index !== index1);
3057
3358
  filteredItems.splice(index2, 0, itemToInsert);
3058
3359
  return filteredItems;
3059
3360
  }
3361
+ mapDropdownValues(values) {
3362
+ if (!values || values.length === 0)
3363
+ return null;
3364
+ return values.reduce((acc, curr) => {
3365
+ if (!curr?.key)
3366
+ return acc;
3367
+ acc[curr.key] = curr.value ?? '';
3368
+ return acc;
3369
+ }, {});
3370
+ }
3060
3371
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetWizardFiltersStepComponent, deps: [{ token: i1$3.FormBuilder }, { token: WidgetWizardService }, { token: i3.IconService }, { token: i2$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
3061
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetWizardFiltersStepComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n<form [formGroup]=\"formGroup\" class=\"valtimo-widget-wizard-filters\">\n <cds-accordion formArrayName=\"filters\" align=\"start\" size=\"sm\">\n @for (filterRow of filters.controls; track $index) {\n <cds-accordion-item\n [title]=\"filterTitle\"\n [expanded]=\"expandedFilterIndex === $index\"\n [context]=\"{\n title: filterRow.get('title')?.value,\n count: $count,\n index: $index,\n }\"\n (selected)=\"onFilterAccordionSelection($event.expanded, $index)\"\n class=\"valtimo-widget-wizard-filters__item\"\n >\n <form\n [formGroup]=\"filterRow\"\n class=\"valtimo-widget-wizard-filters__container\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n <div class=\"valtimo-widget-wizard-filters__row\">\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.title' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.titleTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"title\"\n [placeholder]=\"'widgetTabManagement.filters.titlePlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.key' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.keyTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"key\"\n [placeholder]=\"'widgetTabManagement.filters.keyPlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.dataType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.dataTypePlaceholder' | translate\"\n formControlName=\"dataType\"\n >\n <cds-dropdown-list [items]=\"getDataTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.fieldType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.fieldTypePlaceholder' | translate\"\n formControlName=\"fieldType\"\n >\n <cds-dropdown-list [items]=\"getFieldTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n </div>\n </form>\n </cds-accordion-item>\n }\n </cds-accordion>\n\n <button cdsButton=\"primary\" size=\"sm\" type=\"button\" (click)=\"addFilter()\">\n {{ 'widgetTabManagement.filters.add' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n</form>\n\n<ng-template #filterTitle let-title=\"title\" let-count=\"count\" let-index=\"index\">\n <div class=\"valtimo-widget-wizard-filters__title\">\n <span>\n {{ title || ('widgetTabManagement.filters.titlePlaceholder' | translate) }}\n </span>\n\n <section class=\"valtimo-widget-wizard-filters__actions\">\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === 0\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveUpClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--up\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === count - 1\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveDownClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--down\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"valtimo-widget-wizard-filters__delete-button\"\n (click)=\"removeFilter($event, index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </section>\n </div>\n</ng-template>\n", styles: [".valtimo-widget-wizard-filters{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__item{background:var(--cds-layer-01)}.valtimo-widget-wizard-filters__item .cds--accordion__content{padding-inline-end:20px}.valtimo-widget-wizard-filters__container{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__row{display:grid;grid-template-columns:1fr 1fr 180px 180px;align-items:flex-end;gap:16px}.valtimo-widget-wizard-filters__title{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px}.valtimo-widget-wizard-filters__actions{display:flex;gap:8px;align-items:center}.valtimo-widget-wizard-filters .cds--text-input{background:var(--cds-layer-02)}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i3.Accordion, selector: "cds-accordion, ibm-accordion", inputs: ["align", "size", "skeleton"] }, { kind: "component", type: i3.AccordionItem, selector: "cds-accordion-item, ibm-accordion-item", inputs: ["title", "context", "id", "skeleton", "expanded", "disabled"], outputs: ["selected"] }, { kind: "ngmodule", type: InputModule }, { kind: "component", type: i3.TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid"] }, { kind: "directive", type: i3.TextInput, selector: "[cdsText], [ibmText]", inputs: ["theme", "size", "invalid", "warn", "skeleton"] }, { kind: "ngmodule", type: LayerModule }, { kind: "directive", type: i3.LayerDirective, selector: "[cdsLayer], [ibmLayer]", inputs: ["ibmLayer", "cdsLayer"], exportAs: ["layer"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: InputLabelModule }, { kind: "component", type: i1.InputLabelComponent, selector: "v-input-label", inputs: ["name", "tooltip", "tooltipTranslationKey", "largeMargin", "small", "noMargin", "title", "titleTranslationKey", "required", "disabled", "carbonTheme"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i7.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i7.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3372
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: WidgetWizardFiltersStepComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n<form [formGroup]=\"formGroup\" class=\"valtimo-widget-wizard-filters\">\n <cds-accordion formArrayName=\"filters\" align=\"start\" size=\"sm\">\n @for (filterRow of filters.controls; track $index) {\n <cds-accordion-item\n [title]=\"filterTitle\"\n [expanded]=\"expandedFilterIndex === $index\"\n [context]=\"{\n title: filterRow.get('title')?.value,\n count: $count,\n index: $index,\n }\"\n (selected)=\"onFilterAccordionSelection($event.expanded, $index)\"\n class=\"valtimo-widget-wizard-filters__item\"\n >\n <form\n [formGroup]=\"filterRow\"\n class=\"valtimo-widget-wizard-filters__container\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n <div class=\"valtimo-widget-wizard-filters__row\">\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.title' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.titleTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"title\"\n [placeholder]=\"'widgetTabManagement.filters.titlePlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.key' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.keyTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"key\"\n [placeholder]=\"'widgetTabManagement.filters.keyPlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.dataType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.dataTypePlaceholder' | translate\"\n formControlName=\"dataType\"\n >\n <cds-dropdown-list [items]=\"getDataTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.fieldType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.fieldTypePlaceholder' | translate\"\n formControlName=\"fieldType\"\n >\n <cds-dropdown-list [items]=\"getFieldTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n @if ((filterRow.get('dataType')?.value?.id) === 'text') {\n <cds-dropdown cdsLayer [label]=\"'searchFieldsOverview.matchType' | translate\" formControlName=\"matchType\">\n <cds-dropdown-list [items]=\"getMatchTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n }\n\n @if (\n (filterRow.get('dataType')?.value?.id) === 'text' &&\n ((filterRow.get('fieldType')?.value?.id) === 'single-select-dropdown' ||\n (filterRow.get('fieldType')?.value?.id) === 'multi-select-dropdown')\n ) {\n <cds-dropdown\n cdsLayer\n [label]=\"'searchFieldsOverview.dropdownDataProvider' | translate\"\n formControlName=\"dropdownDataProvider\"\n >\n <cds-dropdown-list\n [items]=\"getDropdownDataProviderItems(filterRow)\"\n ></cds-dropdown-list>\n </cds-dropdown>\n }\n\n @if (shouldShowDropdownValues(filterRow)) {\n <div class=\"valtimo-widget-wizard-filters__list\" formArrayName=\"dropdownValues\">\n <v-input-label\n [title]=\"'searchFieldsOverview.dropdownListValues' | translate\"\n [tooltip]=\"'searchFieldsOverviewTooltips.dropdownListValues' | translate\"\n [noMargin]=\"true\"\n ></v-input-label>\n\n @for (dropdownValue of (filterRow.get('dropdownValues')?.['controls'] ?? []); track $index) {\n <div [formGroup]=\"dropdownValue\" class=\"valtimo-widget-wizard-filters__dropdown-values\">\n <cds-text-label>\n {{ 'interface.value' | translate }}\n <input cdsText type=\"text\" formControlName=\"key\" cdsLayer />\n </cds-text-label>\n\n <cds-text-label>\n {{ 'interface.display' | translate }}\n <input cdsText type=\"text\" formControlName=\"value\" cdsLayer />\n </cds-text-label>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n [disabled]=\"(filterRow.get('dropdownValues')?.value?.length ?? 0) === 1\"\n (click)=\"removeDropdownValue(filterRow, $index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </div>\n }\n\n <button cdsButton=\"primary\" type=\"button\" (click)=\"addDropdownValue(filterRow)\">\n {{ 'interface.addRow' | translate }}\n <svg cdsIcon=\"add\" size=\"16\" class=\"cds--btn__icon\"></svg>\n </button>\n </div>\n }\n </div>\n </form>\n </cds-accordion-item>\n }\n </cds-accordion>\n\n <button cdsButton=\"primary\" size=\"sm\" type=\"button\" (click)=\"addFilter()\">\n {{ 'widgetTabManagement.filters.add' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n</form>\n\n<ng-template #filterTitle let-title=\"title\" let-count=\"count\" let-index=\"index\">\n <div class=\"valtimo-widget-wizard-filters__title\">\n <span>\n {{ title || ('widgetTabManagement.filters.titlePlaceholder' | translate) }}\n </span>\n\n <section class=\"valtimo-widget-wizard-filters__actions\">\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === 0\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveUpClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--up\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === count - 1\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveDownClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--down\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"valtimo-widget-wizard-filters__delete-button\"\n (click)=\"removeFilter($event, index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </section>\n </div>\n</ng-template>\n", styles: [".valtimo-widget-wizard-filters{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__item{background:var(--cds-layer-01)}.valtimo-widget-wizard-filters__item .cds--accordion__content{padding-inline-end:20px}.valtimo-widget-wizard-filters__container{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;align-items:flex-end}.valtimo-widget-wizard-filters__title{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px}.valtimo-widget-wizard-filters__actions{display:flex;gap:8px;align-items:center}.valtimo-widget-wizard-filters__dropdown-values{display:grid;grid-template-columns:minmax(180px,1fr) minmax(180px,1fr) auto;gap:16px;align-items:flex-end;width:100%;margin-bottom:12px}.valtimo-widget-wizard-filters__dropdown-values cds-text-label{width:100%}.valtimo-widget-wizard-filters__dropdown-values button[cdsbutton=danger]{width:40px;height:40px;padding:0;display:flex;align-items:center;justify-content:center}.valtimo-widget-wizard-filters .cds--text-input{background:var(--cds-layer-02)}v-input-label{margin-bottom:8px}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i3.Accordion, selector: "cds-accordion, ibm-accordion", inputs: ["align", "size", "skeleton"] }, { kind: "component", type: i3.AccordionItem, selector: "cds-accordion-item, ibm-accordion-item", inputs: ["title", "context", "id", "skeleton", "expanded", "disabled"], outputs: ["selected"] }, { kind: "ngmodule", type: InputModule }, { kind: "component", type: i3.TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid"] }, { kind: "directive", type: i3.TextInput, selector: "[cdsText], [ibmText]", inputs: ["theme", "size", "invalid", "warn", "skeleton"] }, { kind: "ngmodule", type: LayerModule }, { kind: "directive", type: i3.LayerDirective, selector: "[cdsLayer], [ibmLayer]", inputs: ["ibmLayer", "cdsLayer"], exportAs: ["layer"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: InputLabelModule }, { kind: "component", type: i1.InputLabelComponent, selector: "v-input-label", inputs: ["name", "tooltip", "tooltipTranslationKey", "largeMargin", "small", "noMargin", "title", "titleTranslationKey", "required", "disabled", "carbonTheme"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i7.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i7.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3062
3373
  }
3063
3374
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetWizardFiltersStepComponent, decorators: [{
3064
3375
  type: Component,
@@ -3073,7 +3384,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
3073
3384
  IconModule,
3074
3385
  InputLabelModule,
3075
3386
  DropdownModule,
3076
- ], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n<form [formGroup]=\"formGroup\" class=\"valtimo-widget-wizard-filters\">\n <cds-accordion formArrayName=\"filters\" align=\"start\" size=\"sm\">\n @for (filterRow of filters.controls; track $index) {\n <cds-accordion-item\n [title]=\"filterTitle\"\n [expanded]=\"expandedFilterIndex === $index\"\n [context]=\"{\n title: filterRow.get('title')?.value,\n count: $count,\n index: $index,\n }\"\n (selected)=\"onFilterAccordionSelection($event.expanded, $index)\"\n class=\"valtimo-widget-wizard-filters__item\"\n >\n <form\n [formGroup]=\"filterRow\"\n class=\"valtimo-widget-wizard-filters__container\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n <div class=\"valtimo-widget-wizard-filters__row\">\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.title' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.titleTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"title\"\n [placeholder]=\"'widgetTabManagement.filters.titlePlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.key' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.keyTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"key\"\n [placeholder]=\"'widgetTabManagement.filters.keyPlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.dataType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.dataTypePlaceholder' | translate\"\n formControlName=\"dataType\"\n >\n <cds-dropdown-list [items]=\"getDataTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.fieldType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.fieldTypePlaceholder' | translate\"\n formControlName=\"fieldType\"\n >\n <cds-dropdown-list [items]=\"getFieldTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n </div>\n </form>\n </cds-accordion-item>\n }\n </cds-accordion>\n\n <button cdsButton=\"primary\" size=\"sm\" type=\"button\" (click)=\"addFilter()\">\n {{ 'widgetTabManagement.filters.add' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n</form>\n\n<ng-template #filterTitle let-title=\"title\" let-count=\"count\" let-index=\"index\">\n <div class=\"valtimo-widget-wizard-filters__title\">\n <span>\n {{ title || ('widgetTabManagement.filters.titlePlaceholder' | translate) }}\n </span>\n\n <section class=\"valtimo-widget-wizard-filters__actions\">\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === 0\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveUpClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--up\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === count - 1\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveDownClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--down\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"valtimo-widget-wizard-filters__delete-button\"\n (click)=\"removeFilter($event, index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </section>\n </div>\n</ng-template>\n", styles: [".valtimo-widget-wizard-filters{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__item{background:var(--cds-layer-01)}.valtimo-widget-wizard-filters__item .cds--accordion__content{padding-inline-end:20px}.valtimo-widget-wizard-filters__container{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__row{display:grid;grid-template-columns:1fr 1fr 180px 180px;align-items:flex-end;gap:16px}.valtimo-widget-wizard-filters__title{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px}.valtimo-widget-wizard-filters__actions{display:flex;gap:8px;align-items:center}.valtimo-widget-wizard-filters .cds--text-input{background:var(--cds-layer-02)}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
3387
+ ], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n<form [formGroup]=\"formGroup\" class=\"valtimo-widget-wizard-filters\">\n <cds-accordion formArrayName=\"filters\" align=\"start\" size=\"sm\">\n @for (filterRow of filters.controls; track $index) {\n <cds-accordion-item\n [title]=\"filterTitle\"\n [expanded]=\"expandedFilterIndex === $index\"\n [context]=\"{\n title: filterRow.get('title')?.value,\n count: $count,\n index: $index,\n }\"\n (selected)=\"onFilterAccordionSelection($event.expanded, $index)\"\n class=\"valtimo-widget-wizard-filters__item\"\n >\n <form\n [formGroup]=\"filterRow\"\n class=\"valtimo-widget-wizard-filters__container\"\n (click)=\"$event.stopImmediatePropagation()\"\n >\n <div class=\"valtimo-widget-wizard-filters__row\">\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.title' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.titleTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"title\"\n [placeholder]=\"'widgetTabManagement.filters.titlePlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-text-label>\n <v-input-label\n [title]=\"'widgetTabManagement.filters.key' | translate\"\n [tooltip]=\"'widgetTabManagement.filters.keyTooltip' | translate\"\n ></v-input-label>\n\n <input\n cdsText\n formControlName=\"key\"\n [placeholder]=\"'widgetTabManagement.filters.keyPlaceholder' | translate\"\n type=\"text\"\n />\n </cds-text-label>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.dataType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.dataTypePlaceholder' | translate\"\n formControlName=\"dataType\"\n >\n <cds-dropdown-list [items]=\"getDataTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n <cds-dropdown\n cdsLayer\n [label]=\"'widgetTabManagement.filters.fieldType' | translate\"\n [placeholder]=\"'widgetTabManagement.filters.fieldTypePlaceholder' | translate\"\n formControlName=\"fieldType\"\n >\n <cds-dropdown-list [items]=\"getFieldTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n\n @if ((filterRow.get('dataType')?.value?.id) === 'text') {\n <cds-dropdown cdsLayer [label]=\"'searchFieldsOverview.matchType' | translate\" formControlName=\"matchType\">\n <cds-dropdown-list [items]=\"getMatchTypeDropdownItems(filterRow)\"></cds-dropdown-list>\n </cds-dropdown>\n }\n\n @if (\n (filterRow.get('dataType')?.value?.id) === 'text' &&\n ((filterRow.get('fieldType')?.value?.id) === 'single-select-dropdown' ||\n (filterRow.get('fieldType')?.value?.id) === 'multi-select-dropdown')\n ) {\n <cds-dropdown\n cdsLayer\n [label]=\"'searchFieldsOverview.dropdownDataProvider' | translate\"\n formControlName=\"dropdownDataProvider\"\n >\n <cds-dropdown-list\n [items]=\"getDropdownDataProviderItems(filterRow)\"\n ></cds-dropdown-list>\n </cds-dropdown>\n }\n\n @if (shouldShowDropdownValues(filterRow)) {\n <div class=\"valtimo-widget-wizard-filters__list\" formArrayName=\"dropdownValues\">\n <v-input-label\n [title]=\"'searchFieldsOverview.dropdownListValues' | translate\"\n [tooltip]=\"'searchFieldsOverviewTooltips.dropdownListValues' | translate\"\n [noMargin]=\"true\"\n ></v-input-label>\n\n @for (dropdownValue of (filterRow.get('dropdownValues')?.['controls'] ?? []); track $index) {\n <div [formGroup]=\"dropdownValue\" class=\"valtimo-widget-wizard-filters__dropdown-values\">\n <cds-text-label>\n {{ 'interface.value' | translate }}\n <input cdsText type=\"text\" formControlName=\"key\" cdsLayer />\n </cds-text-label>\n\n <cds-text-label>\n {{ 'interface.display' | translate }}\n <input cdsText type=\"text\" formControlName=\"value\" cdsLayer />\n </cds-text-label>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n [disabled]=\"(filterRow.get('dropdownValues')?.value?.length ?? 0) === 1\"\n (click)=\"removeDropdownValue(filterRow, $index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </div>\n }\n\n <button cdsButton=\"primary\" type=\"button\" (click)=\"addDropdownValue(filterRow)\">\n {{ 'interface.addRow' | translate }}\n <svg cdsIcon=\"add\" size=\"16\" class=\"cds--btn__icon\"></svg>\n </button>\n </div>\n }\n </div>\n </form>\n </cds-accordion-item>\n }\n </cds-accordion>\n\n <button cdsButton=\"primary\" size=\"sm\" type=\"button\" (click)=\"addFilter()\">\n {{ 'widgetTabManagement.filters.add' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n</form>\n\n<ng-template #filterTitle let-title=\"title\" let-count=\"count\" let-index=\"index\">\n <div class=\"valtimo-widget-wizard-filters__title\">\n <span>\n {{ title || ('widgetTabManagement.filters.titlePlaceholder' | translate) }}\n </span>\n\n <section class=\"valtimo-widget-wizard-filters__actions\">\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === 0\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveUpClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--up\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"tertiary\"\n [disabled]=\"index === count - 1\"\n [iconOnly]=\"true\"\n size=\"sm\"\n type=\"button\"\n (click)=\"onMoveDownClick($event, {index: index, length: count})\"\n >\n <svg cdsIcon=\"arrow--down\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"valtimo-widget-wizard-filters__delete-button\"\n (click)=\"removeFilter($event, index)\"\n >\n <svg cdsIcon=\"trash-can\" size=\"16\"></svg>\n </button>\n </section>\n </div>\n</ng-template>\n", styles: [".valtimo-widget-wizard-filters{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__item{background:var(--cds-layer-01)}.valtimo-widget-wizard-filters__item .cds--accordion__content{padding-inline-end:20px}.valtimo-widget-wizard-filters__container{display:flex;flex-direction:column;gap:16px}.valtimo-widget-wizard-filters__row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;align-items:flex-end}.valtimo-widget-wizard-filters__title{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px}.valtimo-widget-wizard-filters__actions{display:flex;gap:8px;align-items:center}.valtimo-widget-wizard-filters__dropdown-values{display:grid;grid-template-columns:minmax(180px,1fr) minmax(180px,1fr) auto;gap:16px;align-items:flex-end;width:100%;margin-bottom:12px}.valtimo-widget-wizard-filters__dropdown-values cds-text-label{width:100%}.valtimo-widget-wizard-filters__dropdown-values button[cdsbutton=danger]{width:40px;height:40px;padding:0;display:flex;align-items:center;justify-content:center}.valtimo-widget-wizard-filters .cds--text-input{background:var(--cds-layer-02)}v-input-label{margin-bottom:8px}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
3077
3388
  }], ctorParameters: () => [{ type: i1$3.FormBuilder }, { type: WidgetWizardService }, { type: i3.IconService }, { type: i2$1.TranslateService }], propDecorators: { class: [{
3078
3389
  type: HostBinding,
3079
3390
  args: ['class']
@@ -5524,6 +5835,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
5524
5835
  }]
5525
5836
  }], ctorParameters: () => [{ type: i1$3.FormBuilder }, { type: i2$1.TranslateService }] });
5526
5837
 
5838
+ /*
5839
+ * Copyright 2015-2026 Ritense BV, the Netherlands.
5840
+ *
5841
+ * Licensed under EUPL, Version 1.2 (the "License");
5842
+ * you may not use this file except in compliance with the License.
5843
+ * You may obtain a copy of the License at
5844
+ *
5845
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
5846
+ *
5847
+ * Unless required by applicable law or agreed to in writing, software
5848
+ * distributed under the License is distributed on an "AS IS" BASIS,
5849
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5850
+ * See the License for the specific language governing permissions and
5851
+ * limitations under the License.
5852
+ */
5853
+ class WidgetInteractiveTableService {
5854
+ constructor(documentService, httpClient, configService, fb) {
5855
+ this.documentService = documentService;
5856
+ this.httpClient = httpClient;
5857
+ this.configService = configService;
5858
+ this.fb = fb;
5859
+ }
5860
+ getDropdownDataProviders() {
5861
+ return this.documentService.getDropdownDataProviders();
5862
+ }
5863
+ supportsDropdownValueUpdates(providerId) {
5864
+ return providerId === FilterDropdownDataProvider.DATABASE;
5865
+ }
5866
+ getDropdownValues(provider, dropdownKey) {
5867
+ if (!provider || !dropdownKey)
5868
+ return of(null);
5869
+ return this.httpClient
5870
+ .get(this.getDropdownListUrl(provider, dropdownKey))
5871
+ .pipe(catchError(() => of(null)));
5872
+ }
5873
+ saveDropdownValues(provider, dropdownKey, dropdownValues) {
5874
+ if (!provider || !dropdownKey || !Object.keys(dropdownValues ?? {}).length)
5875
+ return of({});
5876
+ return this.httpClient.post(this.getDropdownListUrl(provider, dropdownKey), dropdownValues);
5877
+ }
5878
+ deleteDropdownValues(provider, dropdownKey) {
5879
+ if (!provider || !dropdownKey)
5880
+ return of({});
5881
+ return this.httpClient.delete(this.getDropdownListUrl(provider, dropdownKey));
5882
+ }
5883
+ buildDropdownDataKey(context, params, filterKey) {
5884
+ if (!filterKey)
5885
+ return null;
5886
+ if (context === 'case' && this.isCaseParams(params)) {
5887
+ return `${params.caseDefinitionKey}_${filterKey}`;
5888
+ }
5889
+ if (context === 'iko' && this.isIkoParams(params)) {
5890
+ return params.actionKey
5891
+ ? `${params.aggregateKey}_${params.actionKey}_${filterKey}`
5892
+ : null;
5893
+ }
5894
+ return null;
5895
+ }
5896
+ createDropdownValuesFormArray(values) {
5897
+ const entries = Array.isArray(values)
5898
+ ? values.map(({ key, value }) => [key, value])
5899
+ : Object.entries(values ?? {});
5900
+ const controls = entries.map(([key, value]) => this.createDropdownValueGroup(key, value));
5901
+ return this.fb.array(controls.length ? controls : [this.createDropdownValueGroup()]);
5902
+ }
5903
+ createDropdownValueGroup(key = '', value = '') {
5904
+ return this.fb.group({
5905
+ key: this.fb.control(key, Validators.required),
5906
+ value: this.fb.control(value, Validators.required),
5907
+ });
5908
+ }
5909
+ mapDropdownValuesArrayToObject(dropdownValues) {
5910
+ if (!dropdownValues?.length)
5911
+ return null;
5912
+ return dropdownValues.reduce((acc, value) => value?.key && value?.value ? { ...acc, [value.key]: value.value } : acc, {});
5913
+ }
5914
+ isDropdownFieldType(fieldTypeId) {
5915
+ return ['single-select-dropdown', 'multi-select-dropdown'].includes(fieldTypeId ?? '');
5916
+ }
5917
+ getDropdownListUrl(provider, dropdownKey) {
5918
+ const key = encodeURI(dropdownKey);
5919
+ return `${this.configService.config.valtimoApi.endpointUri}v1/data/dropdown-list?provider=${provider}&key=${key}`;
5920
+ }
5921
+ isCaseParams(params) {
5922
+ return typeof params === 'object' && params !== null && 'caseDefinitionKey' in params;
5923
+ }
5924
+ isIkoParams(params) {
5925
+ return typeof params === 'object' && params !== null && 'aggregateKey' in params;
5926
+ }
5927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableService, deps: [{ token: i2$2.DocumentService }, { token: i2$3.HttpClient }, { token: i1$1.ConfigService }, { token: i1$3.FormBuilder }], target: i0.ɵɵFactoryTarget.Injectable }); }
5928
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableService, providedIn: 'root' }); }
5929
+ }
5930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: WidgetInteractiveTableService, decorators: [{
5931
+ type: Injectable,
5932
+ args: [{
5933
+ providedIn: 'root',
5934
+ }]
5935
+ }], ctorParameters: () => [{ type: i2$2.DocumentService }, { type: i2$3.HttpClient }, { type: i1$1.ConfigService }, { type: i1$3.FormBuilder }] });
5936
+
5527
5937
  /*
5528
5938
  * Copyright 2015-2025 Ritense BV, the Netherlands.
5529
5939
  *
@@ -5745,5 +6155,5 @@ class ManagementWidgetDetailsComponent {
5745
6155
  * Generated bundle index. Do not edit.
5746
6156
  */
5747
6157
 
5748
- export { AVAILABLE_WIDGETS, CUSTOM_WIDGET_TOKEN, DEFAULT_WIDGET_COMPONENT_MAP, LayoutComponent, LayoutInternalComponent, LayoutModule, LayoutPublicComponent, LayoutService, ManagementWidgetDetailsComponent, TranslationManagementComponent, TranslationManagementModule, WIDGET_COLOR_ILLUSTRATION_MAP, WIDGET_COLOR_ITEMS, WIDGET_COLOR_LABELS, WIDGET_COLOR_THEME_MAP, WIDGET_DENSITY_LABELS, WIDGET_HEIGHT_1X, WIDGET_MANAGEMENT_SERVICE, WIDGET_WIDTH_1X, WIDGET_WIDTH_LABELS, WIZARD_STEP_COMPONENTS, WidgetActionButtonComponent, WidgetBlockComponent, WidgetCollectionComponent, WidgetColor, WidgetContainerComponent, WidgetCustomComponent, WidgetDensity, WidgetDisplayTypeKey, WidgetFieldComponent, WidgetFieldsService, WidgetFormioComponent, WidgetInteractiveTableComponent, WidgetInteractiveTableSearchComponent, WidgetLayoutService, WidgetManagementCollectionComponent, WidgetManagementComponent, WidgetManagementCustomComponent, WidgetManagementEditorComponent, WidgetManagementFieldsComponent, WidgetManagementMapComponent, WidgetManagementTab, WidgetManagementTableComponent, WidgetManagementWizardComponent, WidgetMapComponent, WidgetTableComponent, WidgetType, WidgetTypeTags, WidgetWizardCloseEventType, WidgetWizardService, WidgetWizardStep };
6158
+ export { AVAILABLE_WIDGETS, CUSTOM_WIDGET_TOKEN, DEFAULT_WIDGET_COMPONENT_MAP, FilterDropdownDataProvider, LayoutComponent, LayoutInternalComponent, LayoutModule, LayoutPublicComponent, LayoutService, ManagementWidgetDetailsComponent, TranslationManagementComponent, TranslationManagementModule, WIDGET_COLOR_ILLUSTRATION_MAP, WIDGET_COLOR_ITEMS, WIDGET_COLOR_LABELS, WIDGET_COLOR_THEME_MAP, WIDGET_DENSITY_LABELS, WIDGET_HEIGHT_1X, WIDGET_MANAGEMENT_SERVICE, WIDGET_WIDTH_1X, WIDGET_WIDTH_LABELS, WIZARD_STEP_COMPONENTS, WidgetActionButtonComponent, WidgetBlockComponent, WidgetCollectionComponent, WidgetColor, WidgetContainerComponent, WidgetCustomComponent, WidgetDensity, WidgetDisplayTypeKey, WidgetFieldComponent, WidgetFieldsService, WidgetFormioComponent, WidgetInteractiveTableComponent, WidgetInteractiveTableSearchComponent, WidgetInteractiveTableService, WidgetLayoutService, WidgetManagementCollectionComponent, WidgetManagementComponent, WidgetManagementCustomComponent, WidgetManagementEditorComponent, WidgetManagementFieldsComponent, WidgetManagementMapComponent, WidgetManagementTab, WidgetManagementTableComponent, WidgetManagementWizardComponent, WidgetMapComponent, WidgetTableComponent, WidgetType, WidgetTypeTags, WidgetWizardCloseEventType, WidgetWizardService, WidgetWizardStep };
5749
6159
  //# sourceMappingURL=valtimo-layout.mjs.map