@masterteam/work-center 0.0.55 → 0.0.57

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,6 +1,7 @@
1
+ import * as i1$1 from '@angular/common';
1
2
  import { CommonModule } from '@angular/common';
2
3
  import * as i0 from '@angular/core';
3
- import { inject, viewChild, input, computed, signal, Component, Injectable, DestroyRef, output, effect, untracked } from '@angular/core';
4
+ import { inject, viewChild, input, computed, signal, Component, Injectable, DestroyRef, effect, untracked, output } from '@angular/core';
4
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
6
  import { TranslocoService, TranslocoDirective } from '@jsverse/transloco';
6
7
  import { Button } from '@masterteam/components/button';
@@ -15,17 +16,17 @@ import { catchError, EMPTY, map, take } from 'rxjs';
15
16
  import { ModalRef } from '@masterteam/components/dialog';
16
17
  import { DrawerController } from '@masterteam/components/dynamic-drawer';
17
18
  import { ClientForm } from '@masterteam/forms/client-form';
18
- import { Action, Selector, State, Store, select } from '@ngxs/store';
19
19
  import { HttpClient } from '@angular/common/http';
20
+ import { Router, ActivatedRoute } from '@angular/router';
21
+ import { Drawer } from '@masterteam/components/drawer';
22
+ import { RuntimeActionContextStore, RuntimeActionRunner, resolveActionLabel } from '@masterteam/components/runtime-action';
23
+ import { Action, Selector, State, Store, select } from '@ngxs/store';
20
24
  import { handleApiRequest } from '@masterteam/components';
21
25
  import { ClientInstancePreview } from '@masterteam/client-components/client-instance-preview';
22
26
  import { EntitiesPreview } from '@masterteam/components/entities';
23
27
  import { Tabs } from '@masterteam/components/tabs';
24
28
  import { DiscussionThread } from '@masterteam/discussion';
25
29
  import { StructureBuilder } from '@masterteam/structure-builder';
26
- import { RuntimeActionContextStore, RuntimeActionRunner, resolveActionLabel } from '@masterteam/components/runtime-action';
27
- import { Router, ActivatedRoute } from '@angular/router';
28
- import { Drawer } from '@masterteam/components/drawer';
29
30
 
30
31
  class WorkCenterClientFormModal {
31
32
  modal = inject(ModalService);
@@ -452,6 +453,7 @@ function createDefaultContext(area) {
452
453
  return {
453
454
  area,
454
455
  templateId: null,
456
+ levelDataId: null,
455
457
  selectedCardKey: null,
456
458
  page: 1,
457
459
  pageSize: WORK_CENTER_LOCAL_FETCH_SIZE,
@@ -499,6 +501,7 @@ const WORK_CENTER_DEFAULT_STATE = {
499
501
  byArea: {
500
502
  MyInbox: createDefaultAreaState('MyInbox'),
501
503
  TasksCenter: createDefaultAreaState('TasksCenter'),
504
+ Workspace: createDefaultAreaState('Workspace'),
502
505
  },
503
506
  lookups: [],
504
507
  loadingActive: [],
@@ -516,6 +519,7 @@ function normalizeContext(context) {
516
519
  function buildContextFromInputs(currentContext, area, inputs = {}) {
517
520
  const parsedCardKey = toSelectedCardKey(inputs.card);
518
521
  const parsedTemplateId = toOptionalInt(inputs.templateId);
522
+ const parsedLevelDataId = toOptionalInt(inputs.levelDataId);
519
523
  const hasPageInput = hasParamValue(inputs.page);
520
524
  const parsedPage = hasPageInput ? toOptionalInt(inputs.page) : null;
521
525
  const parsedPageSize = toOptionalInt(inputs.pageSize);
@@ -526,6 +530,7 @@ function buildContextFromInputs(currentContext, area, inputs = {}) {
526
530
  page: hasPageInput ? (parsedPage ?? 1) : 1,
527
531
  pageSize: parsedPageSize ?? currentContext.pageSize,
528
532
  templateId: parsedTemplateId ?? currentContext.templateId,
533
+ levelDataId: parsedLevelDataId ?? currentContext.levelDataId,
529
534
  sort: hasParamValue(inputs.sort)
530
535
  ? parseSortInput(inputs.sort)
531
536
  : inputs.sort === null
@@ -541,6 +546,7 @@ function buildContextFromInputs(currentContext, area, inputs = {}) {
541
546
  function isSameContext(left, right) {
542
547
  return (left.area === right.area &&
543
548
  left.templateId === right.templateId &&
549
+ left.levelDataId === right.levelDataId &&
544
550
  left.selectedCardKey === right.selectedCardKey &&
545
551
  left.page === right.page &&
546
552
  left.pageSize === right.pageSize &&
@@ -1030,489 +1036,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1030
1036
  }]
1031
1037
  }] });
1032
1038
 
1033
- const OPERATOR_LABELS = {
1034
- Eq: 'Equals',
1035
- Neq: 'Not equal',
1036
- In: 'In',
1037
- Contains: 'Contains',
1038
- StartsWith: 'Starts with',
1039
- Gt: 'Greater than',
1040
- Gte: 'Greater than or equal',
1041
- Lt: 'Less than',
1042
- Lte: 'Less than or equal',
1043
- Between: 'Between',
1044
- IsNull: 'Is empty',
1045
- IsNotNull: 'Is not empty',
1046
- };
1047
- const OPERATOR_VALUE_MODE = {
1048
- In: 'multi',
1049
- Between: 'range',
1050
- IsNull: 'none',
1051
- IsNotNull: 'none',
1052
- };
1053
- const GENERAL_TASK_CARD_KEYS = new Set([
1054
- 'mygeneraltasks',
1055
- 'generaltask',
1056
- 'generaltasks',
1057
- ]);
1058
- function toLabel(value) {
1059
- const normalized = value.split('.').pop() ?? value;
1060
- return normalized
1061
- .replace(/[_-]/g, ' ')
1062
- .replace(/([a-z])([A-Z])/g, '$1 $2')
1063
- .trim()
1064
- .replace(/\b\w/g, (char) => char.toUpperCase());
1065
- }
1066
- function columnTypeToViewType(type) {
1067
- if (type === 'date')
1068
- return 'Date';
1069
- return undefined;
1070
- }
1071
- function normalizeCardKey(value) {
1072
- if (typeof value !== 'string') {
1073
- return '';
1074
- }
1075
- return value
1076
- .trim()
1077
- .replace(/[\s_-]/g, '')
1078
- .toLowerCase();
1079
- }
1080
- /**
1081
- * Strips the user envelope used by `mt-table` user filters down to the
1082
- * scalar id that the BE rule payload accepts. Falls back to the original
1083
- * value for non-user shapes (e.g. simple string in a select filter).
1084
- */
1085
- function extractIdScalar(value) {
1086
- if (value !== null &&
1087
- typeof value === 'object' &&
1088
- 'id' in value) {
1089
- return value['id'];
1090
- }
1091
- return value;
1092
- }
1093
- function toIsoDate(value) {
1094
- if (value instanceof Date)
1095
- return value.toISOString();
1096
- return value;
1097
- }
1098
- /**
1099
- * Translates one in-table column filter value into a `WorkCenterFilterRule`.
1100
- *
1101
- * The shape of `raw` depends on the column's filter type — see
1102
- * `mt-table` `table-filter-field` outputs:
1103
- * - text → string → `Contains`
1104
- * - select → scalar | scalar[] → `Eq` | `In`
1105
- * - boolean → boolean → `Eq`
1106
- * - date → `{ from?, to?, value? }` (Date|null)→ `Between`/`Gte`/`Lte`/`Eq`
1107
- * - user → `{ id, ... }` | `{ id, ... }[]` → `Eq` (id) | `In` (ids)
1108
- *
1109
- * Returns `null` when the value is empty / nothing to send.
1110
- */
1111
- function toRuntimeFilterRule(field, raw, column) {
1112
- if (raw === null || raw === undefined || raw === '')
1039
+ function readItemContext(details) {
1040
+ const item = details.item;
1041
+ if (!item || typeof item !== 'object') {
1113
1042
  return null;
1114
- if (typeof raw === 'boolean') {
1115
- return { field, op: 'Eq', value: raw };
1116
- }
1117
- if (typeof raw === 'number') {
1118
- return { field, op: 'Eq', value: raw };
1119
- }
1120
- if (typeof raw === 'string') {
1121
- if (!raw.trim().length)
1122
- return null;
1123
- return { field, op: 'Contains', value: raw };
1124
- }
1125
- if (Array.isArray(raw)) {
1126
- const values = raw
1127
- .map(extractIdScalar)
1128
- .filter((v) => v !== null && v !== undefined && v !== '');
1129
- if (!values.length)
1130
- return null;
1131
- return { field, op: 'In', values };
1132
- }
1133
- if (typeof raw === 'object') {
1134
- const obj = raw;
1135
- // User filter envelope -> single-id Eq.
1136
- if (obj.id !== undefined && obj.id !== null && obj.id !== '') {
1137
- return { field, op: 'Eq', value: obj.id };
1138
- }
1139
- const hasFrom = obj.from !== undefined && obj.from !== null;
1140
- const hasTo = obj.to !== undefined && obj.to !== null;
1141
- if (hasFrom && hasTo) {
1142
- return {
1143
- field,
1144
- op: 'Between',
1145
- from: toIsoDate(obj.from),
1146
- to: toIsoDate(obj.to),
1147
- };
1148
- }
1149
- if (hasFrom) {
1150
- return { field, op: 'Gte', value: toIsoDate(obj.from) };
1151
- }
1152
- if (hasTo) {
1153
- return { field, op: 'Lte', value: toIsoDate(obj.to) };
1154
- }
1155
- if (obj.value !== undefined && obj.value !== null && obj.value !== '') {
1156
- const treatAsContains = column?.type === 'text' ||
1157
- (column?.filterConfig?.type === 'text' &&
1158
- typeof obj.value === 'string');
1159
- if (treatAsContains) {
1160
- return { field, op: 'Contains', value: obj.value };
1161
- }
1162
- return { field, op: 'Eq', value: extractIdScalar(obj.value) };
1163
- }
1164
1043
  }
1165
- return null;
1044
+ const context = item['context'];
1045
+ return context && typeof context === 'object'
1046
+ ? context
1047
+ : null;
1166
1048
  }
1167
- /**
1168
- * Walks `mt-table`'s filter map and produces the `WorkCenterFilterRule[]`
1169
- * sent on the BE column-filter slice. The synthetic `generalSearch` key is
1170
- * skipped because the page keeps general search local-only.
1171
- */
1172
- function buildColumnRuntimeFilters(filters, columns, allowedFields) {
1173
- if (!filters)
1174
- return [];
1175
- const allowed = allowedFields && allowedFields.length ? new Set(allowedFields) : null;
1176
- const columnByKey = new Map(columns.map((col) => [col.key, col]));
1177
- const rules = [];
1178
- for (const [key, raw] of Object.entries(filters)) {
1179
- if (key === 'generalSearch')
1180
- continue;
1181
- if (allowed && !allowed.has(key))
1182
- continue;
1183
- const rule = toRuntimeFilterRule(key, raw, columnByKey.get(key));
1184
- if (rule)
1185
- rules.push(rule);
1049
+ function readNumber(source, key) {
1050
+ const value = source?.[key];
1051
+ if (typeof value === 'number') {
1052
+ return Number.isFinite(value) ? value : undefined;
1186
1053
  }
1187
- return rules;
1188
- }
1189
- function areFilterRulesEqual(left, right) {
1190
- return JSON.stringify(left) === JSON.stringify(right);
1191
- }
1192
- function mapAllowedFields(schema) {
1193
- const properties = schema.properties ?? [];
1194
- const fromProperties = properties
1195
- .filter((property) => typeof property?.key === 'string' && property.key.length > 0)
1196
- .map((property) => ({
1197
- key: property.key,
1198
- label: property.name?.display ||
1199
- property.name?.en ||
1200
- property.name?.ar ||
1201
- toLabel(property.key),
1202
- viewType: property.viewType,
1203
- }));
1204
- if (fromProperties.length) {
1205
- return fromProperties;
1054
+ if (typeof value === 'string' && value.trim().length) {
1055
+ const parsed = Number(value);
1056
+ return Number.isFinite(parsed) ? parsed : undefined;
1206
1057
  }
1207
- return (schema.allowedFields ?? []).map((field) => ({
1208
- key: field,
1209
- label: toLabel(field),
1210
- }));
1058
+ return undefined;
1211
1059
  }
1212
- function mapAllowedOperators(schema, getLabel) {
1213
- const options = [];
1214
- for (const operator of schema.allowedOperators ?? []) {
1215
- if (typeof operator === 'string') {
1216
- options.push({
1217
- key: operator,
1218
- label: getLabel(operator),
1219
- valueMode: OPERATOR_VALUE_MODE[operator] ?? 'single',
1220
- });
1221
- continue;
1222
- }
1223
- const key = operator?.value;
1224
- if (!key) {
1225
- continue;
1226
- }
1227
- options.push({
1228
- key,
1229
- label: operator.display?.display ||
1230
- operator.display?.en ||
1231
- operator.display?.ar ||
1232
- getLabel(key),
1233
- valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
1234
- });
1235
- }
1236
- return options;
1060
+ function readString$1(source, key) {
1061
+ const value = source?.[key];
1062
+ return typeof value === 'string' && value.trim().length ? value : undefined;
1237
1063
  }
1238
- class WorkCenterPage {
1239
- facade = inject(WorkCenterFacade);
1240
- modal = inject(ModalService);
1064
+
1065
+ class WorkCenterEscalationInstanceType {
1066
+ http = inject(HttpClient);
1241
1067
  transloco = inject(TranslocoService);
1242
1068
  destroyRef = inject(DestroyRef);
1069
+ loadSub;
1070
+ details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
1071
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
1072
+ activeTab = signal('escalationDetails', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
1243
1073
  activeLang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "activeLang" }] : /* istanbul ignore next */ []));
1244
- area = input('MyInbox', ...(ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []));
1245
- pageTitle = input('', ...(ngDevMode ? [{ debugName: "pageTitle" }] : /* istanbul ignore next */ []));
1246
- menuIcon = input('communication.inbox-01', ...(ngDevMode ? [{ debugName: "menuIcon" }] : /* istanbul ignore next */ []));
1247
- lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
1248
- openItemsInModal = input(true, ...(ngDevMode ? [{ debugName: "openItemsInModal" }] : /* istanbul ignore next */ []));
1249
- itemModal = input(null, ...(ngDevMode ? [{ debugName: "itemModal" }] : /* istanbul ignore next */ []));
1250
- generalTaskModal = input(null, ...(ngDevMode ? [{ debugName: "generalTaskModal" }] : /* istanbul ignore next */ []));
1251
- runtimeFiltersChanged = output();
1252
- itemClicked = output();
1253
- cardSelected = output();
1254
- context = this.facade.context;
1255
- headerFilters = this.facade.headerFilters;
1256
- tableFilters = signal({}, ...(ngDevMode ? [{ debugName: "tableFilters" }] : /* istanbul ignore next */ []));
1257
- _menuItems = this.facade.menuItems;
1258
- menuItems = computed(() => {
1259
- this.activeLang();
1260
- return this._menuItems().map((item) => ({
1261
- ...item,
1262
- subtitle: `${item.count} ${item.title}`,
1263
- }));
1264
- }, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
1265
- rows = this.facade.rows;
1266
- columns = this.facade.columns;
1267
- kpis = this.facade.kpis;
1268
- runtimeFilterSchema = this.facade.runtimeFilterSchema;
1269
- totalCount = this.facade.totalCount;
1270
- columnFilters = this.facade.columnFilters;
1271
- loading = this.facade.loading;
1272
- tableColumns = computed(() => this.columns().map((column) => ({
1273
- ...column,
1274
- sortable: true,
1275
- })), ...(ngDevMode ? [{ debugName: "tableColumns" }] : /* istanbul ignore next */ []));
1276
- /**
1277
- * Maps each status/group display label to its total count from the KPI
1278
- * summary cards so the group header shows the real backend total rather than
1279
- * the current-page row count.
1280
- */
1281
- statusGroupCountMap = computed(() => {
1282
- const map = new Map();
1283
- for (const kpi of this.kpis()) {
1284
- const label = kpi.subTitle;
1285
- const count = Number(kpi.title);
1286
- if (label && !isNaN(count)) {
1287
- map.set(label, count);
1288
- }
1289
- }
1290
- return map;
1291
- }, ...(ngDevMode ? [{ debugName: "statusGroupCountMap" }] : /* istanbul ignore next */ []));
1292
- propertyFilterSchema = computed(() => {
1293
- this.activeLang();
1294
- const schema = this.runtimeFilterSchema();
1295
- if (schema) {
1296
- const allowedFields = mapAllowedFields(schema);
1297
- const allowedOperators = mapAllowedOperators(schema, (key) => this.getOpLabel(key));
1298
- if (allowedFields.length && allowedOperators.length) {
1299
- return { allowedFields, allowedOperators };
1300
- }
1301
- }
1302
- const fallbackFields = this.columns()
1303
- .filter((column) => typeof column?.key === 'string' && column.key.length > 0)
1304
- .map((column) => ({
1305
- key: column.key,
1306
- label: column.label || toLabel(column.key),
1307
- viewType: columnTypeToViewType(column.type),
1308
- }));
1309
- if (!fallbackFields.length) {
1310
- return null;
1311
- }
1312
- const fallbackOperators = Object.keys(OPERATOR_LABELS).map((key) => ({
1313
- key,
1314
- label: this.getOpLabel(key),
1315
- valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
1316
- }));
1317
- return {
1318
- allowedFields: fallbackFields,
1319
- allowedOperators: fallbackOperators,
1320
- };
1321
- }, ...(ngDevMode ? [{ debugName: "propertyFilterSchema" }] : /* istanbul ignore next */ []));
1322
- showGeneralTaskCreateButton = computed(() => GENERAL_TASK_CARD_KEYS.has(normalizeCardKey(this.context().selectedCardKey)), ...(ngDevMode ? [{ debugName: "showGeneralTaskCreateButton" }] : /* istanbul ignore next */ []));
1323
- generalTaskButtonLabel = computed(() => {
1324
- this.activeLang();
1325
- return (this.generalTaskModal()?.buttonLabel?.trim() ||
1326
- this.transloco.translate('workCenter.page.new'));
1327
- }, ...(ngDevMode ? [{ debugName: "generalTaskButtonLabel" }] : /* istanbul ignore next */ []));
1328
- resolvedPageTitle = computed(() => {
1329
- this.activeLang();
1330
- return (this.pageTitle() ||
1331
- this.transloco.translate('workCenter.page.title'));
1332
- }, ...(ngDevMode ? [{ debugName: "resolvedPageTitle" }] : /* istanbul ignore next */ []));
1333
- generalTaskButtonIcon = computed(() => this.generalTaskModal()?.buttonIcon?.trim() || 'general.plus', ...(ngDevMode ? [{ debugName: "generalTaskButtonIcon" }] : /* istanbul ignore next */ []));
1334
- defaultModalStyleClass = '!w-[96vw] md:!w-[84vw] xl:!w-[70vw] !shadow-none';
1335
- defaultGeneralTaskModalStyleClass = '!w-[70vw] !h-[90vh]';
1336
- constructor() {
1337
- this.transloco.langChanges$
1338
- .pipe(takeUntilDestroyed(this.destroyRef))
1339
- .subscribe((lang) => this.activeLang.set(lang));
1340
- effect(() => {
1341
- this.facade.setLookups(this.lookups());
1342
- });
1343
- }
1344
- onMenuItemClick(item) {
1345
- if (item.key === this.context().selectedCardKey) {
1346
- return;
1347
- }
1348
- this.facade.selectCardAndLoad(this.area(), item.key);
1349
- this.cardSelected.emit(item.key);
1350
- }
1351
- onRuntimeFiltersApplied(filters) {
1352
- const mappedFilters = filters.map((filter) => ({
1353
- field: filter.field,
1354
- op: filter.op,
1355
- value: filter.value,
1356
- values: filter.values,
1357
- from: filter.from,
1358
- to: filter.to,
1359
- }));
1360
- this.facade.applyHeaderFiltersAndLoad(this.area(), mappedFilters);
1361
- this.runtimeFiltersChanged.emit(mappedFilters);
1362
- }
1363
- onRuntimeFiltersCleared() {
1364
- this.facade.clearAllFiltersAndLoad(this.area());
1365
- this.tableFilters.set({});
1366
- this.runtimeFiltersChanged.emit([]);
1367
- }
1368
- /**
1369
- * Single entry point for `mt-table` (`lazy=true`) — handles both column
1370
- * filters and pagination/sort. Filter changes always reset the page to 1
1371
- * (handled by `applyColumnFiltersAndLoad`); when only paging/sort changed
1372
- * we fall through to `applyTableLazyLoadAndLoad`.
1373
- */
1374
- onTableLazyLoad(event) {
1375
- const schema = this.runtimeFilterSchema();
1376
- const propertyKeys = (schema?.properties ?? [])
1377
- .map((p) => p?.key)
1378
- .filter((k) => typeof k === 'string' && k.length > 0);
1379
- const allowedKeys = schema?.allowedFields ?? [];
1380
- const allowedFields = propertyKeys.length ? propertyKeys : allowedKeys;
1381
- const nextColumnFilters = buildColumnRuntimeFilters(event?.filters, this.columns(), allowedFields.length ? allowedFields : undefined);
1382
- if (!areFilterRulesEqual(nextColumnFilters, this.columnFilters())) {
1383
- this.facade.applyColumnFiltersAndLoad(this.area(), nextColumnFilters);
1384
- return;
1385
- }
1386
- this.facade.applyTableLazyLoadAndLoad(this.area(), event);
1387
- }
1388
- onGeneralTaskCreateClick() {
1389
- const modalOptions = this.generalTaskModal();
1390
- const modalData = {
1391
- moduleKey: 'GeneralTask',
1392
- ...(modalOptions?.data ?? {}),
1393
- };
1394
- const modalHeader = modalOptions?.header ??
1395
- this.transloco.translate('workCenter.page.createGeneralTask');
1396
- const modalStyleClass = modalOptions?.styleClass ?? this.defaultGeneralTaskModalStyleClass;
1397
- const operationKey = modalOptions?.operationKey ?? 'Create';
1398
- const closeOnPendingApproval = modalOptions?.closeOnPendingApproval ?? true;
1399
- const lookups = modalOptions?.lookups ?? this.lookups();
1400
- const ref = this.modal.openModal(WorkCenterClientFormModal, 'dialog', {
1401
- header: modalHeader,
1402
- styleClass: modalStyleClass,
1403
- position: 'end',
1404
- dismissableMask: true,
1405
- inputValues: {
1406
- data: modalData,
1407
- operationKey,
1408
- closeOnPendingApproval,
1409
- lookups,
1410
- },
1411
- });
1412
- ref.onClose.pipe(take(1)).subscribe((result) => {
1413
- if (result) {
1414
- this.facade.loadRuntime(this.area(), 'refresh');
1415
- }
1416
- });
1417
- }
1418
- onRowClick(row) {
1419
- const contextKey = this.resolveRowContextKey(row);
1420
- console.log('[work-center-debug] page row click', {
1421
- contextKey,
1422
- row,
1423
- openItemsInModal: this.openItemsInModal(),
1424
- hasModalComponent: !!this.itemModal()?.component,
1425
- });
1426
- if (!contextKey) {
1427
- return;
1428
- }
1429
- this.itemClicked.emit(contextKey);
1430
- if (!this.openItemsInModal()) {
1431
- return;
1432
- }
1433
- const modalOptions = this.itemModal();
1434
- if (!modalOptions?.component) {
1435
- return;
1436
- }
1437
- const ref = this.modal.openModal(modalOptions.component, 'drawer', {
1438
- header: modalOptions?.header ??
1439
- this.transloco.translate('workCenter.page.itemDetails'),
1440
- styleClass: modalOptions?.styleClass ?? this.defaultModalStyleClass,
1441
- position: modalOptions?.position ?? 'end',
1442
- dismissible: true,
1443
- modal: true,
1444
- ...(modalOptions?.appendTo ? { appendTo: modalOptions.appendTo } : {}),
1445
- inputValues: { contextKey },
1446
- });
1447
- ref.onClose.pipe(take(1)).subscribe(() => {
1448
- this.facade.loadRuntime(this.area(), 'refresh');
1449
- });
1450
- }
1451
- rowsClickable = computed(() => this.openItemsInModal(), ...(ngDevMode ? [{ debugName: "rowsClickable" }] : /* istanbul ignore next */ []));
1452
- getOpLabel(key) {
1453
- return (this.transloco.translate('workCenter.operator.' + key) ||
1454
- OPERATOR_LABELS[key] ||
1455
- toLabel(key));
1456
- }
1457
- resolveRowContextKey(row) {
1458
- const value = row['contextKey'];
1459
- if (typeof value !== 'string') {
1460
- return null;
1461
- }
1462
- const normalized = value.trim();
1463
- return normalized.length ? normalized : null;
1464
- }
1465
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
1466
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", 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 }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, openItemsInModal: { classPropertyName: "openItemsInModal", publicName: "openItemsInModal", isSignal: true, isRequired: false, transformFunction: null }, itemModal: { classPropertyName: "itemModal", publicName: "itemModal", isSignal: true, isRequired: false, transformFunction: null }, generalTaskModal: { classPropertyName: "generalTaskModal", publicName: "generalTaskModal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { runtimeFiltersChanged: "runtimeFiltersChanged", itemClicked: "itemClicked", cardSelected: "cardSelected" }, ngImport: i0, template: "<mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"resolvedPageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n storageKey=\"work-center-client-page\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n>\r\n <ng-template #headerClientPageEnd>\r\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"headerFilters()\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n\r\n @if (showGeneralTaskCreateButton()) {\r\n <mt-button\r\n [label]=\"generalTaskButtonLabel()\"\r\n [icon]=\"generalTaskButtonIcon()\"\r\n size=\"small\"\r\n (onClick)=\"onGeneralTaskCreateClick()\"\r\n />\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-8\">\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\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div class=\"gap-3 flex flex-wrap\">\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" class=\"min-w-[200px]\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n noCard\r\n [data]=\"rows()\"\r\n [columns]=\"tableColumns()\"\r\n tableLayout=\"auto\"\r\n [clickableRows]=\"rowsClickable()\"\r\n [loading]=\"loading()\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [cellClickFilter]=\"true\"\r\n [generalSearch]=\"true\"\r\n [exportable]=\"true\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [freezeActions]=\"true\"\r\n [lazy]=\"true\"\r\n [lazyLocalSearch]=\"true\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"context().page - 1\"\r\n [first]=\"(context().page - 1) * context().pageSize\"\r\n [rowsPerPageOptions]=\"[10, 20, 50, 100]\"\r\n [groupCountMap]=\"statusGroupCountMap()\"\r\n storageKey=\"work-center-page-table\"\r\n [filters]=\"tableFilters()\"\r\n (filtersChange)=\"tableFilters.set($event)\"\r\n (lazyLoad)=\"onTableLazyLoad($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: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ClientPage, selector: "mt-client-page", inputs: ["menuIcon", "menuTitle", "menuItems", "menuItemsLoading", "activeItem", "collapsed", "resizable", "storageKey", "storageMode", "minSidebarWidth", "maxSidebarWidth", "defaultSidebarWidth"], outputs: ["collapsedChange", "menuItemClick", "loadChildren"] }, { 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", "cardClass"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }] });
1467
- }
1468
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterPage, decorators: [{
1469
- type: Component,
1470
- args: [{ selector: 'mt-work-center-page', standalone: true, imports: [
1471
- CommonModule,
1472
- Button,
1473
- ClientPage,
1474
- PropertyFilterBuilder,
1475
- StatisticCard,
1476
- Table,
1477
- SkeletonModule,
1478
- ], template: "<mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"resolvedPageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n storageKey=\"work-center-client-page\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n>\r\n <ng-template #headerClientPageEnd>\r\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"headerFilters()\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n\r\n @if (showGeneralTaskCreateButton()) {\r\n <mt-button\r\n [label]=\"generalTaskButtonLabel()\"\r\n [icon]=\"generalTaskButtonIcon()\"\r\n size=\"small\"\r\n (onClick)=\"onGeneralTaskCreateClick()\"\r\n />\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-8\">\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\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div class=\"gap-3 flex flex-wrap\">\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" class=\"min-w-[200px]\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n noCard\r\n [data]=\"rows()\"\r\n [columns]=\"tableColumns()\"\r\n tableLayout=\"auto\"\r\n [clickableRows]=\"rowsClickable()\"\r\n [loading]=\"loading()\"\r\n [showFilters]=\"true\"\r\n filterMode=\"column\"\r\n [cellClickFilter]=\"true\"\r\n [generalSearch]=\"true\"\r\n [exportable]=\"true\"\r\n [printable]=\"true\"\r\n [groupable]=\"true\"\r\n [freezeActions]=\"true\"\r\n [lazy]=\"true\"\r\n [lazyLocalSearch]=\"true\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"context().page - 1\"\r\n [first]=\"(context().page - 1) * context().pageSize\"\r\n [rowsPerPageOptions]=\"[10, 20, 50, 100]\"\r\n [groupCountMap]=\"statusGroupCountMap()\"\r\n storageKey=\"work-center-page-table\"\r\n [filters]=\"tableFilters()\"\r\n (filtersChange)=\"tableFilters.set($event)\"\r\n (lazyLoad)=\"onTableLazyLoad($event)\"\r\n (rowClick)=\"onRowClick($event)\"\r\n />\r\n </div>\r\n</mt-client-page>\r\n" }]
1479
- }], ctorParameters: () => [], 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 }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], openItemsInModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "openItemsInModal", required: false }] }], itemModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemModal", required: false }] }], generalTaskModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "generalTaskModal", required: false }] }], runtimeFiltersChanged: [{ type: i0.Output, args: ["runtimeFiltersChanged"] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }], cardSelected: [{ type: i0.Output, args: ["cardSelected"] }] } });
1480
-
1481
- function readItemContext(details) {
1482
- const item = details.item;
1483
- if (!item || typeof item !== 'object') {
1484
- return null;
1485
- }
1486
- const context = item['context'];
1487
- return context && typeof context === 'object'
1488
- ? context
1489
- : null;
1490
- }
1491
- function readNumber(source, key) {
1492
- const value = source?.[key];
1493
- if (typeof value === 'number') {
1494
- return Number.isFinite(value) ? value : undefined;
1495
- }
1496
- if (typeof value === 'string' && value.trim().length) {
1497
- const parsed = Number(value);
1498
- return Number.isFinite(parsed) ? parsed : undefined;
1499
- }
1500
- return undefined;
1501
- }
1502
- function readString$1(source, key) {
1503
- const value = source?.[key];
1504
- return typeof value === 'string' && value.trim().length ? value : undefined;
1505
- }
1506
-
1507
- class WorkCenterEscalationInstanceType {
1508
- http = inject(HttpClient);
1509
- transloco = inject(TranslocoService);
1510
- destroyRef = inject(DestroyRef);
1511
- loadSub;
1512
- details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
1513
- activeTab = signal('escalationDetails', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
1514
- activeLang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "activeLang" }] : /* istanbul ignore next */ []));
1515
- tabOptions = computed(() => {
1074
+ tabOptions = computed(() => {
1516
1075
  this.activeLang();
1517
1076
  return [
1518
1077
  {
@@ -1534,11 +1093,15 @@ class WorkCenterEscalationInstanceType {
1534
1093
  value: 'schema',
1535
1094
  icon: 'custom.flow-chart',
1536
1095
  },
1537
- {
1538
- label: this.transloco.translate('workCenter.tabs.discussion'),
1539
- value: 'discussion',
1540
- icon: 'custom.discussion-area',
1541
- },
1096
+ ...(!this.readOnly()
1097
+ ? [
1098
+ {
1099
+ label: this.transloco.translate('workCenter.tabs.discussion'),
1100
+ value: 'discussion',
1101
+ icon: 'custom.discussion-area',
1102
+ },
1103
+ ]
1104
+ : []),
1542
1105
  ];
1543
1106
  }, ...(ngDevMode ? [{ debugName: "tabOptions" }] : /* istanbul ignore next */ []));
1544
1107
  loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
@@ -1721,7 +1284,7 @@ class WorkCenterEscalationInstanceType {
1721
1284
  });
1722
1285
  }
1723
1286
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterEscalationInstanceType, deps: [], target: i0.ɵɵFactoryTarget.Component });
1724
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", 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\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'escalationDetails'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderDetails()) {\r\n @if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"loading.escalationDetails\") }}\r\n </p>\r\n </div>\r\n } @else if (error(); as error) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">\r\n {{ error }}\r\n </p>\r\n </div>\r\n } @else if (preview()) {\r\n <mt-entities-preview [entities]=\"detailEntities()\" />\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationDetailsUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'moduleDetails'\"\r\n >\r\n @if (moduleDetailsConfig(); as moduleDetailsConfig) {\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n <mt-client-instance-preview [config]=\"moduleDetailsConfig\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderDetails()) {\r\n @if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"loading.escalationSchema\") }}\r\n </p>\r\n </div>\r\n } @else if (error(); as error) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">\r\n {{ error }}\r\n </p>\r\n </div>\r\n } @else if (hasSchema()) {\r\n <!--\r\n Only mount the flow once the schema tab is actually active. The\r\n structure-builder fits the diagram to the host size on load\r\n (fLoaded -> fitToScreen) and never re-fits, so mounting it inside\r\n the [hidden] (display:none, zero-size) container produces a blank\r\n canvas that doesn't recover when the tab is shown.\r\n -->\r\n @if (activeTab() === \"schema\") {\r\n <!--\r\n Use a concrete height (not lg:h-full). The diagram has no\r\n intrinsic height, and the tab's ancestor chain is block (not\r\n flex) on lg, so `h-full` collapses to 0 and the canvas renders\r\n blank. Mirrors the process preview's `h-[70vh]`.\r\n -->\r\n <div class=\"h-[70vh] min-h-[22rem] overflow-hidden rounded-lg\">\r\n <mt-structure-builder\r\n class=\"h-full\"\r\n [layoutDirection]=\"'LR'\"\r\n [readonly]=\"true\"\r\n [structureMode]=\"'workflow'\"\r\n [nodeFields]=\"previewNodeFields\"\r\n [nodes]=\"schemaNodes()\"\r\n [connections]=\"schemaConnections()\"\r\n />\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationSchemaUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationSchemaContextUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'EscalationInstance'\"\r\n [recordId]=\"resolvedInstanceId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape", "stackOnNarrow", "clickableKeys", "activeKeys", "clickableTooltip", "activeTooltip"], outputs: ["entityClick"] }, { kind: "component", type: ClientInstancePreview, selector: "mt-client-instance-preview", inputs: ["config", "hideEmptyState", "stackOnNarrow"] }, { kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "connectionGuard", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }] });
1287
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterEscalationInstanceType, isStandalone: true, selector: "mt-work-center-escalation-instance-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'escalationDetails'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"loading.escalationDetails\") }}\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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-lg 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 {{ t(\"context.escalationDetailsUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'moduleDetails'\"\n >\n @if (moduleDetailsConfig(); as moduleDetailsConfig) {\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n <mt-client-instance-preview [config]=\"moduleDetailsConfig\" />\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"loading.escalationSchema\") }}\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 <!--\n Only mount the flow once the schema tab is actually active. The\n structure-builder fits the diagram to the host size on load\n (fLoaded -> fitToScreen) and never re-fits, so mounting it inside\n the [hidden] (display:none, zero-size) container produces a blank\n canvas that doesn't recover when the tab is shown.\n -->\n @if (activeTab() === \"schema\") {\n <!--\n Use a concrete height (not lg:h-full). The diagram has no\n intrinsic height, and the tab's ancestor chain is block (not\n flex) on lg, so `h-full` collapses to 0 and the canvas renders\n blank. Mirrors the process preview's `h-[70vh]`.\n -->\n <div class=\"h-[70vh] min-h-[22rem] overflow-hidden rounded-lg\">\n <mt-structure-builder\n class=\"h-full\"\n [layoutDirection]=\"'LR'\"\n [readonly]=\"true\"\n [structureMode]=\"'workflow'\"\n [nodeFields]=\"previewNodeFields\"\n [nodes]=\"schemaNodes()\"\n [connections]=\"schemaConnections()\"\n />\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationSchemaUnavailable\") }}\n </p>\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationSchemaContextUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'EscalationInstance'\"\n [recordId]=\"resolvedInstanceId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape", "stackOnNarrow", "clickableKeys", "activeKeys", "clickableTooltip", "activeTooltip"], outputs: ["entityClick"] }, { kind: "component", type: ClientInstancePreview, selector: "mt-client-instance-preview", inputs: ["config", "hideEmptyState", "stackOnNarrow"] }, { kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }] });
1725
1288
  }
1726
1289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterEscalationInstanceType, decorators: [{
1727
1290
  type: Component,
@@ -1733,8 +1296,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1733
1296
  EntitiesPreview,
1734
1297
  ClientInstancePreview,
1735
1298
  StructureBuilder,
1736
- ], template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'escalationDetails'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderDetails()) {\r\n @if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"loading.escalationDetails\") }}\r\n </p>\r\n </div>\r\n } @else if (error(); as error) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">\r\n {{ error }}\r\n </p>\r\n </div>\r\n } @else if (preview()) {\r\n <mt-entities-preview [entities]=\"detailEntities()\" />\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationDetailsUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'moduleDetails'\"\r\n >\r\n @if (moduleDetailsConfig(); as moduleDetailsConfig) {\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n <mt-client-instance-preview [config]=\"moduleDetailsConfig\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderDetails()) {\r\n @if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"loading.escalationSchema\") }}\r\n </p>\r\n </div>\r\n } @else if (error(); as error) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">\r\n {{ error }}\r\n </p>\r\n </div>\r\n } @else if (hasSchema()) {\r\n <!--\r\n Only mount the flow once the schema tab is actually active. The\r\n structure-builder fits the diagram to the host size on load\r\n (fLoaded -> fitToScreen) and never re-fits, so mounting it inside\r\n the [hidden] (display:none, zero-size) container produces a blank\r\n canvas that doesn't recover when the tab is shown.\r\n -->\r\n @if (activeTab() === \"schema\") {\r\n <!--\r\n Use a concrete height (not lg:h-full). The diagram has no\r\n intrinsic height, and the tab's ancestor chain is block (not\r\n flex) on lg, so `h-full` collapses to 0 and the canvas renders\r\n blank. Mirrors the process preview's `h-[70vh]`.\r\n -->\r\n <div class=\"h-[70vh] min-h-[22rem] overflow-hidden rounded-lg\">\r\n <mt-structure-builder\r\n class=\"h-full\"\r\n [layoutDirection]=\"'LR'\"\r\n [readonly]=\"true\"\r\n [structureMode]=\"'workflow'\"\r\n [nodeFields]=\"previewNodeFields\"\r\n [nodes]=\"schemaNodes()\"\r\n [connections]=\"schemaConnections()\"\r\n />\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationSchemaUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationSchemaContextUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'EscalationInstance'\"\r\n [recordId]=\"resolvedInstanceId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.escalationDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
1737
- }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }] } });
1299
+ ], template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'escalationDetails'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"loading.escalationDetails\") }}\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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-lg 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 {{ t(\"context.escalationDetailsUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'moduleDetails'\"\n >\n @if (moduleDetailsConfig(); as moduleDetailsConfig) {\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n <mt-client-instance-preview [config]=\"moduleDetailsConfig\" />\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderDetails()) {\n @if (loading()) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"loading.escalationSchema\") }}\n </p>\n </div>\n } @else if (error(); as error) {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 <!--\n Only mount the flow once the schema tab is actually active. The\n structure-builder fits the diagram to the host size on load\n (fLoaded -> fitToScreen) and never re-fits, so mounting it inside\n the [hidden] (display:none, zero-size) container produces a blank\n canvas that doesn't recover when the tab is shown.\n -->\n @if (activeTab() === \"schema\") {\n <!--\n Use a concrete height (not lg:h-full). The diagram has no\n intrinsic height, and the tab's ancestor chain is block (not\n flex) on lg, so `h-full` collapses to 0 and the canvas renders\n blank. Mirrors the process preview's `h-[70vh]`.\n -->\n <div class=\"h-[70vh] min-h-[22rem] overflow-hidden rounded-lg\">\n <mt-structure-builder\n class=\"h-full\"\n [layoutDirection]=\"'LR'\"\n [readonly]=\"true\"\n [structureMode]=\"'workflow'\"\n [nodeFields]=\"previewNodeFields\"\n [nodes]=\"schemaNodes()\"\n [connections]=\"schemaConnections()\"\n />\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationSchemaUnavailable\") }}\n </p>\n </div>\n }\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationSchemaContextUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'EscalationInstance'\"\n [recordId]=\"resolvedInstanceId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.escalationDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
1300
+ }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }] } });
1738
1301
  // The endpoint returns the escalation payload directly, but tolerate the
1739
1302
  // shared `{ data: ... }` envelope used by the other escalation endpoints.
1740
1303
  function extractPreviewData(response) {
@@ -1825,6 +1388,7 @@ class WorkCenterModuleType {
1825
1388
  destroyRef = inject(DestroyRef);
1826
1389
  details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
1827
1390
  lookups = input(null, ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
1391
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
1828
1392
  clientForm = viewChild(ClientForm, ...(ngDevMode ? [{ debugName: "clientForm" }] : /* istanbul ignore next */ []));
1829
1393
  formLookups = computed(() => this.lookups() ?? this.facade.lookups(), ...(ngDevMode ? [{ debugName: "formLookups" }] : /* istanbul ignore next */ []));
1830
1394
  activeTab = signal('details', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
@@ -1837,12 +1401,16 @@ class WorkCenterModuleType {
1837
1401
  value: 'details',
1838
1402
  icon: 'file.folder',
1839
1403
  },
1840
- {
1841
- label: this.transloco.translate('workCenter.tabs.discussion'),
1842
- value: 'discussion',
1843
- icon: 'custom.discussion-area',
1844
- },
1845
- ];
1404
+ ...(!this.readOnly()
1405
+ ? [
1406
+ {
1407
+ label: this.transloco.translate('workCenter.tabs.discussion'),
1408
+ value: 'discussion',
1409
+ icon: 'custom.discussion-area',
1410
+ },
1411
+ ]
1412
+ : []),
1413
+ ];
1846
1414
  }, ...(ngDevMode ? [{ debugName: "tabOptions" }] : /* istanbul ignore next */ []));
1847
1415
  itemContext = computed(() => readItemContext(this.details()), ...(ngDevMode ? [{ debugName: "itemContext" }] : /* istanbul ignore next */ []));
1848
1416
  instanceId = computed(() => readNumber(this.itemContext(), 'instanceId'), ...(ngDevMode ? [{ debugName: "instanceId" }] : /* istanbul ignore next */ []));
@@ -1871,14 +1439,14 @@ class WorkCenterModuleType {
1871
1439
  .pipe(takeUntilDestroyed(this.destroyRef))
1872
1440
  .subscribe((lang) => this.activeLang.set(lang));
1873
1441
  effect(() => {
1874
- this.actionContext?.setFormSource(this.clientForm() ?? null);
1442
+ this.actionContext?.setFormSource(this.readOnly() ? null : (this.clientForm() ?? null));
1875
1443
  });
1876
1444
  }
1877
1445
  ngOnDestroy() {
1878
1446
  this.actionContext?.setFormSource(null);
1879
1447
  }
1880
1448
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterModuleType, deps: [], target: i0.ɵɵFactoryTarget.Component });
1881
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterModuleType, isStandalone: true, selector: "mt-work-center-module-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'details'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"formModuleId()\"\r\n [levelId]=\"formLevelId()\"\r\n [levelDataId]=\"formLevelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [readonly]=\"true\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.moduleFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"discussionModuleType()\"\r\n [recordId]=\"resolvedInstanceId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.moduleDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }] });
1449
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterModuleType, isStandalone: true, selector: "mt-work-center-module-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'details'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n @if (canRenderForm()) {\n <mt-client-form\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"formModuleId()\"\n [levelId]=\"formLevelId()\"\n [levelDataId]=\"formLevelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [readonly]=\"true\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.moduleFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"discussionModuleType()\"\n [recordId]=\"resolvedInstanceId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.moduleDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }] });
1882
1450
  }
1883
1451
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterModuleType, decorators: [{
1884
1452
  type: Component,
@@ -1888,8 +1456,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1888
1456
  Tabs,
1889
1457
  ClientForm,
1890
1458
  DiscussionThread,
1891
- ], template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'details'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"formModuleId()\"\r\n [levelId]=\"formLevelId()\"\r\n [levelDataId]=\"formLevelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [readonly]=\"true\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.moduleFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"discussionModuleType()\"\r\n [recordId]=\"resolvedInstanceId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.moduleDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
1892
- }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
1459
+ ], template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'details'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n @if (canRenderForm()) {\n <mt-client-form\n [moduleKey]=\"moduleKey()\"\n [operationKey]=\"operationKey()\"\n [moduleId]=\"formModuleId()\"\n [levelId]=\"formLevelId()\"\n [levelDataId]=\"formLevelDataId()\"\n [moduleDataId]=\"moduleDataId()\"\n [readonly]=\"true\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.moduleFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"discussionModuleType()\"\n [recordId]=\"resolvedInstanceId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.moduleDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
1460
+ }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
1893
1461
 
1894
1462
  class WorkCenterProcessPreview {
1895
1463
  http = inject(HttpClient);
@@ -2110,7 +1678,7 @@ class WorkCenterProcessPreview {
2110
1678
  });
2111
1679
  }
2112
1680
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
2113
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessPreview, isStandalone: true, selector: "mt-work-center-process-preview", inputs: { requestId: { classPropertyName: "requestId", publicName: "requestId", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (!canRenderPreview()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process preview is not available for this item yet.\r\n </p>\r\n </div>\r\n} @else if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"text-sm text-surface-500\">Loading process preview...</p>\r\n </div>\r\n} @else if (error()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">{{ error() }}</p>\r\n </div>\r\n} @else {\r\n @if (view() === \"schema\") {\r\n @if (hasSchema()) {\r\n <div class=\"wc-process-preview-schema h-[70vh] overflow-hidden\">\r\n <mt-structure-builder\r\n class=\"h-full\"\r\n [layoutDirection]=\"'LR'\"\r\n [readonly]=\"true\"\r\n [structureMode]=\"'workflow'\"\r\n [nodeFields]=\"previewNodeFields\"\r\n [nodes]=\"schemaNodes()\"\r\n [connections]=\"schemaConnections()\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process steps are not available for this item yet.\r\n </p>\r\n </div>\r\n }\r\n } @else if (hasApprovals()) {\r\n <div class=\"max-h-[70vh] overflow-y-auto\">\r\n <mt-table\r\n noCard\r\n [data]=\"approvalRows()\"\r\n [columns]=\"approvalColumns()\"\r\n storageKey=\"work-center-process-preview-table\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [clickableRows]=\"false\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process approvals data is not available for this item yet.\r\n </p>\r\n </div>\r\n }\r\n}\r\n", styles: [":host ::ng-deep .wc-process-preview-schema .wf-detail-row{align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "connectionGuard", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }] });
1681
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessPreview, isStandalone: true, selector: "mt-work-center-process-preview", inputs: { requestId: { classPropertyName: "requestId", publicName: "requestId", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (!canRenderPreview()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process preview is not available for this item yet.\r\n </p>\r\n </div>\r\n} @else if (loading()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"text-sm text-surface-500\">Loading process preview...</p>\r\n </div>\r\n} @else if (error()) {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-red-600\">{{ error() }}</p>\r\n </div>\r\n} @else {\r\n @if (view() === \"schema\") {\r\n @if (hasSchema()) {\r\n <div class=\"wc-process-preview-schema h-[70vh] overflow-hidden\">\r\n <mt-structure-builder\r\n class=\"h-full\"\r\n [layoutDirection]=\"'LR'\"\r\n [readonly]=\"true\"\r\n [structureMode]=\"'workflow'\"\r\n [nodeFields]=\"previewNodeFields\"\r\n [nodes]=\"schemaNodes()\"\r\n [connections]=\"schemaConnections()\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process steps are not available for this item yet.\r\n </p>\r\n </div>\r\n }\r\n } @else if (hasApprovals()) {\r\n <div class=\"max-h-[70vh] overflow-y-auto\">\r\n <mt-table\r\n noCard\r\n [data]=\"approvalRows()\"\r\n [columns]=\"approvalColumns()\"\r\n storageKey=\"work-center-process-preview-table\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [clickableRows]=\"false\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n Process approvals data is not available for this item yet.\r\n </p>\r\n </div>\r\n }\r\n}\r\n", styles: [":host ::ng-deep .wc-process-preview-schema .wf-detail-row{align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "component", type: StructureBuilder, selector: "mt-structure-builder", inputs: ["availableNodes", "availableNodesLabel", "nodeForm", "nodeDialogFooterConfig", "connectionForm", "connectionFormulaSchemaId", "connectionFormulaConfig", "nodeActions", "nodeFields", "isAutoLayout", "readonly", "structureMode", "nodeStyle", "addModalType", "updateModalType", "addModalStyleClass", "updateModalStyleClass", "addModalHeader", "updateModalHeader", "appendTo", "availableTabsClass", "layoutDirection", "nodes", "connections", "nodeTemplate"], outputs: ["nodeActionsEvent", "action", "nodesChange", "connectionsChange"] }] });
2114
1682
  }
2115
1683
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessPreview, decorators: [{
2116
1684
  type: Component,
@@ -2136,6 +1704,7 @@ class WorkCenterProcessRequestType {
2136
1704
  destroyRef = inject(DestroyRef);
2137
1705
  details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
2138
1706
  lookups = input(null, ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
1707
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
2139
1708
  clientForm = viewChild(ClientForm, ...(ngDevMode ? [{ debugName: "clientForm" }] : /* istanbul ignore next */ []));
2140
1709
  formLookups = computed(() => this.lookups() ?? this.facade.lookups(), ...(ngDevMode ? [{ debugName: "formLookups" }] : /* istanbul ignore next */ []));
2141
1710
  activeTab = signal('requestDetails', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
@@ -2158,11 +1727,15 @@ class WorkCenterProcessRequestType {
2158
1727
  value: 'schema',
2159
1728
  icon: 'custom.flow-chart',
2160
1729
  },
2161
- {
2162
- label: this.transloco.translate('workCenter.tabs.discussion'),
2163
- value: 'discussion',
2164
- icon: 'custom.discussion-area',
2165
- },
1730
+ ...(!this.readOnly()
1731
+ ? [
1732
+ {
1733
+ label: this.transloco.translate('workCenter.tabs.discussion'),
1734
+ value: 'discussion',
1735
+ icon: 'custom.discussion-area',
1736
+ },
1737
+ ]
1738
+ : []),
2166
1739
  ];
2167
1740
  }, ...(ngDevMode ? [{ debugName: "tabOptions" }] : /* istanbul ignore next */ []));
2168
1741
  itemContext = computed(() => readItemContext(this.details()), ...(ngDevMode ? [{ debugName: "itemContext" }] : /* istanbul ignore next */ []));
@@ -2179,6 +1752,9 @@ class WorkCenterProcessRequestType {
2179
1752
  readNumber(this.itemContext(), 'requestId'), ...(ngDevMode ? [{ debugName: "draftProcessId" }] : /* istanbul ignore next */ []));
2180
1753
  discussionRecordId = computed(() => this.requestId() ?? 0, ...(ngDevMode ? [{ debugName: "discussionRecordId" }] : /* istanbul ignore next */ []));
2181
1754
  isReadonly = computed(() => {
1755
+ if (this.readOnly()) {
1756
+ return true;
1757
+ }
2182
1758
  const item = this.details().item;
2183
1759
  const status = item?.['status'];
2184
1760
  return status?.key !== 'Returned';
@@ -2191,14 +1767,14 @@ class WorkCenterProcessRequestType {
2191
1767
  .pipe(takeUntilDestroyed(this.destroyRef))
2192
1768
  .subscribe((lang) => this.activeLang.set(lang));
2193
1769
  effect(() => {
2194
- this.actionContext?.setFormSource(this.clientForm() ?? null);
1770
+ this.actionContext?.setFormSource(this.readOnly() ? null : (this.clientForm() ?? null));
2195
1771
  });
2196
1772
  }
2197
1773
  ngOnDestroy() {
2198
1774
  this.actionContext?.setFormSource(null);
2199
1775
  }
2200
1776
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessRequestType, deps: [], target: i0.ɵɵFactoryTarget.Component });
2201
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessRequestType, isStandalone: true, selector: "mt-work-center-process-request-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'requestDetails'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"moduleId()\"\r\n [levelId]=\"levelId()\"\r\n [levelDataId]=\"levelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [requestSchemaId]=\"requestSchemaId()\"\r\n [draftProcessId]=\"draftProcessId()\"\r\n [readonly]=\"isReadonly()\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'approvals'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'approvals'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'schema'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'ProcessRequest'\"\r\n [recordId]=\"discussionRecordId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: WorkCenterProcessPreview, selector: "mt-work-center-process-preview", inputs: ["requestId", "view"] }] });
1777
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessRequestType, isStandalone: true, selector: "mt-work-center-process-request-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'requestDetails'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\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 [readonly]=\"isReadonly()\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'approvals'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'approvals'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'schema'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'ProcessRequest'\"\n [recordId]=\"discussionRecordId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: WorkCenterProcessPreview, selector: "mt-work-center-process-preview", inputs: ["requestId", "view"] }] });
2202
1778
  }
2203
1779
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessRequestType, decorators: [{
2204
1780
  type: Component,
@@ -2209,8 +1785,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2209
1785
  ClientForm,
2210
1786
  DiscussionThread,
2211
1787
  WorkCenterProcessPreview,
2212
- ], template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'requestDetails'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"moduleId()\"\r\n [levelId]=\"levelId()\"\r\n [levelDataId]=\"levelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [requestSchemaId]=\"requestSchemaId()\"\r\n [draftProcessId]=\"draftProcessId()\"\r\n [readonly]=\"isReadonly()\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'approvals'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'approvals'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'schema'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'ProcessRequest'\"\r\n [recordId]=\"discussionRecordId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.requestDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
2213
- }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
1788
+ ], template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'requestDetails'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\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 [readonly]=\"isReadonly()\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'approvals'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'approvals'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'schema'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'ProcessRequest'\"\n [recordId]=\"discussionRecordId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.requestDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
1789
+ }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
2214
1790
 
2215
1791
  class WorkCenterProcessStepType {
2216
1792
  facade = inject(WorkCenterFacade);
@@ -2221,6 +1797,7 @@ class WorkCenterProcessStepType {
2221
1797
  destroyRef = inject(DestroyRef);
2222
1798
  details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
2223
1799
  lookups = input(null, ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
1800
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
2224
1801
  clientForm = viewChild(ClientForm, ...(ngDevMode ? [{ debugName: "clientForm" }] : /* istanbul ignore next */ []));
2225
1802
  formLookups = computed(() => this.lookups() ?? this.facade.lookups(), ...(ngDevMode ? [{ debugName: "formLookups" }] : /* istanbul ignore next */ []));
2226
1803
  activeTab = signal('form', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
@@ -2252,11 +1829,15 @@ class WorkCenterProcessStepType {
2252
1829
  value: 'schema',
2253
1830
  icon: 'custom.flow-chart',
2254
1831
  },
2255
- {
2256
- label: this.transloco.translate('workCenter.tabs.discussion'),
2257
- value: 'discussion',
2258
- icon: 'custom.discussion-area',
2259
- },
1832
+ ...(!this.readOnly()
1833
+ ? [
1834
+ {
1835
+ label: this.transloco.translate('workCenter.tabs.discussion'),
1836
+ value: 'discussion',
1837
+ icon: 'custom.discussion-area',
1838
+ },
1839
+ ]
1840
+ : []),
2260
1841
  ];
2261
1842
  }, ...(ngDevMode ? [{ debugName: "tabOptions" }] : /* istanbul ignore next */ []));
2262
1843
  itemContext = computed(() => readItemContext(this.details()), ...(ngDevMode ? [{ debugName: "itemContext" }] : /* istanbul ignore next */ []));
@@ -2295,14 +1876,14 @@ class WorkCenterProcessStepType {
2295
1876
  .pipe(takeUntilDestroyed(this.destroyRef))
2296
1877
  .subscribe((lang) => this.activeLang.set(lang));
2297
1878
  effect(() => {
2298
- this.actionContext?.setFormSource(this.clientForm() ?? null);
1879
+ this.actionContext?.setFormSource(this.readOnly() ? null : (this.clientForm() ?? null));
2299
1880
  });
2300
1881
  }
2301
1882
  ngOnDestroy() {
2302
1883
  this.actionContext?.setFormSource(null);
2303
1884
  }
2304
1885
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessStepType, deps: [], target: i0.ɵɵFactoryTarget.Component });
2305
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessStepType, isStandalone: true, selector: "mt-work-center-process-step-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'form'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"moduleId()\"\r\n [levelId]=\"levelId()\"\r\n [levelDataId]=\"levelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [requestSchemaId]=\"requestSchemaId()\"\r\n [draftProcessId]=\"draftProcessId()\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'levelDetails'\"\r\n >\r\n @if (levelDetailsConfig(); as levelDetailsConfig) {\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n <mt-client-instance-preview [config]=\"levelDetailsConfig\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'approvals'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'approvals'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'schema'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'ProcessRequest'\"\r\n [recordId]=\"discussionRecordId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: ClientInstancePreview, selector: "mt-client-instance-preview", inputs: ["config", "hideEmptyState", "stackOnNarrow"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: WorkCenterProcessPreview, selector: "mt-work-center-process-preview", inputs: ["requestId", "view"] }] });
1886
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterProcessStepType, isStandalone: true, selector: "mt-work-center-process-step-type", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "clientForm", first: true, predicate: ClientForm, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'form'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\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 [readonly]=\"readOnly()\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'levelDetails'\"\n >\n @if (levelDetailsConfig(); as levelDetailsConfig) {\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n <mt-client-instance-preview [config]=\"levelDetailsConfig\" />\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'approvals'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'approvals'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'schema'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'ProcessRequest'\"\n [recordId]=\"discussionRecordId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "mode", "moreLabel", "defaultIcon", "size", "fluid", "disabled", "searchThreshold"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "templateId", "preview", "forceOriginalForm", "returnUrl", "defaultValues", "submitRequestMapper", "readonly", "autoLoad", "formMode", "renderMode", "showInternalStepActions", "confirmWarningsOnSubmit", "confirmWarningsOnStepChange", "readonlyFieldDisplayMode", "lookups", "statuses", "ignoredFieldKeys", "disabledFieldKeys", "allowedFieldKeys"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected", "footerStateChanged"] }, { kind: "component", type: ClientInstancePreview, selector: "mt-client-instance-preview", inputs: ["config", "hideEmptyState", "stackOnNarrow"] }, { kind: "component", type: DiscussionThread, selector: "mt-discussion-thread", inputs: ["moduleType", "recordId", "title", "subtitle", "placeholder", "pageSize", "currentUserId", "requestContext", "mentionableUsers", "mentionSearchEndpoint", "mentionSearchParam", "mentionSearchDataPath", "allowAttachments", "uploadEndpoint", "attachmentDownloadEndpoint", "showParticipants", "autoMarkRead", "refreshIntervalMs", "styleClass", "disabled"], outputs: ["loaded", "errored", "commentCreated", "commentUpdated", "commentDeleted", "readStateChanged"] }, { kind: "component", type: WorkCenterProcessPreview, selector: "mt-work-center-process-preview", inputs: ["requestId", "view"] }] });
2306
1887
  }
2307
1888
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterProcessStepType, decorators: [{
2308
1889
  type: Component,
@@ -2314,14 +1895,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2314
1895
  ClientInstancePreview,
2315
1896
  DiscussionThread,
2316
1897
  WorkCenterProcessPreview,
2317
- ], template: "<div\r\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <div\r\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\r\n >\r\n @if (tabOptions().length > 1) {\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n mode=\"vertical\"\r\n size=\"small\"\r\n />\r\n }\r\n\r\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'form'\"\r\n >\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n @if (canRenderForm()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"moduleId()\"\r\n [levelId]=\"levelId()\"\r\n [levelDataId]=\"levelDataId()\"\r\n [moduleDataId]=\"moduleDataId()\"\r\n [requestSchemaId]=\"requestSchemaId()\"\r\n [draftProcessId]=\"draftProcessId()\"\r\n [lookups]=\"formLookups()\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processFormUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 lg:overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'levelDetails'\"\r\n >\r\n @if (levelDetailsConfig(); as levelDetailsConfig) {\r\n <div\r\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\r\n >\r\n <mt-client-instance-preview [config]=\"levelDetailsConfig\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'approvals'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'approvals'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"flex-1 min-h-0 overflow-auto\"\r\n [hidden]=\"activeTab() !== 'schema'\"\r\n >\r\n @if (canRenderPreview()) {\r\n <mt-work-center-process-preview\r\n [requestId]=\"requestId()\"\r\n [view]=\"'schema'\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processPreviewUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"h-full min-h-0 overflow-hidden\"\r\n [hidden]=\"activeTab() !== 'discussion'\"\r\n >\r\n @if (canRenderDiscussion()) {\r\n <div\r\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\r\n >\r\n <mt-discussion-thread\r\n [moduleType]=\"'ProcessRequest'\"\r\n [recordId]=\"discussionRecordId()\"\r\n [mentionSearchEndpoint]=\"'Identity/users'\"\r\n [mentionSearchParam]=\"'query'\"\r\n [mentionSearchDataPath]=\"'data'\"\r\n [uploadEndpoint]=\"'uploader'\"\r\n [attachmentDownloadEndpoint]=\"'uploader'\"\r\n [showParticipants]=\"true\"\r\n [autoMarkRead]=\"true\"\r\n [refreshIntervalMs]=\"0\"\r\n [styleClass]=\"'h-full'\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg border border-dashed border-surface-300 bg-surface-50 p-6\"\r\n >\r\n <p class=\"max-w-md text-center text-sm text-surface-500\">\r\n {{ t(\"context.processDiscussionUnavailable\") }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
2318
- }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
1898
+ ], template: "<div\n class=\"mt-modal-content flex h-full min-h-0 flex-col gap-4 p-4 lg:overflow-hidden\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <div\n class=\"flex flex-1 min-h-0 flex-col gap-4 lg:grid lg:grid-cols-[13rem_minmax(0,1fr)] lg:gap-6\"\n >\n @if (tabOptions().length > 1) {\n <mt-tabs\n [(active)]=\"activeTab\"\n [options]=\"tabOptions()\"\n mode=\"vertical\"\n size=\"small\"\n />\n }\n\n <div class=\"min-w-0 flex-1 min-h-0 lg:overflow-hidden\">\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'form'\"\n >\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\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 [readonly]=\"readOnly()\"\n [lookups]=\"formLookups()\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processFormUnavailable\") }}\n </p>\n </div>\n }\n </div>\n </div>\n\n <div\n class=\"h-full min-h-0 lg:overflow-hidden\"\n [hidden]=\"activeTab() !== 'levelDetails'\"\n >\n @if (levelDetailsConfig(); as levelDetailsConfig) {\n <div\n class=\"min-w-0 h-full min-h-0 lg:overflow-y-auto lg:overscroll-contain lg:pr-2\"\n >\n <mt-client-instance-preview [config]=\"levelDetailsConfig\" />\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'approvals'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'approvals'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n <div\n class=\"flex-1 min-h-0 overflow-auto\"\n [hidden]=\"activeTab() !== 'schema'\"\n >\n @if (canRenderPreview()) {\n <mt-work-center-process-preview\n [requestId]=\"requestId()\"\n [view]=\"'schema'\"\n />\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processPreviewUnavailable\") }}\n </p>\n </div>\n }\n </div>\n\n @if (!readOnly()) {\n <div\n class=\"h-full min-h-0 overflow-hidden\"\n [hidden]=\"activeTab() !== 'discussion'\"\n >\n @if (canRenderDiscussion()) {\n <div\n class=\"h-[32rem] min-h-[22rem] overflow-hidden rounded-lg border border-surface-200 bg-surface-50 lg:h-full lg:min-h-0\"\n >\n <mt-discussion-thread\n [moduleType]=\"'ProcessRequest'\"\n [recordId]=\"discussionRecordId()\"\n [mentionSearchEndpoint]=\"'Identity/users'\"\n [mentionSearchParam]=\"'query'\"\n [mentionSearchDataPath]=\"'data'\"\n [uploadEndpoint]=\"'uploader'\"\n [attachmentDownloadEndpoint]=\"'uploader'\"\n [showParticipants]=\"true\"\n [autoMarkRead]=\"true\"\n [refreshIntervalMs]=\"0\"\n [styleClass]=\"'h-full'\"\n />\n </div>\n } @else {\n <div\n class=\"flex min-h-[22rem] items-center justify-center rounded-lg 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 {{ t(\"context.processDiscussionUnavailable\") }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n </div>\n</div>\n" }]
1899
+ }], ctorParameters: () => [], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], clientForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ClientForm), { isSignal: true }] }] } });
2319
1900
 
2320
1901
  class WorkCenterItemModal {
2321
1902
  details = input.required(...(ngDevMode ? [{ debugName: "details" }] : /* istanbul ignore next */ []));
2322
1903
  lookups = input(null, ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
1904
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
2323
1905
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterItemModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
2324
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterItemModal, isStandalone: true, selector: "mt-work-center-item-modal", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block h-full min-h-0" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'workCenter'\">\r\n @if (details().type === \"ProcessStep\") {\r\n <mt-work-center-process-step-type\r\n [details]=\"details()\"\r\n [lookups]=\"lookups()\"\r\n />\r\n } @else if (details().type === \"ProcessRequest\") {\r\n <mt-work-center-process-request-type\r\n [details]=\"details()\"\r\n [lookups]=\"lookups()\"\r\n />\r\n } @else if (details().type === \"EscalationInstance\") {\r\n <mt-work-center-escalation-instance-type [details]=\"details()\" />\r\n } @else if (details().type === \"Module\" || details().type === \"GeneralTask\") {\r\n <mt-work-center-module-type [details]=\"details()\" [lookups]=\"lookups()\" />\r\n } @else {\r\n <div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\r\n <p class=\"text-sm text-surface-500\">{{ t(\"modal.unsupportedType\") }}</p>\r\n </div>\r\n }\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: WorkCenterProcessStepType, selector: "mt-work-center-process-step-type", inputs: ["details", "lookups"] }, { kind: "component", type: WorkCenterProcessRequestType, selector: "mt-work-center-process-request-type", inputs: ["details", "lookups"] }, { kind: "component", type: WorkCenterEscalationInstanceType, selector: "mt-work-center-escalation-instance-type", inputs: ["details"] }, { kind: "component", type: WorkCenterModuleType, selector: "mt-work-center-module-type", inputs: ["details", "lookups"] }] });
1906
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterItemModal, isStandalone: true, selector: "mt-work-center-item-modal", inputs: { details: { classPropertyName: "details", publicName: "details", isSignal: true, isRequired: true, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block h-full min-h-0" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'workCenter'\">\n @if (details().type === \"ProcessStep\") {\n <mt-work-center-process-step-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"ProcessRequest\") {\n <mt-work-center-process-request-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"EscalationInstance\") {\n <mt-work-center-escalation-instance-type\n [details]=\"details()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"Module\" || details().type === \"GeneralTask\") {\n <mt-work-center-module-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\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\">{{ t(\"modal.unsupportedType\") }}</p>\n </div>\n }\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: WorkCenterProcessStepType, selector: "mt-work-center-process-step-type", inputs: ["details", "lookups", "readOnly"] }, { kind: "component", type: WorkCenterProcessRequestType, selector: "mt-work-center-process-request-type", inputs: ["details", "lookups", "readOnly"] }, { kind: "component", type: WorkCenterEscalationInstanceType, selector: "mt-work-center-escalation-instance-type", inputs: ["details", "readOnly"] }, { kind: "component", type: WorkCenterModuleType, selector: "mt-work-center-module-type", inputs: ["details", "lookups", "readOnly"] }] });
2325
1907
  }
2326
1908
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterItemModal, decorators: [{
2327
1909
  type: Component,
@@ -2334,8 +1916,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2334
1916
  WorkCenterModuleType,
2335
1917
  ], host: {
2336
1918
  class: 'block h-full min-h-0',
2337
- }, template: "<ng-container *transloco=\"let t; prefix: 'workCenter'\">\r\n @if (details().type === \"ProcessStep\") {\r\n <mt-work-center-process-step-type\r\n [details]=\"details()\"\r\n [lookups]=\"lookups()\"\r\n />\r\n } @else if (details().type === \"ProcessRequest\") {\r\n <mt-work-center-process-request-type\r\n [details]=\"details()\"\r\n [lookups]=\"lookups()\"\r\n />\r\n } @else if (details().type === \"EscalationInstance\") {\r\n <mt-work-center-escalation-instance-type [details]=\"details()\" />\r\n } @else if (details().type === \"Module\" || details().type === \"GeneralTask\") {\r\n <mt-work-center-module-type [details]=\"details()\" [lookups]=\"lookups()\" />\r\n } @else {\r\n <div class=\"mt-modal-content flex h-full items-center justify-center p-4\">\r\n <p class=\"text-sm text-surface-500\">{{ t(\"modal.unsupportedType\") }}</p>\r\n </div>\r\n }\r\n</ng-container>\r\n" }]
2338
- }], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }] } });
1919
+ }, template: "<ng-container *transloco=\"let t; prefix: 'workCenter'\">\n @if (details().type === \"ProcessStep\") {\n <mt-work-center-process-step-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"ProcessRequest\") {\n <mt-work-center-process-request-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"EscalationInstance\") {\n <mt-work-center-escalation-instance-type\n [details]=\"details()\"\n [readOnly]=\"readOnly()\"\n />\n } @else if (details().type === \"Module\" || details().type === \"GeneralTask\") {\n <mt-work-center-module-type\n [details]=\"details()\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\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\">{{ t(\"modal.unsupportedType\") }}</p>\n </div>\n }\n</ng-container>\n" }]
1920
+ }], propDecorators: { details: [{ type: i0.Input, args: [{ isSignal: true, alias: "details", required: true }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }] } });
2339
1921
 
2340
1922
  const DEFAULT_GENERAL_TASK_MODAL_STYLE_CLASS = '!w-[70vw] !h-[90vh]';
2341
1923
  class WorkCenterItemModalFooterActions {
@@ -2693,7 +2275,13 @@ class WorkCenterItemModalRoute {
2693
2275
  modal = inject(ModalService);
2694
2276
  lookups = this.facade.lookups;
2695
2277
  contextKey = input(null, ...(ngDevMode ? [{ debugName: "contextKey" }] : /* istanbul ignore next */ []));
2278
+ manageRouteOutlet = input(true, ...(ngDevMode ? [{ debugName: "manageRouteOutlet" }] : /* istanbul ignore next */ []));
2279
+ showPreviewLevelAction = input(true, ...(ngDevMode ? [{ debugName: "showPreviewLevelAction" }] : /* istanbul ignore next */ []));
2280
+ readOnly = input(false, ...(ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []));
2281
+ appendTo = input('self', ...(ngDevMode ? [{ debugName: "appendTo" }] : /* istanbul ignore next */ []));
2282
+ drawerStyleClass = input('mt-work-center-item-drawer !absolute !w-[96vw] md:!w-[84vw] xl:!w-[70vw]', ...(ngDevMode ? [{ debugName: "drawerStyleClass" }] : /* istanbul ignore next */ []));
2696
2283
  previewLevel = output();
2284
+ closed = output();
2697
2285
  drawerVisible = signal(true, ...(ngDevMode ? [{ debugName: "drawerVisible" }] : /* istanbul ignore next */ []));
2698
2286
  loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
2699
2287
  error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
@@ -2705,6 +2293,7 @@ class WorkCenterItemModalRoute {
2705
2293
  this.transloco.translate('workCenter.page.itemDetails'), ...(ngDevMode ? [{ debugName: "drawerTitle" }] : /* istanbul ignore next */ []));
2706
2294
  drawerSubtitle = computed(() => this.readDisplayField(this.details()?.item, 'subtitle') ?? '', ...(ngDevMode ? [{ debugName: "drawerSubtitle" }] : /* istanbul ignore next */ []));
2707
2295
  previewLevelTarget = computed(() => this.resolvePreviewLevelTarget(this.details()), ...(ngDevMode ? [{ debugName: "previewLevelTarget" }] : /* istanbul ignore next */ []));
2296
+ displayedPreviewLevelTarget = computed(() => this.showPreviewLevelAction() ? this.previewLevelTarget() : null, ...(ngDevMode ? [{ debugName: "displayedPreviewLevelTarget" }] : /* istanbul ignore next */ []));
2708
2297
  constructor() {
2709
2298
  effect(() => {
2710
2299
  this.footerActionsMounted.set(!!this.resolvedContextKey());
@@ -2766,7 +2355,7 @@ class WorkCenterItemModalRoute {
2766
2355
  // menu/KPI counters are stale regardless of whether the dialog closes.
2767
2356
  this.facade.loadRuntime(this.facade.activeArea(), 'refresh');
2768
2357
  if (result.afterSuccess === 'close') {
2769
- void this.closeRouteOutlet();
2358
+ void this.close();
2770
2359
  return;
2771
2360
  }
2772
2361
  this.detailsReloadTick.update((value) => value + 1);
@@ -2783,7 +2372,14 @@ class WorkCenterItemModalRoute {
2783
2372
  if (visible) {
2784
2373
  return;
2785
2374
  }
2786
- await this.closeRouteOutlet();
2375
+ await this.close();
2376
+ }
2377
+ close() {
2378
+ if (!this.manageRouteOutlet()) {
2379
+ this.closed.emit();
2380
+ return Promise.resolve(true);
2381
+ }
2382
+ return this.closeRouteOutlet();
2787
2383
  }
2788
2384
  closeRouteOutlet() {
2789
2385
  console.log('[work-center-debug] modal route closing', {
@@ -2845,7 +2441,7 @@ class WorkCenterItemModalRoute {
2845
2441
  };
2846
2442
  }
2847
2443
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterItemModalRoute, deps: [], target: i0.ɵɵFactoryTarget.Component });
2848
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterItemModalRoute, isStandalone: true, selector: "mt-work-center-item-modal-route", inputs: { contextKey: { classPropertyName: "contextKey", publicName: "contextKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLevel: "previewLevel" }, providers: [RuntimeActionContextStore], ngImport: i0, template: "<mt-drawer\r\n [visible]=\"drawerVisible()\"\r\n [loadingHeader]=\"loading()\"\r\n [title]=\"drawerTitle()\"\r\n styleClass=\"mt-work-center-item-drawer !absolute !w-[96vw] md:!w-[84vw] xl:!w-[70vw]\"\r\n position=\"right\"\r\n [modal]=\"true\"\r\n (visibleChange)=\"onVisibleChange($event)\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <ng-container content>\r\n @if (loading()) {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\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\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n\r\n <p-skeleton height=\"16rem\" class=\"rounded-lg\" />\r\n </div>\r\n </div>\r\n } @else if (error(); as errorMessage) {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\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 <div [class]=\"modal.contentClass + ' h-full min-h-0'\">\r\n <mt-work-center-item-modal [details]=\"details\" [lookups]=\"lookups()\" />\r\n </div>\r\n } @else {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"text-sm font-medium text-surface-500\">\r\n {{ t(\"modal.noItemSelected\") }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n\r\n @if (footerActionsMounted()) {\r\n <div footer [class]=\"modal.footerClass\">\r\n <mt-work-center-item-modal-footer-actions\r\n [contextKey]=\"resolvedContextKey()\"\r\n [previewLevelTarget]=\"previewLevelTarget()\"\r\n (actionExecuted)=\"onActionExecuted($event)\"\r\n (previewLevelSelected)=\"onPreviewLevelSelected($event)\"\r\n (visibilityChange)=\"onFooterVisibilityChange($event)\"\r\n />\r\n </div>\r\n }\r\n</mt-drawer>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Drawer, selector: "mt-drawer", inputs: ["visible", "position", "fullScreen", "closeOnEscape", "blockScroll", "dismissible", "title", "subtitle", "loadingHeader", "styleClass", "transitionOptions", "appendTo", "modal", "showMaximizeToggle", "maximizeTooltip", "restoreTooltip", "maximized"], outputs: ["visibleChange", "onShow", "onHide", "maximizedChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: WorkCenterItemModal, selector: "mt-work-center-item-modal", inputs: ["details", "lookups"] }, { kind: "component", type: WorkCenterItemModalFooterActions, selector: "mt-work-center-item-modal-footer-actions", inputs: ["contextKey", "previewLevelTarget"], outputs: ["actionExecuted", "previewLevelSelected", "visibilityChange"] }] });
2444
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: WorkCenterItemModalRoute, isStandalone: true, selector: "mt-work-center-item-modal-route", inputs: { contextKey: { classPropertyName: "contextKey", publicName: "contextKey", isSignal: true, isRequired: false, transformFunction: null }, manageRouteOutlet: { classPropertyName: "manageRouteOutlet", publicName: "manageRouteOutlet", isSignal: true, isRequired: false, transformFunction: null }, showPreviewLevelAction: { classPropertyName: "showPreviewLevelAction", publicName: "showPreviewLevelAction", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, drawerStyleClass: { classPropertyName: "drawerStyleClass", publicName: "drawerStyleClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { previewLevel: "previewLevel", closed: "closed" }, providers: [RuntimeActionContextStore], ngImport: i0, template: "<mt-drawer\n [visible]=\"drawerVisible()\"\n [loadingHeader]=\"loading()\"\n [title]=\"drawerTitle()\"\n [styleClass]=\"drawerStyleClass()\"\n [appendTo]=\"appendTo()\"\n position=\"right\"\n [modal]=\"true\"\n (visibleChange)=\"onVisibleChange($event)\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <ng-container content>\n @if (loading()) {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] flex-col gap-5\">\n <div class=\"flex items-center gap-3\">\n <p-skeleton shape=\"circle\" size=\"3rem\" />\n <div class=\"flex flex-1 flex-col gap-2\">\n <p-skeleton width=\"12rem\" height=\"1rem\" />\n <p-skeleton width=\"8rem\" height=\"0.875rem\" />\n </div>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (_ of [1, 2, 3, 4]; track $index) {\n <p-skeleton height=\"5rem\" class=\"rounded-lg\" />\n }\n </div>\n\n <p-skeleton height=\"16rem\" class=\"rounded-lg\" />\n </div>\n </div>\n } @else if (error(); as errorMessage) {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] items-center justify-center\">\n <p class=\"max-w-xl text-sm font-medium text-red-600\">\n {{ errorMessage }}\n </p>\n </div>\n </div>\n } @else if (details(); as details) {\n <div [class]=\"modal.contentClass + ' h-full min-h-0'\">\n <mt-work-center-item-modal\n [details]=\"details\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n </div>\n } @else {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] items-center justify-center\">\n <p class=\"text-sm font-medium text-surface-500\">\n {{ t(\"modal.noItemSelected\") }}\n </p>\n </div>\n </div>\n }\n </ng-container>\n\n @if (!readOnly() && footerActionsMounted()) {\n <div footer [class]=\"modal.footerClass\">\n <mt-work-center-item-modal-footer-actions\n [contextKey]=\"resolvedContextKey()\"\n [previewLevelTarget]=\"displayedPreviewLevelTarget()\"\n (actionExecuted)=\"onActionExecuted($event)\"\n (previewLevelSelected)=\"onPreviewLevelSelected($event)\"\n (visibilityChange)=\"onFooterVisibilityChange($event)\"\n />\n </div>\n }\n</mt-drawer>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Drawer, selector: "mt-drawer", inputs: ["visible", "position", "fullScreen", "closeOnEscape", "blockScroll", "dismissible", "title", "subtitle", "loadingHeader", "styleClass", "transitionOptions", "appendTo", "modal", "showMaximizeToggle", "maximizeTooltip", "restoreTooltip", "maximized"], outputs: ["visibleChange", "onShow", "onHide", "maximizedChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: WorkCenterItemModal, selector: "mt-work-center-item-modal", inputs: ["details", "lookups", "readOnly"] }, { kind: "component", type: WorkCenterItemModalFooterActions, selector: "mt-work-center-item-modal-footer-actions", inputs: ["contextKey", "previewLevelTarget"], outputs: ["actionExecuted", "previewLevelSelected", "visibilityChange"] }] });
2849
2445
  }
2850
2446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterItemModalRoute, decorators: [{
2851
2447
  type: Component,
@@ -2856,8 +2452,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2856
2452
  SkeletonModule,
2857
2453
  WorkCenterItemModal,
2858
2454
  WorkCenterItemModalFooterActions,
2859
- ], providers: [RuntimeActionContextStore], template: "<mt-drawer\r\n [visible]=\"drawerVisible()\"\r\n [loadingHeader]=\"loading()\"\r\n [title]=\"drawerTitle()\"\r\n styleClass=\"mt-work-center-item-drawer !absolute !w-[96vw] md:!w-[84vw] xl:!w-[70vw]\"\r\n position=\"right\"\r\n [modal]=\"true\"\r\n (visibleChange)=\"onVisibleChange($event)\"\r\n *transloco=\"let t; prefix: 'workCenter'\"\r\n>\r\n <ng-container content>\r\n @if (loading()) {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\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\" class=\"rounded-lg\" />\r\n }\r\n </div>\r\n\r\n <p-skeleton height=\"16rem\" class=\"rounded-lg\" />\r\n </div>\r\n </div>\r\n } @else if (error(); as errorMessage) {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\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 <div [class]=\"modal.contentClass + ' h-full min-h-0'\">\r\n <mt-work-center-item-modal [details]=\"details\" [lookups]=\"lookups()\" />\r\n </div>\r\n } @else {\r\n <div class=\"p-4\" [class]=\"modal.contentClass\">\r\n <div class=\"flex min-h-[22rem] items-center justify-center\">\r\n <p class=\"text-sm font-medium text-surface-500\">\r\n {{ t(\"modal.noItemSelected\") }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n </ng-container>\r\n\r\n @if (footerActionsMounted()) {\r\n <div footer [class]=\"modal.footerClass\">\r\n <mt-work-center-item-modal-footer-actions\r\n [contextKey]=\"resolvedContextKey()\"\r\n [previewLevelTarget]=\"previewLevelTarget()\"\r\n (actionExecuted)=\"onActionExecuted($event)\"\r\n (previewLevelSelected)=\"onPreviewLevelSelected($event)\"\r\n (visibilityChange)=\"onFooterVisibilityChange($event)\"\r\n />\r\n </div>\r\n }\r\n</mt-drawer>\r\n" }]
2860
- }], ctorParameters: () => [], propDecorators: { contextKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextKey", required: false }] }], previewLevel: [{ type: i0.Output, args: ["previewLevel"] }] } });
2455
+ ], providers: [RuntimeActionContextStore], template: "<mt-drawer\n [visible]=\"drawerVisible()\"\n [loadingHeader]=\"loading()\"\n [title]=\"drawerTitle()\"\n [styleClass]=\"drawerStyleClass()\"\n [appendTo]=\"appendTo()\"\n position=\"right\"\n [modal]=\"true\"\n (visibleChange)=\"onVisibleChange($event)\"\n *transloco=\"let t; prefix: 'workCenter'\"\n>\n <ng-container content>\n @if (loading()) {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] flex-col gap-5\">\n <div class=\"flex items-center gap-3\">\n <p-skeleton shape=\"circle\" size=\"3rem\" />\n <div class=\"flex flex-1 flex-col gap-2\">\n <p-skeleton width=\"12rem\" height=\"1rem\" />\n <p-skeleton width=\"8rem\" height=\"0.875rem\" />\n </div>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (_ of [1, 2, 3, 4]; track $index) {\n <p-skeleton height=\"5rem\" class=\"rounded-lg\" />\n }\n </div>\n\n <p-skeleton height=\"16rem\" class=\"rounded-lg\" />\n </div>\n </div>\n } @else if (error(); as errorMessage) {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] items-center justify-center\">\n <p class=\"max-w-xl text-sm font-medium text-red-600\">\n {{ errorMessage }}\n </p>\n </div>\n </div>\n } @else if (details(); as details) {\n <div [class]=\"modal.contentClass + ' h-full min-h-0'\">\n <mt-work-center-item-modal\n [details]=\"details\"\n [lookups]=\"lookups()\"\n [readOnly]=\"readOnly()\"\n />\n </div>\n } @else {\n <div class=\"p-4\" [class]=\"modal.contentClass\">\n <div class=\"flex min-h-[22rem] items-center justify-center\">\n <p class=\"text-sm font-medium text-surface-500\">\n {{ t(\"modal.noItemSelected\") }}\n </p>\n </div>\n </div>\n }\n </ng-container>\n\n @if (!readOnly() && footerActionsMounted()) {\n <div footer [class]=\"modal.footerClass\">\n <mt-work-center-item-modal-footer-actions\n [contextKey]=\"resolvedContextKey()\"\n [previewLevelTarget]=\"displayedPreviewLevelTarget()\"\n (actionExecuted)=\"onActionExecuted($event)\"\n (previewLevelSelected)=\"onPreviewLevelSelected($event)\"\n (visibilityChange)=\"onFooterVisibilityChange($event)\"\n />\n </div>\n }\n</mt-drawer>\n" }]
2456
+ }], ctorParameters: () => [], propDecorators: { contextKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextKey", required: false }] }], manageRouteOutlet: [{ type: i0.Input, args: [{ isSignal: true, alias: "manageRouteOutlet", required: false }] }], showPreviewLevelAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPreviewLevelAction", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], appendTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendTo", required: false }] }], drawerStyleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawerStyleClass", required: false }] }], previewLevel: [{ type: i0.Output, args: ["previewLevel"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
2861
2457
  // Accepts either a plain string (e.g. `moduleKey`) or a localized
2862
2458
  // `{ display, en, ar }` translatable, returning the display string.
2863
2459
  function normalizeDisplayName(value) {
@@ -2885,6 +2481,470 @@ function normalizeRouteId(value) {
2885
2481
  return null;
2886
2482
  }
2887
2483
 
2484
+ const OPERATOR_LABELS = {
2485
+ Eq: 'Equals',
2486
+ Neq: 'Not equal',
2487
+ In: 'In',
2488
+ Contains: 'Contains',
2489
+ StartsWith: 'Starts with',
2490
+ Gt: 'Greater than',
2491
+ Gte: 'Greater than or equal',
2492
+ Lt: 'Less than',
2493
+ Lte: 'Less than or equal',
2494
+ Between: 'Between',
2495
+ IsNull: 'Is empty',
2496
+ IsNotNull: 'Is not empty',
2497
+ };
2498
+ const OPERATOR_VALUE_MODE = {
2499
+ In: 'multi',
2500
+ Between: 'range',
2501
+ IsNull: 'none',
2502
+ IsNotNull: 'none',
2503
+ };
2504
+ const GENERAL_TASK_CARD_KEYS = new Set([
2505
+ 'mygeneraltasks',
2506
+ 'generaltask',
2507
+ 'generaltasks',
2508
+ ]);
2509
+ function toLabel(value) {
2510
+ const normalized = value.split('.').pop() ?? value;
2511
+ return normalized
2512
+ .replace(/[_-]/g, ' ')
2513
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
2514
+ .trim()
2515
+ .replace(/\b\w/g, (char) => char.toUpperCase());
2516
+ }
2517
+ function columnTypeToViewType(type) {
2518
+ if (type === 'date')
2519
+ return 'Date';
2520
+ return undefined;
2521
+ }
2522
+ function normalizeCardKey(value) {
2523
+ if (typeof value !== 'string') {
2524
+ return '';
2525
+ }
2526
+ return value
2527
+ .trim()
2528
+ .replace(/[\s_-]/g, '')
2529
+ .toLowerCase();
2530
+ }
2531
+ /**
2532
+ * Strips the user envelope used by `mt-table` user filters down to the
2533
+ * scalar id that the BE rule payload accepts. Falls back to the original
2534
+ * value for non-user shapes (e.g. simple string in a select filter).
2535
+ */
2536
+ function extractIdScalar(value) {
2537
+ if (value !== null &&
2538
+ typeof value === 'object' &&
2539
+ 'id' in value) {
2540
+ return value['id'];
2541
+ }
2542
+ return value;
2543
+ }
2544
+ function toIsoDate(value) {
2545
+ if (value instanceof Date)
2546
+ return value.toISOString();
2547
+ return value;
2548
+ }
2549
+ /**
2550
+ * Translates one in-table column filter value into a `WorkCenterFilterRule`.
2551
+ *
2552
+ * The shape of `raw` depends on the column's filter type — see
2553
+ * `mt-table` `table-filter-field` outputs:
2554
+ * - text → string → `Contains`
2555
+ * - select → scalar | scalar[] → `Eq` | `In`
2556
+ * - boolean → boolean → `Eq`
2557
+ * - date → `{ from?, to?, value? }` (Date|null)→ `Between`/`Gte`/`Lte`/`Eq`
2558
+ * - user → `{ id, ... }` | `{ id, ... }[]` → `Eq` (id) | `In` (ids)
2559
+ *
2560
+ * Returns `null` when the value is empty / nothing to send.
2561
+ */
2562
+ function toRuntimeFilterRule(field, raw, column) {
2563
+ if (raw === null || raw === undefined || raw === '')
2564
+ return null;
2565
+ if (typeof raw === 'boolean') {
2566
+ return { field, op: 'Eq', value: raw };
2567
+ }
2568
+ if (typeof raw === 'number') {
2569
+ return { field, op: 'Eq', value: raw };
2570
+ }
2571
+ if (typeof raw === 'string') {
2572
+ if (!raw.trim().length)
2573
+ return null;
2574
+ return { field, op: 'Contains', value: raw };
2575
+ }
2576
+ if (Array.isArray(raw)) {
2577
+ const values = raw
2578
+ .map(extractIdScalar)
2579
+ .filter((v) => v !== null && v !== undefined && v !== '');
2580
+ if (!values.length)
2581
+ return null;
2582
+ return { field, op: 'In', values };
2583
+ }
2584
+ if (typeof raw === 'object') {
2585
+ const obj = raw;
2586
+ // User filter envelope -> single-id Eq.
2587
+ if (obj.id !== undefined && obj.id !== null && obj.id !== '') {
2588
+ return { field, op: 'Eq', value: obj.id };
2589
+ }
2590
+ const hasFrom = obj.from !== undefined && obj.from !== null;
2591
+ const hasTo = obj.to !== undefined && obj.to !== null;
2592
+ if (hasFrom && hasTo) {
2593
+ return {
2594
+ field,
2595
+ op: 'Between',
2596
+ from: toIsoDate(obj.from),
2597
+ to: toIsoDate(obj.to),
2598
+ };
2599
+ }
2600
+ if (hasFrom) {
2601
+ return { field, op: 'Gte', value: toIsoDate(obj.from) };
2602
+ }
2603
+ if (hasTo) {
2604
+ return { field, op: 'Lte', value: toIsoDate(obj.to) };
2605
+ }
2606
+ if (obj.value !== undefined && obj.value !== null && obj.value !== '') {
2607
+ const treatAsContains = column?.type === 'text' ||
2608
+ (column?.filterConfig?.type === 'text' &&
2609
+ typeof obj.value === 'string');
2610
+ if (treatAsContains) {
2611
+ return { field, op: 'Contains', value: obj.value };
2612
+ }
2613
+ return { field, op: 'Eq', value: extractIdScalar(obj.value) };
2614
+ }
2615
+ }
2616
+ return null;
2617
+ }
2618
+ /**
2619
+ * Walks `mt-table`'s filter map and produces the `WorkCenterFilterRule[]`
2620
+ * sent on the BE column-filter slice. The synthetic `generalSearch` key is
2621
+ * skipped because the page keeps general search local-only.
2622
+ */
2623
+ function buildColumnRuntimeFilters(filters, columns, allowedFields) {
2624
+ if (!filters)
2625
+ return [];
2626
+ const allowed = allowedFields && allowedFields.length ? new Set(allowedFields) : null;
2627
+ const columnByKey = new Map(columns.map((col) => [col.key, col]));
2628
+ const rules = [];
2629
+ for (const [key, raw] of Object.entries(filters)) {
2630
+ if (key === 'generalSearch')
2631
+ continue;
2632
+ if (allowed && !allowed.has(key))
2633
+ continue;
2634
+ const rule = toRuntimeFilterRule(key, raw, columnByKey.get(key));
2635
+ if (rule)
2636
+ rules.push(rule);
2637
+ }
2638
+ return rules;
2639
+ }
2640
+ function areFilterRulesEqual(left, right) {
2641
+ return JSON.stringify(left) === JSON.stringify(right);
2642
+ }
2643
+ function mapAllowedFields(schema) {
2644
+ const properties = schema.properties ?? [];
2645
+ const fromProperties = properties
2646
+ .filter((property) => typeof property?.key === 'string' && property.key.length > 0)
2647
+ .map((property) => ({
2648
+ key: property.key,
2649
+ label: property.name?.display ||
2650
+ property.name?.en ||
2651
+ property.name?.ar ||
2652
+ toLabel(property.key),
2653
+ viewType: property.viewType,
2654
+ }));
2655
+ if (fromProperties.length) {
2656
+ return fromProperties;
2657
+ }
2658
+ return (schema.allowedFields ?? []).map((field) => ({
2659
+ key: field,
2660
+ label: toLabel(field),
2661
+ }));
2662
+ }
2663
+ function mapAllowedOperators(schema, getLabel) {
2664
+ const options = [];
2665
+ for (const operator of schema.allowedOperators ?? []) {
2666
+ if (typeof operator === 'string') {
2667
+ options.push({
2668
+ key: operator,
2669
+ label: getLabel(operator),
2670
+ valueMode: OPERATOR_VALUE_MODE[operator] ?? 'single',
2671
+ });
2672
+ continue;
2673
+ }
2674
+ const key = operator?.value;
2675
+ if (!key) {
2676
+ continue;
2677
+ }
2678
+ options.push({
2679
+ key,
2680
+ label: operator.display?.display ||
2681
+ operator.display?.en ||
2682
+ operator.display?.ar ||
2683
+ getLabel(key),
2684
+ valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
2685
+ });
2686
+ }
2687
+ return options;
2688
+ }
2689
+ class WorkCenterPage {
2690
+ facade = inject(WorkCenterFacade);
2691
+ modal = inject(ModalService);
2692
+ transloco = inject(TranslocoService);
2693
+ destroyRef = inject(DestroyRef);
2694
+ activeLang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "activeLang" }] : /* istanbul ignore next */ []));
2695
+ area = input('MyInbox', ...(ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []));
2696
+ pageTitle = input('', ...(ngDevMode ? [{ debugName: "pageTitle" }] : /* istanbul ignore next */ []));
2697
+ menuIcon = input('communication.inbox-01', ...(ngDevMode ? [{ debugName: "menuIcon" }] : /* istanbul ignore next */ []));
2698
+ lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
2699
+ showSidebar = input(true, ...(ngDevMode ? [{ debugName: "showSidebar" }] : /* istanbul ignore next */ []));
2700
+ bootstrapInputs = input(null, ...(ngDevMode ? [{ debugName: "bootstrapInputs" }] : /* istanbul ignore next */ []));
2701
+ openItemDrawer = input(false, ...(ngDevMode ? [{ debugName: "openItemDrawer" }] : /* istanbul ignore next */ []));
2702
+ itemReadOnly = input(false, ...(ngDevMode ? [{ debugName: "itemReadOnly" }] : /* istanbul ignore next */ []));
2703
+ openItemsInModal = input(true, ...(ngDevMode ? [{ debugName: "openItemsInModal" }] : /* istanbul ignore next */ []));
2704
+ itemModal = input(null, ...(ngDevMode ? [{ debugName: "itemModal" }] : /* istanbul ignore next */ []));
2705
+ generalTaskModal = input(null, ...(ngDevMode ? [{ debugName: "generalTaskModal" }] : /* istanbul ignore next */ []));
2706
+ runtimeFiltersChanged = output();
2707
+ itemClicked = output();
2708
+ cardSelected = output();
2709
+ context = this.facade.context;
2710
+ headerFilters = this.facade.headerFilters;
2711
+ tableFilters = signal({}, ...(ngDevMode ? [{ debugName: "tableFilters" }] : /* istanbul ignore next */ []));
2712
+ selectedItemContextKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedItemContextKey" }] : /* istanbul ignore next */ []));
2713
+ _menuItems = this.facade.menuItems;
2714
+ menuItems = computed(() => {
2715
+ this.activeLang();
2716
+ return this._menuItems().map((item) => ({
2717
+ ...item,
2718
+ subtitle: `${item.count} ${item.title}`,
2719
+ }));
2720
+ }, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
2721
+ rows = this.facade.rows;
2722
+ columns = this.facade.columns;
2723
+ kpis = this.facade.kpis;
2724
+ runtimeFilterSchema = this.facade.runtimeFilterSchema;
2725
+ totalCount = this.facade.totalCount;
2726
+ columnFilters = this.facade.columnFilters;
2727
+ loading = this.facade.loading;
2728
+ tableColumns = computed(() => this.columns().map((column) => ({
2729
+ ...column,
2730
+ sortable: true,
2731
+ })), ...(ngDevMode ? [{ debugName: "tableColumns" }] : /* istanbul ignore next */ []));
2732
+ /**
2733
+ * Maps each status/group display label to its total count from the KPI
2734
+ * summary cards so the group header shows the real backend total rather than
2735
+ * the current-page row count.
2736
+ */
2737
+ statusGroupCountMap = computed(() => {
2738
+ const map = new Map();
2739
+ for (const kpi of this.kpis()) {
2740
+ const label = kpi.subTitle;
2741
+ const count = Number(kpi.title);
2742
+ if (label && !isNaN(count)) {
2743
+ map.set(label, count);
2744
+ }
2745
+ }
2746
+ return map;
2747
+ }, ...(ngDevMode ? [{ debugName: "statusGroupCountMap" }] : /* istanbul ignore next */ []));
2748
+ propertyFilterSchema = computed(() => {
2749
+ this.activeLang();
2750
+ const schema = this.runtimeFilterSchema();
2751
+ if (schema) {
2752
+ const allowedFields = mapAllowedFields(schema);
2753
+ const allowedOperators = mapAllowedOperators(schema, (key) => this.getOpLabel(key));
2754
+ if (allowedFields.length && allowedOperators.length) {
2755
+ return { allowedFields, allowedOperators };
2756
+ }
2757
+ }
2758
+ const fallbackFields = this.columns()
2759
+ .filter((column) => typeof column?.key === 'string' && column.key.length > 0)
2760
+ .map((column) => ({
2761
+ key: column.key,
2762
+ label: column.label || toLabel(column.key),
2763
+ viewType: columnTypeToViewType(column.type),
2764
+ }));
2765
+ if (!fallbackFields.length) {
2766
+ return null;
2767
+ }
2768
+ const fallbackOperators = Object.keys(OPERATOR_LABELS).map((key) => ({
2769
+ key,
2770
+ label: this.getOpLabel(key),
2771
+ valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
2772
+ }));
2773
+ return {
2774
+ allowedFields: fallbackFields,
2775
+ allowedOperators: fallbackOperators,
2776
+ };
2777
+ }, ...(ngDevMode ? [{ debugName: "propertyFilterSchema" }] : /* istanbul ignore next */ []));
2778
+ showGeneralTaskCreateButton = computed(() => GENERAL_TASK_CARD_KEYS.has(normalizeCardKey(this.context().selectedCardKey)), ...(ngDevMode ? [{ debugName: "showGeneralTaskCreateButton" }] : /* istanbul ignore next */ []));
2779
+ generalTaskButtonLabel = computed(() => {
2780
+ this.activeLang();
2781
+ return (this.generalTaskModal()?.buttonLabel?.trim() ||
2782
+ this.transloco.translate('workCenter.page.new'));
2783
+ }, ...(ngDevMode ? [{ debugName: "generalTaskButtonLabel" }] : /* istanbul ignore next */ []));
2784
+ resolvedPageTitle = computed(() => {
2785
+ this.activeLang();
2786
+ return (this.pageTitle() ||
2787
+ this.transloco.translate('workCenter.page.title'));
2788
+ }, ...(ngDevMode ? [{ debugName: "resolvedPageTitle" }] : /* istanbul ignore next */ []));
2789
+ generalTaskButtonIcon = computed(() => this.generalTaskModal()?.buttonIcon?.trim() || 'general.plus', ...(ngDevMode ? [{ debugName: "generalTaskButtonIcon" }] : /* istanbul ignore next */ []));
2790
+ defaultModalStyleClass = '!w-[96vw] md:!w-[84vw] xl:!w-[70vw] !shadow-none';
2791
+ defaultGeneralTaskModalStyleClass = '!w-[70vw] !h-[90vh]';
2792
+ constructor() {
2793
+ this.transloco.langChanges$
2794
+ .pipe(takeUntilDestroyed(this.destroyRef))
2795
+ .subscribe((lang) => this.activeLang.set(lang));
2796
+ effect(() => {
2797
+ this.facade.setLookups(this.lookups());
2798
+ });
2799
+ effect(() => {
2800
+ const inputs = this.bootstrapInputs();
2801
+ if (inputs) {
2802
+ this.facade.setParams(this.area(), inputs);
2803
+ }
2804
+ });
2805
+ }
2806
+ onMenuItemClick(item) {
2807
+ if (item.key === this.context().selectedCardKey) {
2808
+ return;
2809
+ }
2810
+ this.facade.selectCardAndLoad(this.area(), item.key);
2811
+ this.cardSelected.emit(item.key);
2812
+ }
2813
+ onRuntimeFiltersApplied(filters) {
2814
+ const mappedFilters = filters.map((filter) => ({
2815
+ field: filter.field,
2816
+ op: filter.op,
2817
+ value: filter.value,
2818
+ values: filter.values,
2819
+ from: filter.from,
2820
+ to: filter.to,
2821
+ }));
2822
+ this.facade.applyHeaderFiltersAndLoad(this.area(), mappedFilters);
2823
+ this.runtimeFiltersChanged.emit(mappedFilters);
2824
+ }
2825
+ onRuntimeFiltersCleared() {
2826
+ this.facade.clearAllFiltersAndLoad(this.area());
2827
+ this.tableFilters.set({});
2828
+ this.runtimeFiltersChanged.emit([]);
2829
+ }
2830
+ /**
2831
+ * Single entry point for `mt-table` (`lazy=true`) — handles both column
2832
+ * filters and pagination/sort. Filter changes always reset the page to 1
2833
+ * (handled by `applyColumnFiltersAndLoad`); when only paging/sort changed
2834
+ * we fall through to `applyTableLazyLoadAndLoad`.
2835
+ */
2836
+ onTableLazyLoad(event) {
2837
+ const schema = this.runtimeFilterSchema();
2838
+ const propertyKeys = (schema?.properties ?? [])
2839
+ .map((p) => p?.key)
2840
+ .filter((k) => typeof k === 'string' && k.length > 0);
2841
+ const allowedKeys = schema?.allowedFields ?? [];
2842
+ const allowedFields = propertyKeys.length ? propertyKeys : allowedKeys;
2843
+ const nextColumnFilters = buildColumnRuntimeFilters(event?.filters, this.columns(), allowedFields.length ? allowedFields : undefined);
2844
+ if (!areFilterRulesEqual(nextColumnFilters, this.columnFilters())) {
2845
+ this.facade.applyColumnFiltersAndLoad(this.area(), nextColumnFilters);
2846
+ return;
2847
+ }
2848
+ this.facade.applyTableLazyLoadAndLoad(this.area(), event);
2849
+ }
2850
+ onGeneralTaskCreateClick() {
2851
+ const modalOptions = this.generalTaskModal();
2852
+ const modalData = {
2853
+ moduleKey: 'GeneralTask',
2854
+ ...(modalOptions?.data ?? {}),
2855
+ };
2856
+ const modalHeader = modalOptions?.header ??
2857
+ this.transloco.translate('workCenter.page.createGeneralTask');
2858
+ const modalStyleClass = modalOptions?.styleClass ?? this.defaultGeneralTaskModalStyleClass;
2859
+ const operationKey = modalOptions?.operationKey ?? 'Create';
2860
+ const closeOnPendingApproval = modalOptions?.closeOnPendingApproval ?? true;
2861
+ const lookups = modalOptions?.lookups ?? this.lookups();
2862
+ const ref = this.modal.openModal(WorkCenterClientFormModal, 'dialog', {
2863
+ header: modalHeader,
2864
+ styleClass: modalStyleClass,
2865
+ position: 'end',
2866
+ dismissableMask: true,
2867
+ inputValues: {
2868
+ data: modalData,
2869
+ operationKey,
2870
+ closeOnPendingApproval,
2871
+ lookups,
2872
+ },
2873
+ });
2874
+ ref.onClose.pipe(take(1)).subscribe((result) => {
2875
+ if (result) {
2876
+ this.facade.loadRuntime(this.area(), 'refresh');
2877
+ }
2878
+ });
2879
+ }
2880
+ onRowClick(row) {
2881
+ const contextKey = this.resolveRowContextKey(row);
2882
+ console.log('[work-center-debug] page row click', {
2883
+ contextKey,
2884
+ row,
2885
+ openItemsInModal: this.openItemsInModal(),
2886
+ hasModalComponent: !!this.itemModal()?.component,
2887
+ });
2888
+ if (!contextKey) {
2889
+ return;
2890
+ }
2891
+ this.itemClicked.emit(contextKey);
2892
+ if (this.openItemDrawer()) {
2893
+ this.selectedItemContextKey.set(contextKey);
2894
+ return;
2895
+ }
2896
+ if (!this.openItemsInModal()) {
2897
+ return;
2898
+ }
2899
+ const modalOptions = this.itemModal();
2900
+ if (!modalOptions?.component) {
2901
+ return;
2902
+ }
2903
+ const ref = this.modal.openModal(modalOptions.component, 'drawer', {
2904
+ header: modalOptions?.header ??
2905
+ this.transloco.translate('workCenter.page.itemDetails'),
2906
+ styleClass: modalOptions?.styleClass ?? this.defaultModalStyleClass,
2907
+ position: modalOptions?.position ?? 'end',
2908
+ dismissible: true,
2909
+ modal: true,
2910
+ ...(modalOptions?.appendTo ? { appendTo: modalOptions.appendTo } : {}),
2911
+ inputValues: { contextKey },
2912
+ });
2913
+ ref.onClose.pipe(take(1)).subscribe(() => {
2914
+ this.facade.loadRuntime(this.area(), 'refresh');
2915
+ });
2916
+ }
2917
+ rowsClickable = computed(() => this.openItemDrawer() || this.openItemsInModal(), ...(ngDevMode ? [{ debugName: "rowsClickable" }] : /* istanbul ignore next */ []));
2918
+ getOpLabel(key) {
2919
+ return (this.transloco.translate('workCenter.operator.' + key) ||
2920
+ OPERATOR_LABELS[key] ||
2921
+ toLabel(key));
2922
+ }
2923
+ resolveRowContextKey(row) {
2924
+ const value = row['contextKey'];
2925
+ if (typeof value !== 'string') {
2926
+ return null;
2927
+ }
2928
+ const normalized = value.trim();
2929
+ return normalized.length ? normalized : null;
2930
+ }
2931
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
2932
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", 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 }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, showSidebar: { classPropertyName: "showSidebar", publicName: "showSidebar", isSignal: true, isRequired: false, transformFunction: null }, bootstrapInputs: { classPropertyName: "bootstrapInputs", publicName: "bootstrapInputs", isSignal: true, isRequired: false, transformFunction: null }, openItemDrawer: { classPropertyName: "openItemDrawer", publicName: "openItemDrawer", isSignal: true, isRequired: false, transformFunction: null }, itemReadOnly: { classPropertyName: "itemReadOnly", publicName: "itemReadOnly", isSignal: true, isRequired: false, transformFunction: null }, openItemsInModal: { classPropertyName: "openItemsInModal", publicName: "openItemsInModal", isSignal: true, isRequired: false, transformFunction: null }, itemModal: { classPropertyName: "itemModal", publicName: "itemModal", isSignal: true, isRequired: false, transformFunction: null }, generalTaskModal: { classPropertyName: "generalTaskModal", publicName: "generalTaskModal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { runtimeFiltersChanged: "runtimeFiltersChanged", itemClicked: "itemClicked", cardSelected: "cardSelected" }, ngImport: i0, template: "<ng-template #headerActions>\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\n <mt-property-filter-builder\n [schema]=\"propertyFilterSchema()\"\n [filters]=\"headerFilters()\"\n (applied)=\"onRuntimeFiltersApplied($event)\"\n (cleared)=\"onRuntimeFiltersCleared()\"\n />\n\n @if (showGeneralTaskCreateButton()) {\n <mt-button\n [label]=\"generalTaskButtonLabel()\"\n [icon]=\"generalTaskButtonIcon()\"\n size=\"small\"\n (onClick)=\"onGeneralTaskCreateClick()\"\n />\n }\n </div>\n</ng-template>\n\n<ng-template #pageContent>\n <div class=\"flex flex-col gap-8\">\n @if (loading()) {\n <div\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\n >\n @for (_ of [1, 2, 3, 4, 5]; track $index) {\n <p-skeleton height=\"6.5rem\" class=\"rounded-lg\" />\n }\n </div>\n } @else if (kpis().length) {\n <div class=\"gap-3 flex flex-wrap\">\n @for (kpi of kpis(); track $index) {\n <mt-statistic-card [data]=\"kpi\" class=\"min-w-[200px]\" />\n }\n </div>\n }\n\n <mt-table\n noCard\n [data]=\"rows()\"\n [columns]=\"tableColumns()\"\n tableLayout=\"auto\"\n [clickableRows]=\"rowsClickable()\"\n [loading]=\"loading()\"\n [showFilters]=\"true\"\n filterMode=\"column\"\n [cellClickFilter]=\"true\"\n [generalSearch]=\"true\"\n [exportable]=\"true\"\n [printable]=\"true\"\n [groupable]=\"true\"\n [freezeActions]=\"true\"\n [lazy]=\"true\"\n [lazyLocalSearch]=\"true\"\n [lazyTotalRecords]=\"totalCount()\"\n [pageSize]=\"context().pageSize\"\n [currentPage]=\"context().page - 1\"\n [first]=\"(context().page - 1) * context().pageSize\"\n [rowsPerPageOptions]=\"[10, 20, 50, 100]\"\n [groupCountMap]=\"statusGroupCountMap()\"\n storageKey=\"work-center-page-table\"\n [filters]=\"tableFilters()\"\n (filtersChange)=\"tableFilters.set($event)\"\n (lazyLoad)=\"onTableLazyLoad($event)\"\n (rowClick)=\"onRowClick($event)\"\n />\n </div>\n</ng-template>\n\n@if (showSidebar()) {\n <mt-client-page\n [menuIcon]=\"menuIcon()\"\n [menuTitle]=\"resolvedPageTitle()\"\n [menuItems]=\"menuItems()\"\n [menuItemsLoading]=\"loading() && !menuItems().length\"\n [activeItem]=\"context().selectedCardKey ?? undefined\"\n storageKey=\"work-center-client-page\"\n (menuItemClick)=\"onMenuItemClick($event)\"\n >\n <ng-template #headerClientPageEnd>\n <ng-container [ngTemplateOutlet]=\"headerActions\" />\n </ng-template>\n\n <ng-container [ngTemplateOutlet]=\"pageContent\" />\n </mt-client-page>\n} @else {\n <div class=\"flex h-full min-h-0 flex-col bg-surface-0\">\n <div\n class=\"flex shrink-0 items-center justify-end border-b border-surface px-7 py-4\"\n >\n <ng-container [ngTemplateOutlet]=\"headerActions\" />\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto px-7 py-5\">\n <ng-container [ngTemplateOutlet]=\"pageContent\" />\n </div>\n </div>\n}\n\n@if (selectedItemContextKey(); as contextKey) {\n <mt-work-center-item-modal-route\n [contextKey]=\"contextKey\"\n [manageRouteOutlet]=\"false\"\n [showPreviewLevelAction]=\"false\"\n [readOnly]=\"itemReadOnly()\"\n appendTo=\"body\"\n drawerStyleClass=\"mt-work-center-item-drawer !w-[96vw] md:!w-[84vw] xl:!w-[70vw]\"\n (closed)=\"selectedItemContextKey.set(null)\"\n />\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ClientPage, selector: "mt-client-page", inputs: ["menuIcon", "menuTitle", "menuItems", "menuItemsLoading", "activeItem", "collapsed", "resizable", "storageKey", "storageMode", "minSidebarWidth", "maxSidebarWidth", "defaultSidebarWidth"], outputs: ["collapsedChange", "menuItemClick", "loadChildren"] }, { 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", "cardClass"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "filterMode", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "persistStateExclude", "exportable", "printable", "groupable", "groupCountMap", "cellClickFilter", "freezeActions", "virtualScroll", "virtualScrollItemSize", "scrollHeight", "printTitle", "exportFilename", "actionShape", "rowActionsLoadingFn", "tableLayout", "noCard", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "alwaysShowPaginator", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm", "groupBy"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "rowActionsRequested", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange", "groupByChange"] }, { kind: "component", type: WorkCenterItemModalRoute, selector: "mt-work-center-item-modal-route", inputs: ["contextKey", "manageRouteOutlet", "showPreviewLevelAction", "readOnly", "appendTo", "drawerStyleClass"], outputs: ["previewLevel", "closed"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }] });
2933
+ }
2934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: WorkCenterPage, decorators: [{
2935
+ type: Component,
2936
+ args: [{ selector: 'mt-work-center-page', standalone: true, imports: [
2937
+ CommonModule,
2938
+ Button,
2939
+ ClientPage,
2940
+ PropertyFilterBuilder,
2941
+ StatisticCard,
2942
+ Table,
2943
+ WorkCenterItemModalRoute,
2944
+ SkeletonModule,
2945
+ ], template: "<ng-template #headerActions>\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\n <mt-property-filter-builder\n [schema]=\"propertyFilterSchema()\"\n [filters]=\"headerFilters()\"\n (applied)=\"onRuntimeFiltersApplied($event)\"\n (cleared)=\"onRuntimeFiltersCleared()\"\n />\n\n @if (showGeneralTaskCreateButton()) {\n <mt-button\n [label]=\"generalTaskButtonLabel()\"\n [icon]=\"generalTaskButtonIcon()\"\n size=\"small\"\n (onClick)=\"onGeneralTaskCreateClick()\"\n />\n }\n </div>\n</ng-template>\n\n<ng-template #pageContent>\n <div class=\"flex flex-col gap-8\">\n @if (loading()) {\n <div\n class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-3\"\n >\n @for (_ of [1, 2, 3, 4, 5]; track $index) {\n <p-skeleton height=\"6.5rem\" class=\"rounded-lg\" />\n }\n </div>\n } @else if (kpis().length) {\n <div class=\"gap-3 flex flex-wrap\">\n @for (kpi of kpis(); track $index) {\n <mt-statistic-card [data]=\"kpi\" class=\"min-w-[200px]\" />\n }\n </div>\n }\n\n <mt-table\n noCard\n [data]=\"rows()\"\n [columns]=\"tableColumns()\"\n tableLayout=\"auto\"\n [clickableRows]=\"rowsClickable()\"\n [loading]=\"loading()\"\n [showFilters]=\"true\"\n filterMode=\"column\"\n [cellClickFilter]=\"true\"\n [generalSearch]=\"true\"\n [exportable]=\"true\"\n [printable]=\"true\"\n [groupable]=\"true\"\n [freezeActions]=\"true\"\n [lazy]=\"true\"\n [lazyLocalSearch]=\"true\"\n [lazyTotalRecords]=\"totalCount()\"\n [pageSize]=\"context().pageSize\"\n [currentPage]=\"context().page - 1\"\n [first]=\"(context().page - 1) * context().pageSize\"\n [rowsPerPageOptions]=\"[10, 20, 50, 100]\"\n [groupCountMap]=\"statusGroupCountMap()\"\n storageKey=\"work-center-page-table\"\n [filters]=\"tableFilters()\"\n (filtersChange)=\"tableFilters.set($event)\"\n (lazyLoad)=\"onTableLazyLoad($event)\"\n (rowClick)=\"onRowClick($event)\"\n />\n </div>\n</ng-template>\n\n@if (showSidebar()) {\n <mt-client-page\n [menuIcon]=\"menuIcon()\"\n [menuTitle]=\"resolvedPageTitle()\"\n [menuItems]=\"menuItems()\"\n [menuItemsLoading]=\"loading() && !menuItems().length\"\n [activeItem]=\"context().selectedCardKey ?? undefined\"\n storageKey=\"work-center-client-page\"\n (menuItemClick)=\"onMenuItemClick($event)\"\n >\n <ng-template #headerClientPageEnd>\n <ng-container [ngTemplateOutlet]=\"headerActions\" />\n </ng-template>\n\n <ng-container [ngTemplateOutlet]=\"pageContent\" />\n </mt-client-page>\n} @else {\n <div class=\"flex h-full min-h-0 flex-col bg-surface-0\">\n <div\n class=\"flex shrink-0 items-center justify-end border-b border-surface px-7 py-4\"\n >\n <ng-container [ngTemplateOutlet]=\"headerActions\" />\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto px-7 py-5\">\n <ng-container [ngTemplateOutlet]=\"pageContent\" />\n </div>\n </div>\n}\n\n@if (selectedItemContextKey(); as contextKey) {\n <mt-work-center-item-modal-route\n [contextKey]=\"contextKey\"\n [manageRouteOutlet]=\"false\"\n [showPreviewLevelAction]=\"false\"\n [readOnly]=\"itemReadOnly()\"\n appendTo=\"body\"\n drawerStyleClass=\"mt-work-center-item-drawer !w-[96vw] md:!w-[84vw] xl:!w-[70vw]\"\n (closed)=\"selectedItemContextKey.set(null)\"\n />\n}\n" }]
2946
+ }], ctorParameters: () => [], 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 }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], showSidebar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSidebar", required: false }] }], bootstrapInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "bootstrapInputs", required: false }] }], openItemDrawer: [{ type: i0.Input, args: [{ isSignal: true, alias: "openItemDrawer", required: false }] }], itemReadOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemReadOnly", required: false }] }], openItemsInModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "openItemsInModal", required: false }] }], itemModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemModal", required: false }] }], generalTaskModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "generalTaskModal", required: false }] }], runtimeFiltersChanged: [{ type: i0.Output, args: ["runtimeFiltersChanged"] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }], cardSelected: [{ type: i0.Output, args: ["cardSelected"] }] } });
2947
+
2888
2948
  const APP_STATES = [WorkCenterState];
2889
2949
 
2890
2950
  /**