@masterteam/client-components 0.0.54 → 0.0.56
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/assets/client-components.css +1 -1
- package/fesm2022/masterteam-client-components-client-list.mjs +205 -21
- package/fesm2022/masterteam-client-components-client-list.mjs.map +1 -1
- package/fesm2022/masterteam-client-components-escalation-runtime.mjs +1 -1
- package/fesm2022/masterteam-client-components-escalation-runtime.mjs.map +1 -1
- package/package.json +4 -4
- package/types/masterteam-client-components-client-list.d.ts +47 -2
|
@@ -20,6 +20,7 @@ import * as i3 from 'primeng/popover';
|
|
|
20
20
|
import { PopoverModule } from 'primeng/popover';
|
|
21
21
|
import { DashboardViewer } from '@masterteam/dashboard-builder';
|
|
22
22
|
|
|
23
|
+
const DEFAULT_INCLUDE_STATE = ['escalation'];
|
|
23
24
|
class ClientListApiService {
|
|
24
25
|
http = inject(HttpClient);
|
|
25
26
|
runtimeFetchBaseUrl = 'fetch/query';
|
|
@@ -29,6 +30,7 @@ class ClientListApiService {
|
|
|
29
30
|
contextKey,
|
|
30
31
|
projection: 'Table',
|
|
31
32
|
surfaceKey: 'table',
|
|
33
|
+
includeState: [...DEFAULT_INCLUDE_STATE],
|
|
32
34
|
propertyKeys: propertyKeys?.length ? propertyKeys : undefined,
|
|
33
35
|
filters: this.mergeFilters(this.buildInstanceFilters(instanceId), filters),
|
|
34
36
|
page: this.toPage(query.skip, query.take),
|
|
@@ -39,6 +41,7 @@ class ClientListApiService {
|
|
|
39
41
|
return this.queryRuntime({
|
|
40
42
|
contextKey,
|
|
41
43
|
projection: 'Card',
|
|
44
|
+
includeState: [...DEFAULT_INCLUDE_STATE],
|
|
42
45
|
filters: this.mergeFilters(instanceId != null ? this.buildInstanceFilters(instanceId) : undefined, filters),
|
|
43
46
|
display: { areas: ['card'] },
|
|
44
47
|
});
|
|
@@ -108,6 +111,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
108
111
|
args: [{ providedIn: 'root' }]
|
|
109
112
|
}] });
|
|
110
113
|
|
|
114
|
+
const CLIENT_LIST_RECORD_STATE_KEY = '__clientListRecordState';
|
|
115
|
+
|
|
111
116
|
const UNSORTABLE_ENTITY_VIEW_TYPES = new Set([
|
|
112
117
|
'Attachment',
|
|
113
118
|
'Checkbox',
|
|
@@ -149,6 +154,22 @@ class ClientListStateService {
|
|
|
149
154
|
},
|
|
150
155
|
});
|
|
151
156
|
}
|
|
157
|
+
setTablePaging(key, skip, take) {
|
|
158
|
+
const target = this.itemsByKey()[key];
|
|
159
|
+
if (!target ||
|
|
160
|
+
target.type === 'informative' ||
|
|
161
|
+
target.areaType !== 'table') {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
this.itemsByKey.set({
|
|
165
|
+
...this.itemsByKey(),
|
|
166
|
+
[key]: {
|
|
167
|
+
...target,
|
|
168
|
+
skip,
|
|
169
|
+
take,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
152
173
|
setRowsResult(key, response, config, skip, take) {
|
|
153
174
|
const target = this.itemsByKey()[key];
|
|
154
175
|
if (!target ||
|
|
@@ -172,7 +193,10 @@ class ClientListStateService {
|
|
|
172
193
|
}));
|
|
173
194
|
const propertyMaps = this.createPropertyMaps(response.catalog?.properties ?? []);
|
|
174
195
|
const rows = (response.records ?? []).map((record) => {
|
|
175
|
-
const row = {
|
|
196
|
+
const row = {
|
|
197
|
+
Id: record.id,
|
|
198
|
+
[CLIENT_LIST_RECORD_STATE_KEY]: record.state ?? null,
|
|
199
|
+
};
|
|
176
200
|
columns.forEach((column) => {
|
|
177
201
|
const property = this.resolvePropertyMeta(column.key, propertyMaps);
|
|
178
202
|
row[column.key] = this.toEntityData(column.key, record.values?.[property?.key ?? column.key], property, column.viewType, column.label, column.configuration, property?.configuration, record.id, column.order ?? property?.order);
|
|
@@ -284,6 +308,8 @@ class ClientListStateService {
|
|
|
284
308
|
existing.areaType !== item.areaType) {
|
|
285
309
|
return item;
|
|
286
310
|
}
|
|
311
|
+
const keepPaging = existing.config.isPaginated === item.config.isPaginated &&
|
|
312
|
+
existing.take === item.take;
|
|
287
313
|
return {
|
|
288
314
|
...item,
|
|
289
315
|
loading: existing.loading,
|
|
@@ -294,8 +320,8 @@ class ClientListStateService {
|
|
|
294
320
|
columns: existing.columns,
|
|
295
321
|
rows: existing.rows,
|
|
296
322
|
cards: existing.cards,
|
|
297
|
-
skip: existing.skip,
|
|
298
|
-
take:
|
|
323
|
+
skip: keepPaging ? existing.skip : item.skip,
|
|
324
|
+
take: item.take,
|
|
299
325
|
expanded: existing.expanded,
|
|
300
326
|
dashboardData: existing.dashboardData,
|
|
301
327
|
rawData: existing.rawData,
|
|
@@ -329,6 +355,7 @@ class ClientListStateService {
|
|
|
329
355
|
}
|
|
330
356
|
: undefined,
|
|
331
357
|
instanceId: record.id,
|
|
358
|
+
state: record.state ?? null,
|
|
332
359
|
properties: normalizedEntities,
|
|
333
360
|
entities: normalizedEntities,
|
|
334
361
|
};
|
|
@@ -718,6 +745,10 @@ class ClientListTableView {
|
|
|
718
745
|
* so switching area types preserves the toolbar state.
|
|
719
746
|
*/
|
|
720
747
|
bucket = computed(() => this.toolbar.forList(this.state().key), ...(ngDevMode ? [{ debugName: "bucket" }] : /* istanbul ignore next */ []));
|
|
748
|
+
pageSize = computed(() => {
|
|
749
|
+
const table = this.table();
|
|
750
|
+
return table.config.isPaginated ? table.take : table.config.table.pageSize;
|
|
751
|
+
}, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
721
752
|
/**
|
|
722
753
|
* Stable, per-instance storage key. Excludes `areaType` so table and cards
|
|
723
754
|
* views for the same logical list share persistence (matches the toolbar
|
|
@@ -755,11 +786,11 @@ class ClientListTableView {
|
|
|
755
786
|
};
|
|
756
787
|
}
|
|
757
788
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientListTableView, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
758
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ClientListTableView, isStandalone: true, selector: "mt-client-list-table-view", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, actionShape: { classPropertyName: "actionShape", publicName: "actionShape", isSignal: true, isRequired: false, transformFunction: null }, rowActionsLoadingFn: { classPropertyName: "rowActionsLoadingFn", publicName: "rowActionsLoadingFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { lazyLoad: "lazyLoad", rowClick: "rowClick", rowActionsRequested: "rowActionsRequested" }, ngImport: i0, template: "<div class=\"grid gap-4\" [style.gridTemplateColumns]=\"gridTemplateColumns\">\r\n @if (table().config.contentStart) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.startSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentStart\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.tableSpan)\">\r\n @if (table().loading && table().rows.length === 0) {\r\n <div class=\"flex flex-col gap-3 py-3\">\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n </div>\r\n } @else if (table().error) {\r\n <div\r\n class=\"rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700\"\r\n >\r\n {{ table().error }}\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"table().rows\"\r\n [columns]=\"table().columns\"\r\n dataKey=\"Id\"\r\n [storageKey]=\"tableStorageKey()\"\r\n [rowActions]=\"rowActions()\"\r\n [actionShape]=\"actionShape()\"\r\n [rowActionsLoadingFn]=\"rowActionsLoadingFn()\"\r\n (rowActionsRequested)=\"rowActionsRequested.emit($event)\"\r\n [generalSearch]=\"table().config.table.searchable\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [cellClickFilter]=\"true\"\r\n [freezeActions]=\"true\"\r\n [exportable]=\"table().config.table.exportable\"\r\n [loading]=\"table().loading\"\r\n [clickableRows]=\"true\"\r\n [lazy]=\"table().config.isPaginated\"\r\n [lazyTotalRecords]=\"table().totalCount\"\r\n [virtualScroll]=\"
|
|
789
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ClientListTableView, isStandalone: true, selector: "mt-client-list-table-view", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, actionShape: { classPropertyName: "actionShape", publicName: "actionShape", isSignal: true, isRequired: false, transformFunction: null }, rowActionsLoadingFn: { classPropertyName: "rowActionsLoadingFn", publicName: "rowActionsLoadingFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { lazyLoad: "lazyLoad", rowClick: "rowClick", rowActionsRequested: "rowActionsRequested" }, ngImport: i0, template: "<div class=\"grid gap-4\" [style.gridTemplateColumns]=\"gridTemplateColumns\">\r\n @if (table().config.contentStart) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.startSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentStart\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.tableSpan)\">\r\n @if (table().loading && table().rows.length === 0) {\r\n <div class=\"flex flex-col gap-3 py-3\">\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n </div>\r\n } @else if (table().error) {\r\n <div\r\n class=\"rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700\"\r\n >\r\n {{ table().error }}\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"table().rows\"\r\n [columns]=\"table().columns\"\r\n dataKey=\"Id\"\r\n [storageKey]=\"tableStorageKey()\"\r\n [persistStateExclude]=\"table().config.table.persistStateExclude\"\r\n [rowActions]=\"rowActions()\"\r\n [actionShape]=\"actionShape()\"\r\n [rowActionsLoadingFn]=\"rowActionsLoadingFn()\"\r\n (rowActionsRequested)=\"rowActionsRequested.emit($event)\"\r\n [generalSearch]=\"table().config.table.searchable\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [cellClickFilter]=\"true\"\r\n [freezeActions]=\"true\"\r\n [exportable]=\"table().config.table.exportable\"\r\n [loading]=\"table().loading\"\r\n [clickableRows]=\"true\"\r\n [lazy]=\"table().config.isPaginated\"\r\n [lazyTotalRecords]=\"table().totalCount\"\r\n [virtualScroll]=\"!table().config.isPaginated\"\r\n [virtualScrollItemSize]=\"56\"\r\n scrollHeight=\"520px\"\r\n [pageSize]=\"pageSize()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (lazyLoad)=\"lazyLoad.emit($event)\"\r\n (rowClick)=\"rowClick.emit($event)\"\r\n />\r\n }\r\n </div>\r\n\r\n @if (table().config.contentEnd) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.endSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentEnd\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }] });
|
|
759
790
|
}
|
|
760
791
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientListTableView, decorators: [{
|
|
761
792
|
type: Component,
|
|
762
|
-
args: [{ selector: 'mt-client-list-table-view', standalone: true, imports: [CommonModule, Table, SkeletonModule], template: "<div class=\"grid gap-4\" [style.gridTemplateColumns]=\"gridTemplateColumns\">\r\n @if (table().config.contentStart) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.startSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentStart\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.tableSpan)\">\r\n @if (table().loading && table().rows.length === 0) {\r\n <div class=\"flex flex-col gap-3 py-3\">\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n </div>\r\n } @else if (table().error) {\r\n <div\r\n class=\"rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700\"\r\n >\r\n {{ table().error }}\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"table().rows\"\r\n [columns]=\"table().columns\"\r\n dataKey=\"Id\"\r\n [storageKey]=\"tableStorageKey()\"\r\n [rowActions]=\"rowActions()\"\r\n [actionShape]=\"actionShape()\"\r\n [rowActionsLoadingFn]=\"rowActionsLoadingFn()\"\r\n (rowActionsRequested)=\"rowActionsRequested.emit($event)\"\r\n [generalSearch]=\"table().config.table.searchable\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [cellClickFilter]=\"true\"\r\n [freezeActions]=\"true\"\r\n [exportable]=\"table().config.table.exportable\"\r\n [loading]=\"table().loading\"\r\n [clickableRows]=\"true\"\r\n [lazy]=\"table().config.isPaginated\"\r\n [lazyTotalRecords]=\"table().totalCount\"\r\n [virtualScroll]=\"
|
|
793
|
+
args: [{ selector: 'mt-client-list-table-view', standalone: true, imports: [CommonModule, Table, SkeletonModule], template: "<div class=\"grid gap-4\" [style.gridTemplateColumns]=\"gridTemplateColumns\">\r\n @if (table().config.contentStart) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.startSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentStart\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.tableSpan)\">\r\n @if (table().loading && table().rows.length === 0) {\r\n <div class=\"flex flex-col gap-3 py-3\">\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n <p-skeleton height=\"3rem\" />\r\n </div>\r\n } @else if (table().error) {\r\n <div\r\n class=\"rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700\"\r\n >\r\n {{ table().error }}\r\n </div>\r\n } @else {\r\n <mt-table\r\n [noCard]=\"true\"\r\n [data]=\"table().rows\"\r\n [columns]=\"table().columns\"\r\n dataKey=\"Id\"\r\n [storageKey]=\"tableStorageKey()\"\r\n [persistStateExclude]=\"table().config.table.persistStateExclude\"\r\n [rowActions]=\"rowActions()\"\r\n [actionShape]=\"actionShape()\"\r\n [rowActionsLoadingFn]=\"rowActionsLoadingFn()\"\r\n (rowActionsRequested)=\"rowActionsRequested.emit($event)\"\r\n [generalSearch]=\"table().config.table.searchable\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [cellClickFilter]=\"true\"\r\n [freezeActions]=\"true\"\r\n [exportable]=\"table().config.table.exportable\"\r\n [loading]=\"table().loading\"\r\n [clickableRows]=\"true\"\r\n [lazy]=\"table().config.isPaginated\"\r\n [lazyTotalRecords]=\"table().totalCount\"\r\n [virtualScroll]=\"!table().config.isPaginated\"\r\n [virtualScrollItemSize]=\"56\"\r\n scrollHeight=\"520px\"\r\n [pageSize]=\"pageSize()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (lazyLoad)=\"lazyLoad.emit($event)\"\r\n (rowClick)=\"rowClick.emit($event)\"\r\n />\r\n }\r\n </div>\r\n\r\n @if (table().config.contentEnd) {\r\n <div [style.gridColumn]=\"slotGridSpan(table().config.layout.endSpan)\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"table().config.contentEnd\"\r\n [ngTemplateOutletContext]=\"templateContext(table())\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n" }]
|
|
763
794
|
}], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], actionShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionShape", required: false }] }], rowActionsLoadingFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActionsLoadingFn", required: false }] }], lazyLoad: [{ type: i0.Output, args: ["lazyLoad"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowActionsRequested: [{ type: i0.Output, args: ["rowActionsRequested"] }] } });
|
|
764
795
|
|
|
765
796
|
const EMPTY_KEY_SET = new Set();
|
|
@@ -821,8 +852,12 @@ class ClientListCardsView {
|
|
|
821
852
|
cardToRow(card) {
|
|
822
853
|
const fromDisplay = card.displayProperties;
|
|
823
854
|
const record = fromDisplay && Object.keys(fromDisplay).length > 0
|
|
824
|
-
? {
|
|
825
|
-
|
|
855
|
+
? {
|
|
856
|
+
Id: card.id,
|
|
857
|
+
...fromDisplay,
|
|
858
|
+
[CLIENT_LIST_RECORD_STATE_KEY]: card.state ?? null,
|
|
859
|
+
}
|
|
860
|
+
: { Id: card.id, [CLIENT_LIST_RECORD_STATE_KEY]: card.state ?? null };
|
|
826
861
|
for (const entity of card.entities ?? []) {
|
|
827
862
|
const e = entity;
|
|
828
863
|
const key = (typeof e['key'] === 'string' && e['key']) ||
|
|
@@ -858,6 +893,29 @@ class ClientListCardsView {
|
|
|
858
893
|
const row = this.rowForCard(card);
|
|
859
894
|
return this.rowActions().filter((action) => !action.hidden?.(row));
|
|
860
895
|
}
|
|
896
|
+
inlineActionsForCard(card) {
|
|
897
|
+
return this.visibleActionsForCard(card).filter((action) => this.actionPlacement(action) === 'inline');
|
|
898
|
+
}
|
|
899
|
+
menuActionsForCard(card) {
|
|
900
|
+
return this.visibleActionsForCard(card).filter((action) => this.actionPlacement(action) !== 'inline');
|
|
901
|
+
}
|
|
902
|
+
showCardActionsMenu(card) {
|
|
903
|
+
return (this.isCardActionsLoading(card) ||
|
|
904
|
+
this.menuActionsForCard(card).length > 0);
|
|
905
|
+
}
|
|
906
|
+
resolveActionLoading(action, card) {
|
|
907
|
+
const loading = action.loading;
|
|
908
|
+
if (typeof loading === 'function') {
|
|
909
|
+
return loading(this.rowForCard(card));
|
|
910
|
+
}
|
|
911
|
+
return typeof loading === 'boolean' ? loading : undefined;
|
|
912
|
+
}
|
|
913
|
+
actionSize(action) {
|
|
914
|
+
return action.size;
|
|
915
|
+
}
|
|
916
|
+
actionPlacement(action) {
|
|
917
|
+
return action.placement;
|
|
918
|
+
}
|
|
861
919
|
isCardActionsLoading(card) {
|
|
862
920
|
return this.rowActionsLoadingFn()?.(this.rowForCard(card)) ?? false;
|
|
863
921
|
}
|
|
@@ -1169,7 +1227,7 @@ class ClientListCardsView {
|
|
|
1169
1227
|
});
|
|
1170
1228
|
}
|
|
1171
1229
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientListCardsView, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1172
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ClientListCardsView, isStandalone: true, selector: "mt-client-list-cards-view", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, rowActionsLoadingFn: { classPropertyName: "rowActionsLoadingFn", publicName: "rowActionsLoadingFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { lazyLoad: "lazyLoad", cardClick: "cardClick", rowActionsRequested: "rowActionsRequested" }, providers: [MTDateFormatPipe], ngImport: i0, template: "<mt-table-caption\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n filterMode=\"popover\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [exportable]=\"true\"\r\n [columns]=\"columns()\"\r\n [data]=\"rowRepresentations()\"\r\n [groupColumns]=\"grouping.groupableColumns()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (exportRequested)=\"exportExcel()\"\r\n (printRequested)=\"printPdf()\"\r\n/>\r\n\r\n@if (cardsState().loading && cardsState().cards.length === 0) {\r\n <div class=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (i of [1, 2, 3, 4, 5, 6]; track i) {\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n} @else if (cardsState().error) {\r\n <div class=\"rounded-lg border border-red-200 bg-red-50 p-6 text-red-600\">\r\n {{ cardsState().error }}\r\n </div>\r\n} @else if (visibleCards().length === 0) {\r\n <div class=\"p-6 text-center text-gray-400\">\r\n {{ \"components.clientComponents.list.noCardsFound\" | transloco }}\r\n </div>\r\n} @else if (grouping.groupingActive()) {\r\n <div class=\"flex flex-col gap-6\">\r\n @for (group of groupedCards(); track group.key) {\r\n <section class=\"flex flex-col gap-3\">\r\n <header\r\n class=\"flex items-center gap-3 px-2 py-2 bg-surface-50 dark:bg-surface-900 border-y border-surface-200 dark:border-surface-700 rounded\"\r\n [style.--mt-group-accent]=\"group.accent ?? 'var(--p-primary-color)'\"\r\n >\r\n <span\r\n class=\"inline-block w-1 h-5 rounded-full\"\r\n [style.background]=\"'var(--mt-group-accent)'\"\r\n ></span>\r\n <span\r\n class=\"text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400\"\r\n >\r\n {{ group.columnLabel }}\r\n </span>\r\n <span class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ group.label }}\r\n </span>\r\n <span\r\n class=\"ml-auto inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-primary-50 text-primary-700 dark:bg-primary-950 dark:text-primary-300\"\r\n >\r\n {{ group.count }}\r\n </span>\r\n </header>\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of group.cards; track card.id) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"\r\n 'components.table.filterByThis' | transloco\r\n \"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of visibleCards(); track card.id) {\r\n @defer (on viewport) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"'components.table.filterByThis' | transloco\"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n } @placeholder {\r\n <div class=\"min-h-[20rem]\">\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<!--\r\n Per-card 3-dots actions menu \u2014 same contract as the table view's popover\r\n row-actions. Rendered into each card's top-end corner; clicks stop at the\r\n wrapper so the card's own click (cardClick) doesn't fire.\r\n-->\r\n<ng-template #cardActionsMenu let-card>\r\n @if (rowActions().length > 0) {\r\n <div class=\"absolute end-2 top-2 z-10\" (click)=\"$event.stopPropagation()\">\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [tooltip]=\"'components.table.actions' | transloco\"\r\n (onClick)=\"onCardActionsToggle($event, cardPopover, card)\"\r\n />\r\n <p-popover #cardPopover appendTo=\"body\">\r\n <div class=\"flex min-w-44 flex-col gap-1 p-1\">\r\n @if (isCardActionsLoading(card)) {\r\n <div class=\"flex flex-col gap-2 p-1\">\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n </div>\r\n } @else {\r\n @for (action of visibleActionsForCard(card); track $index) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded px-2 py-2 text-start text-sm transition-colors\"\r\n [class]=\"\r\n action.color === 'danger'\r\n ? 'text-red-600 hover:bg-red-50 dark:hover:bg-red-950'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-surface-700'\r\n \"\r\n (click)=\"\r\n runCardAction($event, action, card); cardPopover.hide()\r\n \"\r\n >\r\n @if (action.icon) {\r\n <mt-icon [icon]=\"action.icon\" class=\"text-base\" />\r\n }\r\n <span>{{ action.label || action.tooltip }}</span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </p-popover>\r\n </div>\r\n }\r\n</ng-template>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape", "stackOnNarrow", "clickableKeys", "activeKeys", "clickableTooltip", "activeTooltip"], outputs: ["entityClick"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: TableCaption, selector: "mt-table-caption", inputs: ["generalSearch", "showFilters", "filterMode", "exportable", "printable", "groupable", "columns", "data", "groupColumns", "tabs", "tabsOptionLabel", "tabsOptionValue", "actions", "captionStart", "captionEnd", "activeTab", "filters", "filterTerm", "groupBy"], outputs: ["activeTabChange", "filtersChange", "filterTermChange", "groupByChange", "exportRequested", "printRequested", "onTabChange", "searchChange", "filterApplied", "filterReset"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }], deferBlockDependencies: [() => [i1.NgTemplateOutlet, Card,
|
|
1230
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ClientListCardsView, isStandalone: true, selector: "mt-client-list-cards-view", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, rowActionsLoadingFn: { classPropertyName: "rowActionsLoadingFn", publicName: "rowActionsLoadingFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { lazyLoad: "lazyLoad", cardClick: "cardClick", rowActionsRequested: "rowActionsRequested" }, providers: [MTDateFormatPipe], ngImport: i0, template: "<mt-table-caption\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n filterMode=\"popover\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [exportable]=\"true\"\r\n [columns]=\"columns()\"\r\n [data]=\"rowRepresentations()\"\r\n [groupColumns]=\"grouping.groupableColumns()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (exportRequested)=\"exportExcel()\"\r\n (printRequested)=\"printPdf()\"\r\n/>\r\n\r\n@if (cardsState().loading && cardsState().cards.length === 0) {\r\n <div class=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (i of [1, 2, 3, 4, 5, 6]; track i) {\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n} @else if (cardsState().error) {\r\n <div class=\"rounded-lg border border-red-200 bg-red-50 p-6 text-red-600\">\r\n {{ cardsState().error }}\r\n </div>\r\n} @else if (visibleCards().length === 0) {\r\n <div class=\"p-6 text-center text-gray-400\">\r\n {{ \"components.clientComponents.list.noCardsFound\" | transloco }}\r\n </div>\r\n} @else if (grouping.groupingActive()) {\r\n <div class=\"flex flex-col gap-6\">\r\n @for (group of groupedCards(); track group.key) {\r\n <section class=\"flex flex-col gap-3\">\r\n <header\r\n class=\"flex items-center gap-3 px-2 py-2 bg-surface-50 dark:bg-surface-900 border-y border-surface-200 dark:border-surface-700 rounded\"\r\n [style.--mt-group-accent]=\"group.accent ?? 'var(--p-primary-color)'\"\r\n >\r\n <span\r\n class=\"inline-block w-1 h-5 rounded-full\"\r\n [style.background]=\"'var(--mt-group-accent)'\"\r\n ></span>\r\n <span\r\n class=\"text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400\"\r\n >\r\n {{ group.columnLabel }}\r\n </span>\r\n <span class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ group.label }}\r\n </span>\r\n <span\r\n class=\"ml-auto inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-primary-50 text-primary-700 dark:bg-primary-950 dark:text-primary-300\"\r\n >\r\n {{ group.count }}\r\n </span>\r\n </header>\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of group.cards; track card.id) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"\r\n 'components.table.filterByThis' | transloco\r\n \"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of visibleCards(); track card.id) {\r\n @defer (on viewport) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"'components.table.filterByThis' | transloco\"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n } @placeholder {\r\n <div class=\"min-h-[20rem]\">\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<!--\r\n Per-card 3-dots actions menu \u2014 same contract as the table view's popover\r\n row-actions. Rendered into each card's top-end corner; clicks stop at the\r\n wrapper so the card's own click (cardClick) doesn't fire.\r\n-->\r\n<ng-template #cardActionsMenu let-card>\r\n @if (rowActions().length > 0) {\r\n <div\r\n class=\"absolute end-2 top-2 z-10 flex items-center gap-1\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n @for (action of inlineActionsForCard(card); track $index) {\r\n <mt-button\r\n [icon]=\"action.icon\"\r\n [severity]=\"action.color\"\r\n [variant]=\"action.variant\"\r\n [size]=\"actionSize(action) || 'small'\"\r\n [tooltip]=\"action.tooltip\"\r\n [label]=\"action.label\"\r\n [loading]=\"resolveActionLoading(action, card)\"\r\n (onClick)=\"runCardAction($event, action, card)\"\r\n />\r\n }\r\n @if (showCardActionsMenu(card)) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [tooltip]=\"'components.table.actions' | transloco\"\r\n (onClick)=\"onCardActionsToggle($event, cardPopover, card)\"\r\n />\r\n <p-popover #cardPopover appendTo=\"body\">\r\n <div class=\"flex min-w-44 flex-col gap-1 p-1\">\r\n @if (isCardActionsLoading(card)) {\r\n <div class=\"flex flex-col gap-2 p-1\">\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n </div>\r\n } @else {\r\n @for (action of menuActionsForCard(card); track $index) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded px-2 py-2 text-start text-sm transition-colors\"\r\n [class]=\"\r\n action.color === 'danger'\r\n ? 'text-red-600 hover:bg-red-50 dark:hover:bg-red-950'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-surface-700'\r\n \"\r\n (click)=\"\r\n runCardAction($event, action, card); cardPopover.hide()\r\n \"\r\n >\r\n @if (action.icon) {\r\n <mt-icon [icon]=\"action.icon\" class=\"text-base\" />\r\n }\r\n <span>{{ action.label || action.tooltip }}</span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape", "stackOnNarrow", "clickableKeys", "activeKeys", "clickableTooltip", "activeTooltip"], outputs: ["entityClick"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: TableCaption, selector: "mt-table-caption", inputs: ["generalSearch", "showFilters", "filterMode", "exportable", "printable", "groupable", "columns", "data", "groupColumns", "tabs", "tabsOptionLabel", "tabsOptionValue", "actions", "captionStart", "captionEnd", "activeTab", "filters", "filterTerm", "groupBy"], outputs: ["activeTabChange", "filtersChange", "filterTermChange", "groupByChange", "exportRequested", "printRequested", "onTabChange", "searchChange", "filterApplied", "filterReset"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }], deferBlockDependencies: [() => [i1.NgTemplateOutlet, Card,
|
|
1173
1231
|
EntitiesPreview, i4.TranslocoPipe]] });
|
|
1174
1232
|
}
|
|
1175
1233
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientListCardsView, decorators: [{
|
|
@@ -1184,7 +1242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
1184
1242
|
SkeletonModule,
|
|
1185
1243
|
PopoverModule,
|
|
1186
1244
|
TableCaption,
|
|
1187
|
-
], providers: [MTDateFormatPipe], template: "<mt-table-caption\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n filterMode=\"popover\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [exportable]=\"true\"\r\n [columns]=\"columns()\"\r\n [data]=\"rowRepresentations()\"\r\n [groupColumns]=\"grouping.groupableColumns()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (exportRequested)=\"exportExcel()\"\r\n (printRequested)=\"printPdf()\"\r\n/>\r\n\r\n@if (cardsState().loading && cardsState().cards.length === 0) {\r\n <div class=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (i of [1, 2, 3, 4, 5, 6]; track i) {\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n} @else if (cardsState().error) {\r\n <div class=\"rounded-lg border border-red-200 bg-red-50 p-6 text-red-600\">\r\n {{ cardsState().error }}\r\n </div>\r\n} @else if (visibleCards().length === 0) {\r\n <div class=\"p-6 text-center text-gray-400\">\r\n {{ \"components.clientComponents.list.noCardsFound\" | transloco }}\r\n </div>\r\n} @else if (grouping.groupingActive()) {\r\n <div class=\"flex flex-col gap-6\">\r\n @for (group of groupedCards(); track group.key) {\r\n <section class=\"flex flex-col gap-3\">\r\n <header\r\n class=\"flex items-center gap-3 px-2 py-2 bg-surface-50 dark:bg-surface-900 border-y border-surface-200 dark:border-surface-700 rounded\"\r\n [style.--mt-group-accent]=\"group.accent ?? 'var(--p-primary-color)'\"\r\n >\r\n <span\r\n class=\"inline-block w-1 h-5 rounded-full\"\r\n [style.background]=\"'var(--mt-group-accent)'\"\r\n ></span>\r\n <span\r\n class=\"text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400\"\r\n >\r\n {{ group.columnLabel }}\r\n </span>\r\n <span class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ group.label }}\r\n </span>\r\n <span\r\n class=\"ml-auto inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-primary-50 text-primary-700 dark:bg-primary-950 dark:text-primary-300\"\r\n >\r\n {{ group.count }}\r\n </span>\r\n </header>\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of group.cards; track card.id) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"\r\n 'components.table.filterByThis' | transloco\r\n \"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of visibleCards(); track card.id) {\r\n @defer (on viewport) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"'components.table.filterByThis' | transloco\"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n } @placeholder {\r\n <div class=\"min-h-[20rem]\">\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<!--\r\n Per-card 3-dots actions menu \u2014 same contract as the table view's popover\r\n row-actions. Rendered into each card's top-end corner; clicks stop at the\r\n wrapper so the card's own click (cardClick) doesn't fire.\r\n-->\r\n<ng-template #cardActionsMenu let-card>\r\n @if (rowActions().length > 0) {\r\n <div
|
|
1245
|
+
], providers: [MTDateFormatPipe], template: "<mt-table-caption\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n filterMode=\"popover\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [exportable]=\"true\"\r\n [columns]=\"columns()\"\r\n [data]=\"rowRepresentations()\"\r\n [groupColumns]=\"grouping.groupableColumns()\"\r\n [filters]=\"bucket().filters()\"\r\n (filtersChange)=\"bucket().filters.set($event)\"\r\n [filterTerm]=\"bucket().filterTerm()\"\r\n (filterTermChange)=\"bucket().filterTerm.set($event)\"\r\n [groupBy]=\"bucket().groupBy()\"\r\n (groupByChange)=\"bucket().groupBy.set($event)\"\r\n [activeTab]=\"bucket().activeTab()\"\r\n (activeTabChange)=\"bucket().activeTab.set($event)\"\r\n (exportRequested)=\"exportExcel()\"\r\n (printRequested)=\"printPdf()\"\r\n/>\r\n\r\n@if (cardsState().loading && cardsState().cards.length === 0) {\r\n <div class=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (i of [1, 2, 3, 4, 5, 6]; track i) {\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n} @else if (cardsState().error) {\r\n <div class=\"rounded-lg border border-red-200 bg-red-50 p-6 text-red-600\">\r\n {{ cardsState().error }}\r\n </div>\r\n} @else if (visibleCards().length === 0) {\r\n <div class=\"p-6 text-center text-gray-400\">\r\n {{ \"components.clientComponents.list.noCardsFound\" | transloco }}\r\n </div>\r\n} @else if (grouping.groupingActive()) {\r\n <div class=\"flex flex-col gap-6\">\r\n @for (group of groupedCards(); track group.key) {\r\n <section class=\"flex flex-col gap-3\">\r\n <header\r\n class=\"flex items-center gap-3 px-2 py-2 bg-surface-50 dark:bg-surface-900 border-y border-surface-200 dark:border-surface-700 rounded\"\r\n [style.--mt-group-accent]=\"group.accent ?? 'var(--p-primary-color)'\"\r\n >\r\n <span\r\n class=\"inline-block w-1 h-5 rounded-full\"\r\n [style.background]=\"'var(--mt-group-accent)'\"\r\n ></span>\r\n <span\r\n class=\"text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400\"\r\n >\r\n {{ group.columnLabel }}\r\n </span>\r\n <span class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ group.label }}\r\n </span>\r\n <span\r\n class=\"ml-auto inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-primary-50 text-primary-700 dark:bg-primary-950 dark:text-primary-300\"\r\n >\r\n {{ group.count }}\r\n </span>\r\n </header>\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of group.cards; track card.id) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"\r\n 'components.table.filterByThis' | transloco\r\n \"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </div>\r\n} @else {\r\n <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3\">\r\n @for (card of visibleCards(); track card.id) {\r\n @defer (on viewport) {\r\n <mt-card\r\n class=\"relative cursor-pointer p-5 shadow-sm transition-shadow hover:shadow-md\"\r\n (click)=\"cardClick.emit(card)\"\r\n >\r\n <ng-template #headless>\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardActionsMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: card }\"\r\n />\r\n <mt-entities-preview\r\n [entities]=\"card.entities\"\r\n attachmentShape=\"compact\"\r\n [stackOnNarrow]=\"false\"\r\n [clickableKeys]=\"clickableEntityKeys()\"\r\n [activeKeys]=\"activeKeysForCard(card)\"\r\n [clickableTooltip]=\"'components.table.filterByThis' | transloco\"\r\n [activeTooltip]=\"'components.table.clearFilter' | transloco\"\r\n (entityClick)=\"onEntityFilterClick(card, $event)\"\r\n />\r\n </ng-template>\r\n </mt-card>\r\n } @placeholder {\r\n <div class=\"min-h-[20rem]\">\r\n <p-skeleton height=\"20rem\" class=\"rounded-lg\" />\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<!--\r\n Per-card 3-dots actions menu \u2014 same contract as the table view's popover\r\n row-actions. Rendered into each card's top-end corner; clicks stop at the\r\n wrapper so the card's own click (cardClick) doesn't fire.\r\n-->\r\n<ng-template #cardActionsMenu let-card>\r\n @if (rowActions().length > 0) {\r\n <div\r\n class=\"absolute end-2 top-2 z-10 flex items-center gap-1\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n @for (action of inlineActionsForCard(card); track $index) {\r\n <mt-button\r\n [icon]=\"action.icon\"\r\n [severity]=\"action.color\"\r\n [variant]=\"action.variant\"\r\n [size]=\"actionSize(action) || 'small'\"\r\n [tooltip]=\"action.tooltip\"\r\n [label]=\"action.label\"\r\n [loading]=\"resolveActionLoading(action, card)\"\r\n (onClick)=\"runCardAction($event, action, card)\"\r\n />\r\n }\r\n @if (showCardActionsMenu(card)) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [tooltip]=\"'components.table.actions' | transloco\"\r\n (onClick)=\"onCardActionsToggle($event, cardPopover, card)\"\r\n />\r\n <p-popover #cardPopover appendTo=\"body\">\r\n <div class=\"flex min-w-44 flex-col gap-1 p-1\">\r\n @if (isCardActionsLoading(card)) {\r\n <div class=\"flex flex-col gap-2 p-1\">\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n <p-skeleton height=\"1.75rem\" />\r\n </div>\r\n } @else {\r\n @for (action of menuActionsForCard(card); track $index) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded px-2 py-2 text-start text-sm transition-colors\"\r\n [class]=\"\r\n action.color === 'danger'\r\n ? 'text-red-600 hover:bg-red-50 dark:hover:bg-red-950'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-surface-700'\r\n \"\r\n (click)=\"\r\n runCardAction($event, action, card); cardPopover.hide()\r\n \"\r\n >\r\n @if (action.icon) {\r\n <mt-icon [icon]=\"action.icon\" class=\"text-base\" />\r\n }\r\n <span>{{ action.label || action.tooltip }}</span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n" }]
|
|
1188
1246
|
}], ctorParameters: () => [], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], rowActionsLoadingFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActionsLoadingFn", required: false }] }], lazyLoad: [{ type: i0.Output, args: ["lazyLoad"] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }], rowActionsRequested: [{ type: i0.Output, args: ["rowActionsRequested"] }] } });
|
|
1189
1247
|
|
|
1190
1248
|
const DEFAULT_GRID_COLUMNS$1 = 12;
|
|
@@ -1232,11 +1290,16 @@ const DEFAULT_MODE = 'auto';
|
|
|
1232
1290
|
const DEFAULT_TYPE = 'form';
|
|
1233
1291
|
const DEFAULT_SERVER_PAGE_SIZE = 100;
|
|
1234
1292
|
const DEFAULT_TABLE_PAGE_SIZE = 100;
|
|
1235
|
-
const
|
|
1293
|
+
const DEFAULT_TABLE_PERSIST_STATE_EXCLUDE = [
|
|
1294
|
+
'pagePosition',
|
|
1295
|
+
];
|
|
1236
1296
|
const DEFAULT_COLLAPSE_ICON = 'arrow.chevron-up';
|
|
1237
1297
|
const DEFAULT_EXPAND_ICON = 'arrow.chevron-down';
|
|
1238
1298
|
const DEFAULT_SIDE_CONTENT_SPAN = 3;
|
|
1239
1299
|
const DEFAULT_GRID_COLUMNS = 12;
|
|
1300
|
+
const ESCALATION_STATE_KEY = 'escalation';
|
|
1301
|
+
const VIEW_ESCALATION_ACTION_KEY = 'viewEscalation';
|
|
1302
|
+
const VIEW_ESCALATION_OPERATION_KEY = 'ViewEscalation';
|
|
1240
1303
|
class ClientList {
|
|
1241
1304
|
api = inject(ClientListApiService);
|
|
1242
1305
|
state = inject(ClientListStateService);
|
|
@@ -1271,8 +1334,9 @@ class ClientList {
|
|
|
1271
1334
|
!item.config.isPaginated) {
|
|
1272
1335
|
return;
|
|
1273
1336
|
}
|
|
1274
|
-
const take =
|
|
1275
|
-
const skip =
|
|
1337
|
+
const take = this.resolvePositiveInteger(event.pageSize) ?? item.take;
|
|
1338
|
+
const skip = this.resolveNonNegativeInteger(event.first) ?? 0;
|
|
1339
|
+
this.state.setTablePaging(item.key, skip, take);
|
|
1276
1340
|
this.loadTable(item.key, item.config, skip, take);
|
|
1277
1341
|
}
|
|
1278
1342
|
reload(itemKey) {
|
|
@@ -1376,8 +1440,14 @@ class ClientList {
|
|
|
1376
1440
|
computeMergedRowActions(item, cache) {
|
|
1377
1441
|
const baseActions = item.config.rowActions ?? [];
|
|
1378
1442
|
const config = item.config.runtimeRecordActions;
|
|
1443
|
+
const escalationAction = config?.enabled && this.hasActiveEscalation(item)
|
|
1444
|
+
? this.createEscalationPreviewRowAction(item, config)
|
|
1445
|
+
: null;
|
|
1446
|
+
const baseWithEscalation = escalationAction
|
|
1447
|
+
? [escalationAction, ...baseActions]
|
|
1448
|
+
: baseActions;
|
|
1379
1449
|
if (!config?.enabled)
|
|
1380
|
-
return
|
|
1450
|
+
return baseWithEscalation;
|
|
1381
1451
|
const prefix = `${item.key}:`;
|
|
1382
1452
|
const prototypes = new Map();
|
|
1383
1453
|
for (const [key, actions] of cache) {
|
|
@@ -1390,11 +1460,14 @@ class ClientList {
|
|
|
1390
1460
|
}
|
|
1391
1461
|
}
|
|
1392
1462
|
if (prototypes.size === 0) {
|
|
1393
|
-
return
|
|
1463
|
+
return baseWithEscalation;
|
|
1394
1464
|
}
|
|
1395
1465
|
const icon = config.actionIcon ?? 'media.play-circle';
|
|
1396
1466
|
const runtimeActionEntries = [];
|
|
1397
1467
|
for (const [actionKey, prototype] of prototypes) {
|
|
1468
|
+
if (this.isViewEscalationAction(prototype)) {
|
|
1469
|
+
continue;
|
|
1470
|
+
}
|
|
1398
1471
|
const label = resolveActionLabel(prototype);
|
|
1399
1472
|
const presentation = config.resolveActionPresentation?.(prototype) ?? {};
|
|
1400
1473
|
runtimeActionEntries.push({
|
|
@@ -1423,7 +1496,97 @@ class ClientList {
|
|
|
1423
1496
|
},
|
|
1424
1497
|
});
|
|
1425
1498
|
}
|
|
1426
|
-
return [...
|
|
1499
|
+
return [...baseWithEscalation, ...runtimeActionEntries];
|
|
1500
|
+
}
|
|
1501
|
+
createEscalationPreviewRowAction(item, config) {
|
|
1502
|
+
const label = this.transloco.translate('components.clientComponents.list.viewEscalation');
|
|
1503
|
+
const action = {
|
|
1504
|
+
icon: 'editor.hand',
|
|
1505
|
+
color: 'warn',
|
|
1506
|
+
variant: 'text',
|
|
1507
|
+
placement: 'inline',
|
|
1508
|
+
tooltip: label,
|
|
1509
|
+
hidden: (row) => this.resolveEscalationInstanceId(row) == null,
|
|
1510
|
+
action: (row) => {
|
|
1511
|
+
void this.triggerEscalationPreviewAction(item, row, config);
|
|
1512
|
+
},
|
|
1513
|
+
};
|
|
1514
|
+
return action;
|
|
1515
|
+
}
|
|
1516
|
+
async triggerEscalationPreviewAction(item, row, config) {
|
|
1517
|
+
const instanceId = this.resolveEscalationInstanceId(row);
|
|
1518
|
+
if (instanceId == null)
|
|
1519
|
+
return;
|
|
1520
|
+
const ctx = this.toRuntimeActionsContext(item, row, config);
|
|
1521
|
+
if (!ctx)
|
|
1522
|
+
return;
|
|
1523
|
+
const action = this.toEscalationPreviewRuntimeAction(instanceId);
|
|
1524
|
+
const handled = await Promise.resolve(config.onActionTriggered?.(action, ctx));
|
|
1525
|
+
if (handled === true)
|
|
1526
|
+
return;
|
|
1527
|
+
const result = await this.runtimeRunner.execute(action, {
|
|
1528
|
+
defaultAfterSuccess: 'refresh',
|
|
1529
|
+
});
|
|
1530
|
+
if (result.status !== 'success')
|
|
1531
|
+
return;
|
|
1532
|
+
this.runtimeActions.invalidateList(item.key);
|
|
1533
|
+
this.reloadByKey(item.key);
|
|
1534
|
+
config.onActionExecuted?.(action, ctx);
|
|
1535
|
+
}
|
|
1536
|
+
toEscalationPreviewRuntimeAction(instanceId) {
|
|
1537
|
+
return {
|
|
1538
|
+
actionKey: VIEW_ESCALATION_ACTION_KEY,
|
|
1539
|
+
actionName: this.transloco.translate('components.clientComponents.list.viewEscalation'),
|
|
1540
|
+
httpMethod: 'GET',
|
|
1541
|
+
url: `escalations/${instanceId}/preview`,
|
|
1542
|
+
isAvailable: true,
|
|
1543
|
+
operationKey: VIEW_ESCALATION_OPERATION_KEY,
|
|
1544
|
+
targetType: 'Escalation',
|
|
1545
|
+
targetId: instanceId,
|
|
1546
|
+
payloadTemplate: {
|
|
1547
|
+
escalationInstanceId: instanceId,
|
|
1548
|
+
instanceId,
|
|
1549
|
+
},
|
|
1550
|
+
};
|
|
1551
|
+
}
|
|
1552
|
+
resolveEscalationInstanceId(row) {
|
|
1553
|
+
const state = row[CLIENT_LIST_RECORD_STATE_KEY];
|
|
1554
|
+
return this.resolveEscalationInstanceIdFromState(state);
|
|
1555
|
+
}
|
|
1556
|
+
resolveEscalationInstanceIdFromState(state) {
|
|
1557
|
+
const escalation = state?.[ESCALATION_STATE_KEY];
|
|
1558
|
+
if (escalation?.hasActive !== true) {
|
|
1559
|
+
return null;
|
|
1560
|
+
}
|
|
1561
|
+
return this.toFiniteNumber(escalation.instanceId);
|
|
1562
|
+
}
|
|
1563
|
+
hasActiveEscalation(item) {
|
|
1564
|
+
if (item.type !== 'form') {
|
|
1565
|
+
return false;
|
|
1566
|
+
}
|
|
1567
|
+
if (item.areaType === 'cards') {
|
|
1568
|
+
return item.cards.some((card) => this.resolveEscalationInstanceIdFromState(card.state) != null);
|
|
1569
|
+
}
|
|
1570
|
+
return item.rows.some((row) => this.resolveEscalationInstanceId(row) != null);
|
|
1571
|
+
}
|
|
1572
|
+
isViewEscalationAction(action) {
|
|
1573
|
+
return (this.normalizeActionKey(action.operationKey) ===
|
|
1574
|
+
this.normalizeActionKey(VIEW_ESCALATION_OPERATION_KEY) ||
|
|
1575
|
+
this.normalizeActionKey(action.actionKey) ===
|
|
1576
|
+
this.normalizeActionKey(VIEW_ESCALATION_ACTION_KEY));
|
|
1577
|
+
}
|
|
1578
|
+
normalizeActionKey(value) {
|
|
1579
|
+
return (value ?? '').trim().toLowerCase();
|
|
1580
|
+
}
|
|
1581
|
+
toFiniteNumber(value) {
|
|
1582
|
+
if (typeof value === 'number') {
|
|
1583
|
+
return Number.isFinite(value) ? value : null;
|
|
1584
|
+
}
|
|
1585
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
1586
|
+
const parsed = Number(value);
|
|
1587
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1588
|
+
}
|
|
1589
|
+
return null;
|
|
1427
1590
|
}
|
|
1428
1591
|
async executeRuntimeAction(item, ctx, config, action) {
|
|
1429
1592
|
const handled = await Promise.resolve(config.onActionTriggered?.(action, ctx));
|
|
@@ -1497,13 +1660,14 @@ class ClientList {
|
|
|
1497
1660
|
areaType === 'table' &&
|
|
1498
1661
|
(formConfig?.isPaginated ?? true);
|
|
1499
1662
|
const configuredTablePageSize = this.resolvePositiveInteger(formConfig?.table?.pageSize);
|
|
1663
|
+
const configuredTake = this.resolvePositiveInteger(formConfig?.take);
|
|
1500
1664
|
const showHeader = config.showHeader ?? true;
|
|
1501
1665
|
const take = !isInformative && areaType === 'table'
|
|
1502
1666
|
? isPaginated
|
|
1503
|
-
? (
|
|
1667
|
+
? (configuredTake ??
|
|
1504
1668
|
configuredTablePageSize ??
|
|
1505
|
-
this.
|
|
1506
|
-
:
|
|
1669
|
+
this.resolveDefaultTake())
|
|
1670
|
+
: (configuredTake ?? this.resolveDefaultTake())
|
|
1507
1671
|
: 0;
|
|
1508
1672
|
const collapseEnabled = showHeader &&
|
|
1509
1673
|
(config.collapse?.enabled ?? true) &&
|
|
@@ -1567,7 +1731,11 @@ class ClientList {
|
|
|
1567
1731
|
columns: [],
|
|
1568
1732
|
rows: [],
|
|
1569
1733
|
cards: [],
|
|
1570
|
-
skip: existing?.areaType === 'table'
|
|
1734
|
+
skip: existing?.areaType === 'table' &&
|
|
1735
|
+
existing.config.isPaginated === isPaginated &&
|
|
1736
|
+
existing.take === take
|
|
1737
|
+
? existing.skip
|
|
1738
|
+
: 0,
|
|
1571
1739
|
take,
|
|
1572
1740
|
expanded: existing?.expanded ?? config.collapse?.expandedByDefault ?? true,
|
|
1573
1741
|
dashboardData: null,
|
|
@@ -1842,6 +2010,10 @@ class ClientList {
|
|
|
1842
2010
|
: (configuredPageSize ?? DEFAULT_TABLE_PAGE_SIZE),
|
|
1843
2011
|
searchable: config?.table?.searchable ?? false,
|
|
1844
2012
|
exportable: config?.table?.exportable ?? false,
|
|
2013
|
+
persistStateExclude: [
|
|
2014
|
+
...(config?.table?.persistStateExclude ??
|
|
2015
|
+
DEFAULT_TABLE_PERSIST_STATE_EXCLUDE),
|
|
2016
|
+
],
|
|
1845
2017
|
};
|
|
1846
2018
|
}
|
|
1847
2019
|
clampSpan(value, min = 0, max = DEFAULT_GRID_COLUMNS) {
|
|
@@ -1857,6 +2029,17 @@ class ClientList {
|
|
|
1857
2029
|
}
|
|
1858
2030
|
return Math.trunc(normalized);
|
|
1859
2031
|
}
|
|
2032
|
+
resolveDefaultTake() {
|
|
2033
|
+
return (this.resolvePositiveInteger(this.defaultTake()) ??
|
|
2034
|
+
DEFAULT_SERVER_PAGE_SIZE);
|
|
2035
|
+
}
|
|
2036
|
+
resolveNonNegativeInteger(value) {
|
|
2037
|
+
const normalized = Number(value);
|
|
2038
|
+
if (!Number.isFinite(normalized) || normalized < 0) {
|
|
2039
|
+
return null;
|
|
2040
|
+
}
|
|
2041
|
+
return Math.trunc(normalized);
|
|
2042
|
+
}
|
|
1860
2043
|
cleanupStaleResources(activeKeys) {
|
|
1861
2044
|
for (const [key, sub] of this.subscriptions.entries()) {
|
|
1862
2045
|
if (!activeKeys.has(key)) {
|
|
@@ -1895,11 +2078,12 @@ class ClientList {
|
|
|
1895
2078
|
}
|
|
1896
2079
|
}
|
|
1897
2080
|
toTableQuery(config, skip, take) {
|
|
2081
|
+
const queryTake = this.resolvePositiveInteger(take) ?? this.resolveDefaultTake();
|
|
1898
2082
|
return {
|
|
1899
2083
|
mode: config.mode,
|
|
1900
2084
|
columnKeys: config.mode === 'override' ? config.columnKeys : undefined,
|
|
1901
2085
|
skip: config.isPaginated ? skip : 0,
|
|
1902
|
-
take:
|
|
2086
|
+
take: queryTake,
|
|
1903
2087
|
};
|
|
1904
2088
|
}
|
|
1905
2089
|
createTableRequestSignature(config, query) {
|
|
@@ -1998,5 +2182,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
1998
2182
|
* Generated bundle index. Do not edit.
|
|
1999
2183
|
*/
|
|
2000
2184
|
|
|
2001
|
-
export { ClientList, ClientListApiService, ClientListRuntimeActionsService, ClientListStateService, ClientListToolbarService, defaultResolveRecordId };
|
|
2185
|
+
export { CLIENT_LIST_RECORD_STATE_KEY, ClientList, ClientListApiService, ClientListRuntimeActionsService, ClientListStateService, ClientListToolbarService, defaultResolveRecordId };
|
|
2002
2186
|
//# sourceMappingURL=masterteam-client-components-client-list.mjs.map
|