@fuentis/phoenix-ui 0.0.9-alpha.632 → 0.0.9-alpha.634
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.
- package/fesm2022/fuentis-phoenix-ui.mjs +129 -11
- package/fesm2022/fuentis-phoenix-ui.mjs.map +1 -1
- package/index.d.ts +17 -1
- package/package.json +1 -1
|
@@ -67,11 +67,13 @@ import * as i5$2 from 'primeng/multiselect';
|
|
|
67
67
|
import { MultiSelectModule } from 'primeng/multiselect';
|
|
68
68
|
import * as i10 from 'primeng/listbox';
|
|
69
69
|
import { ListboxModule } from 'primeng/listbox';
|
|
70
|
-
import * as i12 from 'primeng/
|
|
70
|
+
import * as i12 from 'primeng/slider';
|
|
71
|
+
import { SliderModule } from 'primeng/slider';
|
|
72
|
+
import * as i13 from 'primeng/overlaybadge';
|
|
71
73
|
import { OverlayBadgeModule } from 'primeng/overlaybadge';
|
|
72
|
-
import * as
|
|
74
|
+
import * as i14 from 'primeng/ripple';
|
|
73
75
|
import { RippleModule } from 'primeng/ripple';
|
|
74
|
-
import * as
|
|
76
|
+
import * as i15 from 'primeng/floatlabel';
|
|
75
77
|
import { FloatLabelModule } from 'primeng/floatlabel';
|
|
76
78
|
import * as i2$3 from 'primeng/selectbutton';
|
|
77
79
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
@@ -1781,6 +1783,7 @@ var tableFilterType;
|
|
|
1781
1783
|
tableFilterType["BOOLEAN"] = "boolean";
|
|
1782
1784
|
tableFilterType["MULTISELECT"] = "multiselect";
|
|
1783
1785
|
tableFilterType["COMPLETNESS"] = "completness";
|
|
1786
|
+
tableFilterType["RANGE"] = "range";
|
|
1784
1787
|
// ICON = 'icon',
|
|
1785
1788
|
})(tableFilterType || (tableFilterType = {}));
|
|
1786
1789
|
|
|
@@ -2070,7 +2073,9 @@ class TableCaptionComponent {
|
|
|
2070
2073
|
? this.normalizeMultiInitial(f.selected)
|
|
2071
2074
|
: t === 'checkbox'
|
|
2072
2075
|
? !!f.selected
|
|
2073
|
-
:
|
|
2076
|
+
: t === 'range'
|
|
2077
|
+
? this.normalizeRangeInitial(f.selected, f)
|
|
2078
|
+
: f.selected ?? '';
|
|
2074
2079
|
fg.addControl(f.key, this.fb.control(initialValue));
|
|
2075
2080
|
}
|
|
2076
2081
|
this.filtersForm = fg;
|
|
@@ -2147,6 +2152,35 @@ class TableCaptionComponent {
|
|
|
2147
2152
|
return Array.isArray(selected) ? selected : [selected];
|
|
2148
2153
|
}
|
|
2149
2154
|
// ---------------------------------------------------------------------------
|
|
2155
|
+
// range helpers (UI value = [from, to]; output = { type:'range', min, max })
|
|
2156
|
+
// ---------------------------------------------------------------------------
|
|
2157
|
+
/** Full bounds of a range filter as [min, max]. */
|
|
2158
|
+
rangeBounds(cfg) {
|
|
2159
|
+
const min = Number.isFinite(cfg.min) ? cfg.min : 0;
|
|
2160
|
+
const max = Number.isFinite(cfg.max) ? cfg.max : 100;
|
|
2161
|
+
return min <= max ? [min, max] : [max, min];
|
|
2162
|
+
}
|
|
2163
|
+
/** Clamp a selected [from, to] to the config bounds; defaults to full bounds. */
|
|
2164
|
+
normalizeRangeInitial(selected, cfg) {
|
|
2165
|
+
const [min, max] = this.rangeBounds(cfg);
|
|
2166
|
+
const arr = Array.isArray(selected) ? selected : [];
|
|
2167
|
+
let from = Number(arr[0]);
|
|
2168
|
+
let to = Number(arr[1]);
|
|
2169
|
+
if (!Number.isFinite(from))
|
|
2170
|
+
from = min;
|
|
2171
|
+
if (!Number.isFinite(to))
|
|
2172
|
+
to = max;
|
|
2173
|
+
from = Math.min(Math.max(from, min), max);
|
|
2174
|
+
to = Math.min(Math.max(to, min), max);
|
|
2175
|
+
return from <= to ? [from, to] : [to, from];
|
|
2176
|
+
}
|
|
2177
|
+
/** A range is "active" only when it is narrower than the full bounds. */
|
|
2178
|
+
isRangeActive(value, cfg) {
|
|
2179
|
+
const [min, max] = this.rangeBounds(cfg);
|
|
2180
|
+
const [from, to] = this.normalizeRangeInitial(value, cfg);
|
|
2181
|
+
return from > min || to < max;
|
|
2182
|
+
}
|
|
2183
|
+
// ---------------------------------------------------------------------------
|
|
2150
2184
|
// boolean-multiselect helpers (UI value = option objects, output = boolean[])
|
|
2151
2185
|
// ---------------------------------------------------------------------------
|
|
2152
2186
|
coerceBool(x) {
|
|
@@ -2233,6 +2267,13 @@ class TableCaptionComponent {
|
|
|
2233
2267
|
out[key] = true;
|
|
2234
2268
|
continue;
|
|
2235
2269
|
}
|
|
2270
|
+
if (t === 'range') {
|
|
2271
|
+
if (this.isRangeActive(v, f)) {
|
|
2272
|
+
const [min, max] = this.normalizeRangeInitial(v, f);
|
|
2273
|
+
out[key] = { type: 'range', min, max };
|
|
2274
|
+
}
|
|
2275
|
+
continue;
|
|
2276
|
+
}
|
|
2236
2277
|
// dropdown or text:
|
|
2237
2278
|
if (v != null && v !== '')
|
|
2238
2279
|
out[key] = v;
|
|
@@ -2280,6 +2321,17 @@ class TableCaptionComponent {
|
|
|
2280
2321
|
patch[f.key] = !!patch[f.key];
|
|
2281
2322
|
continue;
|
|
2282
2323
|
}
|
|
2324
|
+
if (t === 'range') {
|
|
2325
|
+
// persisted payload is { type:'range', min, max }; map -> [from, to]
|
|
2326
|
+
const stored = patch[f.key];
|
|
2327
|
+
if (stored == null) {
|
|
2328
|
+
delete patch[f.key];
|
|
2329
|
+
}
|
|
2330
|
+
else {
|
|
2331
|
+
patch[f.key] = this.normalizeRangeInitial([stored?.min, stored?.max], f);
|
|
2332
|
+
}
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2283
2335
|
}
|
|
2284
2336
|
this.filtersForm.patchValue(patch, { emitEvent: false });
|
|
2285
2337
|
}
|
|
@@ -2351,7 +2403,11 @@ class TableCaptionComponent {
|
|
|
2351
2403
|
// ---------------------------------------------------------------------------
|
|
2352
2404
|
hasFormValues() {
|
|
2353
2405
|
const v = this.filtersForm?.value ?? {};
|
|
2354
|
-
|
|
2406
|
+
const cfgByKey = new Map(this.normalizeFilters(this.filters).map((f) => [f.key, f]));
|
|
2407
|
+
return Object.entries(v).some(([key, x]) => {
|
|
2408
|
+
const cfg = cfgByKey.get(key);
|
|
2409
|
+
if (cfg?.type === 'range')
|
|
2410
|
+
return this.isRangeActive(x, cfg);
|
|
2355
2411
|
if (x == null || x === '')
|
|
2356
2412
|
return false;
|
|
2357
2413
|
if (Array.isArray(x))
|
|
@@ -2364,6 +2420,15 @@ class TableCaptionComponent {
|
|
|
2364
2420
|
clearSelectFilter(key) {
|
|
2365
2421
|
this.filtersForm.get(key)?.setValue([], { emitEvent: true });
|
|
2366
2422
|
}
|
|
2423
|
+
/** True when a range control has been narrowed below its full bounds. */
|
|
2424
|
+
isRangeControlActive(control) {
|
|
2425
|
+
return this.isRangeActive(this.filtersForm.get(control.key)?.value, control);
|
|
2426
|
+
}
|
|
2427
|
+
/** Reset a range filter back to its full [min, max] bounds. */
|
|
2428
|
+
resetRangeFilter(control) {
|
|
2429
|
+
const [min, max] = this.rangeBounds(control);
|
|
2430
|
+
this.filtersForm.get(control.key)?.setValue([min, max], { emitEvent: true });
|
|
2431
|
+
}
|
|
2367
2432
|
resetFilters() {
|
|
2368
2433
|
this.filtersForm.reset({}, { emitEvent: true });
|
|
2369
2434
|
localStorage.removeItem(this.FILTER_KEY);
|
|
@@ -2390,7 +2455,7 @@ class TableCaptionComponent {
|
|
|
2390
2455
|
.join(', ');
|
|
2391
2456
|
}
|
|
2392
2457
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableCaptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2393
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableCaptionComponent, isStandalone: true, selector: "table-caption", inputs: { tableConfiguration: "tableConfiguration", columns: "columns", selectedItems: "selectedItems", filters: "filters", filterValidValues: "filterValidValues" }, outputs: { applyFiltersEvent: "applyFiltersEvent", applyColumnsEvent: "applyColumnsEvent", searchChange: "searchChange", actionClick: "actionClick" }, viewQueries: [{ propertyName: "filtersPopover", first: true, predicate: ["filtersPopover"], descendants: true }, { propertyName: "columnsPopover", first: true, predicate: ["columnsPopover"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex justify-content-between border-bottom-1 border-300 p-2\">\n <!-- Left: Tabs + Global actions -->\n <div class=\"flex align-items-center gap-2\">\n <phoenix-data-table-tabs\n [attr.data-cy]=\"'table-select-button-' + (tableConfiguration?.tabs?.key ?? 'tabs')\"\n [actions]=\"tableConfiguration?.tabs\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n\n @for (action of (tableConfiguration?.globalActions ?? []); track action?.key ?? $index) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n\n <!-- Right: caption filters + icons + search + more -->\n <div class=\"flex align-items-center gap-2\">\n <!-- Filters in caption row -->\n @for (control of (filters ?? []); track control.key) {\n @if (control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('dropdown') {\n <p-select\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n }\n\n @case ('boolean-multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n }\n\n @case ('checkbox') {\n <p-checkbox binary=\"true\" [formControl]=\"$any(filtersForm.get(control.key))\" />\n }\n\n @default {\n <input\n class=\"w-12rem\"\n pInputText\n [formControl]=\"$any(filtersForm.get(control.key))\"\n placeholder=\"{{ control.label | translate }}\"\n />\n }\n }\n }\n }\n\n <!-- Filter icon -->\n @if (tableConfiguration?.hasFilter) {\n @if (hasFormValues()) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n }\n }\n\n <!-- Columns icon -->\n @if (tableConfiguration?.hasColumns) {\n @if (columnsChanged) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n }\n }\n\n <!-- Search + More -->\n <div class=\"flex\">\n @if (tableConfiguration?.hasSearch) {\n <p-iconfield>\n <p-inputicon styleClass=\"pi pi-search\" />\n <input\n type=\"text\"\n pInputText\n (input)=\"emitSearch($any($event.target).value)\"\n placeholder=\"{{ 'SEARCH_KEYWORD' | translate }}\"\n />\n </p-iconfield>\n }\n\n @if (tableConfiguration?.hasMore && tableConfiguration?.moreActions) {\n <phoenix-data-table-action\n [actionConfig]=\"tableConfiguration.moreActions\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n </div>\n</div>\n\n<!-- Filters Popover -->\n<p-popover #filtersPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.FILTERS' | translate }}</div>\n <p-button\n icon=\"pi pi-refresh\"\n [text]=\"true\"\n label=\"{{ 'ACTION.CLEAR' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetFilters()\"\n />\n </div>\n\n <form [formGroup]=\"filtersForm\">\n @for (control of (filters ?? []); track control.key) {\n @if (!control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('checkbox') {\n <div class=\"mb-2\">\n <p-checkbox binary=\"true\" [formControlName]=\"control.key\" />\n <label class=\"ml-2\">{{ control.label | translate }}</label>\n </div>\n }\n\n @case ('dropdown') {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <p-select\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n </div>\n }\n\n @case ('multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @case ('boolean-multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @default {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <input\n class=\"w-full\"\n pInputText\n [formControlName]=\"control.key\"\n placeholder=\"{{ control.label | translate }}\"\n />\n </div>\n }\n }\n }\n }\n </form>\n </div>\n</p-popover>\n\n<!-- Columns Popover -->\n<p-popover #columnsPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.COLUMNS' | translate }}</div>\n <p-button\n icon=\"pi pi-eye\"\n [text]=\"true\"\n label=\"{{ 'ACTION.SHOW_ALL' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetColumns()\"\n />\n </div>\n\n <p-listbox\n [options]=\"columns\"\n [ngModel]=\"_selectedColumns\"\n (ngModelChange)=\"onColumnSelectionChange($event)\"\n [multiple]=\"true\"\n [metaKeySelection]=\"false\"\n [listStyle]=\"{ 'max-height': '420px' }\"\n [attr.data-cy]=\"'table-list-box'\"\n >\n <ng-template pTemplate=\"item\" let-item>\n @if (item | isSelected : selectedColumns) {\n <i class=\"pi pi-eye\"></i>\n } @else {\n <i class=\"pi pi-eye-slash\"></i>\n }\n <span class=\"ml-2\">{{ item.header | translate }}</span>\n </ng-template>\n </p-listbox>\n </div>\n</p-popover>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3$2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i5$2.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i5.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i4$5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i10.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["hostName", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "styleClass", "listStyle", "listStyleClass", "readonly", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop", "dropListData", "fluid"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: OverlayBadgeModule }, { kind: "component", type: i12.OverlayBadge, selector: "p-overlayBadge, p-overlay-badge, p-overlaybadge", inputs: ["styleClass", "style", "badgeSize", "severity", "value", "badgeDisabled", "size"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i13.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i14.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: PhoenixDataTableActionComponent, selector: "phoenix-data-table-action", inputs: ["actionConfig", "rowData"], outputs: ["actionClick"] }, { kind: "component", type: PhoenixDataTableTabsComponent, selector: "phoenix-data-table-tabs", inputs: ["actions"], outputs: ["actionClick"] }, { kind: "pipe", type: i4$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: IsSelectedPipe, name: "isSelected" }] });
|
|
2458
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableCaptionComponent, isStandalone: true, selector: "table-caption", inputs: { tableConfiguration: "tableConfiguration", columns: "columns", selectedItems: "selectedItems", filters: "filters", filterValidValues: "filterValidValues" }, outputs: { applyFiltersEvent: "applyFiltersEvent", applyColumnsEvent: "applyColumnsEvent", searchChange: "searchChange", actionClick: "actionClick" }, viewQueries: [{ propertyName: "filtersPopover", first: true, predicate: ["filtersPopover"], descendants: true }, { propertyName: "columnsPopover", first: true, predicate: ["columnsPopover"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex justify-content-between border-bottom-1 border-300 p-2\">\n <!-- Left: Tabs + Global actions -->\n <div class=\"flex align-items-center gap-2\">\n <phoenix-data-table-tabs\n [attr.data-cy]=\"'table-select-button-' + (tableConfiguration?.tabs?.key ?? 'tabs')\"\n [actions]=\"tableConfiguration?.tabs\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n\n @for (action of (tableConfiguration?.globalActions ?? []); track action?.key ?? $index) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n\n <!-- Right: caption filters + icons + search + more -->\n <div class=\"flex align-items-center gap-2\">\n <!-- Filters in caption row -->\n @for (control of (filters ?? []); track control.key) {\n @if (control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('dropdown') {\n <p-select\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n }\n\n @case ('boolean-multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n }\n\n @case ('checkbox') {\n <p-checkbox binary=\"true\" [formControl]=\"$any(filtersForm.get(control.key))\" />\n }\n\n @default {\n <input\n class=\"w-12rem\"\n pInputText\n [formControl]=\"$any(filtersForm.get(control.key))\"\n placeholder=\"{{ control.label | translate }}\"\n />\n }\n }\n }\n }\n\n <!-- Filter icon -->\n @if (tableConfiguration?.hasFilter) {\n @if (hasFormValues()) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n }\n }\n\n <!-- Columns icon -->\n @if (tableConfiguration?.hasColumns) {\n @if (columnsChanged) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n }\n }\n\n <!-- Search + More -->\n <div class=\"flex\">\n @if (tableConfiguration?.hasSearch) {\n <p-iconfield>\n <p-inputicon styleClass=\"pi pi-search\" />\n <input\n type=\"text\"\n pInputText\n (input)=\"emitSearch($any($event.target).value)\"\n placeholder=\"{{ 'SEARCH_KEYWORD' | translate }}\"\n />\n </p-iconfield>\n }\n\n @if (tableConfiguration?.hasMore && tableConfiguration?.moreActions) {\n <phoenix-data-table-action\n [actionConfig]=\"tableConfiguration.moreActions\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n </div>\n</div>\n\n<!-- Filters Popover -->\n<p-popover #filtersPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.FILTERS' | translate }}</div>\n <p-button\n icon=\"pi pi-refresh\"\n [text]=\"true\"\n label=\"{{ 'ACTION.CLEAR' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetFilters()\"\n />\n </div>\n\n <form [formGroup]=\"filtersForm\">\n @for (control of (filters ?? []); track control.key) {\n @if (!control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('checkbox') {\n <div class=\"mb-2\">\n <p-checkbox binary=\"true\" [formControlName]=\"control.key\" />\n <label class=\"ml-2\">{{ control.label | translate }}</label>\n </div>\n }\n\n @case ('dropdown') {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <p-select\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n </div>\n }\n\n @case ('multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @case ('range') {\n <div class=\"mb-2 px-3 py-2\">\n <label class=\"block mb-2\">{{ control.label | translate }}</label>\n <div class=\"flex justify-content-between text-sm text-600 mb-2\">\n <span>{{ filtersForm.get(control.key)?.value?.[0] ?? control.min }}</span>\n <span>{{ filtersForm.get(control.key)?.value?.[1] ?? control.max }}</span>\n </div>\n <div class=\"flex align-items-center gap-2\">\n <div class=\"flex-1 px-2\">\n <p-slider\n class=\"w-full\"\n [range]=\"true\"\n [min]=\"control.min ?? 0\"\n [max]=\"control.max ?? 100\"\n [step]=\"control.step ?? 1\"\n [formControlName]=\"control.key\"\n />\n </div>\n <p-button\n icon=\"pi pi-times\"\n [text]=\"true\"\n [rounded]=\"true\"\n size=\"small\"\n [disabled]=\"!isRangeControlActive(control)\"\n (click)=\"resetRangeFilter(control)\"\n />\n </div>\n </div>\n }\n\n @case ('boolean-multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @default {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <input\n class=\"w-full\"\n pInputText\n [formControlName]=\"control.key\"\n placeholder=\"{{ control.label | translate }}\"\n />\n </div>\n }\n }\n }\n }\n </form>\n </div>\n</p-popover>\n\n<!-- Columns Popover -->\n<p-popover #columnsPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.COLUMNS' | translate }}</div>\n <p-button\n icon=\"pi pi-eye\"\n [text]=\"true\"\n label=\"{{ 'ACTION.SHOW_ALL' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetColumns()\"\n />\n </div>\n\n <p-listbox\n [options]=\"columns\"\n [ngModel]=\"_selectedColumns\"\n (ngModelChange)=\"onColumnSelectionChange($event)\"\n [multiple]=\"true\"\n [metaKeySelection]=\"false\"\n [listStyle]=\"{ 'max-height': '420px' }\"\n [attr.data-cy]=\"'table-list-box'\"\n >\n <ng-template pTemplate=\"item\" let-item>\n @if (item | isSelected : selectedColumns) {\n <i class=\"pi pi-eye\"></i>\n } @else {\n <i class=\"pi pi-eye-slash\"></i>\n }\n <span class=\"ml-2\">{{ item.header | translate }}</span>\n </ng-template>\n </p-listbox>\n </div>\n</p-popover>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3$2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i5$2.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i5.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i4$5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i10.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["hostName", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "styleClass", "listStyle", "listStyleClass", "readonly", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop", "dropListData", "fluid"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i12.Slider, selector: "p-slider", inputs: ["animate", "min", "max", "orientation", "step", "range", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: OverlayBadgeModule }, { kind: "component", type: i13.OverlayBadge, selector: "p-overlayBadge, p-overlay-badge, p-overlaybadge", inputs: ["styleClass", "style", "badgeSize", "severity", "value", "badgeDisabled", "size"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i14.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i15.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: PhoenixDataTableActionComponent, selector: "phoenix-data-table-action", inputs: ["actionConfig", "rowData"], outputs: ["actionClick"] }, { kind: "component", type: PhoenixDataTableTabsComponent, selector: "phoenix-data-table-tabs", inputs: ["actions"], outputs: ["actionClick"] }, { kind: "pipe", type: i4$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: IsSelectedPipe, name: "isSelected" }] });
|
|
2394
2459
|
}
|
|
2395
2460
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableCaptionComponent, decorators: [{
|
|
2396
2461
|
type: Component,
|
|
@@ -2407,6 +2472,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2407
2472
|
IconFieldModule,
|
|
2408
2473
|
ListboxModule,
|
|
2409
2474
|
CheckboxModule,
|
|
2475
|
+
SliderModule,
|
|
2410
2476
|
OverlayBadgeModule,
|
|
2411
2477
|
RippleModule,
|
|
2412
2478
|
FloatLabelModule,
|
|
@@ -2414,7 +2480,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2414
2480
|
PhoenixDataTableActionComponent,
|
|
2415
2481
|
PhoenixDataTableTabsComponent,
|
|
2416
2482
|
IsSelectedPipe,
|
|
2417
|
-
], template: "<div class=\"flex justify-content-between border-bottom-1 border-300 p-2\">\n <!-- Left: Tabs + Global actions -->\n <div class=\"flex align-items-center gap-2\">\n <phoenix-data-table-tabs\n [attr.data-cy]=\"'table-select-button-' + (tableConfiguration?.tabs?.key ?? 'tabs')\"\n [actions]=\"tableConfiguration?.tabs\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n\n @for (action of (tableConfiguration?.globalActions ?? []); track action?.key ?? $index) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n\n <!-- Right: caption filters + icons + search + more -->\n <div class=\"flex align-items-center gap-2\">\n <!-- Filters in caption row -->\n @for (control of (filters ?? []); track control.key) {\n @if (control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('dropdown') {\n <p-select\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n }\n\n @case ('boolean-multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n }\n\n @case ('checkbox') {\n <p-checkbox binary=\"true\" [formControl]=\"$any(filtersForm.get(control.key))\" />\n }\n\n @default {\n <input\n class=\"w-12rem\"\n pInputText\n [formControl]=\"$any(filtersForm.get(control.key))\"\n placeholder=\"{{ control.label | translate }}\"\n />\n }\n }\n }\n }\n\n <!-- Filter icon -->\n @if (tableConfiguration?.hasFilter) {\n @if (hasFormValues()) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n }\n }\n\n <!-- Columns icon -->\n @if (tableConfiguration?.hasColumns) {\n @if (columnsChanged) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n }\n }\n\n <!-- Search + More -->\n <div class=\"flex\">\n @if (tableConfiguration?.hasSearch) {\n <p-iconfield>\n <p-inputicon styleClass=\"pi pi-search\" />\n <input\n type=\"text\"\n pInputText\n (input)=\"emitSearch($any($event.target).value)\"\n placeholder=\"{{ 'SEARCH_KEYWORD' | translate }}\"\n />\n </p-iconfield>\n }\n\n @if (tableConfiguration?.hasMore && tableConfiguration?.moreActions) {\n <phoenix-data-table-action\n [actionConfig]=\"tableConfiguration.moreActions\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n </div>\n</div>\n\n<!-- Filters Popover -->\n<p-popover #filtersPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.FILTERS' | translate }}</div>\n <p-button\n icon=\"pi pi-refresh\"\n [text]=\"true\"\n label=\"{{ 'ACTION.CLEAR' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetFilters()\"\n />\n </div>\n\n <form [formGroup]=\"filtersForm\">\n @for (control of (filters ?? []); track control.key) {\n @if (!control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('checkbox') {\n <div class=\"mb-2\">\n <p-checkbox binary=\"true\" [formControlName]=\"control.key\" />\n <label class=\"ml-2\">{{ control.label | translate }}</label>\n </div>\n }\n\n @case ('dropdown') {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <p-select\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n </div>\n }\n\n @case ('multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @case ('boolean-multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @default {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <input\n class=\"w-full\"\n pInputText\n [formControlName]=\"control.key\"\n placeholder=\"{{ control.label | translate }}\"\n />\n </div>\n }\n }\n }\n }\n </form>\n </div>\n</p-popover>\n\n<!-- Columns Popover -->\n<p-popover #columnsPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.COLUMNS' | translate }}</div>\n <p-button\n icon=\"pi pi-eye\"\n [text]=\"true\"\n label=\"{{ 'ACTION.SHOW_ALL' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetColumns()\"\n />\n </div>\n\n <p-listbox\n [options]=\"columns\"\n [ngModel]=\"_selectedColumns\"\n (ngModelChange)=\"onColumnSelectionChange($event)\"\n [multiple]=\"true\"\n [metaKeySelection]=\"false\"\n [listStyle]=\"{ 'max-height': '420px' }\"\n [attr.data-cy]=\"'table-list-box'\"\n >\n <ng-template pTemplate=\"item\" let-item>\n @if (item | isSelected : selectedColumns) {\n <i class=\"pi pi-eye\"></i>\n } @else {\n <i class=\"pi pi-eye-slash\"></i>\n }\n <span class=\"ml-2\">{{ item.header | translate }}</span>\n </ng-template>\n </p-listbox>\n </div>\n</p-popover>" }]
|
|
2483
|
+
], template: "<div class=\"flex justify-content-between border-bottom-1 border-300 p-2\">\n <!-- Left: Tabs + Global actions -->\n <div class=\"flex align-items-center gap-2\">\n <phoenix-data-table-tabs\n [attr.data-cy]=\"'table-select-button-' + (tableConfiguration?.tabs?.key ?? 'tabs')\"\n [actions]=\"tableConfiguration?.tabs\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n\n @for (action of (tableConfiguration?.globalActions ?? []); track action?.key ?? $index) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n\n <!-- Right: caption filters + icons + search + more -->\n <div class=\"flex align-items-center gap-2\">\n <!-- Filters in caption row -->\n @for (control of (filters ?? []); track control.key) {\n @if (control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('dropdown') {\n <p-select\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n }\n\n @case ('boolean-multiselect') {\n <p-multiselect\n class=\"w-12rem\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [formControl]=\"$any(filtersForm.get(control.key))\"\n [showClear]=\"true\"\n placeholder=\"{{ control.label | translate }}\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n }\n\n @case ('checkbox') {\n <p-checkbox binary=\"true\" [formControl]=\"$any(filtersForm.get(control.key))\" />\n }\n\n @default {\n <input\n class=\"w-12rem\"\n pInputText\n [formControl]=\"$any(filtersForm.get(control.key))\"\n placeholder=\"{{ control.label | translate }}\"\n />\n }\n }\n }\n }\n\n <!-- Filter icon -->\n @if (tableConfiguration?.hasFilter) {\n @if (hasFormValues()) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"filtersPopover?.toggle($event)\">\n <i class=\"pi pi-filter\"></i>\n </span>\n }\n }\n\n <!-- Columns icon -->\n @if (tableConfiguration?.hasColumns) {\n @if (columnsChanged) {\n <p-overlaybadge class=\"p-2\" severity=\"danger\">\n <span pRipple class=\"cursor-pointer\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n </p-overlaybadge>\n } @else {\n <span pRipple class=\"cursor-pointer p-2\" (click)=\"columnsPopover?.toggle($event)\">\n <i class=\"pi pi-sliders-v\"></i>\n </span>\n }\n }\n\n <!-- Search + More -->\n <div class=\"flex\">\n @if (tableConfiguration?.hasSearch) {\n <p-iconfield>\n <p-inputicon styleClass=\"pi pi-search\" />\n <input\n type=\"text\"\n pInputText\n (input)=\"emitSearch($any($event.target).value)\"\n placeholder=\"{{ 'SEARCH_KEYWORD' | translate }}\"\n />\n </p-iconfield>\n }\n\n @if (tableConfiguration?.hasMore && tableConfiguration?.moreActions) {\n <phoenix-data-table-action\n [actionConfig]=\"tableConfiguration.moreActions\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n }\n </div>\n </div>\n</div>\n\n<!-- Filters Popover -->\n<p-popover #filtersPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.FILTERS' | translate }}</div>\n <p-button\n icon=\"pi pi-refresh\"\n [text]=\"true\"\n label=\"{{ 'ACTION.CLEAR' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetFilters()\"\n />\n </div>\n\n <form [formGroup]=\"filtersForm\">\n @for (control of (filters ?? []); track control.key) {\n @if (!control.isInCaption) {\n @switch (control.type ?? (control.options?.length ? 'dropdown' : 'text')) {\n @case ('checkbox') {\n <div class=\"mb-2\">\n <p-checkbox binary=\"true\" [formControlName]=\"control.key\" />\n <label class=\"ml-2\">{{ control.label | translate }}</label>\n </div>\n }\n\n @case ('dropdown') {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <p-select\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"filtersForm.get(control.key)?.setValue('')\"\n />\n </div>\n }\n\n @case ('multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [optionValue]=\"control.optionValue ?? 'key'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n />\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @case ('range') {\n <div class=\"mb-2 px-3 py-2\">\n <label class=\"block mb-2\">{{ control.label | translate }}</label>\n <div class=\"flex justify-content-between text-sm text-600 mb-2\">\n <span>{{ filtersForm.get(control.key)?.value?.[0] ?? control.min }}</span>\n <span>{{ filtersForm.get(control.key)?.value?.[1] ?? control.max }}</span>\n </div>\n <div class=\"flex align-items-center gap-2\">\n <div class=\"flex-1 px-2\">\n <p-slider\n class=\"w-full\"\n [range]=\"true\"\n [min]=\"control.min ?? 0\"\n [max]=\"control.max ?? 100\"\n [step]=\"control.step ?? 1\"\n [formControlName]=\"control.key\"\n />\n </div>\n <p-button\n icon=\"pi pi-times\"\n [text]=\"true\"\n [rounded]=\"true\"\n size=\"small\"\n [disabled]=\"!isRangeControlActive(control)\"\n (click)=\"resetRangeFilter(control)\"\n />\n </div>\n </div>\n }\n\n @case ('boolean-multiselect') {\n <div class=\"mb-2\">\n <p-floatlabel variant=\"on\">\n <p-multiselect\n class=\"w-full\"\n [options]=\"control.options ?? []\"\n [optionLabel]=\"control.optionLabel ?? 'label'\"\n [showClear]=\"true\"\n [formControlName]=\"control.key\"\n (onClear)=\"clearSelectFilter(control.key)\"\n >\n <ng-template pTemplate=\"selectedItems\" let-value>\n @if ((value?.length ?? 0) === 0) {\n <span class=\"p-2 text-500\">{{ control.label | translate }}</span>\n } @else {\n <span class=\"p-2\">{{ getSelectedLabels(value, control) }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-item>\n <span>{{ item?.[control.optionLabel ?? 'label'] }}</span>\n </ng-template>\n </p-multiselect>\n <label>{{ control.label | translate }}</label>\n </p-floatlabel>\n </div>\n }\n\n @default {\n <div class=\"mb-2\">\n <label class=\"mb-2 block\">{{ control.label | translate }}</label>\n <input\n class=\"w-full\"\n pInputText\n [formControlName]=\"control.key\"\n placeholder=\"{{ control.label | translate }}\"\n />\n </div>\n }\n }\n }\n }\n </form>\n </div>\n</p-popover>\n\n<!-- Columns Popover -->\n<p-popover #columnsPopover>\n <div class=\"flex flex-column gap-3 w-25rem\">\n <div class=\"flex justify-content-between align-items-center\">\n <div class=\"text-lg font-bold\">{{ 'LABELS.COLUMNS' | translate }}</div>\n <p-button\n icon=\"pi pi-eye\"\n [text]=\"true\"\n label=\"{{ 'ACTION.SHOW_ALL' | translate }}\"\n class=\"mr-2\"\n (click)=\"resetColumns()\"\n />\n </div>\n\n <p-listbox\n [options]=\"columns\"\n [ngModel]=\"_selectedColumns\"\n (ngModelChange)=\"onColumnSelectionChange($event)\"\n [multiple]=\"true\"\n [metaKeySelection]=\"false\"\n [listStyle]=\"{ 'max-height': '420px' }\"\n [attr.data-cy]=\"'table-list-box'\"\n >\n <ng-template pTemplate=\"item\" let-item>\n @if (item | isSelected : selectedColumns) {\n <i class=\"pi pi-eye\"></i>\n } @else {\n <i class=\"pi pi-eye-slash\"></i>\n }\n <span class=\"ml-2\">{{ item.header | translate }}</span>\n </ng-template>\n </p-listbox>\n </div>\n</p-popover>" }]
|
|
2418
2484
|
}], propDecorators: { filtersPopover: [{
|
|
2419
2485
|
type: ViewChild,
|
|
2420
2486
|
args: ['filtersPopover']
|
|
@@ -3446,6 +3512,13 @@ class TableComponent {
|
|
|
3446
3512
|
let hasStale = false;
|
|
3447
3513
|
const result = {};
|
|
3448
3514
|
for (const [key, filterValue] of Object.entries(this.currentFilters)) {
|
|
3515
|
+
// Range filters carry numeric bounds, not enumerable option values — never stale.
|
|
3516
|
+
if (filterValue &&
|
|
3517
|
+
typeof filterValue === 'object' &&
|
|
3518
|
+
!Array.isArray(filterValue) &&
|
|
3519
|
+
filterValue.type === 'range') {
|
|
3520
|
+
continue;
|
|
3521
|
+
}
|
|
3449
3522
|
const values = Array.isArray(filterValue) ? filterValue : filterValue != null ? [filterValue] : [];
|
|
3450
3523
|
if (!values.length)
|
|
3451
3524
|
continue;
|
|
@@ -3501,6 +3574,16 @@ class TableComponent {
|
|
|
3501
3574
|
(Array.isArray(filterValue) && filterValue.length === 0))
|
|
3502
3575
|
return true;
|
|
3503
3576
|
const itemValue = this.getNestedValue(item, key);
|
|
3577
|
+
// Range filter: { type: 'range', min, max } -> numeric between check
|
|
3578
|
+
if (filterValue &&
|
|
3579
|
+
typeof filterValue === 'object' &&
|
|
3580
|
+
!Array.isArray(filterValue) &&
|
|
3581
|
+
filterValue.type === 'range') {
|
|
3582
|
+
const num = Number(itemValue);
|
|
3583
|
+
if (!Number.isFinite(num))
|
|
3584
|
+
return false;
|
|
3585
|
+
return num >= filterValue.min && num <= filterValue.max;
|
|
3586
|
+
}
|
|
3504
3587
|
// Ako je itemValue niz (kao u scopes)
|
|
3505
3588
|
if (Array.isArray(itemValue)) {
|
|
3506
3589
|
return filterValue.some((option) => {
|
|
@@ -10263,16 +10346,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10263
10346
|
type: Input
|
|
10264
10347
|
}] } });
|
|
10265
10348
|
|
|
10349
|
+
/**
|
|
10350
|
+
* Splits a flat list of fields into row chunks for grid rendering.
|
|
10351
|
+
* A field with `style.newRow === true` always starts a fresh row,
|
|
10352
|
+
* regardless of how much space is left in the current row.
|
|
10353
|
+
* Fields without `newRow` keep flowing into the current row (existing
|
|
10354
|
+
* PrimeFlex wrap-by-colWidth behavior is preserved within each chunk).
|
|
10355
|
+
*/
|
|
10356
|
+
function splitControlsIntoRows(controls) {
|
|
10357
|
+
if (!controls || !controls.length)
|
|
10358
|
+
return [];
|
|
10359
|
+
const rows = [];
|
|
10360
|
+
let current = [];
|
|
10361
|
+
for (const field of controls) {
|
|
10362
|
+
if (field?.style?.newRow && current.length) {
|
|
10363
|
+
rows.push(current);
|
|
10364
|
+
current = [];
|
|
10365
|
+
}
|
|
10366
|
+
current.push(field);
|
|
10367
|
+
}
|
|
10368
|
+
if (current.length)
|
|
10369
|
+
rows.push(current);
|
|
10370
|
+
return rows;
|
|
10371
|
+
}
|
|
10372
|
+
|
|
10266
10373
|
class MetaFormGroupV2Component {
|
|
10267
10374
|
group;
|
|
10268
10375
|
form;
|
|
10269
10376
|
readOnly = false;
|
|
10377
|
+
/** Group's fields split into row chunks, honoring `style.newRow` hard breaks. */
|
|
10378
|
+
get rows() {
|
|
10379
|
+
return splitControlsIntoRows(this.group?.ctrl);
|
|
10380
|
+
}
|
|
10270
10381
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MetaFormGroupV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10271
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MetaFormGroupV2Component, isStandalone: true, selector: "phoenix-meta-form-group-v2", inputs: { group: "group", form: "form", readOnly: "readOnly" }, ngImport: i0, template: "<div class=\"pho-group\" [formGroup]=\"form\">\n <div class=\"grid\">\n
|
|
10382
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MetaFormGroupV2Component, isStandalone: true, selector: "phoenix-meta-form-group-v2", inputs: { group: "group", form: "form", readOnly: "readOnly" }, ngImport: i0, template: "<div class=\"pho-group\" [formGroup]=\"form\">\n @for (row of rows; track $index) {\n <div class=\"grid\">\n @for (f of row; track f?.configuration?.key) {\n <div [ngClass]=\"f.style.colWidth || 'col-12 md:col-6'\">\n <phoenix-meta-form-field-v2 [field]=\"f\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-field-v2>\n </div>\n }\n </div>\n }\n\n</div>", styles: [".pho-group{margin-bottom:16px}.pho-group__title{font-weight:700;margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MetaFormFieldV2Component, selector: "phoenix-meta-form-field-v2", inputs: ["field", "form", "readOnly", "disableForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10272
10383
|
}
|
|
10273
10384
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MetaFormGroupV2Component, decorators: [{
|
|
10274
10385
|
type: Component,
|
|
10275
|
-
args: [{ selector: 'phoenix-meta-form-group-v2', standalone: true, imports: [CommonModule, ReactiveFormsModule, MetaFormFieldV2Component], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pho-group\" [formGroup]=\"form\">\n <div class=\"grid\">\n
|
|
10386
|
+
args: [{ selector: 'phoenix-meta-form-group-v2', standalone: true, imports: [CommonModule, ReactiveFormsModule, MetaFormFieldV2Component], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pho-group\" [formGroup]=\"form\">\n @for (row of rows; track $index) {\n <div class=\"grid\">\n @for (f of row; track f?.configuration?.key) {\n <div [ngClass]=\"f.style.colWidth || 'col-12 md:col-6'\">\n <phoenix-meta-form-field-v2 [field]=\"f\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-field-v2>\n </div>\n }\n </div>\n }\n\n</div>", styles: [".pho-group{margin-bottom:16px}.pho-group__title{font-weight:700;margin-bottom:8px}\n"] }]
|
|
10276
10387
|
}], propDecorators: { group: [{
|
|
10277
10388
|
type: Input,
|
|
10278
10389
|
args: [{ required: true }]
|
|
@@ -10885,6 +10996,13 @@ class MetaFormV2Component {
|
|
|
10885
10996
|
get flatControls() {
|
|
10886
10997
|
return this.config?.controls ?? [];
|
|
10887
10998
|
}
|
|
10999
|
+
/**
|
|
11000
|
+
* Flat schema split into row chunks, honoring `style.newRow` hard breaks.
|
|
11001
|
+
* Used by the non-grouped grid template.
|
|
11002
|
+
*/
|
|
11003
|
+
get controlRows() {
|
|
11004
|
+
return splitControlsIntoRows(this.flatControls);
|
|
11005
|
+
}
|
|
10888
11006
|
/** TrackBy for group rendering */
|
|
10889
11007
|
groupTrack(g, idx) {
|
|
10890
11008
|
return g?.id ?? idx;
|
|
@@ -10992,7 +11110,7 @@ class MetaFormV2Component {
|
|
|
10992
11110
|
this.depCleanup?.();
|
|
10993
11111
|
}
|
|
10994
11112
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MetaFormV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10995
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MetaFormV2Component, isStandalone: true, selector: "phoenix-meta-form-v2", inputs: { form: "form", config: "config", readOnly: "readOnly", contentStyle: "contentStyle", contentClass: "contentClass" }, usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"form\">\n @if (hasControls) {\n\n @if (isGrouped) {\n <p-accordion\n [multiple]=\"true\"\n [value]=\"expandedGroupIds\"\n (valueChange)=\"onAccordionValueChange($event)\"\n >\n @for (g of groupedControls; track groupTrack(g, $index)) {\n <p-accordion-panel [value]=\"panelValue(g)\">\n <p-accordion-header>\n\n <!-- plus/minus toggle icon -->\n <ng-template #toggleicon let-active=\"active\">\n @if (active) {\n <i class=\"pi pi-minus-circle\"></i>\n } @else {\n <i class=\"pi pi-plus-circle\"></i>\n }\n </ng-template>\n\n {{ g?.groupName | translate }}\n </p-accordion-header>\n \n <p-accordion-content>\n <div [ngStyle]=\"contentStyle\" [ngClass]=\"contentClass\">\n <phoenix-meta-form-group-v2 [group]=\"g\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-group-v2>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n\n } @else {\n <div class=\"grid\">\n
|
|
11113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MetaFormV2Component, isStandalone: true, selector: "phoenix-meta-form-v2", inputs: { form: "form", config: "config", readOnly: "readOnly", contentStyle: "contentStyle", contentClass: "contentClass" }, usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"form\">\n @if (hasControls) {\n\n @if (isGrouped) {\n <p-accordion\n [multiple]=\"true\"\n [value]=\"expandedGroupIds\"\n (valueChange)=\"onAccordionValueChange($event)\"\n >\n @for (g of groupedControls; track groupTrack(g, $index)) {\n <p-accordion-panel [value]=\"panelValue(g)\">\n <p-accordion-header>\n\n <!-- plus/minus toggle icon -->\n <ng-template #toggleicon let-active=\"active\">\n @if (active) {\n <i class=\"pi pi-minus-circle\"></i>\n } @else {\n <i class=\"pi pi-plus-circle\"></i>\n }\n </ng-template>\n\n {{ g?.groupName | translate }}\n </p-accordion-header>\n \n <p-accordion-content>\n <div [ngStyle]=\"contentStyle\" [ngClass]=\"contentClass\">\n <phoenix-meta-form-group-v2 [group]=\"g\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-group-v2>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n\n } @else {\n @for (row of controlRows; track $index) {\n <div class=\"grid\">\n @for (f of row; track f.configuration.key) {\n <div [ngClass]=\"f.style.colWidth ?? 'col-12 md:col-6'\">\n <phoenix-meta-form-field-v2 [field]=\"f\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-field-v2>\n </div>\n }\n </div>\n }\n }\n\n }\n</div>", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i3$1.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i3$1.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i3$1.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i3$1.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: MetaFormFieldV2Component, selector: "phoenix-meta-form-field-v2", inputs: ["field", "form", "readOnly", "disableForm"] }, { kind: "component", type: MetaFormGroupV2Component, selector: "phoenix-meta-form-group-v2", inputs: ["group", "form", "readOnly"] }, { kind: "pipe", type: i4$2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10996
11114
|
}
|
|
10997
11115
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MetaFormV2Component, decorators: [{
|
|
10998
11116
|
type: Component,
|
|
@@ -11003,7 +11121,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
11003
11121
|
TranslateModule,
|
|
11004
11122
|
MetaFormFieldV2Component,
|
|
11005
11123
|
MetaFormGroupV2Component,
|
|
11006
|
-
], template: "<div [formGroup]=\"form\">\n @if (hasControls) {\n\n @if (isGrouped) {\n <p-accordion\n [multiple]=\"true\"\n [value]=\"expandedGroupIds\"\n (valueChange)=\"onAccordionValueChange($event)\"\n >\n @for (g of groupedControls; track groupTrack(g, $index)) {\n <p-accordion-panel [value]=\"panelValue(g)\">\n <p-accordion-header>\n\n <!-- plus/minus toggle icon -->\n <ng-template #toggleicon let-active=\"active\">\n @if (active) {\n <i class=\"pi pi-minus-circle\"></i>\n } @else {\n <i class=\"pi pi-plus-circle\"></i>\n }\n </ng-template>\n\n {{ g?.groupName | translate }}\n </p-accordion-header>\n \n <p-accordion-content>\n <div [ngStyle]=\"contentStyle\" [ngClass]=\"contentClass\">\n <phoenix-meta-form-group-v2 [group]=\"g\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-group-v2>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n\n } @else {\n <div class=\"grid\">\n
|
|
11124
|
+
], template: "<div [formGroup]=\"form\">\n @if (hasControls) {\n\n @if (isGrouped) {\n <p-accordion\n [multiple]=\"true\"\n [value]=\"expandedGroupIds\"\n (valueChange)=\"onAccordionValueChange($event)\"\n >\n @for (g of groupedControls; track groupTrack(g, $index)) {\n <p-accordion-panel [value]=\"panelValue(g)\">\n <p-accordion-header>\n\n <!-- plus/minus toggle icon -->\n <ng-template #toggleicon let-active=\"active\">\n @if (active) {\n <i class=\"pi pi-minus-circle\"></i>\n } @else {\n <i class=\"pi pi-plus-circle\"></i>\n }\n </ng-template>\n\n {{ g?.groupName | translate }}\n </p-accordion-header>\n \n <p-accordion-content>\n <div [ngStyle]=\"contentStyle\" [ngClass]=\"contentClass\">\n <phoenix-meta-form-group-v2 [group]=\"g\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-group-v2>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n\n } @else {\n @for (row of controlRows; track $index) {\n <div class=\"grid\">\n @for (f of row; track f.configuration.key) {\n <div [ngClass]=\"f.style.colWidth ?? 'col-12 md:col-6'\">\n <phoenix-meta-form-field-v2 [field]=\"f\" [form]=\"form\" [readOnly]=\"readOnly\"></phoenix-meta-form-field-v2>\n </div>\n }\n </div>\n }\n }\n\n }\n</div>", styles: [":host{display:block}\n"] }]
|
|
11007
11125
|
}], propDecorators: { form: [{
|
|
11008
11126
|
type: Input,
|
|
11009
11127
|
args: [{ required: true }]
|