@acorex-platform/module-risk-management-client 0.0.21

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.
@@ -0,0 +1,1089 @@
1
+ import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
2
+ import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, Injectable, NgModule, input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
5
+ import { RootConfig, AXPSafetyRiskPermissionKeys, AXMRiskManagementMenuKeys, RISK_CATALOG_SCOPE_HAZARD, RISK_CATALOG_SCOPE_PPE_ITEMS, RISK_MATRIX_AXIS_PROPERTIES, DEFAULT_RISK_MATRIX_AXIS_MAPPING, DEFAULT_RISK_MATRIX_ORIENTATION, RISK_MATRIX_ORIENTATION_TITLE_KEYS } from '@acorex-platform/module-risk-management-client/contracts';
6
+ import { AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
7
+ import { AXP_MENU_PROVIDER, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle } from '@acorex-platform/framework-client/common';
8
+ import { AXP_MODULE_MANIFEST_PROVIDER, AXP_CATALOG_SCOPE_DEFINITION_PROVIDER, provideLazyProvider } from '@acorex-platform/framework-client/core';
9
+ import { AXP_WIDGETS_EDITOR_CATEGORY, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER, AXPColumnWidgetComponent, AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';
10
+ import { provideCommandSetups } from '@acorex-platform/framework-client/runtime';
11
+ import { AXPWidgetGroupEnum } from '@acorex-platform/framework-shared/widget-core';
12
+ import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_LABEL_PROPERTY, AXP_READONLY_PROPERTY, AXP_DISABLED_PROPERTY } from '@acorex-platform/framework-client/layout/widgets';
13
+ import * as i2 from '@acorex/core/translation';
14
+ import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
15
+ import { extractValue, AXPWidgetsList } from '@acorex-platform/framework-shared/core';
16
+ import { AXPSpreadsheetComponent } from '@acorex-platform/framework-client/layout/components';
17
+ import * as i1 from '@angular/common';
18
+ import { CommonModule } from '@angular/common';
19
+ import { isEmpty, defaultTo, get, isEqual, castArray } from 'lodash';
20
+ import { AXPLayoutBuilderService } from '@acorex-platform/framework-client/layout/builder';
21
+ import * as i1$1 from '@acorex/components/button';
22
+ import { AXButtonModule } from '@acorex/components/button';
23
+ import * as i2$1 from '@acorex/components/decorators';
24
+ import { AXDecoratorModule } from '@acorex/components/decorators';
25
+ import { AXFormatService } from '@acorex/core/format';
26
+
27
+ //#region ---- Imports ----
28
+ //#endregion
29
+ //#region ---- Menu provider ----
30
+ class AXMRiskManagementMenuProvider {
31
+ constructor() {
32
+ this.entityService = inject(AXPEntityService);
33
+ }
34
+ async provide(context) {
35
+ const module = RootConfig.module;
36
+ const entities = RootConfig.entities;
37
+ const keys = AXPSafetyRiskPermissionKeys;
38
+ context.find(AXPCommonMenuKeys.Configuration).addItems([
39
+ {
40
+ name: AXMRiskManagementMenuKeys.Root,
41
+ priority: 8950,
42
+ text: `@${RootConfig.config.i18n}:module.menus.risk`,
43
+ icon: module.icon,
44
+ type: 'menu',
45
+ policy: {
46
+ features: [module.name],
47
+ },
48
+ children: [
49
+ {
50
+ name: AXMRiskManagementMenuKeys.RiskMatrixCells,
51
+ text: entities.riskMatrixCell.titlePlural,
52
+ icon: entities.riskMatrixCell.icon,
53
+ priority: 1,
54
+ path: this.entityService.createPath(module.name, entities.riskMatrixCell.name),
55
+ policy: {
56
+ permissions: [keys.MaintainRisk],
57
+ },
58
+ },
59
+ {
60
+ name: AXMRiskManagementMenuKeys.RiskLikelihoods,
61
+ text: entities.riskLikelihood.titlePlural,
62
+ icon: entities.riskLikelihood.icon,
63
+ priority: 2,
64
+ path: this.entityService.createPath(module.name, entities.riskLikelihood.name),
65
+ policy: {
66
+ permissions: [keys.Setup],
67
+ },
68
+ },
69
+ {
70
+ name: AXMRiskManagementMenuKeys.RiskSeverities,
71
+ text: entities.riskSeverity.titlePlural,
72
+ icon: entities.riskSeverity.icon,
73
+ priority: 3,
74
+ path: this.entityService.createPath(module.name, entities.riskSeverity.name),
75
+ policy: {
76
+ permissions: [keys.Setup],
77
+ },
78
+ },
79
+ {
80
+ name: AXMRiskManagementMenuKeys.RiskRatings,
81
+ text: entities.riskRating.titlePlural,
82
+ icon: entities.riskRating.icon,
83
+ priority: 4,
84
+ path: this.entityService.createPath(module.name, entities.riskRating.name),
85
+ policy: {
86
+ permissions: [keys.Setup],
87
+ },
88
+ },
89
+ ],
90
+ },
91
+ ]);
92
+ }
93
+ }
94
+ //#endregion
95
+
96
+ var menu_provider = /*#__PURE__*/Object.freeze({
97
+ __proto__: null,
98
+ AXMRiskManagementMenuProvider: AXMRiskManagementMenuProvider
99
+ });
100
+
101
+ //#endregion
102
+ //#region ---- Permission Definition Provider ----
103
+ /**
104
+ * Registers risk capabilities into the shared Safety & Risk group.
105
+ */
106
+ class AXMRiskManagementPermissionDefinitionProvider {
107
+ async define(context) {
108
+ const keys = AXPSafetyRiskPermissionKeys;
109
+ const groups = AXPCommonPermissionGroupKeys;
110
+ const P = '@common:safety-risk.permissions';
111
+ const G = '@common:permission-groups';
112
+ context.addGroup(groups.SafetyRisk.Root, `${G}.safety-risk.title`, `${G}.safety-risk.description`, { order: 30 });
113
+ context
114
+ .addGroup(groups.SafetyRisk.Risk, `${G}.safety-risk-risk.title`, `${G}.safety-risk-risk.description`, { parent: groups.SafetyRisk.Root, order: 20 })
115
+ .addPermission(keys.MaintainRisk, `${P}.maintain-risk.title`, `${P}.maintain-risk.description`)
116
+ .endPermission()
117
+ .endGroup();
118
+ }
119
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementPermissionDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
120
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementPermissionDefinitionProvider }); }
121
+ }
122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementPermissionDefinitionProvider, decorators: [{
123
+ type: Injectable
124
+ }] });
125
+
126
+ var permissionDefinition_provider = /*#__PURE__*/Object.freeze({
127
+ __proto__: null,
128
+ AXMRiskManagementPermissionDefinitionProvider: AXMRiskManagementPermissionDefinitionProvider
129
+ });
130
+
131
+ //#region ---- Imports ----
132
+ //#endregion
133
+ //#region ---- Manifest Definition ----
134
+ /**
135
+ * Risk Management module manifest.
136
+ */
137
+ const RiskManagementManifest = {
138
+ name: RootConfig.module.name,
139
+ version: '1.0.0',
140
+ title: RootConfig.module.title,
141
+ icon: RootConfig.module.icon,
142
+ i18n: RootConfig.config.i18n,
143
+ type: 'domain',
144
+ domain: 'workplace-safety',
145
+ required: false,
146
+ };
147
+ //#endregion
148
+
149
+ //#endregion
150
+ //#region ---- Constants ----
151
+ const RISK_MATRIX_CELL = `${RootConfig.module.name}.${RootConfig.entities.riskMatrixCell.name}`;
152
+ const RISK_MATRIX_CELL_CATALOG_TARGETS = [RISK_MATRIX_CELL];
153
+ //#endregion
154
+ //#region ---- Provider ----
155
+ class AXMRiskManagementCatalogScopeDefinitionProvider {
156
+ async items() {
157
+ return [
158
+ {
159
+ name: RISK_CATALOG_SCOPE_HAZARD,
160
+ title: '@risk-management:catalog-scopes.hazard.title',
161
+ description: '@risk-management:catalog-scopes.hazard.description',
162
+ targets: [...RISK_MATRIX_CELL_CATALOG_TARGETS],
163
+ icon: 'fa-light fa-triangle-exclamation',
164
+ cssClass: 'warning-lighter-surface',
165
+ order: 20,
166
+ },
167
+ {
168
+ name: RISK_CATALOG_SCOPE_PPE_ITEMS,
169
+ title: '@risk-management:catalog-scopes.ppe-items.title',
170
+ description: '@risk-management:catalog-scopes.ppe-items.description',
171
+ targets: [...RISK_MATRIX_CELL_CATALOG_TARGETS],
172
+ icon: 'fa-light fa-helmet-safety',
173
+ cssClass: 'info-lighter-surface',
174
+ order: 21,
175
+ },
176
+ ];
177
+ }
178
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementCatalogScopeDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
179
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementCatalogScopeDefinitionProvider }); }
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementCatalogScopeDefinitionProvider, decorators: [{
182
+ type: Injectable
183
+ }] });
184
+
185
+ //#region ---- Imports ----
186
+ //#endregion
187
+ //#region ---- Widget Config ----
188
+ const AXMRiskMatrixWidget = {
189
+ name: 'risk-matrix-editor',
190
+ title: 'Risk Matrix',
191
+ categories: AXP_WIDGETS_EDITOR_CATEGORY,
192
+ groups: [AXPWidgetGroupEnum.UtilityWidget],
193
+ description: 'Matrix widget for mapping likelihood and severity combinations to risk ratings',
194
+ icon: 'fa-light fa-table-cells',
195
+ type: 'editor',
196
+ options: {
197
+ needLabel: false,
198
+ },
199
+ properties: [
200
+ AXP_NAME_PROPERTY,
201
+ AXP_DATA_PATH_PROPERTY,
202
+ AXP_LABEL_PROPERTY,
203
+ AXP_READONLY_PROPERTY,
204
+ AXP_DISABLED_PROPERTY,
205
+ ],
206
+ components: {
207
+ view: {
208
+ component: () => Promise.resolve().then(function () { return riskMatrixWidgetView_component; }).then((c) => c.AXMRiskMatrixWidgetViewComponent),
209
+ },
210
+ edit: {
211
+ component: () => Promise.resolve().then(function () { return riskMatrixWidgetEdit_component; }).then((c) => c.AXMRiskMatrixWidgetEditComponent),
212
+ },
213
+ column: {
214
+ component: () => Promise.resolve().then(function () { return riskMatrixWidgetColumn_component; }).then((c) => c.AXMRiskMatrixWidgetColumnComponent),
215
+ },
216
+ },
217
+ };
218
+ //#endregion
219
+
220
+ //#endregion
221
+ //#region ---- Risk Management Widgets Provider ----
222
+ class AXMRiskManagementWidgetsProvider {
223
+ getWidgets() {
224
+ return [AXMRiskMatrixWidget];
225
+ }
226
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementWidgetsProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
227
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementWidgetsProvider }); }
228
+ }
229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementWidgetsProvider, decorators: [{
230
+ type: Injectable
231
+ }] });
232
+
233
+ //#region ---- Imports ----
234
+ //#endregion
235
+ //#region ---- Module ----
236
+ class AXMRiskManagementModule {
237
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
238
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementModule, imports: [AXPWidgetCoreModule] }); }
239
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementModule, providers: [
240
+ {
241
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
242
+ useValue: RiskManagementManifest,
243
+ multi: true,
244
+ },
245
+ provideLazyProvider(AXP_PERMISSION_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return permissionDefinition_provider; }).then((m) => m.AXMRiskManagementPermissionDefinitionProvider)),
246
+ provideLazyProvider(AXP_MENU_PROVIDER, () => Promise.resolve().then(function () { return menu_provider; }).then((m) => m.AXMRiskManagementMenuProvider)),
247
+ {
248
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
249
+ useClass: AXMRiskManagementWidgetsProvider,
250
+ multi: true,
251
+ },
252
+ {
253
+ provide: AXP_CATALOG_SCOPE_DEFINITION_PROVIDER,
254
+ useClass: AXMRiskManagementCatalogScopeDefinitionProvider,
255
+ multi: true,
256
+ },
257
+ provideCommandSetups([
258
+ {
259
+ key: `${RootConfig.module.name}.${RootConfig.entities.riskMatrixCell.name}:Preview`,
260
+ command: () => import('./acorex-platform-module-risk-management-client-preview-risk-matrix-cell.command-CTGIFUIa.mjs').then((c) => c.AXMPreviewRiskMatrixCellCommand),
261
+ },
262
+ ]),
263
+ ], imports: [AXPWidgetCoreModule] }); }
264
+ }
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementModule, decorators: [{
266
+ type: NgModule,
267
+ args: [{
268
+ imports: [
269
+ AXPWidgetCoreModule,
270
+ ],
271
+ providers: [
272
+ {
273
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
274
+ useValue: RiskManagementManifest,
275
+ multi: true,
276
+ },
277
+ provideLazyProvider(AXP_PERMISSION_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return permissionDefinition_provider; }).then((m) => m.AXMRiskManagementPermissionDefinitionProvider)),
278
+ provideLazyProvider(AXP_MENU_PROVIDER, () => Promise.resolve().then(function () { return menu_provider; }).then((m) => m.AXMRiskManagementMenuProvider)),
279
+ {
280
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
281
+ useClass: AXMRiskManagementWidgetsProvider,
282
+ multi: true,
283
+ },
284
+ {
285
+ provide: AXP_CATALOG_SCOPE_DEFINITION_PROVIDER,
286
+ useClass: AXMRiskManagementCatalogScopeDefinitionProvider,
287
+ multi: true,
288
+ },
289
+ provideCommandSetups([
290
+ {
291
+ key: `${RootConfig.module.name}.${RootConfig.entities.riskMatrixCell.name}:Preview`,
292
+ command: () => import('./acorex-platform-module-risk-management-client-preview-risk-matrix-cell.command-CTGIFUIa.mjs').then((c) => c.AXMPreviewRiskMatrixCellCommand),
293
+ },
294
+ ]),
295
+ ],
296
+ }]
297
+ }] });
298
+
299
+ //#region ---- Imports ----
300
+ //#endregion
301
+ //#region ---- Helpers ----
302
+ function isRiskMatrixAxisProperty(value) {
303
+ return typeof value === 'string' && RISK_MATRIX_AXIS_PROPERTIES.includes(value);
304
+ }
305
+ function resolveRiskMatrixAxisMapping(mapping) {
306
+ const rowProperty = isRiskMatrixAxisProperty(mapping?.rowProperty)
307
+ ? mapping.rowProperty
308
+ : DEFAULT_RISK_MATRIX_AXIS_MAPPING.rowProperty;
309
+ const columnProperty = isRiskMatrixAxisProperty(mapping?.columnProperty)
310
+ ? mapping.columnProperty
311
+ : DEFAULT_RISK_MATRIX_AXIS_MAPPING.columnProperty;
312
+ const depthProperty = isRiskMatrixAxisProperty(mapping?.depthProperty)
313
+ ? mapping.depthProperty
314
+ : DEFAULT_RISK_MATRIX_AXIS_MAPPING.depthProperty;
315
+ if (validateRiskMatrixAxisMapping({ rowProperty, columnProperty, depthProperty })) {
316
+ return { rowProperty, columnProperty, depthProperty };
317
+ }
318
+ return { ...DEFAULT_RISK_MATRIX_AXIS_MAPPING };
319
+ }
320
+ function isRiskMatrixOrientation(value) {
321
+ return value === 'likelihood-rows' || value === 'severity-rows';
322
+ }
323
+ /**
324
+ * Normalizes orientation from persisted strings or SelectionList row objects (`{ id }`).
325
+ */
326
+ function resolveRiskMatrixOrientation(value) {
327
+ const candidate = extractValue(value, 'id') ?? value;
328
+ return isRiskMatrixOrientation(candidate) ? candidate : DEFAULT_RISK_MATRIX_ORIENTATION;
329
+ }
330
+ /** Translation key for the spreadsheet corner title (`row axis / column axis`). */
331
+ function resolveRiskMatrixTitleKey(orientation) {
332
+ return RISK_MATRIX_ORIENTATION_TITLE_KEYS[resolveRiskMatrixOrientation(orientation)];
333
+ }
334
+ function pickDefinedAxisMapping(mapping) {
335
+ if (!mapping) {
336
+ return {};
337
+ }
338
+ const picked = {};
339
+ if (isRiskMatrixAxisProperty(mapping.rowProperty)) {
340
+ picked.rowProperty = mapping.rowProperty;
341
+ }
342
+ if (isRiskMatrixAxisProperty(mapping.columnProperty)) {
343
+ picked.columnProperty = mapping.columnProperty;
344
+ }
345
+ if (isRiskMatrixAxisProperty(mapping.depthProperty)) {
346
+ picked.depthProperty = mapping.depthProperty;
347
+ }
348
+ return picked;
349
+ }
350
+ function resolveRiskMatrixAxisMappingFromOrientation(orientation, mapping) {
351
+ const resolvedOrientation = resolveRiskMatrixOrientation(orientation);
352
+ const orientationMapping = resolvedOrientation === 'severity-rows'
353
+ ? { rowProperty: 'severityId', columnProperty: 'likelihoodId', depthProperty: 'riskRatingId' }
354
+ : { rowProperty: 'likelihoodId', columnProperty: 'severityId', depthProperty: 'riskRatingId' };
355
+ return resolveRiskMatrixAxisMapping({
356
+ ...pickDefinedAxisMapping(mapping),
357
+ ...orientationMapping,
358
+ });
359
+ }
360
+ /**
361
+ * Persisted matrix shape is always likelihood × severity → risk rating.
362
+ * Transpose only for display when severity is shown as rows.
363
+ */
364
+ function toDisplayMatrixData(canonical, orientation) {
365
+ if (resolveRiskMatrixOrientation(orientation) === 'likelihood-rows') {
366
+ return canonical;
367
+ }
368
+ const display = {};
369
+ Object.entries(canonical).forEach(([likelihoodId, severityMap]) => {
370
+ if (!severityMap) {
371
+ return;
372
+ }
373
+ Object.entries(severityMap).forEach(([severityId, ratingId]) => {
374
+ display[severityId] ??= {};
375
+ display[severityId][likelihoodId] = ratingId;
376
+ });
377
+ });
378
+ return display;
379
+ }
380
+ /** Converts display-oriented matrix data back to canonical likelihood × severity storage. */
381
+ function toCanonicalMatrixData(display, orientation) {
382
+ if (resolveRiskMatrixOrientation(orientation) === 'likelihood-rows') {
383
+ return display;
384
+ }
385
+ const canonical = {};
386
+ Object.entries(display).forEach(([severityId, likelihoodMap]) => {
387
+ if (!likelihoodMap) {
388
+ return;
389
+ }
390
+ Object.entries(likelihoodMap).forEach(([likelihoodId, ratingId]) => {
391
+ canonical[likelihoodId] ??= {};
392
+ canonical[likelihoodId][severityId] = ratingId;
393
+ });
394
+ });
395
+ return canonical;
396
+ }
397
+ /** Normalizes lookup axis values (ids or `{ id }` rows) to string ids. */
398
+ function normalizeRiskMatrixAxisIds(value) {
399
+ const items = Array.isArray(value) ? value : value != null ? [value] : [];
400
+ return items
401
+ .map((item) => {
402
+ if (item != null && typeof item === 'object' && 'id' in item) {
403
+ return String(item.id);
404
+ }
405
+ return item != null ? String(item) : '';
406
+ })
407
+ .filter((id) => id.length > 0);
408
+ }
409
+ /**
410
+ * Drops matrix entries for axes no longer selected on the record.
411
+ * Persisted shape stays likelihood × severity → risk rating.
412
+ */
413
+ function pruneMatrixToAxes(matrix, likelihoodIds, severityIds) {
414
+ const likelihoodSet = new Set(likelihoodIds);
415
+ const severitySet = new Set(severityIds);
416
+ const pruned = {};
417
+ Object.entries(matrix ?? {}).forEach(([likelihoodId, severityMap]) => {
418
+ if (!likelihoodSet.has(likelihoodId) || severityMap == null) {
419
+ return;
420
+ }
421
+ const row = {};
422
+ Object.entries(severityMap).forEach(([severityId, ratingId]) => {
423
+ if (severitySet.has(severityId)) {
424
+ row[severityId] = ratingId;
425
+ }
426
+ });
427
+ if (Object.keys(row).length > 0) {
428
+ pruned[likelihoodId] = row;
429
+ }
430
+ });
431
+ return pruned;
432
+ }
433
+ function validateRiskMatrixAxisMapping(mapping) {
434
+ const rowProperty = mapping.rowProperty;
435
+ const columnProperty = mapping.columnProperty;
436
+ const depthProperty = mapping.depthProperty;
437
+ if (!isRiskMatrixAxisProperty(rowProperty)) {
438
+ return false;
439
+ }
440
+ if (!isRiskMatrixAxisProperty(columnProperty)) {
441
+ return false;
442
+ }
443
+ if (!isRiskMatrixAxisProperty(depthProperty)) {
444
+ return false;
445
+ }
446
+ const values = [rowProperty, columnProperty, depthProperty];
447
+ return new Set(values).size === values.length;
448
+ }
449
+ //#endregion
450
+
451
+ //#region ---- Constants ----
452
+ /** Default matrix badge colors when {@link color} is not set on a risk rating record. */
453
+ const DEFAULT_RISK_RATING_BADGE_COLORS = {
454
+ low: 'warning-lighter-surface',
455
+ medium: 'success-lighter-surface',
456
+ high: 'danger-lighter-surface',
457
+ };
458
+ //#endregion
459
+ //#region ---- Helpers ----
460
+ function resolveRiskRatingBadgeColor(rating) {
461
+ const color = rating.color?.trim();
462
+ if (color) {
463
+ return color;
464
+ }
465
+ const code = rating.code?.trim().toUpperCase();
466
+ if (code?.endsWith('0001')) {
467
+ return DEFAULT_RISK_RATING_BADGE_COLORS.low;
468
+ }
469
+ if (code?.endsWith('0002')) {
470
+ return DEFAULT_RISK_RATING_BADGE_COLORS.medium;
471
+ }
472
+ if (code?.endsWith('0003')) {
473
+ return DEFAULT_RISK_RATING_BADGE_COLORS.high;
474
+ }
475
+ const title = rating.title?.trim().toLowerCase();
476
+ if (title === 'low') {
477
+ return DEFAULT_RISK_RATING_BADGE_COLORS.low;
478
+ }
479
+ if (title === 'medium') {
480
+ return DEFAULT_RISK_RATING_BADGE_COLORS.medium;
481
+ }
482
+ if (title === 'high') {
483
+ return DEFAULT_RISK_RATING_BADGE_COLORS.high;
484
+ }
485
+ return undefined;
486
+ }
487
+ //#endregion
488
+
489
+ //#region ---- Imports ----
490
+ //#endregion
491
+ //#region ---- Component Definition ----
492
+ class AXMRiskManagementRiskMatrixComponent {
493
+ //#endregion
494
+ //#region ---- Lifecycle Methods ----
495
+ constructor() {
496
+ //#endregion
497
+ //#region ---- Services & Dependencies ----
498
+ this.entityService = inject(AXPEntityService);
499
+ this.likelihoodDataAccessor = this.entityService
500
+ .withEntity(RootConfig.module.name, RootConfig.entities.riskLikelihood.name)
501
+ .data();
502
+ this.severityDataAccessor = this.entityService
503
+ .withEntity(RootConfig.module.name, RootConfig.entities.riskSeverity.name)
504
+ .data();
505
+ this.riskRatingDataAccessor = this.entityService
506
+ .withEntity(RootConfig.module.name, RootConfig.entities.riskRating.name)
507
+ .data();
508
+ this.multiLanguageResolver = inject(AXTranslationService);
509
+ //#endregion
510
+ //#region ---- Inputs ----
511
+ /** Axis mapping. Defaults to likelihood × severity → risk rating. */
512
+ this.axisMapping = input({}, /* @ts-ignore */
513
+ ...(ngDevMode ? [{ debugName: "axisMapping" }] : /* istanbul ignore next */ []));
514
+ /** Selected axis item ids from the parent matrix record. */
515
+ this.likelihoodIds = input(null, /* @ts-ignore */
516
+ ...(ngDevMode ? [{ debugName: "likelihoodIds" }] : /* istanbul ignore next */ []));
517
+ this.severityIds = input(null, /* @ts-ignore */
518
+ ...(ngDevMode ? [{ debugName: "severityIds" }] : /* istanbul ignore next */ []));
519
+ /** Controls row/column layout only; persisted matrix stays likelihood × severity. */
520
+ this.matrixOrientation = input(null, /* @ts-ignore */
521
+ ...(ngDevMode ? [{ debugName: "matrixOrientation" }] : /* istanbul ignore next */ []));
522
+ /** Matrix data: { [likelihoodId]: { [severityId]: riskRatingId } } */
523
+ this.value = input({}, /* @ts-ignore */
524
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
525
+ this.readonly = input(false, /* @ts-ignore */
526
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
527
+ //#endregion
528
+ //#region ---- Outputs ----
529
+ this.valueChange = output();
530
+ this.cellChange = output();
531
+ //#endregion
532
+ //#region ---- Class Properties ----
533
+ this.likelihoodItems = signal([], /* @ts-ignore */
534
+ ...(ngDevMode ? [{ debugName: "likelihoodItems" }] : /* istanbul ignore next */ []));
535
+ this.severityItems = signal([], /* @ts-ignore */
536
+ ...(ngDevMode ? [{ debugName: "severityItems" }] : /* istanbul ignore next */ []));
537
+ this.depthItems = signal([], /* @ts-ignore */
538
+ ...(ngDevMode ? [{ debugName: "depthItems" }] : /* istanbul ignore next */ []));
539
+ this.hasLoadedAxesOnce = signal(false, /* @ts-ignore */
540
+ ...(ngDevMode ? [{ debugName: "hasLoadedAxesOnce" }] : /* istanbul ignore next */ []));
541
+ this.isLoading = signal(false, /* @ts-ignore */
542
+ ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
543
+ //#endregion
544
+ //#region ---- Computed Properties ----
545
+ this.resolvedMatrixOrientation = computed(() => resolveRiskMatrixOrientation(this.matrixOrientation()), /* @ts-ignore */
546
+ ...(ngDevMode ? [{ debugName: "resolvedMatrixOrientation" }] : /* istanbul ignore next */ []));
547
+ this.resolvedAxisMapping = computed(() => resolveRiskMatrixAxisMappingFromOrientation(this.resolvedMatrixOrientation(), this.axisMapping()), /* @ts-ignore */
548
+ ...(ngDevMode ? [{ debugName: "resolvedAxisMapping" }] : /* istanbul ignore next */ []));
549
+ this.displayMatrix = computed(() => toDisplayMatrixData(this.value(), this.resolvedMatrixOrientation()), /* @ts-ignore */
550
+ ...(ngDevMode ? [{ debugName: "displayMatrix" }] : /* istanbul ignore next */ []));
551
+ this.matrixTitleKey = computed(() => resolveRiskMatrixTitleKey(this.resolvedMatrixOrientation()), /* @ts-ignore */
552
+ ...(ngDevMode ? [{ debugName: "matrixTitleKey" }] : /* istanbul ignore next */ []));
553
+ this.verticalTitles = computed(() => this.toSpreadsheetItems(this.resolvedRowItems()), /* @ts-ignore */
554
+ ...(ngDevMode ? [{ debugName: "verticalTitles" }] : /* istanbul ignore next */ []));
555
+ this.horizontalTitles = computed(() => this.toSpreadsheetItems(this.resolvedColumnItems()), /* @ts-ignore */
556
+ ...(ngDevMode ? [{ debugName: "horizontalTitles" }] : /* istanbul ignore next */ []));
557
+ this.cellOptions = computed(() => this.toSpreadsheetItems(this.depthItems()), /* @ts-ignore */
558
+ ...(ngDevMode ? [{ debugName: "cellOptions" }] : /* istanbul ignore next */ []));
559
+ this.resolvedRowItems = computed(() => {
560
+ const mapping = this.resolvedAxisMapping();
561
+ return mapping.rowProperty === 'likelihoodId' ? this.likelihoodItems() : this.severityItems();
562
+ }, /* @ts-ignore */
563
+ ...(ngDevMode ? [{ debugName: "resolvedRowItems" }] : /* istanbul ignore next */ []));
564
+ this.resolvedColumnItems = computed(() => {
565
+ const mapping = this.resolvedAxisMapping();
566
+ return mapping.columnProperty === 'likelihoodId' ? this.likelihoodItems() : this.severityItems();
567
+ }, /* @ts-ignore */
568
+ ...(ngDevMode ? [{ debugName: "resolvedColumnItems" }] : /* istanbul ignore next */ []));
569
+ this.spreadsheetColumns = computed(() => {
570
+ const horizontalTitles = this.horizontalTitles();
571
+ const ratingItems = this.depthItems();
572
+ const cellOptions = this.toSpreadsheetItems(ratingItems);
573
+ const selectBoxWidget = {
574
+ type: AXPWidgetsList.Editors.SelectBox,
575
+ options: {
576
+ valueField: 'id',
577
+ textField: 'title',
578
+ cssClassField: 'color',
579
+ dataSource: cellOptions.map((option, index) => ({
580
+ id: option.id,
581
+ title: option.title,
582
+ description: option.description,
583
+ color: ratingItems[index]?.color,
584
+ })),
585
+ },
586
+ };
587
+ return horizontalTitles.map((title) => ({
588
+ name: title.id,
589
+ title: title.title,
590
+ description: title.description,
591
+ path: title.id,
592
+ widget: selectBoxWidget,
593
+ }));
594
+ }, /* @ts-ignore */
595
+ ...(ngDevMode ? [{ debugName: "spreadsheetColumns" }] : /* istanbul ignore next */ []));
596
+ this.spreadsheetRows = computed(() => {
597
+ const verticalTitles = this.verticalTitles();
598
+ const horizontalTitles = this.horizontalTitles();
599
+ const matrixData = this.displayMatrix();
600
+ return verticalTitles.map((row) => {
601
+ const rowData = {
602
+ name: row.id,
603
+ _rowTitle: row.title,
604
+ _rowDescription: row.description,
605
+ };
606
+ horizontalTitles.forEach((column) => {
607
+ rowData[column.id] = matrixData[row.id]?.[column.id] ?? null;
608
+ });
609
+ return rowData;
610
+ });
611
+ }, /* @ts-ignore */
612
+ ...(ngDevMode ? [{ debugName: "spreadsheetRows" }] : /* istanbul ignore next */ []));
613
+ effect(() => {
614
+ const likelihoodIds = this.likelihoodIds();
615
+ const severityIds = this.severityIds();
616
+ void this.loadMatrixAxes(likelihoodIds, severityIds);
617
+ });
618
+ }
619
+ //#endregion
620
+ //#region ---- Data Loading Methods ----
621
+ async loadMatrixAxes(likelihoodIds, severityIds) {
622
+ const isInitialLoad = !this.hasLoadedAxesOnce();
623
+ try {
624
+ if (isInitialLoad) {
625
+ this.isLoading.set(true);
626
+ }
627
+ const query = {
628
+ skip: 0,
629
+ take: 1000,
630
+ sort: [{ field: 'levelValue', dir: 'asc' }],
631
+ };
632
+ const [likelihoodResult, severityResult, depthResult] = await Promise.all([
633
+ this.queryAxisItems('likelihoodId', query, likelihoodIds),
634
+ this.queryAxisItems('severityId', query, severityIds),
635
+ this.queryAxisItems('riskRatingId', query),
636
+ ]);
637
+ this.likelihoodItems.set(likelihoodResult);
638
+ this.severityItems.set(severityResult);
639
+ this.depthItems.set(depthResult);
640
+ this.hasLoadedAxesOnce.set(true);
641
+ }
642
+ catch (error) {
643
+ console.error('Error loading risk matrix axes:', error);
644
+ this.likelihoodItems.set([]);
645
+ this.severityItems.set([]);
646
+ this.depthItems.set([]);
647
+ }
648
+ finally {
649
+ if (isInitialLoad) {
650
+ this.isLoading.set(false);
651
+ }
652
+ }
653
+ }
654
+ async queryAxisItems(property, query, selectedIds) {
655
+ const accessor = this.getAxisDataAccessor(property);
656
+ const result = await accessor.query(query);
657
+ const items = (result.items ?? []).map((item) => {
658
+ const base = {
659
+ id: item.id,
660
+ title: item.title,
661
+ description: item.description,
662
+ };
663
+ if (property !== 'riskRatingId') {
664
+ return base;
665
+ }
666
+ const rating = item;
667
+ const color = resolveRiskRatingBadgeColor(rating);
668
+ return color ? { ...base, color } : base;
669
+ });
670
+ if (isEmpty(selectedIds)) {
671
+ return items;
672
+ }
673
+ const selectedIdSet = new Set(selectedIds);
674
+ return items.filter((item) => selectedIdSet.has(item.id));
675
+ }
676
+ getAxisDataAccessor(property) {
677
+ switch (property) {
678
+ case 'severityId':
679
+ return this.severityDataAccessor;
680
+ case 'riskRatingId':
681
+ return this.riskRatingDataAccessor;
682
+ case 'likelihoodId':
683
+ default:
684
+ return this.likelihoodDataAccessor;
685
+ }
686
+ }
687
+ //#endregion
688
+ //#region ---- Data Transformation Methods ----
689
+ toSpreadsheetItems(items) {
690
+ const resolve = (v) => this.multiLanguageResolver.resolve(v);
691
+ return items.map((item) => ({
692
+ id: item.id,
693
+ title: resolve(item.title),
694
+ description: item.description ? resolve(item.description) : undefined,
695
+ }));
696
+ }
697
+ convertSpreadsheetRowsToMatrixData(rows) {
698
+ const horizontalTitles = this.horizontalTitles();
699
+ const matrixData = {};
700
+ rows.forEach((row) => {
701
+ const rowId = row['name'];
702
+ if (!rowId) {
703
+ return;
704
+ }
705
+ matrixData[rowId] = {};
706
+ horizontalTitles.forEach((column) => {
707
+ matrixData[rowId][column.id] = row[column.id] ?? null;
708
+ });
709
+ });
710
+ return matrixData;
711
+ }
712
+ //#endregion
713
+ //#region ---- Event Handlers ----
714
+ handleSpreadsheetChange(rows) {
715
+ const displayMatrix = this.convertSpreadsheetRowsToMatrixData(rows);
716
+ this.valueChange.emit(toCanonicalMatrixData(displayMatrix, this.resolvedMatrixOrientation()));
717
+ }
718
+ handleCellChange(event) {
719
+ this.cellChange.emit(event);
720
+ }
721
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementRiskMatrixComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
722
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMRiskManagementRiskMatrixComponent, isStandalone: true, selector: "axm-risk-matrix", inputs: { axisMapping: { classPropertyName: "axisMapping", publicName: "axisMapping", isSignal: true, isRequired: false, transformFunction: null }, likelihoodIds: { classPropertyName: "likelihoodIds", publicName: "likelihoodIds", isSignal: true, isRequired: false, transformFunction: null }, severityIds: { classPropertyName: "severityIds", publicName: "severityIds", isSignal: true, isRequired: false, transformFunction: null }, matrixOrientation: { classPropertyName: "matrixOrientation", publicName: "matrixOrientation", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", cellChange: "cellChange" }, host: { classAttribute: "axm-risk-matrix" }, ngImport: i0, template: "<div class=\"__container\">\n <div class=\"__matrix-section\">\n @if (isLoading()) {\n <div class=\"__loading\">\n <span>{{ '@risk-management:risk-matrix-cells.components.risk-matrix.messages.loading' | translate | async }}</span>\n </div>\n } @else {\n @for (_ of [resolvedMatrixOrientation()]; track _) {\n <axp-spreadsheet\n [title]=\"(matrixTitleKey() | translate | async) ?? ''\"\n [columns]=\"spreadsheetColumns()\"\n [rowsInput]=\"spreadsheetRows()\"\n [rowMode]=\"'fixed'\"\n [readonly]=\"readonly()\"\n [allowRemoveRows]=\"false\"\n [rowTitlePath]=\"'_rowTitle'\"\n [rowDescriptionPath]=\"'_rowDescription'\"\n (cellChange)=\"handleCellChange($event)\"\n (spreadsheetChange)=\"handleSpreadsheetChange($event)\"\n ></axp-spreadsheet>\n }\n }\n </div>\n</div>\n", styles: [".risk-matrix{display:block;height:100%;width:100%}.risk-matrix .__container,.risk-matrix .__matrix-section{display:flex;flex-direction:column}.risk-matrix .__loading,.risk-matrix .__empty-state{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 8);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgb(var(--ax-sys-color-on-light-surface))}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPSpreadsheetComponent, selector: "axp-spreadsheet", inputs: ["title", "columns", "rowMode", "rowsInput", "rowsModel", "readonly", "emptyCellPlaceholder", "rowTitlePath", "rowDescriptionPath", "allowAddRows", "allowRemoveRows"], outputs: ["rowsModelChange", "cellChange", "rowChange", "spreadsheetChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
723
+ }
724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskManagementRiskMatrixComponent, decorators: [{
725
+ type: Component,
726
+ args: [{ selector: 'axm-risk-matrix', standalone: true, imports: [CommonModule, AXPSpreadsheetComponent, AXTranslationModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
727
+ class: 'axm-risk-matrix',
728
+ }, template: "<div class=\"__container\">\n <div class=\"__matrix-section\">\n @if (isLoading()) {\n <div class=\"__loading\">\n <span>{{ '@risk-management:risk-matrix-cells.components.risk-matrix.messages.loading' | translate | async }}</span>\n </div>\n } @else {\n @for (_ of [resolvedMatrixOrientation()]; track _) {\n <axp-spreadsheet\n [title]=\"(matrixTitleKey() | translate | async) ?? ''\"\n [columns]=\"spreadsheetColumns()\"\n [rowsInput]=\"spreadsheetRows()\"\n [rowMode]=\"'fixed'\"\n [readonly]=\"readonly()\"\n [allowRemoveRows]=\"false\"\n [rowTitlePath]=\"'_rowTitle'\"\n [rowDescriptionPath]=\"'_rowDescription'\"\n (cellChange)=\"handleCellChange($event)\"\n (spreadsheetChange)=\"handleSpreadsheetChange($event)\"\n ></axp-spreadsheet>\n }\n }\n </div>\n</div>\n", styles: [".risk-matrix{display:block;height:100%;width:100%}.risk-matrix .__container,.risk-matrix .__matrix-section{display:flex;flex-direction:column}.risk-matrix .__loading,.risk-matrix .__empty-state{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 8);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgb(var(--ax-sys-color-on-light-surface))}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
729
+ }], ctorParameters: () => [], propDecorators: { axisMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisMapping", required: false }] }], likelihoodIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "likelihoodIds", required: false }] }], severityIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "severityIds", required: false }] }], matrixOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "matrixOrientation", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }] } });
730
+
731
+ //#region ---- Imports ----
732
+ //#endregion
733
+ //#region ---- Risk Matrix Viewer Service ----
734
+ /**
735
+ * Opens a read-only risk matrix preview dialog from row or record context.
736
+ */
737
+ class AXMRiskMatrixViewerService {
738
+ constructor() {
739
+ //#region ---- Services & Dependencies ----
740
+ this.layoutBuilder = inject(AXPLayoutBuilderService);
741
+ this.translation = inject(AXTranslationService);
742
+ }
743
+ //#endregion
744
+ //#region ---- Public API ----
745
+ async open(options) {
746
+ const matrixPath = defaultTo(options.matrixPath, 'matrix');
747
+ const matrixValue = get(options.context, matrixPath);
748
+ if (isEmpty(matrixValue)) {
749
+ return;
750
+ }
751
+ const ref = await this.layoutBuilder
752
+ .create()
753
+ .dialog((dialog) => {
754
+ dialog
755
+ .setTitle(this.resolveDialogTitle(options.title))
756
+ .setSize('lg')
757
+ .setCloseButton(true)
758
+ .setContext({ ...options.context })
759
+ .content((layout) => {
760
+ layout.flex((flex) => {
761
+ flex.setDirection('column');
762
+ flex.formField('', (field) => {
763
+ field
764
+ .path(matrixPath)
765
+ .setShowLabel(false)
766
+ .customWidget(AXPWidgetsList.Editors.RiskMatrix, { readonly: true });
767
+ });
768
+ });
769
+ })
770
+ .setActions((actions) => {
771
+ actions.cancel('@general:actions.close.title');
772
+ });
773
+ })
774
+ .show();
775
+ ref.close();
776
+ }
777
+ //#endregion
778
+ //#region ---- Utility Methods ----
779
+ resolveDialogTitle(title) {
780
+ const resolved = resolveEntityRowDisplayText(title, this.translation.getActiveLang());
781
+ return resolved || 'Risk Matrix';
782
+ }
783
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixViewerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
784
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixViewerService, providedIn: 'root' }); }
785
+ }
786
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixViewerService, decorators: [{
787
+ type: Injectable,
788
+ args: [{ providedIn: 'root' }]
789
+ }] });
790
+
791
+ //#region ---- Imports ----
792
+ //#endregion
793
+ //#region ---- Viewer Open Helper ----
794
+ function buildRiskMatrixViewerOpenOptions(params) {
795
+ const matrixPath = params.matrixPath ?? 'matrix';
796
+ const title = params.data
797
+ ? resolveEntityRowDisplayTitle({
798
+ data: params.data,
799
+ widgetOptions: params.widgetOptions,
800
+ formatService: params.formatService,
801
+ activeLang: params.activeLang,
802
+ entity: params.entity,
803
+ })
804
+ : '';
805
+ return {
806
+ context: params.context,
807
+ matrixPath,
808
+ title: title || params.fallbackTitleKey,
809
+ };
810
+ }
811
+ async function openRiskMatrixViewer(viewer, params) {
812
+ await viewer.open(buildRiskMatrixViewerOpenOptions(params));
813
+ }
814
+ //#endregion
815
+
816
+ //#region ---- Imports ----
817
+ //#endregion
818
+ //#region ---- Component: Risk Matrix Widget Column ----
819
+ class AXMRiskMatrixWidgetColumnComponent extends AXPColumnWidgetComponent {
820
+ constructor() {
821
+ super(...arguments);
822
+ //#region ---- Services & Dependencies ----
823
+ this.riskMatrixViewer = inject(AXMRiskMatrixViewerService);
824
+ this.formatService = inject(AXFormatService);
825
+ this.translation = inject(AXTranslationService);
826
+ }
827
+ //#endregion
828
+ //#region ---- UI Handlers ----
829
+ hasMatrix() {
830
+ return !isEmpty(this.rawValue);
831
+ }
832
+ async showPopup() {
833
+ const rowData = this.rowData;
834
+ if (!rowData || isEmpty(this.rawValue)) {
835
+ return;
836
+ }
837
+ await openRiskMatrixViewer(this.riskMatrixViewer, {
838
+ context: rowData,
839
+ matrixPath: this.path,
840
+ data: rowData,
841
+ widgetOptions: { ...this.options },
842
+ formatService: this.formatService,
843
+ activeLang: this.translation.getActiveLang(),
844
+ fallbackTitleKey: '@risk-management:risk-matrix-cells.entities.risk-matrix-cell.fields.matrix.title',
845
+ });
846
+ }
847
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
848
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMRiskMatrixWidgetColumnComponent, isStandalone: true, selector: "axm-risk-matrix-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, usesInheritance: true, ngImport: i0, template: `
849
+ <div class="flex items-center gap-2">
850
+ @if (hasMatrix()) {
851
+ <ax-button class="ax-sm" look="twotone" color="default" (click)="showPopup()">
852
+ <ax-icon>
853
+ <i class="fa-light fa-table-cells"></i>
854
+ </ax-icon>
855
+ </ax-button>
856
+ } @else {
857
+ <span>-</span>
858
+ }
859
+ </div>
860
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
861
+ }
862
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetColumnComponent, decorators: [{
863
+ type: Component,
864
+ args: [{
865
+ selector: 'axm-risk-matrix-widget-column',
866
+ imports: [AXButtonModule, AXDecoratorModule],
867
+ template: `
868
+ <div class="flex items-center gap-2">
869
+ @if (hasMatrix()) {
870
+ <ax-button class="ax-sm" look="twotone" color="default" (click)="showPopup()">
871
+ <ax-icon>
872
+ <i class="fa-light fa-table-cells"></i>
873
+ </ax-icon>
874
+ </ax-button>
875
+ } @else {
876
+ <span>-</span>
877
+ }
878
+ </div>
879
+ `,
880
+ changeDetection: ChangeDetectionStrategy.OnPush,
881
+ inputs: ['rawValue', 'rowData'],
882
+ }]
883
+ }] });
884
+
885
+ var riskMatrixWidgetColumn_component = /*#__PURE__*/Object.freeze({
886
+ __proto__: null,
887
+ AXMRiskMatrixWidgetColumnComponent: AXMRiskMatrixWidgetColumnComponent
888
+ });
889
+
890
+ //#endregion
891
+ //#region ---- Component Definition ----
892
+ class AXMRiskMatrixWidgetEditComponent extends AXPValueWidgetComponent {
893
+ //#region ---- Lifecycle Methods ----
894
+ constructor() {
895
+ super();
896
+ //#endregion
897
+ //#region ---- Computed Properties ----
898
+ this.readonly = computed(() => {
899
+ const options = this.options();
900
+ return options?.['readonly'] ?? false;
901
+ }, /* @ts-ignore */
902
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
903
+ this.axisMapping = computed(() => {
904
+ this.contextService.changeEvent();
905
+ const options = this.options();
906
+ const orientation = get(this.contextService.data(), 'matrixOrientation');
907
+ return resolveRiskMatrixAxisMappingFromOrientation(orientation, {
908
+ rowProperty: options?.['rowProperty'],
909
+ columnProperty: options?.['columnProperty'],
910
+ depthProperty: options?.['depthProperty'],
911
+ });
912
+ }, /* @ts-ignore */
913
+ ...(ngDevMode ? [{ debugName: "axisMapping" }] : /* istanbul ignore next */ []));
914
+ this.matrixOrientation = computed(() => {
915
+ this.contextService.changeEvent();
916
+ return resolveRiskMatrixOrientation(get(this.contextService.data(), 'matrixOrientation'));
917
+ }, /* @ts-ignore */
918
+ ...(ngDevMode ? [{ debugName: "matrixOrientation" }] : /* istanbul ignore next */ []));
919
+ this.likelihoodIds = computed(() => {
920
+ this.contextService.changeEvent();
921
+ return this.normalizeAxisIds(get(this.contextService.data(), 'likelihoodId'));
922
+ }, /* @ts-ignore */
923
+ ...(ngDevMode ? [{ debugName: "likelihoodIds" }] : /* istanbul ignore next */ []));
924
+ this.severityIds = computed(() => {
925
+ this.contextService.changeEvent();
926
+ return this.normalizeAxisIds(get(this.contextService.data(), 'severityId'));
927
+ }, /* @ts-ignore */
928
+ ...(ngDevMode ? [{ debugName: "severityIds" }] : /* istanbul ignore next */ []));
929
+ this.matrixValue = computed(() => {
930
+ return this.getValue() || {};
931
+ }, /* @ts-ignore */
932
+ ...(ngDevMode ? [{ debugName: "matrixValue" }] : /* istanbul ignore next */ []));
933
+ effect(() => {
934
+ const likelihoodIds = this.likelihoodIds();
935
+ const severityIds = this.severityIds();
936
+ const matrix = this.getValue() ?? {};
937
+ const prunedMatrix = pruneMatrixToAxes(matrix, likelihoodIds, severityIds);
938
+ if (!isEqual(matrix, prunedMatrix)) {
939
+ this.setValue(prunedMatrix);
940
+ }
941
+ });
942
+ }
943
+ //#endregion
944
+ //#region ---- Event Handlers ----
945
+ handleValueChange(data) {
946
+ if (data) {
947
+ this.setValue(data);
948
+ }
949
+ }
950
+ normalizeAxisIds(value) {
951
+ return normalizeRiskMatrixAxisIds(value);
952
+ }
953
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
954
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXMRiskMatrixWidgetEditComponent, isStandalone: true, selector: "axm-risk-matrix-widget-edit", host: { classAttribute: "block w-full" }, usesInheritance: true, ngImport: i0, template: `
955
+ <axm-risk-matrix
956
+ [axisMapping]="axisMapping()"
957
+ [matrixOrientation]="matrixOrientation()"
958
+ [likelihoodIds]="likelihoodIds()"
959
+ [severityIds]="severityIds()"
960
+ [value]="matrixValue()"
961
+ [readonly]="readonly()"
962
+ (valueChange)="handleValueChange($any($event))"
963
+ ></axm-risk-matrix>
964
+ `, isInline: true, dependencies: [{ kind: "component", type: AXMRiskManagementRiskMatrixComponent, selector: "axm-risk-matrix", inputs: ["axisMapping", "likelihoodIds", "severityIds", "matrixOrientation", "value", "readonly"], outputs: ["valueChange", "cellChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
965
+ }
966
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetEditComponent, decorators: [{
967
+ type: Component,
968
+ args: [{
969
+ selector: 'axm-risk-matrix-widget-edit',
970
+ standalone: true,
971
+ imports: [AXMRiskManagementRiskMatrixComponent],
972
+ template: `
973
+ <axm-risk-matrix
974
+ [axisMapping]="axisMapping()"
975
+ [matrixOrientation]="matrixOrientation()"
976
+ [likelihoodIds]="likelihoodIds()"
977
+ [severityIds]="severityIds()"
978
+ [value]="matrixValue()"
979
+ [readonly]="readonly()"
980
+ (valueChange)="handleValueChange($any($event))"
981
+ ></axm-risk-matrix>
982
+ `,
983
+ host: {
984
+ class: 'block w-full',
985
+ },
986
+ encapsulation: ViewEncapsulation.None,
987
+ changeDetection: ChangeDetectionStrategy.OnPush,
988
+ }]
989
+ }], ctorParameters: () => [] });
990
+
991
+ var riskMatrixWidgetEdit_component = /*#__PURE__*/Object.freeze({
992
+ __proto__: null,
993
+ AXMRiskMatrixWidgetEditComponent: AXMRiskMatrixWidgetEditComponent
994
+ });
995
+
996
+ //#endregion
997
+ //#region ---- Component Definition ----
998
+ class AXMRiskMatrixWidgetViewComponent extends AXPValueWidgetComponent {
999
+ constructor() {
1000
+ super(...arguments);
1001
+ //#region ---- Computed Properties ----
1002
+ this.axisMapping = computed(() => {
1003
+ this.contextService.changeEvent();
1004
+ const options = this.options();
1005
+ const orientation = get(this.contextService.data(), 'matrixOrientation');
1006
+ return resolveRiskMatrixAxisMappingFromOrientation(orientation, {
1007
+ rowProperty: options?.['rowProperty'],
1008
+ columnProperty: options?.['columnProperty'],
1009
+ depthProperty: options?.['depthProperty'],
1010
+ });
1011
+ }, /* @ts-ignore */
1012
+ ...(ngDevMode ? [{ debugName: "axisMapping" }] : /* istanbul ignore next */ []));
1013
+ this.matrixOrientation = computed(() => {
1014
+ this.contextService.changeEvent();
1015
+ return resolveRiskMatrixOrientation(get(this.contextService.data(), 'matrixOrientation'));
1016
+ }, /* @ts-ignore */
1017
+ ...(ngDevMode ? [{ debugName: "matrixOrientation" }] : /* istanbul ignore next */ []));
1018
+ this.likelihoodIds = computed(() => {
1019
+ this.contextService.changeEvent();
1020
+ return this.normalizeAxisIds(get(this.contextService.data(), 'likelihoodId'));
1021
+ }, /* @ts-ignore */
1022
+ ...(ngDevMode ? [{ debugName: "likelihoodIds" }] : /* istanbul ignore next */ []));
1023
+ this.severityIds = computed(() => {
1024
+ this.contextService.changeEvent();
1025
+ return this.normalizeAxisIds(get(this.contextService.data(), 'severityId'));
1026
+ }, /* @ts-ignore */
1027
+ ...(ngDevMode ? [{ debugName: "severityIds" }] : /* istanbul ignore next */ []));
1028
+ this.matrixValue = computed(() => {
1029
+ return this.getValue() || {};
1030
+ }, /* @ts-ignore */
1031
+ ...(ngDevMode ? [{ debugName: "matrixValue" }] : /* istanbul ignore next */ []));
1032
+ }
1033
+ normalizeAxisIds(value) {
1034
+ return castArray(value)
1035
+ .map((item) => {
1036
+ if (item != null && typeof item === 'object' && 'id' in item) {
1037
+ return String(item.id);
1038
+ }
1039
+ return item != null ? String(item) : '';
1040
+ })
1041
+ .filter((id) => id.length > 0);
1042
+ }
1043
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1044
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXMRiskMatrixWidgetViewComponent, isStandalone: true, selector: "axm-risk-matrix-widget-view", host: { classAttribute: "block w-full" }, usesInheritance: true, ngImport: i0, template: `
1045
+ <axm-risk-matrix
1046
+ [axisMapping]="axisMapping()"
1047
+ [matrixOrientation]="matrixOrientation()"
1048
+ [likelihoodIds]="likelihoodIds()"
1049
+ [severityIds]="severityIds()"
1050
+ [value]="matrixValue()"
1051
+ [readonly]="true"
1052
+ ></axm-risk-matrix>
1053
+ `, isInline: true, dependencies: [{ kind: "component", type: AXMRiskManagementRiskMatrixComponent, selector: "axm-risk-matrix", inputs: ["axisMapping", "likelihoodIds", "severityIds", "matrixOrientation", "value", "readonly"], outputs: ["valueChange", "cellChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1054
+ }
1055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMRiskMatrixWidgetViewComponent, decorators: [{
1056
+ type: Component,
1057
+ args: [{
1058
+ selector: 'axm-risk-matrix-widget-view',
1059
+ standalone: true,
1060
+ imports: [AXMRiskManagementRiskMatrixComponent],
1061
+ template: `
1062
+ <axm-risk-matrix
1063
+ [axisMapping]="axisMapping()"
1064
+ [matrixOrientation]="matrixOrientation()"
1065
+ [likelihoodIds]="likelihoodIds()"
1066
+ [severityIds]="severityIds()"
1067
+ [value]="matrixValue()"
1068
+ [readonly]="true"
1069
+ ></axm-risk-matrix>
1070
+ `,
1071
+ host: {
1072
+ class: 'block w-full',
1073
+ },
1074
+ encapsulation: ViewEncapsulation.None,
1075
+ changeDetection: ChangeDetectionStrategy.OnPush,
1076
+ }]
1077
+ }] });
1078
+
1079
+ var riskMatrixWidgetView_component = /*#__PURE__*/Object.freeze({
1080
+ __proto__: null,
1081
+ AXMRiskMatrixWidgetViewComponent: AXMRiskMatrixWidgetViewComponent
1082
+ });
1083
+
1084
+ /**
1085
+ * Generated bundle index. Do not edit.
1086
+ */
1087
+
1088
+ export { AXMRiskManagementMenuProvider, AXMRiskManagementModule, AXMRiskManagementPermissionDefinitionProvider, AXMRiskManagementRiskMatrixComponent, AXMRiskMatrixViewerService, AXMRiskMatrixWidgetColumnComponent, AXMRiskMatrixWidgetEditComponent, AXMRiskMatrixWidgetViewComponent, isRiskMatrixAxisProperty, isRiskMatrixOrientation, normalizeRiskMatrixAxisIds, pruneMatrixToAxes, resolveRiskMatrixAxisMapping, resolveRiskMatrixAxisMappingFromOrientation, resolveRiskMatrixOrientation, resolveRiskMatrixTitleKey, toCanonicalMatrixData, toDisplayMatrixData, validateRiskMatrixAxisMapping };
1089
+ //# sourceMappingURL=acorex-platform-module-risk-management-client.mjs.map