@masterteam/work-center 0.0.2 → 0.0.3
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.
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CommonModule } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, Injectable, computed, input, output, Component } from '@angular/core';
|
|
3
|
+
import { inject, Injectable, computed, input, output, Component, signal, effect, untracked } from '@angular/core';
|
|
4
4
|
import { ClientPage } from '@masterteam/components/client-page';
|
|
5
|
+
import { ModalService } from '@masterteam/components/modal';
|
|
5
6
|
import { PropertyFilterBuilder } from '@masterteam/components/property-filter-builder';
|
|
6
7
|
import { StatisticCard } from '@masterteam/components/statistic-card';
|
|
7
8
|
import { Table } from '@masterteam/components/table';
|
|
@@ -11,6 +12,13 @@ import { Action, Selector, State, Store, select } from '@ngxs/store';
|
|
|
11
12
|
import { HttpClient } from '@angular/common/http';
|
|
12
13
|
import { handleApiRequest } from '@masterteam/components';
|
|
13
14
|
import { catchError, EMPTY, map } from 'rxjs';
|
|
15
|
+
import { EntitiesPreview } from '@masterteam/components/entities';
|
|
16
|
+
import { Tabs } from '@masterteam/components/tabs';
|
|
17
|
+
import { StructureBuilder } from '@masterteam/structure-builder';
|
|
18
|
+
import { ClientModulePreview } from '@masterteam/client-components/client-module-preview';
|
|
19
|
+
import { ClientForm } from '@masterteam/forms/client-form';
|
|
20
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
21
|
+
import { Drawer } from '@masterteam/components/drawer';
|
|
14
22
|
|
|
15
23
|
class EnterArea {
|
|
16
24
|
area;
|
|
@@ -150,26 +158,42 @@ function toLabel$1(value) {
|
|
|
150
158
|
.trim()
|
|
151
159
|
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
152
160
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
161
|
+
function toViewType(viewType, key) {
|
|
162
|
+
if (viewType?.trim()) {
|
|
163
|
+
return viewType;
|
|
164
|
+
}
|
|
165
|
+
return key.toLowerCase().includes('date') ? 'Date' : 'Text';
|
|
166
|
+
}
|
|
167
|
+
function getValue(record, key) {
|
|
168
|
+
return key.split('.').reduce((current, part) => {
|
|
169
|
+
if (!current || typeof current !== 'object') {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
return current[part];
|
|
173
|
+
}, record);
|
|
155
174
|
}
|
|
156
|
-
function
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return 'date';
|
|
175
|
+
function toDisplayValue(value, column) {
|
|
176
|
+
if (column.viewType !== 'Text') {
|
|
177
|
+
return value;
|
|
160
178
|
}
|
|
161
|
-
|
|
179
|
+
if (!value || typeof value !== 'object') {
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
const display = value['display'];
|
|
183
|
+
return typeof display === 'string' ? display : value;
|
|
162
184
|
}
|
|
163
185
|
function buildColumnsFromProperties(properties) {
|
|
164
186
|
return properties
|
|
165
187
|
.filter((property) => typeof property?.key === 'string' && property.key.length > 0)
|
|
166
188
|
.map((property) => ({
|
|
189
|
+
...property,
|
|
167
190
|
key: property.key,
|
|
168
191
|
label: property.name?.display ||
|
|
169
192
|
property.name?.en ||
|
|
170
193
|
property.name?.ar ||
|
|
171
194
|
toLabel$1(property.key),
|
|
172
|
-
type:
|
|
195
|
+
type: 'entity',
|
|
196
|
+
viewType: toViewType(property.viewType, property.key),
|
|
173
197
|
}));
|
|
174
198
|
}
|
|
175
199
|
function buildColumns(columnsConfig) {
|
|
@@ -181,9 +205,23 @@ function buildColumns(columnsConfig) {
|
|
|
181
205
|
return keys.map((key) => ({
|
|
182
206
|
key,
|
|
183
207
|
label: toLabel$1(key),
|
|
184
|
-
type:
|
|
208
|
+
type: 'entity',
|
|
209
|
+
viewType: toViewType(undefined, key),
|
|
185
210
|
}));
|
|
186
211
|
}
|
|
212
|
+
function toDisplayRows(rows, columns) {
|
|
213
|
+
return rows.map((row) => {
|
|
214
|
+
const displayRow = { ...row };
|
|
215
|
+
for (const column of columns) {
|
|
216
|
+
const value = getValue(row, column.key);
|
|
217
|
+
displayRow[column.key] = {
|
|
218
|
+
...column,
|
|
219
|
+
value: toDisplayValue(value, column),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return displayRow;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
187
225
|
function buildMenuItems(cards) {
|
|
188
226
|
const mapped = cards.map((card, index) => ({
|
|
189
227
|
key: card.key,
|
|
@@ -270,10 +308,14 @@ function buildContextFromInputs(currentContext, area, inputs = {}) {
|
|
|
270
308
|
templateId: parsedTemplateId ?? currentContext.templateId,
|
|
271
309
|
sort: hasParamValue(inputs.sort)
|
|
272
310
|
? parseSortInput(inputs.sort)
|
|
273
|
-
:
|
|
311
|
+
: inputs.sort === null
|
|
312
|
+
? []
|
|
313
|
+
: currentContext.sort,
|
|
274
314
|
runtimeFilters: hasParamValue(inputs.filters)
|
|
275
315
|
? parseFiltersInput(inputs.filters)
|
|
276
|
-
:
|
|
316
|
+
: inputs.filters === null
|
|
317
|
+
? []
|
|
318
|
+
: currentContext.runtimeFilters,
|
|
277
319
|
});
|
|
278
320
|
}
|
|
279
321
|
function isSameContext(left, right) {
|
|
@@ -288,7 +330,6 @@ function isSameContext(left, right) {
|
|
|
288
330
|
}
|
|
289
331
|
function mapRuntimeResponse(current, response) {
|
|
290
332
|
const selectedCard = response.selectedCard;
|
|
291
|
-
const rows = selectedCard?.items ?? [];
|
|
292
333
|
const menuItems = buildMenuItems(response.cards);
|
|
293
334
|
const requestedCardKey = selectedCard?.key ?? current.context.selectedCardKey ?? null;
|
|
294
335
|
const selectedCardKey = requestedCardKey &&
|
|
@@ -300,6 +341,7 @@ function mapRuntimeResponse(current, response) {
|
|
|
300
341
|
: null;
|
|
301
342
|
const selectedMenuItem = menuItems.find((item) => item.key === selectedCardKey);
|
|
302
343
|
const columns = buildColumns(selectedCard?.columnsConfig ?? selectedCardFromList?.columnsConfig);
|
|
344
|
+
const rows = toDisplayRows(selectedCard?.items ?? [], columns);
|
|
303
345
|
const kpis = buildKpis(selectedCard?.stats ?? [], selectedMenuItem?.icon ?? null);
|
|
304
346
|
return {
|
|
305
347
|
...current,
|
|
@@ -716,10 +758,14 @@ function mapAllowedOperators(schema) {
|
|
|
716
758
|
}
|
|
717
759
|
class WorkCenterPage {
|
|
718
760
|
facade = inject(WorkCenterFacade);
|
|
761
|
+
modal = inject(ModalService);
|
|
719
762
|
area = input('MyInbox', ...(ngDevMode ? [{ debugName: "area" }] : []));
|
|
720
763
|
pageTitle = input('Work Center', ...(ngDevMode ? [{ debugName: "pageTitle" }] : []));
|
|
721
764
|
menuIcon = input('communication.inbox-01', ...(ngDevMode ? [{ debugName: "menuIcon" }] : []));
|
|
765
|
+
openItemsInDrawer = input(true, ...(ngDevMode ? [{ debugName: "openItemsInDrawer" }] : []));
|
|
766
|
+
itemDrawer = input(null, ...(ngDevMode ? [{ debugName: "itemDrawer" }] : []));
|
|
722
767
|
runtimeFiltersChanged = output();
|
|
768
|
+
itemClicked = output();
|
|
723
769
|
context = this.facade.context;
|
|
724
770
|
menuItems = this.facade.menuItems;
|
|
725
771
|
rows = this.facade.rows;
|
|
@@ -759,6 +805,7 @@ class WorkCenterPage {
|
|
|
759
805
|
allowedOperators: fallbackOperators,
|
|
760
806
|
};
|
|
761
807
|
}, ...(ngDevMode ? [{ debugName: "propertyFilterSchema" }] : []));
|
|
808
|
+
defaultDrawerStyleClass = '!w-[96vw] xl:!w-[calc(100%-8rem)] 2xl:!w-[calc(100%-12rem)] !absolute !shadow-none';
|
|
762
809
|
onMenuItemClick(item) {
|
|
763
810
|
this.facade.selectCardAndLoad(this.area(), item.key);
|
|
764
811
|
}
|
|
@@ -766,20 +813,61 @@ class WorkCenterPage {
|
|
|
766
813
|
this.facade.applyTableLazyLoadAndLoad(this.area(), event);
|
|
767
814
|
}
|
|
768
815
|
onRuntimeFiltersApplied(filters) {
|
|
769
|
-
|
|
816
|
+
const mappedFilters = filters.map((filter) => ({
|
|
770
817
|
field: filter.field,
|
|
771
818
|
op: filter.op,
|
|
772
819
|
value: filter.value,
|
|
773
820
|
values: filter.values,
|
|
774
821
|
from: filter.from,
|
|
775
822
|
to: filter.to,
|
|
776
|
-
}))
|
|
823
|
+
}));
|
|
824
|
+
this.facade.applyRuntimeFiltersAndLoad(this.area(), mappedFilters);
|
|
825
|
+
this.runtimeFiltersChanged.emit(mappedFilters);
|
|
777
826
|
}
|
|
778
827
|
onRuntimeFiltersCleared() {
|
|
828
|
+
this.facade.applyRuntimeFiltersAndLoad(this.area(), []);
|
|
779
829
|
this.runtimeFiltersChanged.emit([]);
|
|
780
830
|
}
|
|
831
|
+
onRowClick(row) {
|
|
832
|
+
const contextKey = this.resolveRowContextKey(row);
|
|
833
|
+
console.log('[work-center-debug] page row click', {
|
|
834
|
+
contextKey,
|
|
835
|
+
row,
|
|
836
|
+
openItemsInDrawer: this.openItemsInDrawer(),
|
|
837
|
+
hasDrawerComponent: !!this.itemDrawer()?.component,
|
|
838
|
+
});
|
|
839
|
+
if (!contextKey) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
this.itemClicked.emit(contextKey);
|
|
843
|
+
if (!this.openItemsInDrawer()) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
const drawerOptions = this.itemDrawer();
|
|
847
|
+
if (!drawerOptions?.component) {
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
this.modal.openModal(drawerOptions.component, 'drawer', {
|
|
851
|
+
header: drawerOptions?.header ?? 'Item Details',
|
|
852
|
+
styleClass: drawerOptions?.styleClass ?? this.defaultDrawerStyleClass,
|
|
853
|
+
position: drawerOptions?.position ?? 'end',
|
|
854
|
+
dismissible: true,
|
|
855
|
+
modal: true,
|
|
856
|
+
...(drawerOptions?.appendTo ? { appendTo: drawerOptions.appendTo } : {}),
|
|
857
|
+
inputValues: { contextKey },
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
rowsClickable = computed(() => this.openItemsInDrawer(), ...(ngDevMode ? [{ debugName: "rowsClickable" }] : []));
|
|
861
|
+
resolveRowContextKey(row) {
|
|
862
|
+
const value = row['contextKey'];
|
|
863
|
+
if (typeof value !== 'string') {
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
const normalized = value.trim();
|
|
867
|
+
return normalized.length ? normalized : null;
|
|
868
|
+
}
|
|
781
869
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
782
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterPage, isStandalone: true, selector: "mt-work-center-page", inputs: { area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, menuIcon: { classPropertyName: "menuIcon", publicName: "menuIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { runtimeFiltersChanged: "runtimeFiltersChanged" }, ngImport: i0, template: "
|
|
870
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterPage, isStandalone: true, selector: "mt-work-center-page", inputs: { area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, menuIcon: { classPropertyName: "menuIcon", publicName: "menuIcon", isSignal: true, isRequired: false, transformFunction: null }, openItemsInDrawer: { classPropertyName: "openItemsInDrawer", publicName: "openItemsInDrawer", isSignal: true, isRequired: false, transformFunction: null }, itemDrawer: { classPropertyName: "itemDrawer", publicName: "itemDrawer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { runtimeFiltersChanged: "runtimeFiltersChanged", itemClicked: "itemClicked" }, ngImport: i0, template: "<mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"pageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n>\r\n <ng-template #headerClientPageEnd>\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"context().runtimeFilters\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n @if (loading()) {\r\n <div\r\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\r\n >\r\n @for (_ of [1, 2, 3, 4, 5]; track $index) {\r\n <p-skeleton height=\"6.5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div\r\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\r\n >\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [lazy]=\"true\"\r\n [clickableRows]=\"rowsClickable()\"\r\n [loading]=\"loading()\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"tableCurrentPage()\"\r\n [first]=\"tableFirst()\"\r\n (lazyLoad)=\"onLazyLoad($event)\"\r\n (rowClick)=\"onRowClick($event)\"\r\n />\r\n </div>\r\n</mt-client-page>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ClientPage, selector: "mt-client-page", inputs: ["menuIcon", "menuTitle", "menuItems", "menuItemsLoading", "activeItem", "collapsed"], outputs: ["collapsedChange", "menuItemClick"] }, { kind: "component", type: PropertyFilterBuilder, selector: "mt-property-filter-builder", inputs: ["schema", "filters", "title", "buttonLabel", "disabled"], outputs: ["filtersChange", "applied", "cleared"] }, { kind: "component", type: StatisticCard, selector: "mt-statistic-card", inputs: ["data"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }] });
|
|
783
871
|
}
|
|
784
872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, decorators: [{
|
|
785
873
|
type: Component,
|
|
@@ -790,8 +878,411 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
790
878
|
StatisticCard,
|
|
791
879
|
Table,
|
|
792
880
|
SkeletonModule,
|
|
793
|
-
], template: "
|
|
794
|
-
}], propDecorators: { area: [{ type: i0.Input, args: [{ isSignal: true, alias: "area", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], menuIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuIcon", required: false }] }], runtimeFiltersChanged: [{ type: i0.Output, args: ["runtimeFiltersChanged"] }] } });
|
|
881
|
+
], template: "<mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"pageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n>\r\n <ng-template #headerClientPageEnd>\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"context().runtimeFilters\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n @if (loading()) {\r\n <div\r\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\r\n >\r\n @for (_ of [1, 2, 3, 4, 5]; track $index) {\r\n <p-skeleton height=\"6.5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div\r\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\r\n >\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [lazy]=\"true\"\r\n [clickableRows]=\"rowsClickable()\"\r\n [loading]=\"loading()\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"tableCurrentPage()\"\r\n [first]=\"tableFirst()\"\r\n (lazyLoad)=\"onLazyLoad($event)\"\r\n (rowClick)=\"onRowClick($event)\"\r\n />\r\n </div>\r\n</mt-client-page>\r\n" }]
|
|
882
|
+
}], propDecorators: { area: [{ type: i0.Input, args: [{ isSignal: true, alias: "area", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], menuIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuIcon", required: false }] }], openItemsInDrawer: [{ type: i0.Input, args: [{ isSignal: true, alias: "openItemsInDrawer", required: false }] }], itemDrawer: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemDrawer", required: false }] }], runtimeFiltersChanged: [{ type: i0.Output, args: ["runtimeFiltersChanged"] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }] } });
|
|
883
|
+
|
|
884
|
+
function readItemContext(details) {
|
|
885
|
+
const item = details.item;
|
|
886
|
+
if (!item || typeof item !== 'object') {
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
const context = item['context'];
|
|
890
|
+
return context && typeof context === 'object'
|
|
891
|
+
? context
|
|
892
|
+
: null;
|
|
893
|
+
}
|
|
894
|
+
function readNumber(source, key) {
|
|
895
|
+
const value = source?.[key];
|
|
896
|
+
if (typeof value === 'number') {
|
|
897
|
+
return Number.isFinite(value) ? value : undefined;
|
|
898
|
+
}
|
|
899
|
+
if (typeof value === 'string' && value.trim().length) {
|
|
900
|
+
const parsed = Number(value);
|
|
901
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
902
|
+
}
|
|
903
|
+
return undefined;
|
|
904
|
+
}
|
|
905
|
+
function readString$1(source, key) {
|
|
906
|
+
const value = source?.[key];
|
|
907
|
+
return typeof value === 'string' && value.trim().length ? value : undefined;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
class WorkCenterEscalationInstanceType {
|
|
911
|
+
http = inject(HttpClient);
|
|
912
|
+
loadSub;
|
|
913
|
+
details = input.required(...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
914
|
+
activeTab = signal('escalationDetails', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
915
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
916
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
917
|
+
preview = signal(null, ...(ngDevMode ? [{ debugName: "preview" }] : []));
|
|
918
|
+
tabOptions = [
|
|
919
|
+
{
|
|
920
|
+
label: 'Escalation Details',
|
|
921
|
+
value: 'escalationDetails',
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
label: 'Schema',
|
|
925
|
+
value: 'schema',
|
|
926
|
+
},
|
|
927
|
+
];
|
|
928
|
+
detailEntities = computed(() => {
|
|
929
|
+
const preview = this.preview();
|
|
930
|
+
if (!preview) {
|
|
931
|
+
return [];
|
|
932
|
+
}
|
|
933
|
+
return [
|
|
934
|
+
{
|
|
935
|
+
key: 'initiatedBy',
|
|
936
|
+
name: 'Initiated By',
|
|
937
|
+
value: mapUserValue(preview.initiatedBy),
|
|
938
|
+
viewType: 'User',
|
|
939
|
+
order: 1,
|
|
940
|
+
configuration: { size: 12 },
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
key: 'startedAt',
|
|
944
|
+
name: 'Started At',
|
|
945
|
+
value: resolveDisplayValue(preview.startedAt),
|
|
946
|
+
rawValue: resolveRawValue(preview.startedAt),
|
|
947
|
+
viewType: 'DateTime',
|
|
948
|
+
order: 2,
|
|
949
|
+
configuration: { size: 12 },
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
key: 'reason',
|
|
953
|
+
name: 'Reason',
|
|
954
|
+
value: preview.reason ?? '',
|
|
955
|
+
viewType: 'LongText',
|
|
956
|
+
order: 3,
|
|
957
|
+
configuration: { size: 24 },
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
key: 'attachments',
|
|
961
|
+
name: 'Attachments',
|
|
962
|
+
value: mapAttachments(preview.attachments),
|
|
963
|
+
viewType: 'Attachment',
|
|
964
|
+
order: 4,
|
|
965
|
+
configuration: { size: 24 },
|
|
966
|
+
},
|
|
967
|
+
];
|
|
968
|
+
}, ...(ngDevMode ? [{ debugName: "detailEntities" }] : []));
|
|
969
|
+
schemaNodes = computed(() => resolveSchemaSteps(this.preview()).map((step) => ({
|
|
970
|
+
id: String(step.id),
|
|
971
|
+
name: resolveTranslatable(step.name) || `Step ${step.id}`,
|
|
972
|
+
color: step.isFinal ? '#059669' : step.isInitial ? '#2563eb' : '#0f172a',
|
|
973
|
+
})), ...(ngDevMode ? [{ debugName: "schemaNodes" }] : []));
|
|
974
|
+
schemaConnections = computed(() => (this.preview()?.schema?.connections ?? []).map((connection, index) => ({
|
|
975
|
+
id: String(connection.id ?? `${connection.source}-${connection.target}-${index}`),
|
|
976
|
+
from: String(connection.source),
|
|
977
|
+
to: String(connection.target),
|
|
978
|
+
})), ...(ngDevMode ? [{ debugName: "schemaConnections" }] : []));
|
|
979
|
+
hasSchema = computed(() => this.schemaNodes().length > 0, ...(ngDevMode ? [{ debugName: "hasSchema" }] : []));
|
|
980
|
+
itemContext = computed(() => readItemContext(this.details()), ...(ngDevMode ? [{ debugName: "itemContext" }] : []));
|
|
981
|
+
instanceId = computed(() => readNumber(this.itemContext(), 'escalationInstanceId') ??
|
|
982
|
+
readNumber(this.itemContext(), 'instanceId'), ...(ngDevMode ? [{ debugName: "instanceId" }] : []));
|
|
983
|
+
resolvedInstanceId = computed(() => this.instanceId() ?? 0, ...(ngDevMode ? [{ debugName: "resolvedInstanceId" }] : []));
|
|
984
|
+
canRenderDetails = computed(() => this.resolvedInstanceId() > 0, ...(ngDevMode ? [{ debugName: "canRenderDetails" }] : []));
|
|
985
|
+
constructor() {
|
|
986
|
+
effect(() => {
|
|
987
|
+
const instanceId = this.resolvedInstanceId();
|
|
988
|
+
if (instanceId > 0) {
|
|
989
|
+
untracked(() => this.loadPreview(instanceId));
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
this.preview.set(null);
|
|
993
|
+
this.error.set(null);
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
ngOnDestroy() {
|
|
997
|
+
this.loadSub?.unsubscribe();
|
|
998
|
+
}
|
|
999
|
+
loadPreview(instanceId) {
|
|
1000
|
+
this.loadSub?.unsubscribe();
|
|
1001
|
+
this.loading.set(true);
|
|
1002
|
+
this.error.set(null);
|
|
1003
|
+
this.loadSub = this.http
|
|
1004
|
+
.get(`escalations/${instanceId}/preview`)
|
|
1005
|
+
.subscribe({
|
|
1006
|
+
next: (response) => {
|
|
1007
|
+
this.loading.set(false);
|
|
1008
|
+
this.preview.set(response.data ?? null);
|
|
1009
|
+
},
|
|
1010
|
+
error: (error) => {
|
|
1011
|
+
this.loading.set(false);
|
|
1012
|
+
this.preview.set(null);
|
|
1013
|
+
this.error.set(error?.error?.message ??
|
|
1014
|
+
error?.message ??
|
|
1015
|
+
'Failed to load escalation preview');
|
|
1016
|
+
},
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterEscalationInstanceType, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1020
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterEscalationInstanceType, isStandalone: true, selector: "mt-work-center-escalation-instance-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"mt-modal-content flex h-full flex-col gap-4 p-4\">\n <mt-tabs [(active)]=\"activeTab\" [options]=\"tabOptions\" />\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'escalationDetails'\">\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Loading escalation details...\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-red-300 bg-red-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-red-600\">\n {{ error }}\n </p>\n </div>\n } @else if (preview()) {\n <mt-entities-preview [entities]=\"detailEntities()\" />\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation details context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'schema'\">\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Loading escalation schema...\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-red-300 bg-red-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-red-600\">\n {{ error }}\n </p>\n </div>\n } @else if (hasSchema()) {\n <div class=\"h-[70vh] overflow-hidden rounded-2xl\">\n <mt-structure-builder\n class=\"h-full\"\n [readonly]=\"true\"\n [nodes]=\"schemaNodes()\"\n [connections]=\"schemaConnections()\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation schema is not available for this item yet.\n </p>\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation schema context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities"] }, { kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "nodeForm", "connectionForm", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }] });
|
|
1021
|
+
}
|
|
1022
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterEscalationInstanceType, decorators: [{
|
|
1023
|
+
type: Component,
|
|
1024
|
+
args: [{ selector: 'mt-work-center-escalation-instance-type', standalone: true, imports: [CommonModule, Tabs, EntitiesPreview, StructureBuilder], template: "<div class=\"mt-modal-content flex h-full flex-col gap-4 p-4\">\n <mt-tabs [(active)]=\"activeTab\" [options]=\"tabOptions\" />\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'escalationDetails'\">\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Loading escalation details...\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-red-300 bg-red-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-red-600\">\n {{ error }}\n </p>\n </div>\n } @else if (preview()) {\n <mt-entities-preview [entities]=\"detailEntities()\" />\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation details context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'schema'\">\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Loading escalation schema...\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-red-300 bg-red-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-red-600\">\n {{ error }}\n </p>\n </div>\n } @else if (hasSchema()) {\n <div class=\"h-[70vh] overflow-hidden rounded-2xl\">\n <mt-structure-builder\n class=\"h-full\"\n [readonly]=\"true\"\n [nodes]=\"schemaNodes()\"\n [connections]=\"schemaConnections()\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation schema is not available for this item yet.\n </p>\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Escalation schema context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n</div>\n" }]
|
|
1025
|
+
}], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }] } });
|
|
1026
|
+
function mapUserValue(value) {
|
|
1027
|
+
if (!value || typeof value !== 'object') {
|
|
1028
|
+
return {
|
|
1029
|
+
displayName: '',
|
|
1030
|
+
userName: '',
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
return {
|
|
1034
|
+
id: readString(value, 'id'),
|
|
1035
|
+
userName: readString(value, 'userName'),
|
|
1036
|
+
displayName: readString(value, 'displayName') ??
|
|
1037
|
+
readString(value, 'fullName') ??
|
|
1038
|
+
readString(value, 'userName') ??
|
|
1039
|
+
'',
|
|
1040
|
+
photoUrl: readString(value, 'photoUrl'),
|
|
1041
|
+
phoneNumber: readString(value, 'phoneNumber') ?? readString(value, 'mobileNumber'),
|
|
1042
|
+
email: readString(value, 'email') ?? readString(value, 'emailAddress'),
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
function mapAttachments(attachments) {
|
|
1046
|
+
return (attachments ?? []).map((attachment) => ({
|
|
1047
|
+
id: attachment.id,
|
|
1048
|
+
name: attachment.name,
|
|
1049
|
+
fileName: attachment.fileName,
|
|
1050
|
+
contentType: attachment.contentType,
|
|
1051
|
+
extension: attachment.extension,
|
|
1052
|
+
size: attachment.size,
|
|
1053
|
+
}));
|
|
1054
|
+
}
|
|
1055
|
+
function resolveSchemaSteps(preview) {
|
|
1056
|
+
return preview?.schema?.stepsSchema ?? preview?.schemaSteps ?? [];
|
|
1057
|
+
}
|
|
1058
|
+
function resolveTranslatable(value) {
|
|
1059
|
+
if (!value || typeof value !== 'object') {
|
|
1060
|
+
return '';
|
|
1061
|
+
}
|
|
1062
|
+
return value.display ?? value.en ?? value.ar ?? '';
|
|
1063
|
+
}
|
|
1064
|
+
function resolveDisplayValue(value) {
|
|
1065
|
+
if (!value || typeof value !== 'object') {
|
|
1066
|
+
return typeof value === 'string' ? value : '';
|
|
1067
|
+
}
|
|
1068
|
+
return (readString(value, 'displayValue') ??
|
|
1069
|
+
readString(value, 'display') ??
|
|
1070
|
+
readString(value, 'actualValue') ??
|
|
1071
|
+
'');
|
|
1072
|
+
}
|
|
1073
|
+
function resolveRawValue(value) {
|
|
1074
|
+
if (!value || typeof value !== 'object') {
|
|
1075
|
+
return typeof value === 'string' ? value : undefined;
|
|
1076
|
+
}
|
|
1077
|
+
return (readString(value, 'actualValue') ??
|
|
1078
|
+
readString(value, 'displayValue') ??
|
|
1079
|
+
undefined);
|
|
1080
|
+
}
|
|
1081
|
+
function readString(value, key) {
|
|
1082
|
+
if (!value || typeof value !== 'object') {
|
|
1083
|
+
return undefined;
|
|
1084
|
+
}
|
|
1085
|
+
const result = value[key];
|
|
1086
|
+
return typeof result === 'string' && result.length ? result : undefined;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
class WorkCenterProcessRequestType {
|
|
1090
|
+
details = input.required(...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
1091
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterProcessRequestType, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1092
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: WorkCenterProcessRequestType, isStandalone: true, selector: "mt-work-center-process-request-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\n <p class=\"text-sm text-surface-500\">\n Process request content will be added here.\n </p>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
1093
|
+
}
|
|
1094
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterProcessRequestType, decorators: [{
|
|
1095
|
+
type: Component,
|
|
1096
|
+
args: [{ selector: 'mt-work-center-process-request-type', standalone: true, imports: [CommonModule], template: "<div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\n <p class=\"text-sm text-surface-500\">\n Process request content will be added here.\n </p>\n</div>\n" }]
|
|
1097
|
+
}], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }] } });
|
|
1098
|
+
|
|
1099
|
+
class WorkCenterProcessStepType {
|
|
1100
|
+
details = input.required(...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
1101
|
+
activeTab = signal('processForm', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
1102
|
+
tabOptions = [
|
|
1103
|
+
{
|
|
1104
|
+
label: 'Process Form',
|
|
1105
|
+
value: 'processForm',
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
label: 'Module Preview',
|
|
1109
|
+
value: 'modulePreview',
|
|
1110
|
+
},
|
|
1111
|
+
];
|
|
1112
|
+
itemContext = computed(() => readItemContext(this.details()), ...(ngDevMode ? [{ debugName: "itemContext" }] : []));
|
|
1113
|
+
moduleKey = computed(() => readString$1(this.itemContext(), 'moduleKey') ?? '', ...(ngDevMode ? [{ debugName: "moduleKey" }] : []));
|
|
1114
|
+
operationKey = computed(() => readString$1(this.itemContext(), 'operationKey') ?? '', ...(ngDevMode ? [{ debugName: "operationKey" }] : []));
|
|
1115
|
+
moduleId = computed(() => readNumber(this.itemContext(), 'moduleId'), ...(ngDevMode ? [{ debugName: "moduleId" }] : []));
|
|
1116
|
+
levelId = computed(() => readNumber(this.itemContext(), 'levelId'), ...(ngDevMode ? [{ debugName: "levelId" }] : []));
|
|
1117
|
+
levelDataId = computed(() => readNumber(this.itemContext(), 'levelDataId'), ...(ngDevMode ? [{ debugName: "levelDataId" }] : []));
|
|
1118
|
+
moduleDataId = computed(() => readNumber(this.itemContext(), 'moduleDataId'), ...(ngDevMode ? [{ debugName: "moduleDataId" }] : []));
|
|
1119
|
+
requestSchemaId = computed(() => readNumber(this.itemContext(), 'requestSchemaId'), ...(ngDevMode ? [{ debugName: "requestSchemaId" }] : []));
|
|
1120
|
+
draftProcessId = computed(() => readNumber(this.itemContext(), 'draftProcessId') ??
|
|
1121
|
+
readNumber(this.itemContext(), 'requestId'), ...(ngDevMode ? [{ debugName: "draftProcessId" }] : []));
|
|
1122
|
+
canRenderForm = computed(() => !!this.moduleKey() && !!this.operationKey(), ...(ngDevMode ? [{ debugName: "canRenderForm" }] : []));
|
|
1123
|
+
canRenderPreview = computed(() => !!this.moduleKey() && !!this.operationKey(), ...(ngDevMode ? [{ debugName: "canRenderPreview" }] : []));
|
|
1124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterProcessStepType, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1125
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterProcessStepType, isStandalone: true, selector: "mt-work-center-process-step-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"mt-modal-content flex h-full flex-col gap-4 p-4\">\n <mt-tabs [(active)]=\"activeTab\" [options]=\"tabOptions\" />\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'processForm'\">\n @if (canRenderForm()) {\n <mt-client-form\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"moduleId()\"\n [levelId]=\"levelId()\"\n [levelDataId]=\"levelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [requestSchemaId]=\"requestSchemaId()\"\n [draftProcessId]=\"draftProcessId()\"\n [renderMode]=\"'steps'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Process form context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'modulePreview'\">\n @if (canRenderPreview()) {\n <mt-client-module-preview\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"moduleId()\"\n [levelId]=\"levelId()\"\n [levelDataId]=\"levelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [requestSchemaId]=\"requestSchemaId()\"\n [draftProcessId]=\"draftProcessId()\"\n [formMode]=\"'edit'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Module preview context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "preview", "returnUrl", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "lang", "lookups"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected"] }, { kind: "component", type: ClientModulePreview, selector: "mt-client-module-preview", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "preview", "autoLoad", "lang", "formMode"], outputs: ["loaded", "errored"] }] });
|
|
1126
|
+
}
|
|
1127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterProcessStepType, decorators: [{
|
|
1128
|
+
type: Component,
|
|
1129
|
+
args: [{ selector: 'mt-work-center-process-step-type', standalone: true, imports: [CommonModule, Tabs, ClientForm, ClientModulePreview], template: "<div class=\"mt-modal-content flex h-full flex-col gap-4 p-4\">\n <mt-tabs [(active)]=\"activeTab\" [options]=\"tabOptions\" />\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'processForm'\">\n @if (canRenderForm()) {\n <mt-client-form\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"moduleId()\"\n [levelId]=\"levelId()\"\n [levelDataId]=\"levelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [requestSchemaId]=\"requestSchemaId()\"\n [draftProcessId]=\"draftProcessId()\"\n [renderMode]=\"'steps'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Process form context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n\n <div class=\"flex-1\" [hidden]=\"activeTab() !== 'modulePreview'\">\n @if (canRenderPreview()) {\n <mt-client-module-preview\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"moduleId()\"\n [levelId]=\"levelId()\"\n [levelDataId]=\"levelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [requestSchemaId]=\"requestSchemaId()\"\n [draftProcessId]=\"draftProcessId()\"\n [formMode]=\"'edit'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-2xl border border-dashed border-surface-300 bg-surface-50 p-6\"\n >\n <p class=\"max-w-md text-center text-sm text-surface-500\">\n Module preview context is not available for this item yet.\n </p>\n </div>\n }\n </div>\n</div>\n" }]
|
|
1130
|
+
}], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }] } });
|
|
1131
|
+
|
|
1132
|
+
class WorkCenterItemDrawer {
|
|
1133
|
+
details = input.required(...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
1134
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterItemDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1135
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterItemDrawer, isStandalone: true, selector: "mt-work-center-item-drawer", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (details().type === 'ProcessStep') {\n <mt-work-center-process-step-type [details]=\"details()\" />\n} @else if (details().type === 'ProcessRequest') {\n <mt-work-center-process-request-type [details]=\"details()\" />\n} @else if (details().type === 'EscalationInstance') {\n <mt-work-center-escalation-instance-type [details]=\"details()\" />\n} @else {\n <div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\n <p class=\"text-sm text-surface-500\">This item type is not supported yet.</p>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WorkCenterProcessStepType, selector: "mt-work-center-process-step-type", inputs: ["details"] }, { kind: "component", type: WorkCenterProcessRequestType, selector: "mt-work-center-process-request-type", inputs: ["details"] }, { kind: "component", type: WorkCenterEscalationInstanceType, selector: "mt-work-center-escalation-instance-type", inputs: ["details"] }] });
|
|
1136
|
+
}
|
|
1137
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterItemDrawer, decorators: [{
|
|
1138
|
+
type: Component,
|
|
1139
|
+
args: [{ selector: 'mt-work-center-item-drawer', standalone: true, imports: [
|
|
1140
|
+
CommonModule,
|
|
1141
|
+
WorkCenterProcessStepType,
|
|
1142
|
+
WorkCenterProcessRequestType,
|
|
1143
|
+
WorkCenterEscalationInstanceType,
|
|
1144
|
+
], template: "@if (details().type === 'ProcessStep') {\n <mt-work-center-process-step-type [details]=\"details()\" />\n} @else if (details().type === 'ProcessRequest') {\n <mt-work-center-process-request-type [details]=\"details()\" />\n} @else if (details().type === 'EscalationInstance') {\n <mt-work-center-escalation-instance-type [details]=\"details()\" />\n} @else {\n <div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\n <p class=\"text-sm text-surface-500\">This item type is not supported yet.</p>\n </div>\n}\n" }]
|
|
1145
|
+
}], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }] } });
|
|
1146
|
+
|
|
1147
|
+
class WorkCenterItemDrawerRoute {
|
|
1148
|
+
http = inject(HttpClient);
|
|
1149
|
+
router = inject(Router);
|
|
1150
|
+
route = inject(ActivatedRoute);
|
|
1151
|
+
contextKey = input(null, ...(ngDevMode ? [{ debugName: "contextKey" }] : []));
|
|
1152
|
+
drawerVisible = signal(true, ...(ngDevMode ? [{ debugName: "drawerVisible" }] : []));
|
|
1153
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1154
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
1155
|
+
details = signal(null, ...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
1156
|
+
resolvedContextKey = computed(() => this.decodeContextKey(this.contextKey()), ...(ngDevMode ? [{ debugName: "resolvedContextKey" }] : []));
|
|
1157
|
+
drawerTitle = computed(() => this.readDisplayField(this.details()?.item, 'title') ?? 'Item Details', ...(ngDevMode ? [{ debugName: "drawerTitle" }] : []));
|
|
1158
|
+
drawerSubtitle = computed(() => this.readDisplayField(this.details()?.item, 'subtitle') ?? '', ...(ngDevMode ? [{ debugName: "drawerSubtitle" }] : []));
|
|
1159
|
+
constructor() {
|
|
1160
|
+
effect(() => {
|
|
1161
|
+
console.log('[work-center-debug] drawer route state', {
|
|
1162
|
+
rawContextKey: this.contextKey(),
|
|
1163
|
+
resolvedContextKey: this.resolvedContextKey(),
|
|
1164
|
+
visible: this.drawerVisible(),
|
|
1165
|
+
loading: this.loading(),
|
|
1166
|
+
hasDetails: !!this.details(),
|
|
1167
|
+
error: this.error(),
|
|
1168
|
+
currentUrl: this.router.url,
|
|
1169
|
+
outlet: this.route.outlet,
|
|
1170
|
+
});
|
|
1171
|
+
});
|
|
1172
|
+
effect((onCleanup) => {
|
|
1173
|
+
const contextKey = this.resolvedContextKey();
|
|
1174
|
+
console.log('[work-center-debug] drawer route load effect', {
|
|
1175
|
+
contextKey,
|
|
1176
|
+
});
|
|
1177
|
+
this.error.set(null);
|
|
1178
|
+
this.details.set(null);
|
|
1179
|
+
if (!contextKey) {
|
|
1180
|
+
this.loading.set(false);
|
|
1181
|
+
console.log('[work-center-debug] drawer route load skipped, no context key');
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
this.loading.set(true);
|
|
1185
|
+
console.log('[work-center-debug] drawer route fetch start', {
|
|
1186
|
+
endpoint: 'workcenter/runtime/item-basic-info',
|
|
1187
|
+
contextKey,
|
|
1188
|
+
});
|
|
1189
|
+
const subscription = this.http
|
|
1190
|
+
.get('workcenter/runtime/item-basic-info', {
|
|
1191
|
+
params: { contextKey },
|
|
1192
|
+
})
|
|
1193
|
+
.pipe(map((response) => {
|
|
1194
|
+
if (response.code === 1) {
|
|
1195
|
+
return response.data;
|
|
1196
|
+
}
|
|
1197
|
+
throw new Error(this.resolveErrorMessage(response));
|
|
1198
|
+
}))
|
|
1199
|
+
.subscribe({
|
|
1200
|
+
next: (details) => {
|
|
1201
|
+
console.log('[work-center-debug] drawer route fetch success', {
|
|
1202
|
+
contextKey,
|
|
1203
|
+
details,
|
|
1204
|
+
});
|
|
1205
|
+
this.details.set(details);
|
|
1206
|
+
this.loading.set(false);
|
|
1207
|
+
},
|
|
1208
|
+
error: (error) => {
|
|
1209
|
+
console.error('[work-center-debug] drawer route fetch failed', {
|
|
1210
|
+
contextKey,
|
|
1211
|
+
error,
|
|
1212
|
+
});
|
|
1213
|
+
this.error.set(error instanceof Error
|
|
1214
|
+
? error.message
|
|
1215
|
+
: 'Failed to load item details.');
|
|
1216
|
+
this.loading.set(false);
|
|
1217
|
+
},
|
|
1218
|
+
});
|
|
1219
|
+
onCleanup(() => subscription.unsubscribe());
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
async onVisibleChange(visible) {
|
|
1223
|
+
this.drawerVisible.set(visible);
|
|
1224
|
+
console.log('[work-center-debug] drawer visible change', { visible });
|
|
1225
|
+
if (visible) {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
await this.closeDrawer();
|
|
1229
|
+
}
|
|
1230
|
+
closeDrawer() {
|
|
1231
|
+
console.log('[work-center-debug] drawer closing', {
|
|
1232
|
+
outlet: this.route.outlet || 'sidebar',
|
|
1233
|
+
parentUrl: this.route.parent?.snapshot.url.map((segment) => segment.path),
|
|
1234
|
+
});
|
|
1235
|
+
return this.router
|
|
1236
|
+
.navigate([{ outlets: { [this.route.outlet || 'sidebar']: null } }], {
|
|
1237
|
+
relativeTo: this.route.parent,
|
|
1238
|
+
queryParamsHandling: 'merge',
|
|
1239
|
+
replaceUrl: true,
|
|
1240
|
+
})
|
|
1241
|
+
.then((success) => {
|
|
1242
|
+
console.log('[work-center-debug] drawer close navigate result', {
|
|
1243
|
+
success,
|
|
1244
|
+
currentUrl: this.router.url,
|
|
1245
|
+
});
|
|
1246
|
+
return success;
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
decodeContextKey(value) {
|
|
1250
|
+
if (!value) {
|
|
1251
|
+
return null;
|
|
1252
|
+
}
|
|
1253
|
+
try {
|
|
1254
|
+
return decodeURIComponent(value);
|
|
1255
|
+
}
|
|
1256
|
+
catch {
|
|
1257
|
+
return value;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
resolveErrorMessage(response) {
|
|
1261
|
+
const fallbackError = 'Failed to load item details.';
|
|
1262
|
+
return (response.errors?.message ??
|
|
1263
|
+
response.message ??
|
|
1264
|
+
fallbackError);
|
|
1265
|
+
}
|
|
1266
|
+
readDisplayField(item, key) {
|
|
1267
|
+
const field = item?.[key];
|
|
1268
|
+
if (typeof field === 'string' && field.trim().length) {
|
|
1269
|
+
return field;
|
|
1270
|
+
}
|
|
1271
|
+
if (!field || typeof field !== 'object') {
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
const display = field.display;
|
|
1275
|
+
return typeof display === 'string' && display.trim().length
|
|
1276
|
+
? display
|
|
1277
|
+
: null;
|
|
1278
|
+
}
|
|
1279
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterItemDrawerRoute, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1280
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterItemDrawerRoute, isStandalone: true, selector: "mt-work-center-item-drawer-route", inputs: { contextKey: { classPropertyName: "contextKey", publicName: "contextKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-drawer\r\n [visible]=\"drawerVisible()\"\r\n [loadingHeader]=\"loading()\"\r\n [title]=\"drawerTitle()\"\r\n [subtitle]=\"drawerSubtitle()\"\r\n [appendTo]=\"'system-content'\"\r\n styleClass=\"!w-[84%] !absolute !shadow-none\"\r\n position=\"right\"\r\n (visibleChange)=\"onVisibleChange($event)\"\r\n>\r\n <ng-container content>\r\n @if (loading()) {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] flex-col gap-5\">\r\n <div class=\"flex items-center gap-3\">\r\n <p-skeleton shape=\"circle\" size=\"3rem\" />\r\n <div class=\"flex flex-1 flex-col gap-2\">\r\n <p-skeleton width=\"12rem\" height=\"1rem\" />\r\n <p-skeleton width=\"8rem\" height=\"0.875rem\" />\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-3 md:grid-cols-2\">\r\n @for (_ of [1, 2, 3, 4]; track $index) {\r\n <p-skeleton height=\"5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n\r\n <p-skeleton height=\"16rem\" borderRadius=\"1rem\" />\r\n </div>\r\n </div>\r\n } @else if (error(); as errorMessage) {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"max-w-xl text-sm font-medium text-red-600\">\r\n {{ errorMessage }}\r\n </p>\r\n </div>\r\n </div>\r\n } @else if (details(); as details) {\r\n <mt-work-center-item-drawer [details]=\"details\" />\r\n } @else {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"text-sm font-medium text-surface-500\">No item selected.</p>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n</mt-drawer>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Drawer, selector: "mt-drawer", inputs: ["visible", "position", "fullScreen", "closeOnEscape", "blockScroll", "dismissible", "title", "subtitle", "loadingHeader", "styleClass", "transitionOptions", "appendTo", "modal"], outputs: ["visibleChange", "onShow", "onHide"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: WorkCenterItemDrawer, selector: "mt-work-center-item-drawer", inputs: ["details"] }] });
|
|
1281
|
+
}
|
|
1282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterItemDrawerRoute, decorators: [{
|
|
1283
|
+
type: Component,
|
|
1284
|
+
args: [{ selector: 'mt-work-center-item-drawer-route', standalone: true, imports: [CommonModule, Drawer, SkeletonModule, WorkCenterItemDrawer], template: "<mt-drawer\r\n [visible]=\"drawerVisible()\"\r\n [loadingHeader]=\"loading()\"\r\n [title]=\"drawerTitle()\"\r\n [subtitle]=\"drawerSubtitle()\"\r\n [appendTo]=\"'system-content'\"\r\n styleClass=\"!w-[84%] !absolute !shadow-none\"\r\n position=\"right\"\r\n (visibleChange)=\"onVisibleChange($event)\"\r\n>\r\n <ng-container content>\r\n @if (loading()) {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] flex-col gap-5\">\r\n <div class=\"flex items-center gap-3\">\r\n <p-skeleton shape=\"circle\" size=\"3rem\" />\r\n <div class=\"flex flex-1 flex-col gap-2\">\r\n <p-skeleton width=\"12rem\" height=\"1rem\" />\r\n <p-skeleton width=\"8rem\" height=\"0.875rem\" />\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid gap-3 md:grid-cols-2\">\r\n @for (_ of [1, 2, 3, 4]; track $index) {\r\n <p-skeleton height=\"5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n\r\n <p-skeleton height=\"16rem\" borderRadius=\"1rem\" />\r\n </div>\r\n </div>\r\n } @else if (error(); as errorMessage) {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"max-w-xl text-sm font-medium text-red-600\">\r\n {{ errorMessage }}\r\n </p>\r\n </div>\r\n </div>\r\n } @else if (details(); as details) {\r\n <mt-work-center-item-drawer [details]=\"details\" />\r\n } @else {\r\n <div class=\"mt-modal-content p-4\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"text-sm font-medium text-surface-500\">No item selected.</p>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n</mt-drawer>\r\n" }]
|
|
1285
|
+
}], ctorParameters: () => [], propDecorators: { contextKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextKey", required: false }] }] } });
|
|
795
1286
|
|
|
796
1287
|
const APP_STATES = [WorkCenterState];
|
|
797
1288
|
|
|
@@ -799,5 +1290,5 @@ const APP_STATES = [WorkCenterState];
|
|
|
799
1290
|
* Generated bundle index. Do not edit.
|
|
800
1291
|
*/
|
|
801
1292
|
|
|
802
|
-
export { APP_STATES, EnterArea, HydrateFromContext, LoadRuntime, SetParams, WORK_CENTER_MAX_FILTERS, WORK_CENTER_MAX_PAGE_SIZE, WORK_CENTER_MAX_SORT, WORK_CENTER_QUERY_VERSION, WorkCenterActionKey, WorkCenterFacade, WorkCenterPage, WorkCenterState };
|
|
1293
|
+
export { APP_STATES, EnterArea, HydrateFromContext, LoadRuntime, SetParams, WORK_CENTER_MAX_FILTERS, WORK_CENTER_MAX_PAGE_SIZE, WORK_CENTER_MAX_SORT, WORK_CENTER_QUERY_VERSION, WorkCenterActionKey, WorkCenterFacade, WorkCenterItemDrawer, WorkCenterItemDrawerRoute, WorkCenterPage, WorkCenterState };
|
|
803
1294
|
//# sourceMappingURL=masterteam-work-center.mjs.map
|