@fuentis/phoenix-ui 0.0.9-alpha.633 → 0.0.9-alpha.635
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 +159 -10
- package/fesm2022/fuentis-phoenix-ui.mjs.map +1 -1
- package/index.d.ts +20 -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;
|
|
@@ -2114,7 +2119,13 @@ class TableCaptionComponent {
|
|
|
2114
2119
|
});
|
|
2115
2120
|
}
|
|
2116
2121
|
buildSignature(tableKey, filtersCfg) {
|
|
2117
|
-
const keys = (filtersCfg ?? [])
|
|
2122
|
+
const keys = (filtersCfg ?? [])
|
|
2123
|
+
.map((f) =>
|
|
2124
|
+
// Range bounds are data-derived and can change without the key set
|
|
2125
|
+
// changing; fold them into the signature so the form rebuilds when
|
|
2126
|
+
// the min/max move.
|
|
2127
|
+
f.type === 'range' ? `${f.key}:${f.min}-${f.max}` : f.key)
|
|
2128
|
+
.join('|');
|
|
2118
2129
|
return `${tableKey ?? 'table'}::${keys}`;
|
|
2119
2130
|
}
|
|
2120
2131
|
applyValidValuesPatch(validMap) {
|
|
@@ -2147,6 +2158,35 @@ class TableCaptionComponent {
|
|
|
2147
2158
|
return Array.isArray(selected) ? selected : [selected];
|
|
2148
2159
|
}
|
|
2149
2160
|
// ---------------------------------------------------------------------------
|
|
2161
|
+
// range helpers (UI value = [from, to]; output = { type:'range', min, max })
|
|
2162
|
+
// ---------------------------------------------------------------------------
|
|
2163
|
+
/** Full bounds of a range filter as [min, max]. */
|
|
2164
|
+
rangeBounds(cfg) {
|
|
2165
|
+
const min = Number.isFinite(cfg.min) ? cfg.min : 0;
|
|
2166
|
+
const max = Number.isFinite(cfg.max) ? cfg.max : 100;
|
|
2167
|
+
return min <= max ? [min, max] : [max, min];
|
|
2168
|
+
}
|
|
2169
|
+
/** Clamp a selected [from, to] to the config bounds; defaults to full bounds. */
|
|
2170
|
+
normalizeRangeInitial(selected, cfg) {
|
|
2171
|
+
const [min, max] = this.rangeBounds(cfg);
|
|
2172
|
+
const arr = Array.isArray(selected) ? selected : [];
|
|
2173
|
+
let from = Number(arr[0]);
|
|
2174
|
+
let to = Number(arr[1]);
|
|
2175
|
+
if (!Number.isFinite(from))
|
|
2176
|
+
from = min;
|
|
2177
|
+
if (!Number.isFinite(to))
|
|
2178
|
+
to = max;
|
|
2179
|
+
from = Math.min(Math.max(from, min), max);
|
|
2180
|
+
to = Math.min(Math.max(to, min), max);
|
|
2181
|
+
return from <= to ? [from, to] : [to, from];
|
|
2182
|
+
}
|
|
2183
|
+
/** A range is "active" only when it is narrower than the full bounds. */
|
|
2184
|
+
isRangeActive(value, cfg) {
|
|
2185
|
+
const [min, max] = this.rangeBounds(cfg);
|
|
2186
|
+
const [from, to] = this.normalizeRangeInitial(value, cfg);
|
|
2187
|
+
return from > min || to < max;
|
|
2188
|
+
}
|
|
2189
|
+
// ---------------------------------------------------------------------------
|
|
2150
2190
|
// boolean-multiselect helpers (UI value = option objects, output = boolean[])
|
|
2151
2191
|
// ---------------------------------------------------------------------------
|
|
2152
2192
|
coerceBool(x) {
|
|
@@ -2233,6 +2273,13 @@ class TableCaptionComponent {
|
|
|
2233
2273
|
out[key] = true;
|
|
2234
2274
|
continue;
|
|
2235
2275
|
}
|
|
2276
|
+
if (t === 'range') {
|
|
2277
|
+
if (this.isRangeActive(v, f)) {
|
|
2278
|
+
const [min, max] = this.normalizeRangeInitial(v, f);
|
|
2279
|
+
out[key] = { type: 'range', min, max };
|
|
2280
|
+
}
|
|
2281
|
+
continue;
|
|
2282
|
+
}
|
|
2236
2283
|
// dropdown or text:
|
|
2237
2284
|
if (v != null && v !== '')
|
|
2238
2285
|
out[key] = v;
|
|
@@ -2280,6 +2327,17 @@ class TableCaptionComponent {
|
|
|
2280
2327
|
patch[f.key] = !!patch[f.key];
|
|
2281
2328
|
continue;
|
|
2282
2329
|
}
|
|
2330
|
+
if (t === 'range') {
|
|
2331
|
+
// persisted payload is { type:'range', min, max }; map -> [from, to]
|
|
2332
|
+
const stored = patch[f.key];
|
|
2333
|
+
if (stored == null) {
|
|
2334
|
+
delete patch[f.key];
|
|
2335
|
+
}
|
|
2336
|
+
else {
|
|
2337
|
+
patch[f.key] = this.normalizeRangeInitial([stored?.min, stored?.max], f);
|
|
2338
|
+
}
|
|
2339
|
+
continue;
|
|
2340
|
+
}
|
|
2283
2341
|
}
|
|
2284
2342
|
this.filtersForm.patchValue(patch, { emitEvent: false });
|
|
2285
2343
|
}
|
|
@@ -2351,7 +2409,11 @@ class TableCaptionComponent {
|
|
|
2351
2409
|
// ---------------------------------------------------------------------------
|
|
2352
2410
|
hasFormValues() {
|
|
2353
2411
|
const v = this.filtersForm?.value ?? {};
|
|
2354
|
-
|
|
2412
|
+
const cfgByKey = new Map(this.normalizeFilters(this.filters).map((f) => [f.key, f]));
|
|
2413
|
+
return Object.entries(v).some(([key, x]) => {
|
|
2414
|
+
const cfg = cfgByKey.get(key);
|
|
2415
|
+
if (cfg?.type === 'range')
|
|
2416
|
+
return this.isRangeActive(x, cfg);
|
|
2355
2417
|
if (x == null || x === '')
|
|
2356
2418
|
return false;
|
|
2357
2419
|
if (Array.isArray(x))
|
|
@@ -2364,6 +2426,15 @@ class TableCaptionComponent {
|
|
|
2364
2426
|
clearSelectFilter(key) {
|
|
2365
2427
|
this.filtersForm.get(key)?.setValue([], { emitEvent: true });
|
|
2366
2428
|
}
|
|
2429
|
+
/** True when a range control has been narrowed below its full bounds. */
|
|
2430
|
+
isRangeControlActive(control) {
|
|
2431
|
+
return this.isRangeActive(this.filtersForm.get(control.key)?.value, control);
|
|
2432
|
+
}
|
|
2433
|
+
/** Reset a range filter back to its full [min, max] bounds. */
|
|
2434
|
+
resetRangeFilter(control) {
|
|
2435
|
+
const [min, max] = this.rangeBounds(control);
|
|
2436
|
+
this.filtersForm.get(control.key)?.setValue([min, max], { emitEvent: true });
|
|
2437
|
+
}
|
|
2367
2438
|
resetFilters() {
|
|
2368
2439
|
this.filtersForm.reset({}, { emitEvent: true });
|
|
2369
2440
|
localStorage.removeItem(this.FILTER_KEY);
|
|
@@ -2390,7 +2461,7 @@ class TableCaptionComponent {
|
|
|
2390
2461
|
.join(', ');
|
|
2391
2462
|
}
|
|
2392
2463
|
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" }] });
|
|
2464
|
+
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
2465
|
}
|
|
2395
2466
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableCaptionComponent, decorators: [{
|
|
2396
2467
|
type: Component,
|
|
@@ -2407,6 +2478,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2407
2478
|
IconFieldModule,
|
|
2408
2479
|
ListboxModule,
|
|
2409
2480
|
CheckboxModule,
|
|
2481
|
+
SliderModule,
|
|
2410
2482
|
OverlayBadgeModule,
|
|
2411
2483
|
RippleModule,
|
|
2412
2484
|
FloatLabelModule,
|
|
@@ -2414,7 +2486,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2414
2486
|
PhoenixDataTableActionComponent,
|
|
2415
2487
|
PhoenixDataTableTabsComponent,
|
|
2416
2488
|
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>" }]
|
|
2489
|
+
], 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
2490
|
}], propDecorators: { filtersPopover: [{
|
|
2419
2491
|
type: ViewChild,
|
|
2420
2492
|
args: ['filtersPopover']
|
|
@@ -2982,6 +3054,13 @@ class TableComponent {
|
|
|
2982
3054
|
selectedColumnsInput = [];
|
|
2983
3055
|
tableConfiguration;
|
|
2984
3056
|
filters;
|
|
3057
|
+
/**
|
|
3058
|
+
* Filters passed down to table-caption.
|
|
3059
|
+
* Identical to `filters`, except range filters get their numeric bounds
|
|
3060
|
+
* (min/max) derived from the actual dataset so the slider reflects the
|
|
3061
|
+
* real values present in the table. Explicit min/max in config still win.
|
|
3062
|
+
*/
|
|
3063
|
+
computedFilters = [];
|
|
2985
3064
|
// ============================================================
|
|
2986
3065
|
// OUTPUTS
|
|
2987
3066
|
// ============================================================
|
|
@@ -3152,6 +3231,8 @@ class TableComponent {
|
|
|
3152
3231
|
*/
|
|
3153
3232
|
set data(value) {
|
|
3154
3233
|
this.originalData = value ?? [];
|
|
3234
|
+
// Recompute range-filter bounds from the new dataset.
|
|
3235
|
+
this.enrichRangeFilters();
|
|
3155
3236
|
if (Object.keys(this.currentFilters).length > 0) {
|
|
3156
3237
|
const validMap = this.getValidFilterValues();
|
|
3157
3238
|
if (validMap) {
|
|
@@ -3185,6 +3266,10 @@ class TableComponent {
|
|
|
3185
3266
|
ngOnChanges(changes) {
|
|
3186
3267
|
// clear selection on inputs update (safe default behavior)
|
|
3187
3268
|
this.selectedItems.set([]);
|
|
3269
|
+
// Keep computedFilters in sync when the filters config changes.
|
|
3270
|
+
if (changes['filters']) {
|
|
3271
|
+
this.enrichRangeFilters();
|
|
3272
|
+
}
|
|
3188
3273
|
if (this.tableConfiguration?.key) {
|
|
3189
3274
|
this.SORT_KEY = `sort_${this.tableConfiguration.key}`;
|
|
3190
3275
|
}
|
|
@@ -3446,6 +3531,13 @@ class TableComponent {
|
|
|
3446
3531
|
let hasStale = false;
|
|
3447
3532
|
const result = {};
|
|
3448
3533
|
for (const [key, filterValue] of Object.entries(this.currentFilters)) {
|
|
3534
|
+
// Range filters carry numeric bounds, not enumerable option values — never stale.
|
|
3535
|
+
if (filterValue &&
|
|
3536
|
+
typeof filterValue === 'object' &&
|
|
3537
|
+
!Array.isArray(filterValue) &&
|
|
3538
|
+
filterValue.type === 'range') {
|
|
3539
|
+
continue;
|
|
3540
|
+
}
|
|
3449
3541
|
const values = Array.isArray(filterValue) ? filterValue : filterValue != null ? [filterValue] : [];
|
|
3450
3542
|
if (!values.length)
|
|
3451
3543
|
continue;
|
|
@@ -3501,6 +3593,16 @@ class TableComponent {
|
|
|
3501
3593
|
(Array.isArray(filterValue) && filterValue.length === 0))
|
|
3502
3594
|
return true;
|
|
3503
3595
|
const itemValue = this.getNestedValue(item, key);
|
|
3596
|
+
// Range filter: { type: 'range', min, max } -> numeric between check
|
|
3597
|
+
if (filterValue &&
|
|
3598
|
+
typeof filterValue === 'object' &&
|
|
3599
|
+
!Array.isArray(filterValue) &&
|
|
3600
|
+
filterValue.type === 'range') {
|
|
3601
|
+
const num = Number(itemValue);
|
|
3602
|
+
if (!Number.isFinite(num))
|
|
3603
|
+
return false;
|
|
3604
|
+
return num >= filterValue.min && num <= filterValue.max;
|
|
3605
|
+
}
|
|
3504
3606
|
// Ako je itemValue niz (kao u scopes)
|
|
3505
3607
|
if (Array.isArray(itemValue)) {
|
|
3506
3608
|
return filterValue.some((option) => {
|
|
@@ -3526,6 +3628,53 @@ class TableComponent {
|
|
|
3526
3628
|
});
|
|
3527
3629
|
});
|
|
3528
3630
|
}
|
|
3631
|
+
// ============================================================
|
|
3632
|
+
// RANGE FILTER BOUNDS
|
|
3633
|
+
// ============================================================
|
|
3634
|
+
/**
|
|
3635
|
+
* Rebuild `computedFilters` from `filters`, deriving numeric bounds
|
|
3636
|
+
* (min/max) for every range filter from the current dataset.
|
|
3637
|
+
* An explicitly configured min/max always wins over the data-derived value.
|
|
3638
|
+
*/
|
|
3639
|
+
enrichRangeFilters() {
|
|
3640
|
+
const list = Array.isArray(this.filters) ? this.filters : [];
|
|
3641
|
+
this.computedFilters = list.map((f) => {
|
|
3642
|
+
if (f?.type !== 'range')
|
|
3643
|
+
return f;
|
|
3644
|
+
const explicitMin = Number.isFinite(f.min) ? f.min : undefined;
|
|
3645
|
+
const explicitMax = Number.isFinite(f.max) ? f.max : undefined;
|
|
3646
|
+
// Both bounds provided by config -> nothing to compute.
|
|
3647
|
+
if (explicitMin !== undefined && explicitMax !== undefined)
|
|
3648
|
+
return f;
|
|
3649
|
+
const bounds = this.computeDataBounds(f.key);
|
|
3650
|
+
return {
|
|
3651
|
+
...f,
|
|
3652
|
+
min: explicitMin ?? bounds.min,
|
|
3653
|
+
max: explicitMax ?? bounds.max,
|
|
3654
|
+
};
|
|
3655
|
+
});
|
|
3656
|
+
}
|
|
3657
|
+
/**
|
|
3658
|
+
* Min/max numeric bounds for a field across originalData.
|
|
3659
|
+
* Falls back to [0, 100] when no numeric values are present.
|
|
3660
|
+
*/
|
|
3661
|
+
computeDataBounds(key) {
|
|
3662
|
+
let min = Infinity;
|
|
3663
|
+
let max = -Infinity;
|
|
3664
|
+
for (const item of this.originalData) {
|
|
3665
|
+
const num = Number(this.getNestedValue(item, key));
|
|
3666
|
+
if (!Number.isFinite(num))
|
|
3667
|
+
continue;
|
|
3668
|
+
if (num < min)
|
|
3669
|
+
min = num;
|
|
3670
|
+
if (num > max)
|
|
3671
|
+
max = num;
|
|
3672
|
+
}
|
|
3673
|
+
if (!Number.isFinite(min) || !Number.isFinite(max)) {
|
|
3674
|
+
return { min: 0, max: 100 };
|
|
3675
|
+
}
|
|
3676
|
+
return { min, max };
|
|
3677
|
+
}
|
|
3529
3678
|
/**
|
|
3530
3679
|
* Reads nested values using dot paths and unwraps `.key` when present.
|
|
3531
3680
|
*/
|
|
@@ -3675,7 +3824,7 @@ class TableComponent {
|
|
|
3675
3824
|
});
|
|
3676
3825
|
}
|
|
3677
3826
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3678
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableComponent, isStandalone: true, selector: "phoenix-table", inputs: { columns: "columns", selectedColumnsInput: "selectedColumnsInput", tableConfiguration: "tableConfiguration", filters: "filters", data: "data" }, outputs: { actionClick: "actionClick", rowSelection: "rowSelection", checkBoxSelection: "checkBoxSelection", saveColumns: "saveColumns" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"border-1 border-round-sm border-300 border-round-md m-2\">\n @if (selectedItems().length === 0) {\n <table-caption\n [columns]=\"columns\"\n [tableConfiguration]=\"tableConfiguration\"\n [filters]=\"filters\"\n [selectedItems]=\"selectedItems()\"\n [filterValidValues]=\"filterValidValues\"\n (applyFiltersEvent)=\"applyFilters($event)\"\n (applyColumnsEvent)=\"applyColumns($event)\"\n (searchChange)=\"onSearch($event)\"\n (actionClick)=\"handleActionClick($event)\"\n ></table-caption>\n } @else {\n <div\n style=\"min-height: 40px; padding: 8px\"\n class=\"flex justify-content-between align-items-center border-bottom-1 border-300 pl-5 pr-5 text-sm text-500\"\n >\n <div>\n @if (tableConfiguration.selectionType === selectionTypeEnum.CHECKBOX) {\n <span>\n {{ selectedItems().length }}\n {{\n selectedItems().length === 1\n ? (\"LABELS.ITEM_SELECTED\" | translate)\n : (\"LABELS.ITEMS_SELECTED\" | translate)\n }}\n </span>\n }\n </div>\n\n <div>\n @for (\n action of tableConfiguration.bulkActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"\n handleActionClick({\n action: action,\n selectedItems: selectedItems(),\n });\n clearSelection()\n \"\n ></phoenix-data-table-action>\n }\n\n <button\n [attr.data-cy]=\"'clear-selection-button'\"\n class=\"p-button p-button-text p-button-plain\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear Selection\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n }\n <div\n class=\"table-host\"\n [style.height]=\"tableConfiguration.scrollHeight ?? null\"\n >\n <p-table\n #dt\n [columns]=\"selectedColumns\"\n [value]=\"tableData\"\n [size]=\"'small'\"\n scrollable=\"true\"\n scrollHeight=\"flex\"\n [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"40\"\n [virtualScrollDelay]=\"80\"\n [totalRecords]=\"totalRecords\"\n [sortMode]=\"'multiple'\"\n [customSort]=\"true\"\n (sortFunction)=\"onCustomSort($event)\"\n [selection]=\"selectedItems()\"\n (selectionChange)=\"onSelectionChange($event)\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [loading]=\"initialSortLoading\"\n >\n <ng-template #header let-columns>\n <tr style=\"height: 40px\" class=\"dt-header\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <th class=\"custom-th\">\n <p-tableHeaderCheckbox\n [attr.data-cy]=\"'table-header-checkbox'\"\n ></p-tableHeaderCheckbox>\n </th>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <th class=\"custom-th\"></th>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let colIdx = $index\n ) {\n <th\n pResizableColumn\n class=\"custom-th text-primary font-bold\"\n [pSortableColumn]=\"col.field\"\n >\n {{ col.header | translate }}\n <p-sortIcon\n [field]=\"col.field\"\n [attr.data-cy]=\"'sort-button-' + col.header\"\n ></p-sortIcon>\n </th>\n }\n\n <th class=\"custom-th\"></th>\n </tr>\n </ng-template>\n\n <ng-template\n #body\n let-rowData\n let-columns=\"columns\"\n let-rowIndex=\"rowIndex\"\n >\n <tr>\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-tableCheckbox\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.CHECKBOX + '-' + rowIndex\n \"\n [disabled]=\"\n rowData?.canSelect !== undefined\n ? !rowData.canSelect\n : false\n \"\n [value]=\"rowData\"\n ></p-tableCheckbox>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td>\n <p-tableRadioButton\n [value]=\"rowData\"\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.RADIO_BTN + '-' + rowIndex\n \"\n ></p-tableRadioButton>\n </td>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let i = $index\n ) {\n <td\n (click)=\"\n isColumnClickable(i) ? onRowClick($event, rowData) : null\n \"\n [ngClass]=\"{\n 'text-blue-500 underline cursor-pointer': isColumnClickable(i),\n }\"\n >\n @switch (col.columnType) {\n @case (columnTypeEnum.TAG) {\n @if (rowData[col.field]) {\n <div class=\"flex align-items-center gap-2\">\n <div\n class=\"border-round-md font-semibold\"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field + 'Color'] || '#ccc') + '56',\n color: rowData[col.field + 'Color'],\n }\"\n >\n {{\n rowData[col.field]?.name ||\n (rowData[col.field] | translate)\n }}\n </div>\n @if (rowData[col.field + \"Tooltip\"]) {\n <i\n [class]=\"\n rowData[col.field + 'Icon'].class +\n ' cursor-pointer'\n \"\n [style]=\"rowData[col.field + 'Icon'].style\"\n [pTooltip]=\"rowData[col.field + 'Tooltip']\"\n tooltipPosition=\"top\"\n ></i>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST_TAG) {\n @if (rowData[col.field]) {\n @for (item of rowData[col.field]; track $index) {\n <p-badge severity=\"warn\" class=\"mr-1\" [value]=\"item\" />\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.OBJ_TAG) {\n @if (rowData[col.field]) {\n <p-tag\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.OBJ_TAG +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field].color || '#ccc') + '56',\n color: rowData[col.field].color,\n }\"\n [value]=\"rowData[col.field]?.value | translate\"\n ></p-tag>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.PERSON) {\n @if (rowData[col.field]) {\n <p-avatar\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.PERSON +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [label]=\"rowData[col.field]?.name | initials\"\n class=\"cursor-pointer\"\n [style]=\"{\n 'background-color': '#9c27b0',\n color: '#ffffff',\n 'font-size': '0.8rem!important',\n }\"\n shape=\"circle\"\n (click)=\"personPop.toggle($event)\"\n ></p-avatar>\n\n <p-popover #personPop [dismissable]=\"true\">\n <div>\n <span class=\"text-lg\">{{\n rowData[col.field].name\n }}</span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-envelope mr-1 text-500\"></i>\n {{ rowData[col.field].email ?? \" --\" }}\n </span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-phone text-500\"></i>\n {{ rowData[col.field].phone ?? \" --\" }}\n </span>\n </div>\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST) {\n @if (rowData[col.field]?.length) {\n @if (rowData[col.field].length > 1) {\n <div\n class=\"cursor-pointer\"\n (click)=\"listPop.toggle($event)\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.LIST +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span class=\"mr-1\">{{\n rowData[col.field][0].name\n }}</span>\n <p-chip\n class=\"text-sm font-semibold p-1 m-0\"\n [label]=\"'+' + (rowData[col.field].length - 1)\"\n />\n </div>\n } @else {\n <span>{{ rowData[col.field][0].name }}</span>\n }\n\n <p-popover #listPop [dismissable]=\"true\">\n @for (\n item of rowData[col.field];\n track item.name;\n let isFirst = $first\n ) {\n @if (!isFirst) {\n <ul class=\"list-none m-0 p-0\">\n <li>{{ item.name }}</li>\n </ul>\n }\n }\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.BOOLEAN) {\n @if (rowData[col.field] | isBoolean) {\n <i\n [pTooltip]=\"rowData?.[col.field + 'Tooltip']\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.BOOLEAN +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"pi\"\n [ngClass]=\"\n rowData[col.field]\n ? 'text-green-500 pi-check-circle'\n : 'text-red-500 pi-times-circle'\n \"\n ></i>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TEXT_AREA) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT_AREA +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field]\"\n >\n {{\n rowData[col.field].length > (col.maxLength ?? 50)\n ? (rowData[col.field]\n | slice: 0 : col.maxLength ?? 50) + \"...\"\n : rowData[col.field]\n }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.EMAIL) {\n @if (rowData[col.field]) {\n <div\n class=\"email-cell\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.EMAIL +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span>{{ rowData[col.field] }}</span>\n <i\n class=\"pi pi-copy email-copy-icon\"\n (click)=\"copyToClipboard($event, rowData[col.field])\"\n [pTooltip]=\"'LABELS.COPY_EMAIL' | translate\"\n >\n </i>\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TIMEPERIOD) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TIMEPERIOD +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field] | timePeriod\"\n style=\"max-width: 200px\"\n >\n {{ rowData[col.field] | timePeriod }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @default {\n @if (col.flag && getNested(rowData, col.flagCodeField)) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"flex align-items-center gap-2\"\n style=\"max-width: 200px\"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n >\n <img\n src=\"https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png\"\n [class]=\"\n 'flag flag-' +\n (getNested(rowData, col.flagCodeField) || '')\n .toString()\n .toLowerCase()\n \"\n style=\"width: 22px\"\n alt=\"\"\n />\n <span\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></span>\n </div>\n } @else {\n @if (rowData | cell: col : dateFormat) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n style=\"max-width: 200px\"\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n }\n }\n </td>\n }\n\n <td class=\"p-0\">\n @for (\n action of tableConfiguration.rowActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n [rowData]=\"rowData\"\n (actionClick)=\"handleActionClick($event)\"\n ></phoenix-data-table-action>\n }\n </td>\n </tr>\n </ng-template>\n\n <!-- <ng-template pTemplate=\"loadingbody\" let-columns>\n @for (_ of skeletonRows; track $index; let rowIdx = $index) {\n <tr style=\"height: 40px\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n }\n\n @for (col of columns; track col.field ?? col.header ?? $index) {\n <td>\n <p-skeleton\n [ngStyle]=\"{\n width: (60 + (rowIdx % 3) * 10) + '%',\n height: '1rem'\n }\"\n ></p-skeleton>\n </td>\n }\n\n <td>\n <p-skeleton width=\"2rem\" height=\"1rem\"></p-skeleton>\n </td>\n </tr>\n }\n </ng-template> -->\n\n <ng-template #emptyCell let-dataCy=\"dataCy\">\n <span [attr.data-cy]=\"dataCy\">--</span>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <td class=\"p-2\" colspan=\"100\">\n <div class=\"flex align-items-center\">\n <i class=\"pi pi-info-circle mr-2\"></i>\n {{ \"NO_RESULTS_FOUND\" | translate }}\n </div>\n </td>\n </ng-template>\n </p-table>\n\n <div class=\"border-top-1 border-300 pl-2 p-1 text-sm text-500\">\n {{ \"LABELS.TOTAL_RECORDS\" | translate }}: {{ totalRecords }}\n </div>\n </div>\n</div>\n", styles: [":is() .p-avatar{border-radius:50%!important}::ng-deep .p-paginator button{scale:.7}::ng-deep .p-paginator-rpp-options{scale:.7}::ng-deep .p-datatable .p-datatable-header{border-radius:10px 10px 0 0}:host::ng-deep .p-tag{font-weight:400!important;font-size:.875rem!important}.email-cell{position:relative;display:inline-block;padding-right:24px}.email-cell .email-copy-icon{position:absolute;top:0;right:0;opacity:0;cursor:pointer;transition:opacity .2s}.email-cell:hover .email-copy-icon{opacity:1}.table-host{display:flex;flex-direction:column;min-height:0;overflow:hidden}.table-host,.table-host>.p-datatable,.table-host>.p-datatable .p-datatable-wrapper{min-height:0}:host ::ng-deep .p-datatable-loading-overlay{display:none!important}:host ::ng-deep .p-datatable-mask{display:none!important}:host ::ng-deep .p-datatable.p-datatable-loading{opacity:1!important;pointer-events:auto!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2$4.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i2$4.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "component", type: i2$4.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i2$4.TableRadioButton, selector: "p-tableRadioButton", inputs: ["value", "disabled", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2$4.TableCheckbox, selector: "p-tableCheckbox", inputs: ["value", "disabled", "required", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2$4.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "component", type: TableCaptionComponent, selector: "table-caption", inputs: ["tableConfiguration", "columns", "selectedItems", "filters", "filterValidValues"], outputs: ["applyFiltersEvent", "applyColumnsEvent", "searchChange", "actionClick"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: PhoenixDataTableActionComponent, selector: "phoenix-data-table-action", inputs: ["actionConfig", "rowData"], outputs: ["actionClick"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: PanelModule }, { 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: "ngmodule", type: ChipModule }, { kind: "component", type: i8$2.Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "styleClass", "disabled", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i4$6.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "pipe", type: i1$2.SlicePipe, name: "slice" }, { kind: "pipe", type: i4$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: TableCellPipe, name: "cell" }, { kind: "pipe", type: InitialsPipe, name: "initials" }, { kind: "pipe", type: TimePeriodPipe, name: "timePeriod" }, { kind: "pipe", type: IsBooleanPipe, name: "isBoolean" }] });
|
|
3827
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TableComponent, isStandalone: true, selector: "phoenix-table", inputs: { columns: "columns", selectedColumnsInput: "selectedColumnsInput", tableConfiguration: "tableConfiguration", filters: "filters", data: "data" }, outputs: { actionClick: "actionClick", rowSelection: "rowSelection", checkBoxSelection: "checkBoxSelection", saveColumns: "saveColumns" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"border-1 border-round-sm border-300 border-round-md m-2\">\n @if (selectedItems().length === 0) {\n <table-caption\n [columns]=\"columns\"\n [tableConfiguration]=\"tableConfiguration\"\n [filters]=\"computedFilters\"\n [selectedItems]=\"selectedItems()\"\n [filterValidValues]=\"filterValidValues\"\n (applyFiltersEvent)=\"applyFilters($event)\"\n (applyColumnsEvent)=\"applyColumns($event)\"\n (searchChange)=\"onSearch($event)\"\n (actionClick)=\"handleActionClick($event)\"\n ></table-caption>\n } @else {\n <div\n style=\"min-height: 40px; padding: 8px\"\n class=\"flex justify-content-between align-items-center border-bottom-1 border-300 pl-5 pr-5 text-sm text-500\"\n >\n <div>\n @if (tableConfiguration.selectionType === selectionTypeEnum.CHECKBOX) {\n <span>\n {{ selectedItems().length }}\n {{\n selectedItems().length === 1\n ? (\"LABELS.ITEM_SELECTED\" | translate)\n : (\"LABELS.ITEMS_SELECTED\" | translate)\n }}\n </span>\n }\n </div>\n\n <div>\n @for (\n action of tableConfiguration.bulkActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"\n handleActionClick({\n action: action,\n selectedItems: selectedItems(),\n });\n clearSelection()\n \"\n ></phoenix-data-table-action>\n }\n\n <button\n [attr.data-cy]=\"'clear-selection-button'\"\n class=\"p-button p-button-text p-button-plain\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear Selection\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n }\n <div\n class=\"table-host\"\n [style.height]=\"tableConfiguration.scrollHeight ?? null\"\n >\n <p-table\n #dt\n [columns]=\"selectedColumns\"\n [value]=\"tableData\"\n [size]=\"'small'\"\n scrollable=\"true\"\n scrollHeight=\"flex\"\n [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"40\"\n [virtualScrollDelay]=\"80\"\n [totalRecords]=\"totalRecords\"\n [sortMode]=\"'multiple'\"\n [customSort]=\"true\"\n (sortFunction)=\"onCustomSort($event)\"\n [selection]=\"selectedItems()\"\n (selectionChange)=\"onSelectionChange($event)\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [loading]=\"initialSortLoading\"\n >\n <ng-template #header let-columns>\n <tr style=\"height: 40px\" class=\"dt-header\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <th class=\"custom-th\">\n <p-tableHeaderCheckbox\n [attr.data-cy]=\"'table-header-checkbox'\"\n ></p-tableHeaderCheckbox>\n </th>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <th class=\"custom-th\"></th>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let colIdx = $index\n ) {\n <th\n pResizableColumn\n class=\"custom-th text-primary font-bold\"\n [pSortableColumn]=\"col.field\"\n >\n {{ col.header | translate }}\n <p-sortIcon\n [field]=\"col.field\"\n [attr.data-cy]=\"'sort-button-' + col.header\"\n ></p-sortIcon>\n </th>\n }\n\n <th class=\"custom-th\"></th>\n </tr>\n </ng-template>\n\n <ng-template\n #body\n let-rowData\n let-columns=\"columns\"\n let-rowIndex=\"rowIndex\"\n >\n <tr>\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-tableCheckbox\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.CHECKBOX + '-' + rowIndex\n \"\n [disabled]=\"\n rowData?.canSelect !== undefined\n ? !rowData.canSelect\n : false\n \"\n [value]=\"rowData\"\n ></p-tableCheckbox>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td>\n <p-tableRadioButton\n [value]=\"rowData\"\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.RADIO_BTN + '-' + rowIndex\n \"\n ></p-tableRadioButton>\n </td>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let i = $index\n ) {\n <td\n (click)=\"\n isColumnClickable(i) ? onRowClick($event, rowData) : null\n \"\n [ngClass]=\"{\n 'text-blue-500 underline cursor-pointer': isColumnClickable(i),\n }\"\n >\n @switch (col.columnType) {\n @case (columnTypeEnum.TAG) {\n @if (rowData[col.field]) {\n <div class=\"flex align-items-center gap-2\">\n <div\n class=\"border-round-md font-semibold\"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field + 'Color'] || '#ccc') + '56',\n color: rowData[col.field + 'Color'],\n }\"\n >\n {{\n rowData[col.field]?.name ||\n (rowData[col.field] | translate)\n }}\n </div>\n @if (rowData[col.field + \"Tooltip\"]) {\n <i\n [class]=\"\n rowData[col.field + 'Icon'].class +\n ' cursor-pointer'\n \"\n [style]=\"rowData[col.field + 'Icon'].style\"\n [pTooltip]=\"rowData[col.field + 'Tooltip']\"\n tooltipPosition=\"top\"\n ></i>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST_TAG) {\n @if (rowData[col.field]) {\n @for (item of rowData[col.field]; track $index) {\n <p-badge severity=\"warn\" class=\"mr-1\" [value]=\"item\" />\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.OBJ_TAG) {\n @if (rowData[col.field]) {\n <p-tag\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.OBJ_TAG +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field].color || '#ccc') + '56',\n color: rowData[col.field].color,\n }\"\n [value]=\"rowData[col.field]?.value | translate\"\n ></p-tag>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.PERSON) {\n @if (rowData[col.field]) {\n <p-avatar\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.PERSON +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [label]=\"rowData[col.field]?.name | initials\"\n class=\"cursor-pointer\"\n [style]=\"{\n 'background-color': '#9c27b0',\n color: '#ffffff',\n 'font-size': '0.8rem!important',\n }\"\n shape=\"circle\"\n (click)=\"personPop.toggle($event)\"\n ></p-avatar>\n\n <p-popover #personPop [dismissable]=\"true\">\n <div>\n <span class=\"text-lg\">{{\n rowData[col.field].name\n }}</span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-envelope mr-1 text-500\"></i>\n {{ rowData[col.field].email ?? \" --\" }}\n </span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-phone text-500\"></i>\n {{ rowData[col.field].phone ?? \" --\" }}\n </span>\n </div>\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST) {\n @if (rowData[col.field]?.length) {\n @if (rowData[col.field].length > 1) {\n <div\n class=\"cursor-pointer\"\n (click)=\"listPop.toggle($event)\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.LIST +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span class=\"mr-1\">{{\n rowData[col.field][0].name\n }}</span>\n <p-chip\n class=\"text-sm font-semibold p-1 m-0\"\n [label]=\"'+' + (rowData[col.field].length - 1)\"\n />\n </div>\n } @else {\n <span>{{ rowData[col.field][0].name }}</span>\n }\n\n <p-popover #listPop [dismissable]=\"true\">\n @for (\n item of rowData[col.field];\n track item.name;\n let isFirst = $first\n ) {\n @if (!isFirst) {\n <ul class=\"list-none m-0 p-0\">\n <li>{{ item.name }}</li>\n </ul>\n }\n }\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.BOOLEAN) {\n @if (rowData[col.field] | isBoolean) {\n <i\n [pTooltip]=\"rowData?.[col.field + 'Tooltip']\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.BOOLEAN +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"pi\"\n [ngClass]=\"\n rowData[col.field]\n ? 'text-green-500 pi-check-circle'\n : 'text-red-500 pi-times-circle'\n \"\n ></i>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TEXT_AREA) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT_AREA +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field]\"\n >\n {{\n rowData[col.field].length > (col.maxLength ?? 50)\n ? (rowData[col.field]\n | slice: 0 : col.maxLength ?? 50) + \"...\"\n : rowData[col.field]\n }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.EMAIL) {\n @if (rowData[col.field]) {\n <div\n class=\"email-cell\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.EMAIL +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span>{{ rowData[col.field] }}</span>\n <i\n class=\"pi pi-copy email-copy-icon\"\n (click)=\"copyToClipboard($event, rowData[col.field])\"\n [pTooltip]=\"'LABELS.COPY_EMAIL' | translate\"\n >\n </i>\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TIMEPERIOD) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TIMEPERIOD +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field] | timePeriod\"\n style=\"max-width: 200px\"\n >\n {{ rowData[col.field] | timePeriod }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @default {\n @if (col.flag && getNested(rowData, col.flagCodeField)) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"flex align-items-center gap-2\"\n style=\"max-width: 200px\"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n >\n <img\n src=\"https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png\"\n [class]=\"\n 'flag flag-' +\n (getNested(rowData, col.flagCodeField) || '')\n .toString()\n .toLowerCase()\n \"\n style=\"width: 22px\"\n alt=\"\"\n />\n <span\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></span>\n </div>\n } @else {\n @if (rowData | cell: col : dateFormat) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n style=\"max-width: 200px\"\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n }\n }\n </td>\n }\n\n <td class=\"p-0\">\n @for (\n action of tableConfiguration.rowActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n [rowData]=\"rowData\"\n (actionClick)=\"handleActionClick($event)\"\n ></phoenix-data-table-action>\n }\n </td>\n </tr>\n </ng-template>\n\n <!-- <ng-template pTemplate=\"loadingbody\" let-columns>\n @for (_ of skeletonRows; track $index; let rowIdx = $index) {\n <tr style=\"height: 40px\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n }\n\n @for (col of columns; track col.field ?? col.header ?? $index) {\n <td>\n <p-skeleton\n [ngStyle]=\"{\n width: (60 + (rowIdx % 3) * 10) + '%',\n height: '1rem'\n }\"\n ></p-skeleton>\n </td>\n }\n\n <td>\n <p-skeleton width=\"2rem\" height=\"1rem\"></p-skeleton>\n </td>\n </tr>\n }\n </ng-template> -->\n\n <ng-template #emptyCell let-dataCy=\"dataCy\">\n <span [attr.data-cy]=\"dataCy\">--</span>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <td class=\"p-2\" colspan=\"100\">\n <div class=\"flex align-items-center\">\n <i class=\"pi pi-info-circle mr-2\"></i>\n {{ \"NO_RESULTS_FOUND\" | translate }}\n </div>\n </td>\n </ng-template>\n </p-table>\n\n <div class=\"border-top-1 border-300 pl-2 p-1 text-sm text-500\">\n {{ \"LABELS.TOTAL_RECORDS\" | translate }}: {{ totalRecords }}\n </div>\n </div>\n</div>\n", styles: [":is() .p-avatar{border-radius:50%!important}::ng-deep .p-paginator button{scale:.7}::ng-deep .p-paginator-rpp-options{scale:.7}::ng-deep .p-datatable .p-datatable-header{border-radius:10px 10px 0 0}:host::ng-deep .p-tag{font-weight:400!important;font-size:.875rem!important}.email-cell{position:relative;display:inline-block;padding-right:24px}.email-cell .email-copy-icon{position:absolute;top:0;right:0;opacity:0;cursor:pointer;transition:opacity .2s}.email-cell:hover .email-copy-icon{opacity:1}.table-host{display:flex;flex-direction:column;min-height:0;overflow:hidden}.table-host,.table-host>.p-datatable,.table-host>.p-datatable .p-datatable-wrapper{min-height:0}:host ::ng-deep .p-datatable-loading-overlay{display:none!important}:host ::ng-deep .p-datatable-mask{display:none!important}:host ::ng-deep .p-datatable.p-datatable-loading{opacity:1!important;pointer-events:auto!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2$4.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i2$4.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "component", type: i2$4.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i2$4.TableRadioButton, selector: "p-tableRadioButton", inputs: ["value", "disabled", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2$4.TableCheckbox, selector: "p-tableCheckbox", inputs: ["value", "disabled", "required", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2$4.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "component", type: TableCaptionComponent, selector: "table-caption", inputs: ["tableConfiguration", "columns", "selectedItems", "filters", "filterValidValues"], outputs: ["applyFiltersEvent", "applyColumnsEvent", "searchChange", "actionClick"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: PhoenixDataTableActionComponent, selector: "phoenix-data-table-action", inputs: ["actionConfig", "rowData"], outputs: ["actionClick"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: PanelModule }, { 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: "ngmodule", type: ChipModule }, { kind: "component", type: i8$2.Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "styleClass", "disabled", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i4$6.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "pipe", type: i1$2.SlicePipe, name: "slice" }, { kind: "pipe", type: i4$2.TranslatePipe, name: "translate" }, { kind: "pipe", type: TableCellPipe, name: "cell" }, { kind: "pipe", type: InitialsPipe, name: "initials" }, { kind: "pipe", type: TimePeriodPipe, name: "timePeriod" }, { kind: "pipe", type: IsBooleanPipe, name: "isBoolean" }] });
|
|
3679
3828
|
}
|
|
3680
3829
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TableComponent, decorators: [{
|
|
3681
3830
|
type: Component,
|
|
@@ -3697,7 +3846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3697
3846
|
TimePeriodPipe,
|
|
3698
3847
|
IsBooleanPipe,
|
|
3699
3848
|
BadgeModule,
|
|
3700
|
-
], template: "<div class=\"border-1 border-round-sm border-300 border-round-md m-2\">\n @if (selectedItems().length === 0) {\n <table-caption\n [columns]=\"columns\"\n [tableConfiguration]=\"tableConfiguration\"\n [filters]=\"filters\"\n [selectedItems]=\"selectedItems()\"\n [filterValidValues]=\"filterValidValues\"\n (applyFiltersEvent)=\"applyFilters($event)\"\n (applyColumnsEvent)=\"applyColumns($event)\"\n (searchChange)=\"onSearch($event)\"\n (actionClick)=\"handleActionClick($event)\"\n ></table-caption>\n } @else {\n <div\n style=\"min-height: 40px; padding: 8px\"\n class=\"flex justify-content-between align-items-center border-bottom-1 border-300 pl-5 pr-5 text-sm text-500\"\n >\n <div>\n @if (tableConfiguration.selectionType === selectionTypeEnum.CHECKBOX) {\n <span>\n {{ selectedItems().length }}\n {{\n selectedItems().length === 1\n ? (\"LABELS.ITEM_SELECTED\" | translate)\n : (\"LABELS.ITEMS_SELECTED\" | translate)\n }}\n </span>\n }\n </div>\n\n <div>\n @for (\n action of tableConfiguration.bulkActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"\n handleActionClick({\n action: action,\n selectedItems: selectedItems(),\n });\n clearSelection()\n \"\n ></phoenix-data-table-action>\n }\n\n <button\n [attr.data-cy]=\"'clear-selection-button'\"\n class=\"p-button p-button-text p-button-plain\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear Selection\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n }\n <div\n class=\"table-host\"\n [style.height]=\"tableConfiguration.scrollHeight ?? null\"\n >\n <p-table\n #dt\n [columns]=\"selectedColumns\"\n [value]=\"tableData\"\n [size]=\"'small'\"\n scrollable=\"true\"\n scrollHeight=\"flex\"\n [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"40\"\n [virtualScrollDelay]=\"80\"\n [totalRecords]=\"totalRecords\"\n [sortMode]=\"'multiple'\"\n [customSort]=\"true\"\n (sortFunction)=\"onCustomSort($event)\"\n [selection]=\"selectedItems()\"\n (selectionChange)=\"onSelectionChange($event)\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [loading]=\"initialSortLoading\"\n >\n <ng-template #header let-columns>\n <tr style=\"height: 40px\" class=\"dt-header\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <th class=\"custom-th\">\n <p-tableHeaderCheckbox\n [attr.data-cy]=\"'table-header-checkbox'\"\n ></p-tableHeaderCheckbox>\n </th>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <th class=\"custom-th\"></th>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let colIdx = $index\n ) {\n <th\n pResizableColumn\n class=\"custom-th text-primary font-bold\"\n [pSortableColumn]=\"col.field\"\n >\n {{ col.header | translate }}\n <p-sortIcon\n [field]=\"col.field\"\n [attr.data-cy]=\"'sort-button-' + col.header\"\n ></p-sortIcon>\n </th>\n }\n\n <th class=\"custom-th\"></th>\n </tr>\n </ng-template>\n\n <ng-template\n #body\n let-rowData\n let-columns=\"columns\"\n let-rowIndex=\"rowIndex\"\n >\n <tr>\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-tableCheckbox\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.CHECKBOX + '-' + rowIndex\n \"\n [disabled]=\"\n rowData?.canSelect !== undefined\n ? !rowData.canSelect\n : false\n \"\n [value]=\"rowData\"\n ></p-tableCheckbox>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td>\n <p-tableRadioButton\n [value]=\"rowData\"\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.RADIO_BTN + '-' + rowIndex\n \"\n ></p-tableRadioButton>\n </td>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let i = $index\n ) {\n <td\n (click)=\"\n isColumnClickable(i) ? onRowClick($event, rowData) : null\n \"\n [ngClass]=\"{\n 'text-blue-500 underline cursor-pointer': isColumnClickable(i),\n }\"\n >\n @switch (col.columnType) {\n @case (columnTypeEnum.TAG) {\n @if (rowData[col.field]) {\n <div class=\"flex align-items-center gap-2\">\n <div\n class=\"border-round-md font-semibold\"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field + 'Color'] || '#ccc') + '56',\n color: rowData[col.field + 'Color'],\n }\"\n >\n {{\n rowData[col.field]?.name ||\n (rowData[col.field] | translate)\n }}\n </div>\n @if (rowData[col.field + \"Tooltip\"]) {\n <i\n [class]=\"\n rowData[col.field + 'Icon'].class +\n ' cursor-pointer'\n \"\n [style]=\"rowData[col.field + 'Icon'].style\"\n [pTooltip]=\"rowData[col.field + 'Tooltip']\"\n tooltipPosition=\"top\"\n ></i>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST_TAG) {\n @if (rowData[col.field]) {\n @for (item of rowData[col.field]; track $index) {\n <p-badge severity=\"warn\" class=\"mr-1\" [value]=\"item\" />\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.OBJ_TAG) {\n @if (rowData[col.field]) {\n <p-tag\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.OBJ_TAG +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field].color || '#ccc') + '56',\n color: rowData[col.field].color,\n }\"\n [value]=\"rowData[col.field]?.value | translate\"\n ></p-tag>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.PERSON) {\n @if (rowData[col.field]) {\n <p-avatar\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.PERSON +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [label]=\"rowData[col.field]?.name | initials\"\n class=\"cursor-pointer\"\n [style]=\"{\n 'background-color': '#9c27b0',\n color: '#ffffff',\n 'font-size': '0.8rem!important',\n }\"\n shape=\"circle\"\n (click)=\"personPop.toggle($event)\"\n ></p-avatar>\n\n <p-popover #personPop [dismissable]=\"true\">\n <div>\n <span class=\"text-lg\">{{\n rowData[col.field].name\n }}</span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-envelope mr-1 text-500\"></i>\n {{ rowData[col.field].email ?? \" --\" }}\n </span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-phone text-500\"></i>\n {{ rowData[col.field].phone ?? \" --\" }}\n </span>\n </div>\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST) {\n @if (rowData[col.field]?.length) {\n @if (rowData[col.field].length > 1) {\n <div\n class=\"cursor-pointer\"\n (click)=\"listPop.toggle($event)\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.LIST +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span class=\"mr-1\">{{\n rowData[col.field][0].name\n }}</span>\n <p-chip\n class=\"text-sm font-semibold p-1 m-0\"\n [label]=\"'+' + (rowData[col.field].length - 1)\"\n />\n </div>\n } @else {\n <span>{{ rowData[col.field][0].name }}</span>\n }\n\n <p-popover #listPop [dismissable]=\"true\">\n @for (\n item of rowData[col.field];\n track item.name;\n let isFirst = $first\n ) {\n @if (!isFirst) {\n <ul class=\"list-none m-0 p-0\">\n <li>{{ item.name }}</li>\n </ul>\n }\n }\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.BOOLEAN) {\n @if (rowData[col.field] | isBoolean) {\n <i\n [pTooltip]=\"rowData?.[col.field + 'Tooltip']\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.BOOLEAN +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"pi\"\n [ngClass]=\"\n rowData[col.field]\n ? 'text-green-500 pi-check-circle'\n : 'text-red-500 pi-times-circle'\n \"\n ></i>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TEXT_AREA) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT_AREA +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field]\"\n >\n {{\n rowData[col.field].length > (col.maxLength ?? 50)\n ? (rowData[col.field]\n | slice: 0 : col.maxLength ?? 50) + \"...\"\n : rowData[col.field]\n }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.EMAIL) {\n @if (rowData[col.field]) {\n <div\n class=\"email-cell\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.EMAIL +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span>{{ rowData[col.field] }}</span>\n <i\n class=\"pi pi-copy email-copy-icon\"\n (click)=\"copyToClipboard($event, rowData[col.field])\"\n [pTooltip]=\"'LABELS.COPY_EMAIL' | translate\"\n >\n </i>\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TIMEPERIOD) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TIMEPERIOD +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field] | timePeriod\"\n style=\"max-width: 200px\"\n >\n {{ rowData[col.field] | timePeriod }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @default {\n @if (col.flag && getNested(rowData, col.flagCodeField)) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"flex align-items-center gap-2\"\n style=\"max-width: 200px\"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n >\n <img\n src=\"https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png\"\n [class]=\"\n 'flag flag-' +\n (getNested(rowData, col.flagCodeField) || '')\n .toString()\n .toLowerCase()\n \"\n style=\"width: 22px\"\n alt=\"\"\n />\n <span\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></span>\n </div>\n } @else {\n @if (rowData | cell: col : dateFormat) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n style=\"max-width: 200px\"\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n }\n }\n </td>\n }\n\n <td class=\"p-0\">\n @for (\n action of tableConfiguration.rowActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n [rowData]=\"rowData\"\n (actionClick)=\"handleActionClick($event)\"\n ></phoenix-data-table-action>\n }\n </td>\n </tr>\n </ng-template>\n\n <!-- <ng-template pTemplate=\"loadingbody\" let-columns>\n @for (_ of skeletonRows; track $index; let rowIdx = $index) {\n <tr style=\"height: 40px\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n }\n\n @for (col of columns; track col.field ?? col.header ?? $index) {\n <td>\n <p-skeleton\n [ngStyle]=\"{\n width: (60 + (rowIdx % 3) * 10) + '%',\n height: '1rem'\n }\"\n ></p-skeleton>\n </td>\n }\n\n <td>\n <p-skeleton width=\"2rem\" height=\"1rem\"></p-skeleton>\n </td>\n </tr>\n }\n </ng-template> -->\n\n <ng-template #emptyCell let-dataCy=\"dataCy\">\n <span [attr.data-cy]=\"dataCy\">--</span>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <td class=\"p-2\" colspan=\"100\">\n <div class=\"flex align-items-center\">\n <i class=\"pi pi-info-circle mr-2\"></i>\n {{ \"NO_RESULTS_FOUND\" | translate }}\n </div>\n </td>\n </ng-template>\n </p-table>\n\n <div class=\"border-top-1 border-300 pl-2 p-1 text-sm text-500\">\n {{ \"LABELS.TOTAL_RECORDS\" | translate }}: {{ totalRecords }}\n </div>\n </div>\n</div>\n", styles: [":is() .p-avatar{border-radius:50%!important}::ng-deep .p-paginator button{scale:.7}::ng-deep .p-paginator-rpp-options{scale:.7}::ng-deep .p-datatable .p-datatable-header{border-radius:10px 10px 0 0}:host::ng-deep .p-tag{font-weight:400!important;font-size:.875rem!important}.email-cell{position:relative;display:inline-block;padding-right:24px}.email-cell .email-copy-icon{position:absolute;top:0;right:0;opacity:0;cursor:pointer;transition:opacity .2s}.email-cell:hover .email-copy-icon{opacity:1}.table-host{display:flex;flex-direction:column;min-height:0;overflow:hidden}.table-host,.table-host>.p-datatable,.table-host>.p-datatable .p-datatable-wrapper{min-height:0}:host ::ng-deep .p-datatable-loading-overlay{display:none!important}:host ::ng-deep .p-datatable-mask{display:none!important}:host ::ng-deep .p-datatable.p-datatable-loading{opacity:1!important;pointer-events:auto!important}\n"] }]
|
|
3849
|
+
], template: "<div class=\"border-1 border-round-sm border-300 border-round-md m-2\">\n @if (selectedItems().length === 0) {\n <table-caption\n [columns]=\"columns\"\n [tableConfiguration]=\"tableConfiguration\"\n [filters]=\"computedFilters\"\n [selectedItems]=\"selectedItems()\"\n [filterValidValues]=\"filterValidValues\"\n (applyFiltersEvent)=\"applyFilters($event)\"\n (applyColumnsEvent)=\"applyColumns($event)\"\n (searchChange)=\"onSearch($event)\"\n (actionClick)=\"handleActionClick($event)\"\n ></table-caption>\n } @else {\n <div\n style=\"min-height: 40px; padding: 8px\"\n class=\"flex justify-content-between align-items-center border-bottom-1 border-300 pl-5 pr-5 text-sm text-500\"\n >\n <div>\n @if (tableConfiguration.selectionType === selectionTypeEnum.CHECKBOX) {\n <span>\n {{ selectedItems().length }}\n {{\n selectedItems().length === 1\n ? (\"LABELS.ITEM_SELECTED\" | translate)\n : (\"LABELS.ITEMS_SELECTED\" | translate)\n }}\n </span>\n }\n </div>\n\n <div>\n @for (\n action of tableConfiguration.bulkActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n (actionClick)=\"\n handleActionClick({\n action: action,\n selectedItems: selectedItems(),\n });\n clearSelection()\n \"\n ></phoenix-data-table-action>\n }\n\n <button\n [attr.data-cy]=\"'clear-selection-button'\"\n class=\"p-button p-button-text p-button-plain\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear Selection\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n }\n <div\n class=\"table-host\"\n [style.height]=\"tableConfiguration.scrollHeight ?? null\"\n >\n <p-table\n #dt\n [columns]=\"selectedColumns\"\n [value]=\"tableData\"\n [size]=\"'small'\"\n scrollable=\"true\"\n scrollHeight=\"flex\"\n [virtualScroll]=\"true\"\n [virtualScrollItemSize]=\"40\"\n [virtualScrollDelay]=\"80\"\n [totalRecords]=\"totalRecords\"\n [sortMode]=\"'multiple'\"\n [customSort]=\"true\"\n (sortFunction)=\"onCustomSort($event)\"\n [selection]=\"selectedItems()\"\n (selectionChange)=\"onSelectionChange($event)\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [loading]=\"initialSortLoading\"\n >\n <ng-template #header let-columns>\n <tr style=\"height: 40px\" class=\"dt-header\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <th class=\"custom-th\">\n <p-tableHeaderCheckbox\n [attr.data-cy]=\"'table-header-checkbox'\"\n ></p-tableHeaderCheckbox>\n </th>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <th class=\"custom-th\"></th>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let colIdx = $index\n ) {\n <th\n pResizableColumn\n class=\"custom-th text-primary font-bold\"\n [pSortableColumn]=\"col.field\"\n >\n {{ col.header | translate }}\n <p-sortIcon\n [field]=\"col.field\"\n [attr.data-cy]=\"'sort-button-' + col.header\"\n ></p-sortIcon>\n </th>\n }\n\n <th class=\"custom-th\"></th>\n </tr>\n </ng-template>\n\n <ng-template\n #body\n let-rowData\n let-columns=\"columns\"\n let-rowIndex=\"rowIndex\"\n >\n <tr>\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-tableCheckbox\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.CHECKBOX + '-' + rowIndex\n \"\n [disabled]=\"\n rowData?.canSelect !== undefined\n ? !rowData.canSelect\n : false\n \"\n [value]=\"rowData\"\n ></p-tableCheckbox>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td>\n <p-tableRadioButton\n [value]=\"rowData\"\n [attr.data-cy]=\"\n 'table-row-' + selectionTypeEnum.RADIO_BTN + '-' + rowIndex\n \"\n ></p-tableRadioButton>\n </td>\n }\n }\n @for (\n col of columns;\n track col.field ?? col.header ?? $index;\n let i = $index\n ) {\n <td\n (click)=\"\n isColumnClickable(i) ? onRowClick($event, rowData) : null\n \"\n [ngClass]=\"{\n 'text-blue-500 underline cursor-pointer': isColumnClickable(i),\n }\"\n >\n @switch (col.columnType) {\n @case (columnTypeEnum.TAG) {\n @if (rowData[col.field]) {\n <div class=\"flex align-items-center gap-2\">\n <div\n class=\"border-round-md font-semibold\"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field + 'Color'] || '#ccc') + '56',\n color: rowData[col.field + 'Color'],\n }\"\n >\n {{\n rowData[col.field]?.name ||\n (rowData[col.field] | translate)\n }}\n </div>\n @if (rowData[col.field + \"Tooltip\"]) {\n <i\n [class]=\"\n rowData[col.field + 'Icon'].class +\n ' cursor-pointer'\n \"\n [style]=\"rowData[col.field + 'Icon'].style\"\n [pTooltip]=\"rowData[col.field + 'Tooltip']\"\n tooltipPosition=\"top\"\n ></i>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST_TAG) {\n @if (rowData[col.field]) {\n @for (item of rowData[col.field]; track $index) {\n <p-badge severity=\"warn\" class=\"mr-1\" [value]=\"item\" />\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.OBJ_TAG) {\n @if (rowData[col.field]) {\n <p-tag\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.OBJ_TAG +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [style]=\"{\n fontSize: '12px',\n padding: '3px 8px',\n width: 'fit-content',\n 'background-color':\n (rowData[col.field].color || '#ccc') + '56',\n color: rowData[col.field].color,\n }\"\n [value]=\"rowData[col.field]?.value | translate\"\n ></p-tag>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.PERSON) {\n @if (rowData[col.field]) {\n <p-avatar\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.PERSON +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [label]=\"rowData[col.field]?.name | initials\"\n class=\"cursor-pointer\"\n [style]=\"{\n 'background-color': '#9c27b0',\n color: '#ffffff',\n 'font-size': '0.8rem!important',\n }\"\n shape=\"circle\"\n (click)=\"personPop.toggle($event)\"\n ></p-avatar>\n\n <p-popover #personPop [dismissable]=\"true\">\n <div>\n <span class=\"text-lg\">{{\n rowData[col.field].name\n }}</span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-envelope mr-1 text-500\"></i>\n {{ rowData[col.field].email ?? \" --\" }}\n </span>\n <span class=\"block text-sm\">\n <i class=\"pi pi-phone text-500\"></i>\n {{ rowData[col.field].phone ?? \" --\" }}\n </span>\n </div>\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.LIST) {\n @if (rowData[col.field]?.length) {\n @if (rowData[col.field].length > 1) {\n <div\n class=\"cursor-pointer\"\n (click)=\"listPop.toggle($event)\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.LIST +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span class=\"mr-1\">{{\n rowData[col.field][0].name\n }}</span>\n <p-chip\n class=\"text-sm font-semibold p-1 m-0\"\n [label]=\"'+' + (rowData[col.field].length - 1)\"\n />\n </div>\n } @else {\n <span>{{ rowData[col.field][0].name }}</span>\n }\n\n <p-popover #listPop [dismissable]=\"true\">\n @for (\n item of rowData[col.field];\n track item.name;\n let isFirst = $first\n ) {\n @if (!isFirst) {\n <ul class=\"list-none m-0 p-0\">\n <li>{{ item.name }}</li>\n </ul>\n }\n }\n </p-popover>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.BOOLEAN) {\n @if (rowData[col.field] | isBoolean) {\n <i\n [pTooltip]=\"rowData?.[col.field + 'Tooltip']\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.BOOLEAN +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"pi\"\n [ngClass]=\"\n rowData[col.field]\n ? 'text-green-500 pi-check-circle'\n : 'text-red-500 pi-times-circle'\n \"\n ></i>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TEXT_AREA) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT_AREA +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field]\"\n >\n {{\n rowData[col.field].length > (col.maxLength ?? 50)\n ? (rowData[col.field]\n | slice: 0 : col.maxLength ?? 50) + \"...\"\n : rowData[col.field]\n }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.EMAIL) {\n @if (rowData[col.field]) {\n <div\n class=\"email-cell\"\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.EMAIL +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n >\n <span>{{ rowData[col.field] }}</span>\n <i\n class=\"pi pi-copy email-copy-icon\"\n (click)=\"copyToClipboard($event, rowData[col.field])\"\n [pTooltip]=\"'LABELS.COPY_EMAIL' | translate\"\n >\n </i>\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @case (columnTypeEnum.TIMEPERIOD) {\n @if (rowData[col.field]) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TIMEPERIOD +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData[col.field] | timePeriod\"\n style=\"max-width: 200px\"\n >\n {{ rowData[col.field] | timePeriod }}\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n @default {\n @if (col.flag && getNested(rowData, col.flagCodeField)) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n class=\"flex align-items-center gap-2\"\n style=\"max-width: 200px\"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n >\n <img\n src=\"https://primefaces.org/cdn/primeng/images/demo/flag/flag_placeholder.png\"\n [class]=\"\n 'flag flag-' +\n (getNested(rowData, col.flagCodeField) || '')\n .toString()\n .toLowerCase()\n \"\n style=\"width: 22px\"\n alt=\"\"\n />\n <span\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></span>\n </div>\n } @else {\n @if (rowData | cell: col : dateFormat) {\n <div\n [attr.data-cy]=\"\n 'table-row-' +\n columnTypeEnum.TEXT +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i\n \"\n [pTooltip]=\"rowData | cell: col : dateFormat\"\n style=\"max-width: 200px\"\n [innerHTML]=\"rowData | cell: col : dateFormat\"\n ></div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"emptyCell\"\n [ngTemplateOutletContext]=\"{\n dataCy:\n 'table-row-' +\n col.columnType +\n '-row-index-' +\n rowIndex +\n '-col-index-' +\n i,\n }\"\n />\n }\n }\n }\n }\n </td>\n }\n\n <td class=\"p-0\">\n @for (\n action of tableConfiguration.rowActions;\n track action?.key ?? $index\n ) {\n <phoenix-data-table-action\n [actionConfig]=\"action\"\n [rowData]=\"rowData\"\n (actionClick)=\"handleActionClick($event)\"\n ></phoenix-data-table-action>\n }\n </td>\n </tr>\n </ng-template>\n\n <!-- <ng-template pTemplate=\"loadingbody\" let-columns>\n @for (_ of skeletonRows; track $index; let rowIdx = $index) {\n <tr style=\"height: 40px\">\n @switch (tableConfiguration.selectionType) {\n @case (selectionTypeEnum.CHECKBOX) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n @case (selectionTypeEnum.RADIO_BTN) {\n <td class=\"w-2rem\">\n <p-skeleton width=\"1.2rem\" height=\"1.2rem\"></p-skeleton>\n </td>\n }\n }\n\n @for (col of columns; track col.field ?? col.header ?? $index) {\n <td>\n <p-skeleton\n [ngStyle]=\"{\n width: (60 + (rowIdx % 3) * 10) + '%',\n height: '1rem'\n }\"\n ></p-skeleton>\n </td>\n }\n\n <td>\n <p-skeleton width=\"2rem\" height=\"1rem\"></p-skeleton>\n </td>\n </tr>\n }\n </ng-template> -->\n\n <ng-template #emptyCell let-dataCy=\"dataCy\">\n <span [attr.data-cy]=\"dataCy\">--</span>\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <td class=\"p-2\" colspan=\"100\">\n <div class=\"flex align-items-center\">\n <i class=\"pi pi-info-circle mr-2\"></i>\n {{ \"NO_RESULTS_FOUND\" | translate }}\n </div>\n </td>\n </ng-template>\n </p-table>\n\n <div class=\"border-top-1 border-300 pl-2 p-1 text-sm text-500\">\n {{ \"LABELS.TOTAL_RECORDS\" | translate }}: {{ totalRecords }}\n </div>\n </div>\n</div>\n", styles: [":is() .p-avatar{border-radius:50%!important}::ng-deep .p-paginator button{scale:.7}::ng-deep .p-paginator-rpp-options{scale:.7}::ng-deep .p-datatable .p-datatable-header{border-radius:10px 10px 0 0}:host::ng-deep .p-tag{font-weight:400!important;font-size:.875rem!important}.email-cell{position:relative;display:inline-block;padding-right:24px}.email-cell .email-copy-icon{position:absolute;top:0;right:0;opacity:0;cursor:pointer;transition:opacity .2s}.email-cell:hover .email-copy-icon{opacity:1}.table-host{display:flex;flex-direction:column;min-height:0;overflow:hidden}.table-host,.table-host>.p-datatable,.table-host>.p-datatable .p-datatable-wrapper{min-height:0}:host ::ng-deep .p-datatable-loading-overlay{display:none!important}:host ::ng-deep .p-datatable-mask{display:none!important}:host ::ng-deep .p-datatable.p-datatable-loading{opacity:1!important;pointer-events:auto!important}\n"] }]
|
|
3701
3850
|
}], ctorParameters: () => [], propDecorators: { dt: [{
|
|
3702
3851
|
type: ViewChild,
|
|
3703
3852
|
args: ['dt']
|