@masterteam/work-center 0.0.1 → 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,8 +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 {
|
|
5
|
+
import { ModalService } from '@masterteam/components/modal';
|
|
6
6
|
import { PropertyFilterBuilder } from '@masterteam/components/property-filter-builder';
|
|
7
7
|
import { StatisticCard } from '@masterteam/components/statistic-card';
|
|
8
8
|
import { Table } from '@masterteam/components/table';
|
|
@@ -12,6 +12,13 @@ import { Action, Selector, State, Store, select } from '@ngxs/store';
|
|
|
12
12
|
import { HttpClient } from '@angular/common/http';
|
|
13
13
|
import { handleApiRequest } from '@masterteam/components';
|
|
14
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';
|
|
15
22
|
|
|
16
23
|
class EnterArea {
|
|
17
24
|
area;
|
|
@@ -151,26 +158,42 @@ function toLabel$1(value) {
|
|
|
151
158
|
.trim()
|
|
152
159
|
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
153
160
|
}
|
|
154
|
-
function
|
|
155
|
-
|
|
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);
|
|
156
174
|
}
|
|
157
|
-
function
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return 'date';
|
|
175
|
+
function toDisplayValue(value, column) {
|
|
176
|
+
if (column.viewType !== 'Text') {
|
|
177
|
+
return value;
|
|
161
178
|
}
|
|
162
|
-
|
|
179
|
+
if (!value || typeof value !== 'object') {
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
const display = value['display'];
|
|
183
|
+
return typeof display === 'string' ? display : value;
|
|
163
184
|
}
|
|
164
185
|
function buildColumnsFromProperties(properties) {
|
|
165
186
|
return properties
|
|
166
187
|
.filter((property) => typeof property?.key === 'string' && property.key.length > 0)
|
|
167
188
|
.map((property) => ({
|
|
189
|
+
...property,
|
|
168
190
|
key: property.key,
|
|
169
191
|
label: property.name?.display ||
|
|
170
192
|
property.name?.en ||
|
|
171
193
|
property.name?.ar ||
|
|
172
194
|
toLabel$1(property.key),
|
|
173
|
-
type:
|
|
195
|
+
type: 'entity',
|
|
196
|
+
viewType: toViewType(property.viewType, property.key),
|
|
174
197
|
}));
|
|
175
198
|
}
|
|
176
199
|
function buildColumns(columnsConfig) {
|
|
@@ -182,9 +205,23 @@ function buildColumns(columnsConfig) {
|
|
|
182
205
|
return keys.map((key) => ({
|
|
183
206
|
key,
|
|
184
207
|
label: toLabel$1(key),
|
|
185
|
-
type:
|
|
208
|
+
type: 'entity',
|
|
209
|
+
viewType: toViewType(undefined, key),
|
|
186
210
|
}));
|
|
187
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
|
+
}
|
|
188
225
|
function buildMenuItems(cards) {
|
|
189
226
|
const mapped = cards.map((card, index) => ({
|
|
190
227
|
key: card.key,
|
|
@@ -271,10 +308,14 @@ function buildContextFromInputs(currentContext, area, inputs = {}) {
|
|
|
271
308
|
templateId: parsedTemplateId ?? currentContext.templateId,
|
|
272
309
|
sort: hasParamValue(inputs.sort)
|
|
273
310
|
? parseSortInput(inputs.sort)
|
|
274
|
-
:
|
|
311
|
+
: inputs.sort === null
|
|
312
|
+
? []
|
|
313
|
+
: currentContext.sort,
|
|
275
314
|
runtimeFilters: hasParamValue(inputs.filters)
|
|
276
315
|
? parseFiltersInput(inputs.filters)
|
|
277
|
-
:
|
|
316
|
+
: inputs.filters === null
|
|
317
|
+
? []
|
|
318
|
+
: currentContext.runtimeFilters,
|
|
278
319
|
});
|
|
279
320
|
}
|
|
280
321
|
function isSameContext(left, right) {
|
|
@@ -289,7 +330,6 @@ function isSameContext(left, right) {
|
|
|
289
330
|
}
|
|
290
331
|
function mapRuntimeResponse(current, response) {
|
|
291
332
|
const selectedCard = response.selectedCard;
|
|
292
|
-
const rows = selectedCard?.items ?? [];
|
|
293
333
|
const menuItems = buildMenuItems(response.cards);
|
|
294
334
|
const requestedCardKey = selectedCard?.key ?? current.context.selectedCardKey ?? null;
|
|
295
335
|
const selectedCardKey = requestedCardKey &&
|
|
@@ -301,6 +341,7 @@ function mapRuntimeResponse(current, response) {
|
|
|
301
341
|
: null;
|
|
302
342
|
const selectedMenuItem = menuItems.find((item) => item.key === selectedCardKey);
|
|
303
343
|
const columns = buildColumns(selectedCard?.columnsConfig ?? selectedCardFromList?.columnsConfig);
|
|
344
|
+
const rows = toDisplayRows(selectedCard?.items ?? [], columns);
|
|
304
345
|
const kpis = buildKpis(selectedCard?.stats ?? [], selectedMenuItem?.icon ?? null);
|
|
305
346
|
return {
|
|
306
347
|
...current,
|
|
@@ -717,10 +758,14 @@ function mapAllowedOperators(schema) {
|
|
|
717
758
|
}
|
|
718
759
|
class WorkCenterPage {
|
|
719
760
|
facade = inject(WorkCenterFacade);
|
|
761
|
+
modal = inject(ModalService);
|
|
720
762
|
area = input('MyInbox', ...(ngDevMode ? [{ debugName: "area" }] : []));
|
|
721
763
|
pageTitle = input('Work Center', ...(ngDevMode ? [{ debugName: "pageTitle" }] : []));
|
|
722
764
|
menuIcon = input('communication.inbox-01', ...(ngDevMode ? [{ debugName: "menuIcon" }] : []));
|
|
765
|
+
openItemsInDrawer = input(true, ...(ngDevMode ? [{ debugName: "openItemsInDrawer" }] : []));
|
|
766
|
+
itemDrawer = input(null, ...(ngDevMode ? [{ debugName: "itemDrawer" }] : []));
|
|
723
767
|
runtimeFiltersChanged = output();
|
|
768
|
+
itemClicked = output();
|
|
724
769
|
context = this.facade.context;
|
|
725
770
|
menuItems = this.facade.menuItems;
|
|
726
771
|
rows = this.facade.rows;
|
|
@@ -760,6 +805,7 @@ class WorkCenterPage {
|
|
|
760
805
|
allowedOperators: fallbackOperators,
|
|
761
806
|
};
|
|
762
807
|
}, ...(ngDevMode ? [{ debugName: "propertyFilterSchema" }] : []));
|
|
808
|
+
defaultDrawerStyleClass = '!w-[96vw] xl:!w-[calc(100%-8rem)] 2xl:!w-[calc(100%-12rem)] !absolute !shadow-none';
|
|
763
809
|
onMenuItemClick(item) {
|
|
764
810
|
this.facade.selectCardAndLoad(this.area(), item.key);
|
|
765
811
|
}
|
|
@@ -767,33 +813,476 @@ class WorkCenterPage {
|
|
|
767
813
|
this.facade.applyTableLazyLoadAndLoad(this.area(), event);
|
|
768
814
|
}
|
|
769
815
|
onRuntimeFiltersApplied(filters) {
|
|
770
|
-
|
|
816
|
+
const mappedFilters = filters.map((filter) => ({
|
|
771
817
|
field: filter.field,
|
|
772
818
|
op: filter.op,
|
|
773
819
|
value: filter.value,
|
|
774
820
|
values: filter.values,
|
|
775
821
|
from: filter.from,
|
|
776
822
|
to: filter.to,
|
|
777
|
-
}))
|
|
823
|
+
}));
|
|
824
|
+
this.facade.applyRuntimeFiltersAndLoad(this.area(), mappedFilters);
|
|
825
|
+
this.runtimeFiltersChanged.emit(mappedFilters);
|
|
778
826
|
}
|
|
779
827
|
onRuntimeFiltersCleared() {
|
|
828
|
+
this.facade.applyRuntimeFiltersAndLoad(this.area(), []);
|
|
780
829
|
this.runtimeFiltersChanged.emit([]);
|
|
781
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
|
+
}
|
|
782
869
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
783
|
-
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 }
|
|
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"] }] });
|
|
784
871
|
}
|
|
785
872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, decorators: [{
|
|
786
873
|
type: Component,
|
|
787
874
|
args: [{ selector: 'mt-work-center-page', standalone: true, imports: [
|
|
788
875
|
CommonModule,
|
|
789
876
|
ClientPage,
|
|
790
|
-
Page,
|
|
791
877
|
PropertyFilterBuilder,
|
|
792
878
|
StatisticCard,
|
|
793
879
|
Table,
|
|
794
880
|
SkeletonModule,
|
|
795
|
-
], template: "<mt-
|
|
796
|
-
}], 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 }] }] } });
|
|
797
1286
|
|
|
798
1287
|
const APP_STATES = [WorkCenterState];
|
|
799
1288
|
|
|
@@ -801,5 +1290,5 @@ const APP_STATES = [WorkCenterState];
|
|
|
801
1290
|
* Generated bundle index. Do not edit.
|
|
802
1291
|
*/
|
|
803
1292
|
|
|
804
|
-
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 };
|
|
805
1294
|
//# sourceMappingURL=masterteam-work-center.mjs.map
|