@acorex-platform/module-asset-management-client 0.0.56 → 0.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs +2789 -0
- package/fesm2022/acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs +276 -0
- package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs +55 -0
- package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset-type.mjs +105 -1
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset-type.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset.mjs +290 -5
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-acorex-platform-module-asset-management-client-contracts-entity-catalog--qb3bhd-.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-acorex-platform-module-asset-management-client-contracts-entity-catalog-CnuEulTO.mjs} +9 -9
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-acorex-platform-module-asset-management-client-contracts-entity-catalog--qb3bhd-.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-acorex-platform-module-asset-management-client-contracts-entity-catalog-CnuEulTO.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-rental-history.entity-DoXOgclo.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-rental-history.entity-Cy6qssiv.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-rental-history.entity-DoXOgclo.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-rental-history.entity-Cy6qssiv.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-assignment.entity-DodjW3aR.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-assignment.entity-BvXjVaqK.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-assignment.entity-DodjW3aR.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-assignment.entity-BvXjVaqK.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-type.entity-BNV5_Bwu.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-type.entity-DanmgSHH.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-type.entity-BNV5_Bwu.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system-type.entity-DanmgSHH.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system.entity-BBHHbwxU.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system.entity-BO2GQu2_.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system.entity-BBHHbwxU.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-system.entity-BO2GQu2_.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section-component.entity-D-P7HwQU.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section-component.entity-DumWQV-O.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section-component.entity-D-P7HwQU.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section-component.entity-DumWQV-O.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section.entity-TsV2eE47.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section.entity-B5Z8s8_4.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section.entity-TsV2eE47.mjs.map → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type-section.entity-B5Z8s8_4.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-CUZ1xIl3.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-BO3otOO_.mjs} +65 -3
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-BO3otOO_.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-Ckx8fhZ-.mjs → acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-CvCBkNVZ.mjs} +250 -7
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-CvCBkNVZ.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.interval-kind-nMKvWqpx.mjs +45 -0
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.interval-kind-nMKvWqpx.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog.mjs +1 -1
- package/fesm2022/acorex-platform-module-asset-management-client-contracts.mjs +241 -1
- package/fesm2022/acorex-platform-module-asset-management-client-contracts.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-ueTauO_k.mjs → acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-RGXS9fI1.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-ueTauO_k.mjs.map → acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-RGXS9fI1.mjs.map} +1 -1
- package/fesm2022/acorex-platform-module-asset-management-client.mjs +1 -2496
- package/fesm2022/acorex-platform-module-asset-management-client.mjs.map +1 -1
- package/i18n/en-AU/asset-management.json +44 -0
- package/i18n/en-US/asset-management.json +44 -0
- package/i18n/fa-IR/asset-management.json +44 -0
- package/package.json +2 -2
- package/types/acorex-platform-module-asset-management-client-contracts.d.ts +72 -2
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-CUZ1xIl3.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-Ckx8fhZ-.mjs.map +0 -1
|
@@ -0,0 +1,2789 @@
|
|
|
1
|
+
import { AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
|
|
2
|
+
import { AXP_MENU_PROVIDER, AXP_SEARCH_PROVIDER, AXP_STATUS_PROVIDERS, AXPSearchCommandProvider, createEntityCommandOptions } from '@acorex-platform/framework-client/common';
|
|
3
|
+
import { AXP_CATALOG_SCOPE_DEFINITION_PROVIDER, provideLazyProvider, AXP_FEATURE_DEFINITION_PROVIDER, AXPDataGenerator } from '@acorex-platform/framework-client/core';
|
|
4
|
+
import { AXP_PAGE_COMPONENT_PROVIDER, AXPStandardSectionItemsBuilderComponent } from '@acorex-platform/framework-client/layout/components';
|
|
5
|
+
import { AXPMiddlewareAbortError, AXP_ENTITY_STORAGE_MIDDLEWARE, AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
|
|
6
|
+
import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/layout/widget-core';
|
|
7
|
+
import { provideCommand, provideCommandSetups, AXPCommandService } from '@acorex-platform/framework-client/runtime';
|
|
8
|
+
import * as i0 from '@angular/core';
|
|
9
|
+
import { Injectable, NgModule, inject, input, output, viewChild, signal, computed, effect, ChangeDetectionStrategy, Component, untracked } from '@angular/core';
|
|
10
|
+
import * as contracts from '@acorex-platform/module-asset-management-client/contracts';
|
|
11
|
+
import { ASSET_CATALOG_SCOPE_BOOKING, AXMAssetIntervalKind, AXMAssetIntervalUnit, resolveSupportedIntervalKinds, isAXMAssetUsageKind, AXM_ASSET_USAGE_VALUES_WIDGET, RootConfig, readAssetUsageValues, resolveAssetUsageWrite, AXM_ASSET_USAGE_WRITE_ERRORS, AXMAssetManagementCommandKeys, AXMAssetManagementFeatureKeys, AXPAssetsMaintenancePermissionKeys, AXMAssetManagementMenuKeys, AXM_ASSET_STATUS_DEFINITION_KEY, AXMAssetStatus, ASSET_TYPE_COMPONENTS_PAGE_COMPONENT_KEY, AXMAssetLifecycleStatus } from '@acorex-platform/module-asset-management-client/contracts';
|
|
12
|
+
import { AXPWidgetGroupEnum } from '@acorex-platform/framework-shared/widget-core';
|
|
13
|
+
import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
|
|
14
|
+
import { AXPStatusProvider, AXPWidgetsCatalog } from '@acorex-platform/framework-shared/core';
|
|
15
|
+
import { merge, get, isEqual, cloneDeep, isString, defaultTo } from 'lodash';
|
|
16
|
+
import * as i1 from '@acorex/components/button';
|
|
17
|
+
import { AXButtonModule } from '@acorex/components/button';
|
|
18
|
+
import * as i2 from '@acorex/components/decorators';
|
|
19
|
+
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
20
|
+
import * as i4 from '@acorex/core/translation';
|
|
21
|
+
import { AXTranslationService, resolveMultiLanguageString, AXTranslationModule } from '@acorex/core/translation';
|
|
22
|
+
import { AXPLayoutBuilderService } from '@acorex-platform/framework-client/layout/builder';
|
|
23
|
+
import * as i3 from '@angular/common';
|
|
24
|
+
import { CommonModule } from '@angular/common';
|
|
25
|
+
import { AXPPageLayoutBaseComponent, AXPPageLayoutBase } from '@acorex-platform/framework-client/layout/views';
|
|
26
|
+
|
|
27
|
+
function _mergeNamespaces(n, m) {
|
|
28
|
+
m.forEach(function (e) {
|
|
29
|
+
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
|
|
30
|
+
if (k !== 'default' && !(k in n)) {
|
|
31
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
32
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () { return e[k]; }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return Object.freeze(n);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region ---- Constants ----
|
|
44
|
+
const QUESTIONNAIRE = 'AssessmentManagement.Questionnaire';
|
|
45
|
+
const QUESTION_BANK_ITEM = 'AssessmentManagement.QuestionBankItem';
|
|
46
|
+
const WORKFLOW_DEFINITION = 'WorkflowManagement.WorkflowDefinition';
|
|
47
|
+
const ASSET_CATALOG_TARGETS = [QUESTIONNAIRE, QUESTION_BANK_ITEM, WORKFLOW_DEFINITION];
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region ---- Provider ----
|
|
50
|
+
class AXMAssetManagementCatalogScopeDefinitionProvider {
|
|
51
|
+
async items() {
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
name: ASSET_CATALOG_SCOPE_BOOKING,
|
|
55
|
+
title: '@asset-management:catalog-scopes.booking.title',
|
|
56
|
+
description: '@asset-management:catalog-scopes.booking.description',
|
|
57
|
+
targets: [...ASSET_CATALOG_TARGETS],
|
|
58
|
+
icon: 'fa-light fa-calendar-check',
|
|
59
|
+
cssClass: 'primary-surface',
|
|
60
|
+
order: 25,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementCatalogScopeDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
65
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementCatalogScopeDefinitionProvider }); }
|
|
66
|
+
}
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementCatalogScopeDefinitionProvider, decorators: [{
|
|
68
|
+
type: Injectable
|
|
69
|
+
}] });
|
|
70
|
+
|
|
71
|
+
//#region ----- Constants -----
|
|
72
|
+
const AXM_ASSET_USAGE_I18N = '@asset-management:assets.entities.asset.fields.usage-values';
|
|
73
|
+
const CONTEXT_PATHS = ['assetType.supportedIntervalKinds'];
|
|
74
|
+
const USAGE_METER_KIND_ORDER = [
|
|
75
|
+
AXMAssetIntervalKind.Distance,
|
|
76
|
+
AXMAssetIntervalKind.OperatingHours,
|
|
77
|
+
AXMAssetIntervalKind.OperationCount,
|
|
78
|
+
];
|
|
79
|
+
const USAGE_KIND_LABEL_KEYS = {
|
|
80
|
+
[AXMAssetIntervalKind.Date]: `${AXM_ASSET_USAGE_I18N}.kinds.date`,
|
|
81
|
+
[AXMAssetIntervalKind.Distance]: `${AXM_ASSET_USAGE_I18N}.kinds.distance`,
|
|
82
|
+
[AXMAssetIntervalKind.OperatingHours]: `${AXM_ASSET_USAGE_I18N}.kinds.operating-hours`,
|
|
83
|
+
[AXMAssetIntervalKind.OperationCount]: `${AXM_ASSET_USAGE_I18N}.kinds.operation-count`,
|
|
84
|
+
};
|
|
85
|
+
const USAGE_UNIT_LABEL_KEYS = {
|
|
86
|
+
[AXMAssetIntervalUnit.Kilometer]: `${AXM_ASSET_USAGE_I18N}.units.kilometer`,
|
|
87
|
+
[AXMAssetIntervalUnit.Mile]: `${AXM_ASSET_USAGE_I18N}.units.mile`,
|
|
88
|
+
[AXMAssetIntervalUnit.Hour]: `${AXM_ASSET_USAGE_I18N}.units.hour`,
|
|
89
|
+
[AXMAssetIntervalUnit.Operation]: `${AXM_ASSET_USAGE_I18N}.units.operation`,
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region ----- Supported kinds -----
|
|
93
|
+
/** Widget option first, then the asset type already on the form. */
|
|
94
|
+
function readAssetUsageIntervalKinds(options, readContext) {
|
|
95
|
+
const record = options;
|
|
96
|
+
if ('supportedIntervalKinds' in record) {
|
|
97
|
+
return resolveSupportedIntervalKinds(record['supportedIntervalKinds']).kinds;
|
|
98
|
+
}
|
|
99
|
+
for (const path of CONTEXT_PATHS) {
|
|
100
|
+
const resolved = resolveSupportedIntervalKinds(readContext(path));
|
|
101
|
+
if (resolved.kinds.length > 0) {
|
|
102
|
+
return resolved.kinds;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
function orderedUsageMeterKinds(kinds) {
|
|
108
|
+
return USAGE_METER_KIND_ORDER.filter((kind) => kinds.includes(kind));
|
|
109
|
+
}
|
|
110
|
+
function isUsageMeterKind(value) {
|
|
111
|
+
return isAXMAssetUsageKind(value);
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
|
|
115
|
+
//#region ----- Imports -----
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region ----- Widget config -----
|
|
118
|
+
const AXMAssetUsageValuesWidget = {
|
|
119
|
+
name: AXM_ASSET_USAGE_VALUES_WIDGET,
|
|
120
|
+
title: `${AXM_ASSET_USAGE_I18N}.title`,
|
|
121
|
+
description: `${AXM_ASSET_USAGE_I18N}.description`,
|
|
122
|
+
type: 'editor',
|
|
123
|
+
designer: { needLabel: true },
|
|
124
|
+
categories: [],
|
|
125
|
+
groups: [AXPWidgetGroupEnum.EntityWidget],
|
|
126
|
+
icon: 'fa-light fa-gauge',
|
|
127
|
+
properties: [AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY],
|
|
128
|
+
components: {
|
|
129
|
+
view: {
|
|
130
|
+
component: () => import('./acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs').then((c) => c.AXMAssetUsageValuesWidgetViewComponent),
|
|
131
|
+
},
|
|
132
|
+
edit: {
|
|
133
|
+
component: () => import('./acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs').then((c) => c.AXMAssetUsageValuesWidgetEditComponent),
|
|
134
|
+
},
|
|
135
|
+
designer: {
|
|
136
|
+
component: () => import('./acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs').then((c) => c.AXMAssetUsageValuesWidgetEditComponent),
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region ----- Provider -----
|
|
144
|
+
class AXMAssetUsageValuesWidgetProvider {
|
|
145
|
+
getWidgets() {
|
|
146
|
+
return [AXMAssetUsageValuesWidget];
|
|
147
|
+
}
|
|
148
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
149
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetProvider }); }
|
|
150
|
+
}
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetProvider, decorators: [{
|
|
152
|
+
type: Injectable
|
|
153
|
+
}] });
|
|
154
|
+
|
|
155
|
+
//#region ---- Imports ----
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region ---- Asset System Type Has Child Middleware ----
|
|
158
|
+
/**
|
|
159
|
+
* Enriches AssetSystemType query results with `hasChild` for hierarchical tree views.
|
|
160
|
+
* Uses `childrenCount` from the storage query pipeline when available.
|
|
161
|
+
*/
|
|
162
|
+
const assetSystemTypeHasChildMiddleware = {
|
|
163
|
+
target: {
|
|
164
|
+
ops: ['query', 'queryAll'],
|
|
165
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.assetSystemType.name}`,
|
|
166
|
+
order: 10,
|
|
167
|
+
},
|
|
168
|
+
execute: async (ctx, next) => {
|
|
169
|
+
await next();
|
|
170
|
+
if (!ctx.result?.items?.length) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
ctx.result = {
|
|
174
|
+
...ctx.result,
|
|
175
|
+
items: ctx.result.items.map((item) => ({
|
|
176
|
+
...item,
|
|
177
|
+
hasChild: (item.childrenCount ?? 0) > 0,
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
//#endregion
|
|
183
|
+
|
|
184
|
+
//#region ---- Imports ----
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region ---- Persist validation ----
|
|
187
|
+
function hasPartyId(value) {
|
|
188
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
189
|
+
}
|
|
190
|
+
function assertRentalPartyForDirection(data) {
|
|
191
|
+
if (data.rentalDirection === 'rentTo' && !hasPartyId(data.rentedToId)) {
|
|
192
|
+
throw new Error('@asset-management:assetRentalHistories.entities.assetRentalHistory.validations.rented-to-required');
|
|
193
|
+
}
|
|
194
|
+
if (data.rentalDirection === 'rentFrom' && !hasPartyId(data.rentedFromId)) {
|
|
195
|
+
throw new Error('@asset-management:assetRentalHistories.entities.assetRentalHistory.validations.rented-from-required');
|
|
196
|
+
}
|
|
197
|
+
if (!hasPartyId(data.rentedToId) && !hasPartyId(data.rentedFromId)) {
|
|
198
|
+
throw new Error('@asset-management:assetRentalHistories.entities.assetRentalHistory.validations.rental-party-required');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//#endregion
|
|
202
|
+
|
|
203
|
+
//#region ---- Imports ----
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region ---- Asset Rental History Party Middleware ----
|
|
206
|
+
/**
|
|
207
|
+
* Ensures the supplier party matching rentalDirection is set, and clears the opposite party.
|
|
208
|
+
*/
|
|
209
|
+
const assetRentalHistoryPartyMiddleware = {
|
|
210
|
+
target: {
|
|
211
|
+
ops: ['create', 'update'],
|
|
212
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.assetRentalHistory.name}`,
|
|
213
|
+
order: 8,
|
|
214
|
+
},
|
|
215
|
+
execute: async (ctx, next) => {
|
|
216
|
+
if (!ctx.data || typeof ctx.data !== 'object') {
|
|
217
|
+
await next();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const incoming = ctx.data;
|
|
221
|
+
let previous = (ctx.previous ?? {});
|
|
222
|
+
if (ctx.op === 'update' && ctx.id != null && !ctx.previous) {
|
|
223
|
+
previous = (await ctx.backend.getOne(ctx.entityName, ctx.id).catch(() => ({})));
|
|
224
|
+
}
|
|
225
|
+
const merged = {
|
|
226
|
+
...previous,
|
|
227
|
+
...incoming,
|
|
228
|
+
};
|
|
229
|
+
if (merged.rentalDirection === 'rentTo') {
|
|
230
|
+
incoming.rentedFromId = null;
|
|
231
|
+
incoming.rentedFrom = undefined;
|
|
232
|
+
merged.rentedFromId = null;
|
|
233
|
+
merged.rentedFrom = undefined;
|
|
234
|
+
}
|
|
235
|
+
else if (merged.rentalDirection === 'rentFrom') {
|
|
236
|
+
incoming.rentedToId = null;
|
|
237
|
+
incoming.rentedTo = undefined;
|
|
238
|
+
merged.rentedToId = null;
|
|
239
|
+
merged.rentedTo = undefined;
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
assertRentalPartyForDirection(merged);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
throw new AXPMiddlewareAbortError(error instanceof Error ? error.message : String(error), {
|
|
246
|
+
code: 'RENTAL_PARTY_REQUIRED',
|
|
247
|
+
status: 400,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
await next();
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
//#endregion
|
|
254
|
+
|
|
255
|
+
//#region ---- Imports ----
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region ---- Constants ----
|
|
258
|
+
const ASSET_TYPE_ENTITY$1 = `${RootConfig.module.name}.${RootConfig.entities.assetType.name}`;
|
|
259
|
+
const INVALID_INTERVAL_KINDS_MESSAGE = '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.validation.invalid';
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region ---- Helpers ----
|
|
262
|
+
function applySupportedIntervalKinds(record, kinds) {
|
|
263
|
+
record['supportedIntervalKinds'] = kinds;
|
|
264
|
+
}
|
|
265
|
+
function readRecord$1(value) {
|
|
266
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region ---- Asset type interval kinds middleware ----
|
|
273
|
+
/**
|
|
274
|
+
* Persists `supportedIntervalKinds` as a string array.
|
|
275
|
+
* Missing or empty input is saved and returned as `[]`. Unknown values abort the write.
|
|
276
|
+
*/
|
|
277
|
+
const assetTypeIntervalKindsMiddleware = {
|
|
278
|
+
target: {
|
|
279
|
+
ops: ['create', 'update', 'upsertOne', 'getOne', 'getAll', 'query', 'queryAll', 'getMany'],
|
|
280
|
+
entity: ASSET_TYPE_ENTITY$1,
|
|
281
|
+
order: 12,
|
|
282
|
+
},
|
|
283
|
+
execute: async (ctx, next) => {
|
|
284
|
+
const isWrite = ctx.op === 'create' || ctx.op === 'update' || ctx.op === 'upsertOne';
|
|
285
|
+
if (isWrite && ctx.data && typeof ctx.data === 'object') {
|
|
286
|
+
const data = ctx.data;
|
|
287
|
+
const fieldPresent = ctx.op === 'create' || ctx.op === 'upsertOne' || 'supportedIntervalKinds' in data;
|
|
288
|
+
if (fieldPresent) {
|
|
289
|
+
const resolved = resolveSupportedIntervalKinds(data['supportedIntervalKinds']);
|
|
290
|
+
if (resolved.invalid) {
|
|
291
|
+
throw new AXPMiddlewareAbortError(INVALID_INTERVAL_KINDS_MESSAGE, {
|
|
292
|
+
code: 'ASSET_TYPE_INTERVAL_KIND_INVALID',
|
|
293
|
+
status: 400,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
applySupportedIntervalKinds(data, resolved.kinds);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
await next();
|
|
300
|
+
if (ctx.op === 'getOne') {
|
|
301
|
+
const record = readRecord$1(ctx.result);
|
|
302
|
+
if (record) {
|
|
303
|
+
applySupportedIntervalKinds(record, resolveSupportedIntervalKinds(record['supportedIntervalKinds']).kinds);
|
|
304
|
+
}
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const items = Array.isArray(ctx.result)
|
|
308
|
+
? ctx.result
|
|
309
|
+
: Array.isArray(ctx.result?.items)
|
|
310
|
+
? ctx.result.items
|
|
311
|
+
: null;
|
|
312
|
+
if (!items) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
for (const item of items) {
|
|
316
|
+
const record = readRecord$1(item);
|
|
317
|
+
if (!record) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
applySupportedIntervalKinds(record, resolveSupportedIntervalKinds(record['supportedIntervalKinds']).kinds);
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
//#endregion
|
|
325
|
+
|
|
326
|
+
//#region ---- Imports ----
|
|
327
|
+
//#endregion
|
|
328
|
+
//#region ---- Constants ----
|
|
329
|
+
const ASSET_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.asset.name}`;
|
|
330
|
+
const ASSET_TYPE_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.assetType.name}`;
|
|
331
|
+
const WRITE_OPS = new Set(['create', 'update', 'upsertOne']);
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region ---- Helpers ----
|
|
334
|
+
function readRecord(value) {
|
|
335
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
return value;
|
|
339
|
+
}
|
|
340
|
+
function assignUsageValues(record) {
|
|
341
|
+
record['usageValues'] = readAssetUsageValues(record['usageValues']);
|
|
342
|
+
}
|
|
343
|
+
async function loadStoredAsset(ctx) {
|
|
344
|
+
const previous = readRecord(ctx.previous);
|
|
345
|
+
if (previous) {
|
|
346
|
+
return previous;
|
|
347
|
+
}
|
|
348
|
+
if (ctx.op === 'create' || ctx.id == null || ctx.id === '') {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
if (ctx.op === 'upsertOne') {
|
|
352
|
+
try {
|
|
353
|
+
return readRecord(await ctx.backend.getOne(ASSET_ENTITY, ctx.id));
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return readRecord(await ctx.backend.getOne(ASSET_ENTITY, ctx.id));
|
|
360
|
+
}
|
|
361
|
+
async function loadSupportedKinds(ctx, assetTypeId) {
|
|
362
|
+
if (typeof assetTypeId !== 'string' || assetTypeId.length === 0) {
|
|
363
|
+
return [];
|
|
364
|
+
}
|
|
365
|
+
const assetType = readRecord(await ctx.backend.getOne(ASSET_TYPE_ENTITY, assetTypeId));
|
|
366
|
+
return resolveSupportedIntervalKinds(assetType?.['supportedIntervalKinds']).kinds;
|
|
367
|
+
}
|
|
368
|
+
//#endregion
|
|
369
|
+
//#region ---- Asset usage values middleware ----
|
|
370
|
+
/**
|
|
371
|
+
* Stores one current reading per meter kind.
|
|
372
|
+
* A missing create value is `[]`. An update replaces the same kind and keeps the others.
|
|
373
|
+
*/
|
|
374
|
+
const assetUsageValuesMiddleware = {
|
|
375
|
+
target: {
|
|
376
|
+
ops: ['create', 'update', 'upsertOne', 'getOne', 'getAll', 'query', 'queryAll', 'getMany'],
|
|
377
|
+
entity: ASSET_ENTITY,
|
|
378
|
+
order: 14,
|
|
379
|
+
},
|
|
380
|
+
execute: async (ctx, next) => {
|
|
381
|
+
if (WRITE_OPS.has(ctx.op)) {
|
|
382
|
+
const data = readRecord(ctx.data);
|
|
383
|
+
const fieldPresent = ctx.op === 'create' || ctx.op === 'upsertOne' || (data != null && 'usageValues' in data);
|
|
384
|
+
if (data && fieldPresent) {
|
|
385
|
+
const stored = await loadStoredAsset(ctx);
|
|
386
|
+
const incoming = data['usageValues'];
|
|
387
|
+
const supportedKinds = Array.isArray(incoming) && incoming.length > 0
|
|
388
|
+
? await loadSupportedKinds(ctx, data['assetTypeId'] ?? stored?.['assetTypeId'])
|
|
389
|
+
: [];
|
|
390
|
+
const resolved = resolveAssetUsageWrite(incoming, {
|
|
391
|
+
supportedKinds,
|
|
392
|
+
previous: stored?.['usageValues'],
|
|
393
|
+
mergeWithPrevious: stored != null && ctx.op !== 'create',
|
|
394
|
+
});
|
|
395
|
+
if (resolved.issue) {
|
|
396
|
+
const error = AXM_ASSET_USAGE_WRITE_ERRORS[resolved.issue];
|
|
397
|
+
throw new AXPMiddlewareAbortError(error.message, { code: error.code, status: 400 });
|
|
398
|
+
}
|
|
399
|
+
data['usageValues'] = resolved.values;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
await next();
|
|
403
|
+
if (WRITE_OPS.has(ctx.op)) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (ctx.op === 'getOne') {
|
|
407
|
+
const record = readRecord(ctx.result);
|
|
408
|
+
if (record) {
|
|
409
|
+
assignUsageValues(record);
|
|
410
|
+
}
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const items = Array.isArray(ctx.result)
|
|
414
|
+
? ctx.result
|
|
415
|
+
: Array.isArray(ctx.result?.items)
|
|
416
|
+
? ctx.result.items
|
|
417
|
+
: null;
|
|
418
|
+
if (!items) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
for (const item of items) {
|
|
422
|
+
const record = readRecord(item);
|
|
423
|
+
if (record) {
|
|
424
|
+
assignUsageValues(record);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
//#endregion
|
|
430
|
+
|
|
431
|
+
//#region ---- Middleware Exports ----
|
|
432
|
+
//#endregion
|
|
433
|
+
|
|
434
|
+
//#region ---- Imports ----
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region ---- Module ----
|
|
437
|
+
class AXMAssetManagementModule {
|
|
438
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
439
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementModule }); }
|
|
440
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementModule, providers: [
|
|
441
|
+
{
|
|
442
|
+
provide: AXP_CATALOG_SCOPE_DEFINITION_PROVIDER,
|
|
443
|
+
useClass: AXMAssetManagementCatalogScopeDefinitionProvider,
|
|
444
|
+
multi: true,
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
provide: AXP_WIDGET_DEFINITION_PROVIDER,
|
|
448
|
+
useClass: AXMAssetUsageValuesWidgetProvider,
|
|
449
|
+
multi: true,
|
|
450
|
+
},
|
|
451
|
+
// Feature Definition Provider (lazy-loaded)
|
|
452
|
+
provideLazyProvider(AXP_FEATURE_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return featureDefinition_provider; }).then((m) => m.AXMAssetManagementFeatureDefinitionProvider)),
|
|
453
|
+
// Permission Definition Provider (lazy-loaded)
|
|
454
|
+
provideLazyProvider(AXP_PERMISSION_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return permissionDefinition_provider; }).then((m) => m.AXMAssetManagementPermissionDefinitionProvider)),
|
|
455
|
+
// Menu Provider (lazy-loaded)
|
|
456
|
+
provideLazyProvider(AXP_MENU_PROVIDER, () => Promise.resolve().then(function () { return menu_provider; }).then((m) => m.AXMAssetManagementMenuProvider)),
|
|
457
|
+
// Entity Provider (lazy-loaded)
|
|
458
|
+
// Search Provider (lazy-loaded)
|
|
459
|
+
provideLazyProvider(AXP_SEARCH_PROVIDER, () => Promise.resolve().then(function () { return searchCommand_provider; }).then((m) => m.AXMAssetManagementSearchCommandProvider)),
|
|
460
|
+
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => Promise.resolve().then(function () { return index; }).then((m) => m.AXMAssetTypeComponentsPageComponentProvider)),
|
|
461
|
+
provideCommand('AssetType:Components:Save', () => Promise.resolve().then(function () { return saveAssetTypeComponents_command; }).then((m) => m.AXMSaveAssetTypeComponentsCommand)),
|
|
462
|
+
provideCommand(AXMAssetManagementCommandKeys.AssetRentalHistory.RentFrom, () => Promise.resolve().then(function () { return createAssetRentalHistoryRent_commands; }).then((m) => m.AXMCreateAssetRentalHistoryRentFromCommand)),
|
|
463
|
+
provideCommand(AXMAssetManagementCommandKeys.AssetRentalHistory.RentTo, () => Promise.resolve().then(function () { return createAssetRentalHistoryRent_commands; }).then((m) => m.AXMCreateAssetRentalHistoryRentToCommand)),
|
|
464
|
+
provideCommandSetups([
|
|
465
|
+
{
|
|
466
|
+
key: AXMAssetManagementCommandKeys.WorkflowActivity.RecalculateOperationalStatus,
|
|
467
|
+
command: () => import('./acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-RGXS9fI1.mjs').then((c) => c.RecalculateAssetOperationalStatusActivity),
|
|
468
|
+
},
|
|
469
|
+
]),
|
|
470
|
+
// provideLazyProvider(AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, () =>
|
|
471
|
+
// import('./features/asset-status.rules').then((m) => m.AXMAssetManagementAssetStatusRulesExpressionScopeProvider),
|
|
472
|
+
// ),
|
|
473
|
+
// Status Providers
|
|
474
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => Promise.resolve().then(function () { return assetStatus_provider; }).then((m) => m.AXMAssetManagementAssetStatusProvider)),
|
|
475
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => import('./acorex-platform-module-asset-management-client-asset-rental-history-status.provider-DwhQPb0-.mjs').then((m) => m.AXMAssetManagementAssetRentalHistoryStatusProvider)),
|
|
476
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => import('./acorex-platform-module-asset-management-client-asset-lifecycle.provider-BDaCpGsv.mjs').then((m) => m.AXMAssetManagementAssetLifecycleStatusProvider)),
|
|
477
|
+
{
|
|
478
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
479
|
+
useValue: assetSystemTypeHasChildMiddleware,
|
|
480
|
+
multi: true,
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
484
|
+
useValue: assetRentalHistoryPartyMiddleware,
|
|
485
|
+
multi: true,
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
489
|
+
useValue: assetTypeIntervalKindsMiddleware,
|
|
490
|
+
multi: true,
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
494
|
+
useValue: assetUsageValuesMiddleware,
|
|
495
|
+
multi: true,
|
|
496
|
+
},
|
|
497
|
+
] }); }
|
|
498
|
+
}
|
|
499
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementModule, decorators: [{
|
|
500
|
+
type: NgModule,
|
|
501
|
+
args: [{
|
|
502
|
+
imports: [],
|
|
503
|
+
providers: [
|
|
504
|
+
{
|
|
505
|
+
provide: AXP_CATALOG_SCOPE_DEFINITION_PROVIDER,
|
|
506
|
+
useClass: AXMAssetManagementCatalogScopeDefinitionProvider,
|
|
507
|
+
multi: true,
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
provide: AXP_WIDGET_DEFINITION_PROVIDER,
|
|
511
|
+
useClass: AXMAssetUsageValuesWidgetProvider,
|
|
512
|
+
multi: true,
|
|
513
|
+
},
|
|
514
|
+
// Feature Definition Provider (lazy-loaded)
|
|
515
|
+
provideLazyProvider(AXP_FEATURE_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return featureDefinition_provider; }).then((m) => m.AXMAssetManagementFeatureDefinitionProvider)),
|
|
516
|
+
// Permission Definition Provider (lazy-loaded)
|
|
517
|
+
provideLazyProvider(AXP_PERMISSION_DEFINITION_PROVIDER, () => Promise.resolve().then(function () { return permissionDefinition_provider; }).then((m) => m.AXMAssetManagementPermissionDefinitionProvider)),
|
|
518
|
+
// Menu Provider (lazy-loaded)
|
|
519
|
+
provideLazyProvider(AXP_MENU_PROVIDER, () => Promise.resolve().then(function () { return menu_provider; }).then((m) => m.AXMAssetManagementMenuProvider)),
|
|
520
|
+
// Entity Provider (lazy-loaded)
|
|
521
|
+
// Search Provider (lazy-loaded)
|
|
522
|
+
provideLazyProvider(AXP_SEARCH_PROVIDER, () => Promise.resolve().then(function () { return searchCommand_provider; }).then((m) => m.AXMAssetManagementSearchCommandProvider)),
|
|
523
|
+
provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => Promise.resolve().then(function () { return index; }).then((m) => m.AXMAssetTypeComponentsPageComponentProvider)),
|
|
524
|
+
provideCommand('AssetType:Components:Save', () => Promise.resolve().then(function () { return saveAssetTypeComponents_command; }).then((m) => m.AXMSaveAssetTypeComponentsCommand)),
|
|
525
|
+
provideCommand(AXMAssetManagementCommandKeys.AssetRentalHistory.RentFrom, () => Promise.resolve().then(function () { return createAssetRentalHistoryRent_commands; }).then((m) => m.AXMCreateAssetRentalHistoryRentFromCommand)),
|
|
526
|
+
provideCommand(AXMAssetManagementCommandKeys.AssetRentalHistory.RentTo, () => Promise.resolve().then(function () { return createAssetRentalHistoryRent_commands; }).then((m) => m.AXMCreateAssetRentalHistoryRentToCommand)),
|
|
527
|
+
provideCommandSetups([
|
|
528
|
+
{
|
|
529
|
+
key: AXMAssetManagementCommandKeys.WorkflowActivity.RecalculateOperationalStatus,
|
|
530
|
+
command: () => import('./acorex-platform-module-asset-management-client-recalculate-asset-operational-status.activity-RGXS9fI1.mjs').then((c) => c.RecalculateAssetOperationalStatusActivity),
|
|
531
|
+
},
|
|
532
|
+
]),
|
|
533
|
+
// provideLazyProvider(AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, () =>
|
|
534
|
+
// import('./features/asset-status.rules').then((m) => m.AXMAssetManagementAssetStatusRulesExpressionScopeProvider),
|
|
535
|
+
// ),
|
|
536
|
+
// Status Providers
|
|
537
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => Promise.resolve().then(function () { return assetStatus_provider; }).then((m) => m.AXMAssetManagementAssetStatusProvider)),
|
|
538
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => import('./acorex-platform-module-asset-management-client-asset-rental-history-status.provider-DwhQPb0-.mjs').then((m) => m.AXMAssetManagementAssetRentalHistoryStatusProvider)),
|
|
539
|
+
provideLazyProvider(AXP_STATUS_PROVIDERS, () => import('./acorex-platform-module-asset-management-client-asset-lifecycle.provider-BDaCpGsv.mjs').then((m) => m.AXMAssetManagementAssetLifecycleStatusProvider)),
|
|
540
|
+
{
|
|
541
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
542
|
+
useValue: assetSystemTypeHasChildMiddleware,
|
|
543
|
+
multi: true,
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
547
|
+
useValue: assetRentalHistoryPartyMiddleware,
|
|
548
|
+
multi: true,
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
552
|
+
useValue: assetTypeIntervalKindsMiddleware,
|
|
553
|
+
multi: true,
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
557
|
+
useValue: assetUsageValuesMiddleware,
|
|
558
|
+
multi: true,
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
}]
|
|
562
|
+
}] });
|
|
563
|
+
|
|
564
|
+
//#region ---- Imports ----
|
|
565
|
+
//#endregion
|
|
566
|
+
//#region ---- Feature Definition Provider ----
|
|
567
|
+
/**
|
|
568
|
+
* Asset Management Feature Definition Provider.
|
|
569
|
+
* Provides feature definitions for the Asset Management module.
|
|
570
|
+
*/
|
|
571
|
+
class AXMAssetManagementFeatureDefinitionProvider {
|
|
572
|
+
async provide(context) {
|
|
573
|
+
// Asset Management feature
|
|
574
|
+
context.addFeature(AXMAssetManagementFeatureKeys.AssetManagement, {
|
|
575
|
+
title: '@asset-management:features.asset-management.title',
|
|
576
|
+
description: '@asset-management:features.asset-management.description',
|
|
577
|
+
defaultValue: true,
|
|
578
|
+
type: 'boolean',
|
|
579
|
+
});
|
|
580
|
+
// // Advanced Maintenance feature
|
|
581
|
+
// context.addFeature(AXMAssetManagementFeatureKeys.AdvancedMaintenance, {
|
|
582
|
+
// title: '@asset-management:features.advanced-maintenance.title',
|
|
583
|
+
// description: '@asset-management:features.advanced-maintenance.description',
|
|
584
|
+
// defaultValue: false,
|
|
585
|
+
// type: 'boolean',
|
|
586
|
+
// });
|
|
587
|
+
// // Maintenance Scheduling feature
|
|
588
|
+
// context.addFeature(AXMAssetManagementFeatureKeys.MaintenanceScheduling, {
|
|
589
|
+
// title: '@asset-management:features.maintenance-scheduling.title',
|
|
590
|
+
// description: '@asset-management:features.maintenance-scheduling.description',
|
|
591
|
+
// defaultValue: true,
|
|
592
|
+
// type: 'boolean',
|
|
593
|
+
// });
|
|
594
|
+
// // Inspection Workflow feature
|
|
595
|
+
// context.addFeature(AXMAssetManagementFeatureKeys.InspectionWorkflow, {
|
|
596
|
+
// title: '@asset-management:features.inspection-workflow.title',
|
|
597
|
+
// description: '@asset-management:features.inspection-workflow.description',
|
|
598
|
+
// defaultValue: true,
|
|
599
|
+
// type: 'boolean',
|
|
600
|
+
// });
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
//#endregion
|
|
604
|
+
|
|
605
|
+
var featureDefinition_provider = /*#__PURE__*/Object.freeze({
|
|
606
|
+
__proto__: null,
|
|
607
|
+
AXMAssetManagementFeatureDefinitionProvider: AXMAssetManagementFeatureDefinitionProvider
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
//#region ---- Imports ----
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region ---- Menu Provider ----
|
|
613
|
+
/**
|
|
614
|
+
* Asset Management Menu Provider.
|
|
615
|
+
* Provides menu items for the Asset Management module with permission and feature checks.
|
|
616
|
+
*/
|
|
617
|
+
class AXMAssetManagementMenuProvider {
|
|
618
|
+
constructor() {
|
|
619
|
+
this.entityService = inject(AXPEntityService);
|
|
620
|
+
}
|
|
621
|
+
async provide(context) {
|
|
622
|
+
const module = RootConfig.module;
|
|
623
|
+
const keys = AXPAssetsMaintenancePermissionKeys;
|
|
624
|
+
const PLAN_EQUIPMENT_MENU_KEY = 'Configuration:Menu:PlantEquipment';
|
|
625
|
+
context.find(AXPCommonMenuKeys.PlantEquipment).addItems([
|
|
626
|
+
{
|
|
627
|
+
name: AXMAssetManagementMenuKeys.Assets,
|
|
628
|
+
text: '@asset-management:assets.menus.root.title',
|
|
629
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.asset.name),
|
|
630
|
+
priority: 2,
|
|
631
|
+
icon: RootConfig.entities.asset.icon,
|
|
632
|
+
policy: {
|
|
633
|
+
features: [module.name],
|
|
634
|
+
permissions: [keys.MaintainAssets],
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
name: AXMAssetManagementMenuKeys.AssetSystems,
|
|
639
|
+
text: '@asset-management:assetSystems.menus.root.title',
|
|
640
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.assetSystem.name),
|
|
641
|
+
priority: 3,
|
|
642
|
+
icon: RootConfig.entities.assetSystem.icon,
|
|
643
|
+
policy: {
|
|
644
|
+
features: [module.name],
|
|
645
|
+
permissions: [keys.MaintainAssets],
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
]);
|
|
649
|
+
const mainAssetsMaintenanceDivider = context.find(AXMAssetManagementMenuKeys.MainPlanEquipmentAssetsMaintenanceDivider);
|
|
650
|
+
if (!mainAssetsMaintenanceDivider.exists) {
|
|
651
|
+
context.find(AXPCommonMenuKeys.PlantEquipment).addItems([
|
|
652
|
+
{
|
|
653
|
+
name: AXMAssetManagementMenuKeys.MainPlanEquipmentAssetsMaintenanceDivider,
|
|
654
|
+
text: '',
|
|
655
|
+
type: 'break',
|
|
656
|
+
priority: 10,
|
|
657
|
+
},
|
|
658
|
+
]);
|
|
659
|
+
}
|
|
660
|
+
const planEquipmentMenu = context.find(PLAN_EQUIPMENT_MENU_KEY);
|
|
661
|
+
if (!planEquipmentMenu.exists) {
|
|
662
|
+
context.find(AXPCommonMenuKeys.Configuration).addItems([
|
|
663
|
+
{
|
|
664
|
+
name: PLAN_EQUIPMENT_MENU_KEY,
|
|
665
|
+
priority: 9000,
|
|
666
|
+
text: '@general:menus.plan-equipment.title',
|
|
667
|
+
icon: module.icon,
|
|
668
|
+
},
|
|
669
|
+
]);
|
|
670
|
+
}
|
|
671
|
+
context.find(PLAN_EQUIPMENT_MENU_KEY).addItems([
|
|
672
|
+
{
|
|
673
|
+
name: AXMAssetManagementMenuKeys.AssetTypes,
|
|
674
|
+
text: '@asset-management:assetTypes.menus.root.title',
|
|
675
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.assetType.name),
|
|
676
|
+
priority: 2,
|
|
677
|
+
icon: RootConfig.entities.assetType.icon,
|
|
678
|
+
policy: {
|
|
679
|
+
features: [module.name],
|
|
680
|
+
permissions: [keys.Setup],
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
name: AXMAssetManagementMenuKeys.AssetSystemTypes,
|
|
685
|
+
text: '@asset-management:assetSystemTypes.menus.root.title',
|
|
686
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.assetSystemType.name),
|
|
687
|
+
priority: 3,
|
|
688
|
+
icon: RootConfig.entities.assetSystemType.icon,
|
|
689
|
+
policy: {
|
|
690
|
+
features: [module.name],
|
|
691
|
+
permissions: [keys.Setup],
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
]);
|
|
695
|
+
const planEquipmentAssetsMaintenanceDivider = context.find(AXMAssetManagementMenuKeys.PlanEquipmentAssetsMaintenanceDivider);
|
|
696
|
+
if (!planEquipmentAssetsMaintenanceDivider.exists) {
|
|
697
|
+
context.find(PLAN_EQUIPMENT_MENU_KEY).addItems([
|
|
698
|
+
{
|
|
699
|
+
name: AXMAssetManagementMenuKeys.PlanEquipmentAssetsMaintenanceDivider,
|
|
700
|
+
text: '',
|
|
701
|
+
type: 'break',
|
|
702
|
+
priority: 10,
|
|
703
|
+
},
|
|
704
|
+
]);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
//#endregion
|
|
709
|
+
|
|
710
|
+
var menu_provider = /*#__PURE__*/Object.freeze({
|
|
711
|
+
__proto__: null,
|
|
712
|
+
AXMAssetManagementMenuProvider: AXMAssetManagementMenuProvider
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
//#endregion
|
|
716
|
+
//#region ----- Permission Definition Provider -----
|
|
717
|
+
/**
|
|
718
|
+
* Registers Assets & Maintenance capabilities owned by asset-management.
|
|
719
|
+
*/
|
|
720
|
+
class AXMAssetManagementPermissionDefinitionProvider {
|
|
721
|
+
async define(context) {
|
|
722
|
+
const keys = AXPAssetsMaintenancePermissionKeys;
|
|
723
|
+
const groups = AXPCommonPermissionGroupKeys;
|
|
724
|
+
const P = '@common:assets-maintenance.permissions';
|
|
725
|
+
const G = '@common:permission-groups';
|
|
726
|
+
context.addGroup(groups.AssetsMaintenance.Root, `${G}.assets-maintenance.title`, `${G}.assets-maintenance.description`, { order: 70 });
|
|
727
|
+
context
|
|
728
|
+
.addGroup(groups.AssetsMaintenance.Assets, `${G}.assets-maintenance-assets.title`, `${G}.assets-maintenance-assets.description`, { parent: groups.AssetsMaintenance.Root, order: 10 })
|
|
729
|
+
.addPermission(keys.Access, `${P}.access.title`, `${P}.access.description`)
|
|
730
|
+
.endPermission()
|
|
731
|
+
.addPermission(keys.MaintainAssets, `${P}.maintain-assets.title`, `${P}.maintain-assets.description`)
|
|
732
|
+
.endPermission()
|
|
733
|
+
.addPermission(keys.Setup, `${P}.setup.title`, `${P}.setup.description`)
|
|
734
|
+
.endPermission()
|
|
735
|
+
.endGroup();
|
|
736
|
+
}
|
|
737
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementPermissionDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
738
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementPermissionDefinitionProvider }); }
|
|
739
|
+
}
|
|
740
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetManagementPermissionDefinitionProvider, decorators: [{
|
|
741
|
+
type: Injectable
|
|
742
|
+
}] });
|
|
743
|
+
|
|
744
|
+
var permissionDefinition_provider = /*#__PURE__*/Object.freeze({
|
|
745
|
+
__proto__: null,
|
|
746
|
+
AXMAssetManagementPermissionDefinitionProvider: AXMAssetManagementPermissionDefinitionProvider
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
//#region ---- Imports ----
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region ---- Search Command Provider ----
|
|
752
|
+
class AXMAssetManagementSearchCommandProvider extends AXPSearchCommandProvider {
|
|
753
|
+
constructor() {
|
|
754
|
+
super(...arguments);
|
|
755
|
+
this.commands = [
|
|
756
|
+
{
|
|
757
|
+
id: 'create-asset',
|
|
758
|
+
group: 'command',
|
|
759
|
+
title: '@asset-management:assets.search.create-asset.title',
|
|
760
|
+
icon: RootConfig.entities.asset.icon,
|
|
761
|
+
description: '@asset-management:assets.search.create-asset.description',
|
|
762
|
+
command: {
|
|
763
|
+
name: 'Entity:Create',
|
|
764
|
+
options: createEntityCommandOptions(`${RootConfig.module.name}.${RootConfig.entities.asset.name}`, {
|
|
765
|
+
name: RootConfig.entities.asset.name,
|
|
766
|
+
module: RootConfig.module.name,
|
|
767
|
+
title: RootConfig.entities.asset.title,
|
|
768
|
+
}),
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
];
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
//#endregion
|
|
775
|
+
|
|
776
|
+
var searchCommand_provider = /*#__PURE__*/Object.freeze({
|
|
777
|
+
__proto__: null,
|
|
778
|
+
AXMAssetManagementSearchCommandProvider: AXMAssetManagementSearchCommandProvider
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
class AXMAssetManagementAssetStatusProvider extends AXPStatusProvider {
|
|
782
|
+
constructor() {
|
|
783
|
+
super(...arguments);
|
|
784
|
+
this.key = AXM_ASSET_STATUS_DEFINITION_KEY;
|
|
785
|
+
this.statuses = [
|
|
786
|
+
{
|
|
787
|
+
name: AXMAssetStatus.Available,
|
|
788
|
+
title: '@asset-management:assets.states.available',
|
|
789
|
+
icon: 'fa-light fa-circle-check',
|
|
790
|
+
color: 'success',
|
|
791
|
+
order: 1,
|
|
792
|
+
isInitial: true,
|
|
793
|
+
isFinal: false,
|
|
794
|
+
generateView: true,
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
name: AXMAssetStatus.Assigned,
|
|
798
|
+
title: '@asset-management:assets.states.assigned',
|
|
799
|
+
icon: 'fa-light fa-user-check',
|
|
800
|
+
color: 'info',
|
|
801
|
+
order: 2,
|
|
802
|
+
isInitial: false,
|
|
803
|
+
isFinal: false,
|
|
804
|
+
generateView: true,
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
name: AXMAssetStatus.UnderMaintenanceInspection,
|
|
808
|
+
title: '@asset-management:assets.states.under-maintenance',
|
|
809
|
+
icon: 'fa-light fa-toolbox',
|
|
810
|
+
color: 'warning',
|
|
811
|
+
order: 3,
|
|
812
|
+
isInitial: false,
|
|
813
|
+
isFinal: false,
|
|
814
|
+
generateView: true,
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
name: AXMAssetStatus.OutOfService,
|
|
818
|
+
title: '@asset-management:assets.states.out-of-service',
|
|
819
|
+
icon: 'fa-light fa-triangle-exclamation',
|
|
820
|
+
color: 'danger',
|
|
821
|
+
order: 4,
|
|
822
|
+
isInitial: false,
|
|
823
|
+
isFinal: false,
|
|
824
|
+
generateView: true,
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
name: AXMAssetStatus.Lost,
|
|
828
|
+
title: '@asset-management:assets.states.lost',
|
|
829
|
+
icon: 'fa-light fa-magnifying-glass-minus',
|
|
830
|
+
color: 'danger',
|
|
831
|
+
order: 5,
|
|
832
|
+
isInitial: false,
|
|
833
|
+
isFinal: false,
|
|
834
|
+
generateView: true,
|
|
835
|
+
},
|
|
836
|
+
];
|
|
837
|
+
this.transitions = [
|
|
838
|
+
{
|
|
839
|
+
from: AXMAssetStatus.Available,
|
|
840
|
+
to: AXMAssetStatus.Assigned,
|
|
841
|
+
title: '@asset-management:assets.transitions.assign',
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
from: AXMAssetStatus.Assigned,
|
|
845
|
+
to: AXMAssetStatus.Available,
|
|
846
|
+
title: '@asset-management:assets.transitions.unassign',
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
from: AXMAssetStatus.Available,
|
|
850
|
+
to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
851
|
+
title: '@asset-management:assets.transitions.start-maintenance',
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
from: AXMAssetStatus.Assigned,
|
|
855
|
+
to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
856
|
+
title: '@asset-management:assets.transitions.start-maintenance',
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
from: AXMAssetStatus.OutOfService,
|
|
860
|
+
to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
861
|
+
title: '@asset-management:assets.transitions.start-maintenance',
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
from: AXMAssetStatus.UnderMaintenanceInspection,
|
|
865
|
+
to: AXMAssetStatus.Available,
|
|
866
|
+
title: '@asset-management:assets.transitions.release-as-available',
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
from: AXMAssetStatus.UnderMaintenanceInspection,
|
|
870
|
+
to: AXMAssetStatus.Assigned,
|
|
871
|
+
title: '@asset-management:assets.transitions.restore-assignment',
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
from: AXMAssetStatus.UnderMaintenanceInspection,
|
|
875
|
+
to: AXMAssetStatus.OutOfService,
|
|
876
|
+
title: '@asset-management:assets.transitions.keep-out-of-service',
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
from: AXMAssetStatus.Available,
|
|
880
|
+
to: AXMAssetStatus.OutOfService,
|
|
881
|
+
title: '@asset-management:assets.transitions.mark-out-of-service',
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
from: AXMAssetStatus.Assigned,
|
|
885
|
+
to: AXMAssetStatus.OutOfService,
|
|
886
|
+
title: '@asset-management:assets.transitions.mark-out-of-service',
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
from: AXMAssetStatus.OutOfService,
|
|
890
|
+
to: AXMAssetStatus.Available,
|
|
891
|
+
title: '@asset-management:assets.transitions.restore-service',
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
from: AXMAssetStatus.OutOfService,
|
|
895
|
+
to: AXMAssetStatus.Assigned,
|
|
896
|
+
title: '@asset-management:assets.transitions.restore-service',
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
from: AXMAssetStatus.Available,
|
|
900
|
+
to: AXMAssetStatus.Lost,
|
|
901
|
+
title: '@asset-management:assets.transitions.mark-lost',
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
from: AXMAssetStatus.Assigned,
|
|
905
|
+
to: AXMAssetStatus.Lost,
|
|
906
|
+
title: '@asset-management:assets.transitions.mark-lost',
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
from: AXMAssetStatus.OutOfService,
|
|
910
|
+
to: AXMAssetStatus.Lost,
|
|
911
|
+
title: '@asset-management:assets.transitions.mark-lost',
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
from: AXMAssetStatus.UnderMaintenanceInspection,
|
|
915
|
+
to: AXMAssetStatus.Lost,
|
|
916
|
+
title: '@asset-management:assets.transitions.mark-lost',
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
from: AXMAssetStatus.Lost,
|
|
920
|
+
to: AXMAssetStatus.Available,
|
|
921
|
+
title: '@asset-management:assets.transitions.found',
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
from: AXMAssetStatus.Lost,
|
|
925
|
+
to: AXMAssetStatus.Assigned,
|
|
926
|
+
title: '@asset-management:assets.transitions.found',
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
from: AXMAssetStatus.Lost,
|
|
930
|
+
to: AXMAssetStatus.OutOfService,
|
|
931
|
+
title: '@asset-management:assets.transitions.found-out-of-service',
|
|
932
|
+
},
|
|
933
|
+
];
|
|
934
|
+
// readonly transitions: AXPStatusTransition[] = [
|
|
935
|
+
// {
|
|
936
|
+
// from: AXMAssetStatus.Available,
|
|
937
|
+
// to: AXMAssetStatus.Assigned,
|
|
938
|
+
// title: '@asset-management:assets.transitions.assign',
|
|
939
|
+
// },
|
|
940
|
+
// {
|
|
941
|
+
// from: AXMAssetStatus.Assigned,
|
|
942
|
+
// to: AXMAssetStatus.Available,
|
|
943
|
+
// title: '@asset-management:assets.transitions.unassign',
|
|
944
|
+
// },
|
|
945
|
+
// {
|
|
946
|
+
// from: AXMAssetStatus.Assigned,
|
|
947
|
+
// to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
948
|
+
// title: '@asset-management:assets.transitions.start-maintenance',
|
|
949
|
+
// },
|
|
950
|
+
// {
|
|
951
|
+
// from: AXMAssetStatus.Assigned,
|
|
952
|
+
// to: AXMAssetStatus.OutOfService,
|
|
953
|
+
// title: '@asset-management:assets.transitions.mark-out-of-service',
|
|
954
|
+
// },
|
|
955
|
+
// {
|
|
956
|
+
// from: AXMAssetStatus.Available,
|
|
957
|
+
// to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
958
|
+
// title: '@asset-management:assets.transitions.start-maintenance',
|
|
959
|
+
// },
|
|
960
|
+
// {
|
|
961
|
+
// from: AXMAssetStatus.OutOfService,
|
|
962
|
+
// to: AXMAssetStatus.UnderMaintenanceInspection,
|
|
963
|
+
// title: '@asset-management:assets.transitions.start-maintenance',
|
|
964
|
+
// },
|
|
965
|
+
// {
|
|
966
|
+
// from: AXMAssetStatus.UnderMaintenanceInspection,
|
|
967
|
+
// to: AXMAssetStatus.Available,
|
|
968
|
+
// title: '@asset-management:assets.transitions.complete-maintenance',
|
|
969
|
+
// },
|
|
970
|
+
// {
|
|
971
|
+
// from: AXMAssetStatus.Available,
|
|
972
|
+
// to: AXMAssetStatus.OutOfService,
|
|
973
|
+
// title: '@asset-management:assets.transitions.mark-out-of-service',
|
|
974
|
+
// },
|
|
975
|
+
// {
|
|
976
|
+
// from: AXMAssetStatus.OutOfService,
|
|
977
|
+
// to: AXMAssetStatus.Available,
|
|
978
|
+
// title: '@asset-management:assets.transitions.restore-service',
|
|
979
|
+
// },
|
|
980
|
+
// {
|
|
981
|
+
// from: AXMAssetStatus.Available,
|
|
982
|
+
// to: AXMAssetStatus.Lost,
|
|
983
|
+
// title: '@asset-management:assets.transitions.mark-lost',
|
|
984
|
+
// },
|
|
985
|
+
// {
|
|
986
|
+
// from: AXMAssetStatus.Assigned,
|
|
987
|
+
// to: AXMAssetStatus.Lost,
|
|
988
|
+
// title: '@asset-management:assets.transitions.mark-lost',
|
|
989
|
+
// },
|
|
990
|
+
// {
|
|
991
|
+
// from: AXMAssetStatus.Lost,
|
|
992
|
+
// to: AXMAssetStatus.Available,
|
|
993
|
+
// title: '@asset-management:assets.transitions.found',
|
|
994
|
+
// },
|
|
995
|
+
// ];
|
|
996
|
+
this.defaultStatus = AXMAssetStatus.Available;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
var assetStatus_provider = /*#__PURE__*/Object.freeze({
|
|
1001
|
+
__proto__: null,
|
|
1002
|
+
AXMAssetManagementAssetStatusProvider: AXMAssetManagementAssetStatusProvider
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
const rentalHistorySharedCreateFields = [
|
|
1006
|
+
'rentalDirection',
|
|
1007
|
+
'createdDate',
|
|
1008
|
+
'startDate',
|
|
1009
|
+
'monthlyRent',
|
|
1010
|
+
'expectedReturnDate',
|
|
1011
|
+
'actualReturnDate',
|
|
1012
|
+
'status',
|
|
1013
|
+
'description',
|
|
1014
|
+
];
|
|
1015
|
+
//#endregion
|
|
1016
|
+
//#region ---- Helpers ----
|
|
1017
|
+
function buildRentCreateOptions(direction) {
|
|
1018
|
+
const isRentFrom = direction === 'rentFrom';
|
|
1019
|
+
return {
|
|
1020
|
+
includeProperties: [
|
|
1021
|
+
...rentalHistorySharedCreateFields,
|
|
1022
|
+
isRentFrom ? 'rentedFromId' : 'rentedToId',
|
|
1023
|
+
],
|
|
1024
|
+
excludeProperties: [isRentFrom ? 'rentedToId' : 'rentedFromId'],
|
|
1025
|
+
decoration: {
|
|
1026
|
+
header: {
|
|
1027
|
+
title: isRentFrom
|
|
1028
|
+
? '@asset-management:assetRentalHistories.entities.assetRentalHistory.actions.rent-from.dialog-title'
|
|
1029
|
+
: '@asset-management:assetRentalHistories.entities.assetRentalHistory.actions.rent-to.dialog-title',
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
process: {
|
|
1033
|
+
redirect: false,
|
|
1034
|
+
canCreateNewOne: true,
|
|
1035
|
+
},
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
//#endregion
|
|
1039
|
+
//#region ---- Commands ----
|
|
1040
|
+
class AXMCreateAssetRentalHistoryRentCommandBase {
|
|
1041
|
+
constructor() {
|
|
1042
|
+
this.commandService = inject(AXPCommandService);
|
|
1043
|
+
}
|
|
1044
|
+
async execute(input) {
|
|
1045
|
+
const seedData = this.resolveSeedData(input);
|
|
1046
|
+
const createOptions = buildRentCreateOptions(this.rentalDirection);
|
|
1047
|
+
const result = await this.commandService.execute('Entity:Create', {
|
|
1048
|
+
entity: RootConfig.entities.assetRentalHistory.source,
|
|
1049
|
+
entityInfo: {
|
|
1050
|
+
name: RootConfig.entities.assetRentalHistory.name,
|
|
1051
|
+
module: RootConfig.module.name,
|
|
1052
|
+
title: RootConfig.entities.assetRentalHistory.title,
|
|
1053
|
+
},
|
|
1054
|
+
data: seedData,
|
|
1055
|
+
options: createOptions,
|
|
1056
|
+
});
|
|
1057
|
+
return result ?? { success: false };
|
|
1058
|
+
}
|
|
1059
|
+
resolveSeedData(input) {
|
|
1060
|
+
const ctx = input;
|
|
1061
|
+
const options = (input.options ?? ctx.options ?? {});
|
|
1062
|
+
const process = (options['process'] ?? {});
|
|
1063
|
+
const processData = process['data'];
|
|
1064
|
+
const contextData = ctx.data ?? input.data ?? {};
|
|
1065
|
+
return merge({}, typeof contextData === 'object' &&
|
|
1066
|
+
contextData !== null &&
|
|
1067
|
+
!Array.isArray(contextData)
|
|
1068
|
+
? contextData
|
|
1069
|
+
: {}, typeof processData === 'object' &&
|
|
1070
|
+
processData !== null &&
|
|
1071
|
+
!Array.isArray(processData)
|
|
1072
|
+
? processData
|
|
1073
|
+
: {}, { rentalDirection: this.rentalDirection });
|
|
1074
|
+
}
|
|
1075
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentCommandBase, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1076
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentCommandBase, providedIn: 'root' }); }
|
|
1077
|
+
}
|
|
1078
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentCommandBase, decorators: [{
|
|
1079
|
+
type: Injectable,
|
|
1080
|
+
args: [{ providedIn: 'root' }]
|
|
1081
|
+
}] });
|
|
1082
|
+
class AXMCreateAssetRentalHistoryRentFromCommand extends AXMCreateAssetRentalHistoryRentCommandBase {
|
|
1083
|
+
constructor() {
|
|
1084
|
+
super(...arguments);
|
|
1085
|
+
this.rentalDirection = 'rentFrom';
|
|
1086
|
+
}
|
|
1087
|
+
static { this.commandKey = AXMAssetManagementCommandKeys.AssetRentalHistory.RentFrom; }
|
|
1088
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentFromCommand, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1089
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentFromCommand, providedIn: 'root' }); }
|
|
1090
|
+
}
|
|
1091
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentFromCommand, decorators: [{
|
|
1092
|
+
type: Injectable,
|
|
1093
|
+
args: [{ providedIn: 'root' }]
|
|
1094
|
+
}] });
|
|
1095
|
+
class AXMCreateAssetRentalHistoryRentToCommand extends AXMCreateAssetRentalHistoryRentCommandBase {
|
|
1096
|
+
constructor() {
|
|
1097
|
+
super(...arguments);
|
|
1098
|
+
this.rentalDirection = 'rentTo';
|
|
1099
|
+
}
|
|
1100
|
+
static { this.commandKey = AXMAssetManagementCommandKeys.AssetRentalHistory.RentTo; }
|
|
1101
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentToCommand, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1102
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentToCommand, providedIn: 'root' }); }
|
|
1103
|
+
}
|
|
1104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateAssetRentalHistoryRentToCommand, decorators: [{
|
|
1105
|
+
type: Injectable,
|
|
1106
|
+
args: [{ providedIn: 'root' }]
|
|
1107
|
+
}] });
|
|
1108
|
+
|
|
1109
|
+
var createAssetRentalHistoryRent_commands = /*#__PURE__*/Object.freeze({
|
|
1110
|
+
__proto__: null,
|
|
1111
|
+
AXMCreateAssetRentalHistoryRentFromCommand: AXMCreateAssetRentalHistoryRentFromCommand,
|
|
1112
|
+
AXMCreateAssetRentalHistoryRentToCommand: AXMCreateAssetRentalHistoryRentToCommand
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
function normalizeAssetTypeBuilderLocalizedField(value, fallback) {
|
|
1116
|
+
if (value == null || value === '') {
|
|
1117
|
+
return fallback;
|
|
1118
|
+
}
|
|
1119
|
+
if (typeof value === 'string') {
|
|
1120
|
+
const trimmed = value.trim();
|
|
1121
|
+
return trimmed || fallback;
|
|
1122
|
+
}
|
|
1123
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
1124
|
+
const record = value;
|
|
1125
|
+
const anyLocaleText = Object.values(record).some((v) => typeof v === 'string' && String(v).trim() !== '');
|
|
1126
|
+
if (anyLocaleText) {
|
|
1127
|
+
return value;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
return fallback;
|
|
1131
|
+
}
|
|
1132
|
+
function createAssetTypeSectionBuilderDefaultValue(assetTypeId) {
|
|
1133
|
+
return {
|
|
1134
|
+
sections: [
|
|
1135
|
+
{
|
|
1136
|
+
id: AXPDataGenerator.uuid(),
|
|
1137
|
+
code: 1,
|
|
1138
|
+
title: 'New Section',
|
|
1139
|
+
assetTypeId: assetTypeId ?? '',
|
|
1140
|
+
description: '',
|
|
1141
|
+
items: [],
|
|
1142
|
+
},
|
|
1143
|
+
],
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
function normalizeAssetTypeSectionBuilderValue(value, assetTypeId) {
|
|
1147
|
+
if (!value || typeof value !== 'object') {
|
|
1148
|
+
return createAssetTypeSectionBuilderDefaultValue(assetTypeId);
|
|
1149
|
+
}
|
|
1150
|
+
const raw = value;
|
|
1151
|
+
if (!Array.isArray(raw.sections) || raw.sections.length === 0) {
|
|
1152
|
+
return createAssetTypeSectionBuilderDefaultValue(assetTypeId);
|
|
1153
|
+
}
|
|
1154
|
+
return {
|
|
1155
|
+
sections: raw.sections.map((section, sectionIndex) => {
|
|
1156
|
+
const sectionData = (section ?? {});
|
|
1157
|
+
const id = typeof sectionData.id === 'string' && sectionData.id ? sectionData.id : AXPDataGenerator.uuid();
|
|
1158
|
+
const sectionItems = Array.isArray(sectionData.items) ? sectionData.items : [];
|
|
1159
|
+
return {
|
|
1160
|
+
id,
|
|
1161
|
+
code: typeof sectionData.code === 'number' ? sectionData.code : sectionIndex + 1,
|
|
1162
|
+
title: normalizeAssetTypeBuilderLocalizedField(sectionData.title, `Section ${sectionIndex + 1}`),
|
|
1163
|
+
assetTypeId: typeof sectionData.assetTypeId === 'string' && sectionData.assetTypeId
|
|
1164
|
+
? sectionData.assetTypeId
|
|
1165
|
+
: assetTypeId ?? '',
|
|
1166
|
+
description: normalizeAssetTypeBuilderLocalizedField(sectionData.description, ''),
|
|
1167
|
+
items: sectionItems.map((item, itemIndex) => {
|
|
1168
|
+
const itemData = (item ?? {});
|
|
1169
|
+
const rawAt = itemData.assetType;
|
|
1170
|
+
const assetTypeIdFromRef = rawAt &&
|
|
1171
|
+
typeof rawAt === 'object' &&
|
|
1172
|
+
typeof rawAt.id === 'string' &&
|
|
1173
|
+
String(rawAt.id).trim()
|
|
1174
|
+
? String(rawAt.id).trim()
|
|
1175
|
+
: '';
|
|
1176
|
+
const normalizedAssetTypeId = typeof itemData.assetTypeId === 'string' && itemData.assetTypeId.trim()
|
|
1177
|
+
? itemData.assetTypeId.trim()
|
|
1178
|
+
: assetTypeIdFromRef || (assetTypeId ?? '');
|
|
1179
|
+
const assetTypeRef = rawAt && typeof rawAt === 'object'
|
|
1180
|
+
? {
|
|
1181
|
+
id: typeof rawAt.id === 'string' && String(rawAt.id).trim()
|
|
1182
|
+
? String(rawAt.id).trim()
|
|
1183
|
+
: normalizedAssetTypeId,
|
|
1184
|
+
name: normalizeAssetTypeBuilderLocalizedField(rawAt.name, ''),
|
|
1185
|
+
}
|
|
1186
|
+
: {
|
|
1187
|
+
id: normalizedAssetTypeId,
|
|
1188
|
+
name: '',
|
|
1189
|
+
};
|
|
1190
|
+
return {
|
|
1191
|
+
id: typeof itemData.id === 'string' && itemData.id ? itemData.id : AXPDataGenerator.uuid(),
|
|
1192
|
+
assetTypeSectionId: typeof itemData.assetTypeSectionId === 'string' && itemData.assetTypeSectionId
|
|
1193
|
+
? itemData.assetTypeSectionId
|
|
1194
|
+
: id,
|
|
1195
|
+
assetTypeSectionComponentId: typeof itemData.assetTypeSectionComponentId === 'string' && itemData.assetTypeSectionComponentId
|
|
1196
|
+
? itemData.assetTypeSectionComponentId
|
|
1197
|
+
: undefined,
|
|
1198
|
+
assetTypeId: normalizedAssetTypeId,
|
|
1199
|
+
assetType: assetTypeRef,
|
|
1200
|
+
assetTypeSection: itemData.assetTypeSection,
|
|
1201
|
+
roleName: normalizeAssetTypeBuilderLocalizedField(itemData.roleName, ''),
|
|
1202
|
+
count: typeof itemData.count === 'number' ? itemData.count : 1,
|
|
1203
|
+
hasMaintenance: itemData.hasMaintenance === true,
|
|
1204
|
+
assetId: typeof itemData.assetId === 'string' && itemData.assetId ? itemData.assetId : undefined,
|
|
1205
|
+
asset: itemData.asset && typeof itemData.asset === 'object'
|
|
1206
|
+
? {
|
|
1207
|
+
id: typeof itemData.asset.id === 'string'
|
|
1208
|
+
? (itemData.asset.id ?? '')
|
|
1209
|
+
: '',
|
|
1210
|
+
code: typeof itemData.asset.code === 'string'
|
|
1211
|
+
? itemData.asset.code
|
|
1212
|
+
: undefined,
|
|
1213
|
+
title: normalizeAssetTypeBuilderLocalizedField(itemData.asset.title, ''),
|
|
1214
|
+
}
|
|
1215
|
+
: undefined,
|
|
1216
|
+
};
|
|
1217
|
+
}),
|
|
1218
|
+
};
|
|
1219
|
+
}),
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
class AXMAssetTypeSectionBuilderComponent {
|
|
1224
|
+
constructor() {
|
|
1225
|
+
this.value = input(null, /* @ts-ignore */
|
|
1226
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1227
|
+
this.assetTypeId = input(undefined, /* @ts-ignore */
|
|
1228
|
+
...(ngDevMode ? [{ debugName: "assetTypeId" }] : /* istanbul ignore next */ []));
|
|
1229
|
+
this.options = input({}, /* @ts-ignore */
|
|
1230
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
1231
|
+
this.valueChange = output();
|
|
1232
|
+
this.standardRef = viewChild(AXPStandardSectionItemsBuilderComponent, /* @ts-ignore */
|
|
1233
|
+
...(ngDevMode ? [{ debugName: "standardRef" }] : /* istanbul ignore next */ []));
|
|
1234
|
+
this.layoutBuilder = inject(AXPLayoutBuilderService);
|
|
1235
|
+
this.translationService = inject(AXTranslationService);
|
|
1236
|
+
this.disabledSectionPrompt = false;
|
|
1237
|
+
this.disabledAddSectionPrompt = async () => null;
|
|
1238
|
+
this.builderValue = signal({ sections: [] }, /* @ts-ignore */
|
|
1239
|
+
...(ngDevMode ? [{ debugName: "builderValue" }] : /* istanbul ignore next */ []));
|
|
1240
|
+
this.standardConfig = computed(() => ({
|
|
1241
|
+
mapItemToView: (item, _section) => this.mapItemToView(item),
|
|
1242
|
+
promptAddSection: this.allowAddSection() ? (value) => this.promptAddSection(value) : this.disabledAddSectionPrompt,
|
|
1243
|
+
promptEditSection: this.allowEditSection()
|
|
1244
|
+
? (section, value) => this.promptEditSection(section, value)
|
|
1245
|
+
: this.disabledSectionPrompt,
|
|
1246
|
+
promptAddItems: this.allowAddItems() ? (sectionId, value) => this.promptAddItems(sectionId, value) : undefined,
|
|
1247
|
+
promptEditItem: (item, sectionId, value) => this.linkAssetMode()
|
|
1248
|
+
? this.promptEditLinkedAssetItem(item, sectionId, value)
|
|
1249
|
+
: this.promptEditItem(item, sectionId, value),
|
|
1250
|
+
confirmRemoveSection: this.linkAssetMode() ? async () => false : undefined,
|
|
1251
|
+
confirmRemoveItem: this.linkAssetMode()
|
|
1252
|
+
? (item, sectionId) => this.confirmRemoveLinkedAssetItem(item, sectionId)
|
|
1253
|
+
: undefined,
|
|
1254
|
+
showSectionTechnicalName: false,
|
|
1255
|
+
allowReorderSections: this.allowReorderSections(),
|
|
1256
|
+
minSectionCount: this.allowAddSection() ? 1 : Number.MAX_SAFE_INTEGER,
|
|
1257
|
+
texts: {
|
|
1258
|
+
addSection: '@asset-management:assetTypeSections.entities.assetTypeSection.actions.add-section.title',
|
|
1259
|
+
addItem: '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.actions.add-item.title',
|
|
1260
|
+
},
|
|
1261
|
+
}), /* @ts-ignore */
|
|
1262
|
+
...(ngDevMode ? [{ debugName: "standardConfig" }] : /* istanbul ignore next */ []));
|
|
1263
|
+
this.hideHeaderActions = computed(() => this.options()['hideHeaderActions'] === true, /* @ts-ignore */
|
|
1264
|
+
...(ngDevMode ? [{ debugName: "hideHeaderActions" }] : /* istanbul ignore next */ []));
|
|
1265
|
+
this.allowAddSection = computed(() => this.options()['allowAddSection'] !== false, /* @ts-ignore */
|
|
1266
|
+
...(ngDevMode ? [{ debugName: "allowAddSection" }] : /* istanbul ignore next */ []));
|
|
1267
|
+
this.allowEditSection = computed(() => {
|
|
1268
|
+
if (this.linkAssetMode()) {
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
return this.options()['allowEditSection'] !== false;
|
|
1272
|
+
}, /* @ts-ignore */
|
|
1273
|
+
...(ngDevMode ? [{ debugName: "allowEditSection" }] : /* istanbul ignore next */ []));
|
|
1274
|
+
this.allowAddItems = computed(() => this.options()['allowAddItems'] !== false, /* @ts-ignore */
|
|
1275
|
+
...(ngDevMode ? [{ debugName: "allowAddItems" }] : /* istanbul ignore next */ []));
|
|
1276
|
+
this.allowReorderSections = computed(() => {
|
|
1277
|
+
const option = this.options()['allowReorderSections'];
|
|
1278
|
+
return typeof option === 'boolean' ? option : true;
|
|
1279
|
+
}, /* @ts-ignore */
|
|
1280
|
+
...(ngDevMode ? [{ debugName: "allowReorderSections" }] : /* istanbul ignore next */ []));
|
|
1281
|
+
this.readonly = computed(() => this.options()['readonly'] === true, /* @ts-ignore */
|
|
1282
|
+
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
1283
|
+
this.linkAssetMode = computed(() => this.options()['linkAssetMode'] === true, /* @ts-ignore */
|
|
1284
|
+
...(ngDevMode ? [{ debugName: "linkAssetMode" }] : /* istanbul ignore next */ []));
|
|
1285
|
+
this.#syncValueToBuilder = effect(() => {
|
|
1286
|
+
const raw = this.value();
|
|
1287
|
+
// In link mode an empty value means "template not loaded yet" — do not invent a default section.
|
|
1288
|
+
if (this.linkAssetMode() && (!raw || !Array.isArray(raw.sections) || raw.sections.length === 0)) {
|
|
1289
|
+
this.builderValue.set({ sections: [] });
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
const normalized = normalizeAssetTypeSectionBuilderValue(raw, this.assetTypeId());
|
|
1293
|
+
this.builderValue.set(this.toBuilderValue(normalized));
|
|
1294
|
+
}, /* @ts-ignore */
|
|
1295
|
+
...(ngDevMode ? [{ debugName: "#syncValueToBuilder" }] : /* istanbul ignore next */ []));
|
|
1296
|
+
}
|
|
1297
|
+
#syncValueToBuilder;
|
|
1298
|
+
async addSection() {
|
|
1299
|
+
await this.standardRef()?.addSection();
|
|
1300
|
+
}
|
|
1301
|
+
/** Aligns section-items baseline to persisted value after save. */
|
|
1302
|
+
syncAfterSave(value) {
|
|
1303
|
+
const normalized = normalizeAssetTypeSectionBuilderValue(value, this.assetTypeId());
|
|
1304
|
+
this.builderValue.set(this.toBuilderValue(normalized));
|
|
1305
|
+
queueMicrotask(() => this.standardRef()?.markClean());
|
|
1306
|
+
}
|
|
1307
|
+
/** Re-applies the current `[value]` input and clears builder dirty state after discard. */
|
|
1308
|
+
resetAfterDiscard() {
|
|
1309
|
+
const normalized = normalizeAssetTypeSectionBuilderValue(this.value(), this.assetTypeId());
|
|
1310
|
+
this.builderValue.set(this.toBuilderValue(normalized));
|
|
1311
|
+
queueMicrotask(() => this.standardRef()?.markClean());
|
|
1312
|
+
}
|
|
1313
|
+
onBuilderValueChange(next) {
|
|
1314
|
+
this.builderValue.set(next);
|
|
1315
|
+
const value = this.fromBuilderValue(next);
|
|
1316
|
+
this.valueChange.emit(value);
|
|
1317
|
+
}
|
|
1318
|
+
async promptAddSection(value) {
|
|
1319
|
+
const seed = {
|
|
1320
|
+
code: this.getNextSectionCode(value),
|
|
1321
|
+
title: '',
|
|
1322
|
+
description: '',
|
|
1323
|
+
};
|
|
1324
|
+
const dialogValue = await this.promptSectionForm('create', seed, value);
|
|
1325
|
+
if (!dialogValue)
|
|
1326
|
+
return null;
|
|
1327
|
+
const sectionId = AXPDataGenerator.uuid();
|
|
1328
|
+
return {
|
|
1329
|
+
id: sectionId,
|
|
1330
|
+
name: sectionId,
|
|
1331
|
+
code: dialogValue.code,
|
|
1332
|
+
title: dialogValue.title,
|
|
1333
|
+
description: dialogValue.description,
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
async promptEditSection(section, value) {
|
|
1337
|
+
const seed = {
|
|
1338
|
+
code: Number(section['code'] ?? 0) || this.getNextSectionCode(value),
|
|
1339
|
+
title: this.resolveLocalizedTextForDialog(section['title']),
|
|
1340
|
+
description: this.resolveLocalizedTextForDialog(section['description']),
|
|
1341
|
+
};
|
|
1342
|
+
const dialogValue = await this.promptSectionForm('edit', seed, value, section.id);
|
|
1343
|
+
if (!dialogValue)
|
|
1344
|
+
return null;
|
|
1345
|
+
return {
|
|
1346
|
+
...section,
|
|
1347
|
+
code: dialogValue.code,
|
|
1348
|
+
title: dialogValue.title,
|
|
1349
|
+
description: dialogValue.description,
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
async promptSectionForm(mode, seed, value, currentSectionId) {
|
|
1353
|
+
const title = mode === 'create'
|
|
1354
|
+
? (await this.translationService.translateAsync('@asset-management:assetTypeSections.entities.assetTypeSection.actions.add-section.title')) || 'Add Section'
|
|
1355
|
+
: (await this.translationService.translateAsync('@general:actions.edit.title')) || 'Edit';
|
|
1356
|
+
const result = await this.layoutBuilder
|
|
1357
|
+
.create()
|
|
1358
|
+
.dialog((dialog) => {
|
|
1359
|
+
dialog
|
|
1360
|
+
.setTitle(title)
|
|
1361
|
+
.setSize('sm')
|
|
1362
|
+
.setCloseButton(true)
|
|
1363
|
+
.setContext({ ...seed })
|
|
1364
|
+
.content((layout) => {
|
|
1365
|
+
layout.mode('edit');
|
|
1366
|
+
layout.dynamicForm(this.buildSectionFormDefinition());
|
|
1367
|
+
})
|
|
1368
|
+
.setActions((actions) => {
|
|
1369
|
+
actions.cancel('@general:actions.cancel.title').submit('@general:actions.save.title');
|
|
1370
|
+
})
|
|
1371
|
+
.onAction((dialogRef) => {
|
|
1372
|
+
if (dialogRef.action() === 'cancel') {
|
|
1373
|
+
return { success: false };
|
|
1374
|
+
}
|
|
1375
|
+
const context = dialogRef.context();
|
|
1376
|
+
const code = Number(context.code ?? 0);
|
|
1377
|
+
const titleValue = String(context.title ?? '').trim();
|
|
1378
|
+
const description = String(context.description ?? '');
|
|
1379
|
+
if (!Number.isFinite(code) || code <= 0 || !titleValue) {
|
|
1380
|
+
return { success: false };
|
|
1381
|
+
}
|
|
1382
|
+
if (this.isDuplicateSectionCode(value, code, currentSectionId)) {
|
|
1383
|
+
return { success: false };
|
|
1384
|
+
}
|
|
1385
|
+
return { success: true, kind: 'object', value: {
|
|
1386
|
+
code,
|
|
1387
|
+
title: titleValue,
|
|
1388
|
+
description,
|
|
1389
|
+
},
|
|
1390
|
+
};
|
|
1391
|
+
});
|
|
1392
|
+
})
|
|
1393
|
+
.show();
|
|
1394
|
+
return result?.success && result.value ? result.value : null;
|
|
1395
|
+
}
|
|
1396
|
+
isDuplicateSectionCode(value, code, currentSectionId) {
|
|
1397
|
+
return value.sections.some((section) => {
|
|
1398
|
+
if (currentSectionId && section.id === currentSectionId)
|
|
1399
|
+
return false;
|
|
1400
|
+
const sectionCode = Number(section['code'] ?? 0);
|
|
1401
|
+
return Number.isFinite(sectionCode) && sectionCode === code;
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
getNextSectionCode(value) {
|
|
1405
|
+
const maxCode = value.sections.reduce((max, section) => {
|
|
1406
|
+
const sectionCode = Number(section['code'] ?? 0);
|
|
1407
|
+
if (!Number.isFinite(sectionCode))
|
|
1408
|
+
return max;
|
|
1409
|
+
return Math.max(max, sectionCode);
|
|
1410
|
+
}, 0);
|
|
1411
|
+
return maxCode + 1;
|
|
1412
|
+
}
|
|
1413
|
+
mapItemToView(item) {
|
|
1414
|
+
const roleName = this.resolveLocalizedTextForDialog(item['roleName'] ?? '');
|
|
1415
|
+
const assetTypeName = this.resolveLocalizedTextForDialog(item['assetType']?.name ?? '');
|
|
1416
|
+
const count = Number(item['count'] ?? 0);
|
|
1417
|
+
const hasMaintenance = item['hasMaintenance'] === true;
|
|
1418
|
+
const linkedAsset = item['asset'];
|
|
1419
|
+
const linkedAssetCode = typeof linkedAsset?.code === 'string' ? linkedAsset.code : '';
|
|
1420
|
+
const linkedAssetTitle = this.resolveLocalizedTextForDialog(linkedAsset?.title ?? '');
|
|
1421
|
+
if (this.linkAssetMode()) {
|
|
1422
|
+
const hasLinkedAsset = !!item['assetId'];
|
|
1423
|
+
const linkedAssetName = linkedAssetTitle || '@asset-management:assets.entities.asset.components.asset-component.no-link';
|
|
1424
|
+
const linkedAssetDisplay = linkedAssetCode ? `${linkedAssetName} (${linkedAssetCode})` : linkedAssetName;
|
|
1425
|
+
return {
|
|
1426
|
+
icon: hasLinkedAsset ? 'fa-light fa-link' : 'fa-light fa-link-slash',
|
|
1427
|
+
iconTone: hasLinkedAsset ? 'easy' : 'hard',
|
|
1428
|
+
title: roleName,
|
|
1429
|
+
name: linkedAssetDisplay,
|
|
1430
|
+
badges: [
|
|
1431
|
+
{
|
|
1432
|
+
text: hasLinkedAsset
|
|
1433
|
+
? '@asset-management:assets.entities.asset.components.asset-component.assigned'
|
|
1434
|
+
: '@asset-management:assets.entities.asset.components.asset-component.unassigned',
|
|
1435
|
+
variant: hasLinkedAsset ? 'success' : 'warning',
|
|
1436
|
+
},
|
|
1437
|
+
...(hasLinkedAsset && linkedAssetTitle
|
|
1438
|
+
? [
|
|
1439
|
+
{
|
|
1440
|
+
text: linkedAssetTitle,
|
|
1441
|
+
variant: 'neutral',
|
|
1442
|
+
},
|
|
1443
|
+
]
|
|
1444
|
+
: []),
|
|
1445
|
+
{
|
|
1446
|
+
text: assetTypeName,
|
|
1447
|
+
variant: 'neutral',
|
|
1448
|
+
},
|
|
1449
|
+
],
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
return {
|
|
1453
|
+
icon: 'fa-light fa-cube',
|
|
1454
|
+
title: roleName,
|
|
1455
|
+
name: assetTypeName,
|
|
1456
|
+
badges: [
|
|
1457
|
+
{
|
|
1458
|
+
text: `x${count}`,
|
|
1459
|
+
variant: 'neutral',
|
|
1460
|
+
},
|
|
1461
|
+
...(hasMaintenance
|
|
1462
|
+
? [
|
|
1463
|
+
{
|
|
1464
|
+
text: '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.fields.hasMaintenance.title',
|
|
1465
|
+
variant: 'success',
|
|
1466
|
+
},
|
|
1467
|
+
]
|
|
1468
|
+
: []),
|
|
1469
|
+
],
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
async promptAddItems(sectionId, value) {
|
|
1473
|
+
const section = value.sections.find((item) => item.id === sectionId);
|
|
1474
|
+
if (!section)
|
|
1475
|
+
return null;
|
|
1476
|
+
const itemValue = await this.promptItemForm('create');
|
|
1477
|
+
if (!itemValue)
|
|
1478
|
+
return null;
|
|
1479
|
+
const nextOrder = section.items.length;
|
|
1480
|
+
const id = AXPDataGenerator.uuid();
|
|
1481
|
+
return [
|
|
1482
|
+
{
|
|
1483
|
+
id,
|
|
1484
|
+
order: nextOrder,
|
|
1485
|
+
name: itemValue.assetType.name,
|
|
1486
|
+
roleName: itemValue.roleName,
|
|
1487
|
+
count: itemValue.count,
|
|
1488
|
+
hasMaintenance: itemValue.hasMaintenance,
|
|
1489
|
+
assetType: itemValue.assetType,
|
|
1490
|
+
assetTypeSectionId: section.id,
|
|
1491
|
+
assetTypeId: itemValue.assetTypeId || this.assetTypeId() || '',
|
|
1492
|
+
},
|
|
1493
|
+
];
|
|
1494
|
+
}
|
|
1495
|
+
async promptEditItem(item, _sectionId, _value) {
|
|
1496
|
+
const dialogValue = await this.promptItemForm('edit', {
|
|
1497
|
+
assetTypeId: String(item['assetTypeId'] ?? this.assetTypeId() ?? ''),
|
|
1498
|
+
assetType: item['assetType'] ?? {
|
|
1499
|
+
id: String(item['assetTypeId'] ?? this.assetTypeId() ?? ''),
|
|
1500
|
+
name: '',
|
|
1501
|
+
},
|
|
1502
|
+
roleName: this.resolveLocalizedTextForDialog(item['roleName'] ?? item['name'] ?? ''),
|
|
1503
|
+
count: Number(item['count'] ?? 1),
|
|
1504
|
+
hasMaintenance: item['hasMaintenance'] === true,
|
|
1505
|
+
});
|
|
1506
|
+
if (!dialogValue)
|
|
1507
|
+
return null;
|
|
1508
|
+
return {
|
|
1509
|
+
...item,
|
|
1510
|
+
name: dialogValue.assetType.name,
|
|
1511
|
+
roleName: dialogValue.roleName,
|
|
1512
|
+
count: dialogValue.count,
|
|
1513
|
+
hasMaintenance: dialogValue.hasMaintenance,
|
|
1514
|
+
assetTypeId: dialogValue.assetTypeId,
|
|
1515
|
+
assetType: dialogValue.assetType,
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
async promptEditLinkedAssetItem(item, _sectionId, _value) {
|
|
1519
|
+
const assetTypeId = this.resolveLinkedItemAssetTypeId(item);
|
|
1520
|
+
const seed = {
|
|
1521
|
+
assetId: String(item['assetId'] ?? ''),
|
|
1522
|
+
assetTypeId,
|
|
1523
|
+
asset: item['asset'] ?? {
|
|
1524
|
+
id: '',
|
|
1525
|
+
code: '',
|
|
1526
|
+
title: '',
|
|
1527
|
+
},
|
|
1528
|
+
};
|
|
1529
|
+
const result = await this.promptLinkAssetForm(seed);
|
|
1530
|
+
if (!result) {
|
|
1531
|
+
return null;
|
|
1532
|
+
}
|
|
1533
|
+
return {
|
|
1534
|
+
...item,
|
|
1535
|
+
assetId: result.assetId || undefined,
|
|
1536
|
+
asset: result.assetId ? result.asset : undefined,
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
resolveLinkedItemAssetTypeId(item) {
|
|
1540
|
+
const fromField = typeof item['assetTypeId'] === 'string' ? item['assetTypeId'].trim() : '';
|
|
1541
|
+
if (fromField) {
|
|
1542
|
+
return fromField;
|
|
1543
|
+
}
|
|
1544
|
+
const nested = item['assetType'];
|
|
1545
|
+
if (nested && typeof nested.id === 'string' && nested.id.trim()) {
|
|
1546
|
+
return nested.id.trim();
|
|
1547
|
+
}
|
|
1548
|
+
return '';
|
|
1549
|
+
}
|
|
1550
|
+
async promptLinkAssetForm(seed) {
|
|
1551
|
+
const title = (await this.translationService.translateAsync('@asset-management:assets.entities.asset.components.asset-component.actions.edit.title')) || 'Edit Component Asset';
|
|
1552
|
+
const result = await this.layoutBuilder
|
|
1553
|
+
.create()
|
|
1554
|
+
.dialog((dialog) => {
|
|
1555
|
+
dialog
|
|
1556
|
+
.setTitle(title)
|
|
1557
|
+
.setSize('sm')
|
|
1558
|
+
.setCloseButton(true)
|
|
1559
|
+
.setContext({ ...seed })
|
|
1560
|
+
.content((layout) => {
|
|
1561
|
+
layout.mode('edit');
|
|
1562
|
+
layout.dynamicForm(this.buildLinkAssetFormDefinition(seed.assetTypeId));
|
|
1563
|
+
})
|
|
1564
|
+
.setActions((actions) => {
|
|
1565
|
+
actions.cancel('@general:actions.cancel.title').submit('@general:actions.save.title');
|
|
1566
|
+
})
|
|
1567
|
+
.onAction((dialogRef) => {
|
|
1568
|
+
if (dialogRef.action() === 'cancel') {
|
|
1569
|
+
return { success: false };
|
|
1570
|
+
}
|
|
1571
|
+
const context = dialogRef.context();
|
|
1572
|
+
const assetId = String(context.assetId ?? '').trim();
|
|
1573
|
+
const asset = context.asset ?? { id: assetId, code: '', title: '' };
|
|
1574
|
+
return { success: true, kind: 'object', value: {
|
|
1575
|
+
assetId,
|
|
1576
|
+
assetTypeId: String(context.assetTypeId ?? seed.assetTypeId ?? ''),
|
|
1577
|
+
asset: {
|
|
1578
|
+
id: String(asset.id ?? assetId),
|
|
1579
|
+
code: String(asset.code ?? ''),
|
|
1580
|
+
title: String(asset.title ?? ''),
|
|
1581
|
+
},
|
|
1582
|
+
},
|
|
1583
|
+
};
|
|
1584
|
+
});
|
|
1585
|
+
})
|
|
1586
|
+
.show();
|
|
1587
|
+
return result?.success && result.value ? result.value : null;
|
|
1588
|
+
}
|
|
1589
|
+
async confirmRemoveLinkedAssetItem(item, sectionId) {
|
|
1590
|
+
const hasLinkedAsset = typeof item['assetId'] === 'string' && item['assetId'].length > 0;
|
|
1591
|
+
if (!hasLinkedAsset) {
|
|
1592
|
+
return false;
|
|
1593
|
+
}
|
|
1594
|
+
const deleteTitle = (await this.translationService.translateAsync('@asset-management:assets.entities.asset.components.asset-component.actions.delete.title')) || 'Remove Component Asset';
|
|
1595
|
+
const linkedAsset = item['asset'];
|
|
1596
|
+
const linkedAssetTitle = this.resolveLocalizedTextForDialog(linkedAsset?.title ?? '');
|
|
1597
|
+
const linkedAssetCode = typeof linkedAsset?.code === 'string' ? linkedAsset.code : '';
|
|
1598
|
+
const assetDisplay = linkedAssetTitle || linkedAssetCode || String(item['assetId'] ?? '');
|
|
1599
|
+
const assetLabel = `${assetDisplay}${linkedAssetCode && linkedAssetTitle ? ` (${linkedAssetCode})` : ''}`;
|
|
1600
|
+
const deleteResult = await this.layoutBuilder
|
|
1601
|
+
.create()
|
|
1602
|
+
.dialog((dialog) => {
|
|
1603
|
+
dialog
|
|
1604
|
+
.setTitle(deleteTitle)
|
|
1605
|
+
.setMessage('@general:workflow.confirm-delete')
|
|
1606
|
+
.setSize('sm')
|
|
1607
|
+
.setCloseButton(true)
|
|
1608
|
+
.setContext({ assetLabel })
|
|
1609
|
+
.content((layout) => {
|
|
1610
|
+
layout.mode('edit');
|
|
1611
|
+
layout.dynamicForm(this.buildRemoveLinkedAssetFormDefinition());
|
|
1612
|
+
})
|
|
1613
|
+
.setActions((actions) => {
|
|
1614
|
+
actions.cancel('@general:actions.cancel.title').custom({
|
|
1615
|
+
title: '@general:actions.delete.title',
|
|
1616
|
+
color: 'danger',
|
|
1617
|
+
command: {
|
|
1618
|
+
name: 'delete',
|
|
1619
|
+
options: {
|
|
1620
|
+
validate: false,
|
|
1621
|
+
},
|
|
1622
|
+
},
|
|
1623
|
+
});
|
|
1624
|
+
})
|
|
1625
|
+
.onAction((dialogRef) => {
|
|
1626
|
+
if (dialogRef.action() !== 'delete') {
|
|
1627
|
+
return { success: false };
|
|
1628
|
+
}
|
|
1629
|
+
return { success: true, kind: 'object', data: undefined };
|
|
1630
|
+
});
|
|
1631
|
+
})
|
|
1632
|
+
.show();
|
|
1633
|
+
if (deleteResult?.success === true) {
|
|
1634
|
+
this.unlinkLinkedAssetItem(item.id, sectionId);
|
|
1635
|
+
}
|
|
1636
|
+
// Prevent structural row removal; only unlink asset assignment.
|
|
1637
|
+
return false;
|
|
1638
|
+
}
|
|
1639
|
+
buildRemoveLinkedAssetFormDefinition() {
|
|
1640
|
+
const group = {
|
|
1641
|
+
name: 'unlink-asset',
|
|
1642
|
+
title: '@asset-management:assets.entities.asset.components.asset-component.title',
|
|
1643
|
+
parameters: [
|
|
1644
|
+
{
|
|
1645
|
+
path: 'assetLabel',
|
|
1646
|
+
title: '@asset-management:assets.entities.asset.title',
|
|
1647
|
+
widget: {
|
|
1648
|
+
path: 'assetLabel',
|
|
1649
|
+
type: AXPWidgetsCatalog.text,
|
|
1650
|
+
options: {
|
|
1651
|
+
disabled: true,
|
|
1652
|
+
},
|
|
1653
|
+
},
|
|
1654
|
+
},
|
|
1655
|
+
],
|
|
1656
|
+
};
|
|
1657
|
+
return { groups: [group] };
|
|
1658
|
+
}
|
|
1659
|
+
unlinkLinkedAssetItem(itemId, sectionId) {
|
|
1660
|
+
const nextValue = {
|
|
1661
|
+
sections: this.builderValue().sections.map((section) => {
|
|
1662
|
+
if (section.id !== sectionId) {
|
|
1663
|
+
return section;
|
|
1664
|
+
}
|
|
1665
|
+
return {
|
|
1666
|
+
...section,
|
|
1667
|
+
items: section.items.map((item) => {
|
|
1668
|
+
if (item.id !== itemId) {
|
|
1669
|
+
return item;
|
|
1670
|
+
}
|
|
1671
|
+
return {
|
|
1672
|
+
...item,
|
|
1673
|
+
assetId: undefined,
|
|
1674
|
+
asset: undefined,
|
|
1675
|
+
};
|
|
1676
|
+
}),
|
|
1677
|
+
};
|
|
1678
|
+
}),
|
|
1679
|
+
};
|
|
1680
|
+
this.onBuilderValueChange(nextValue);
|
|
1681
|
+
}
|
|
1682
|
+
async promptItemForm(mode, seed) {
|
|
1683
|
+
const defaultSeed = seed ?? {
|
|
1684
|
+
assetTypeId: '',
|
|
1685
|
+
assetType: {
|
|
1686
|
+
id: '',
|
|
1687
|
+
name: '',
|
|
1688
|
+
},
|
|
1689
|
+
roleName: '',
|
|
1690
|
+
count: 1,
|
|
1691
|
+
hasMaintenance: false,
|
|
1692
|
+
};
|
|
1693
|
+
const title = mode === 'create'
|
|
1694
|
+
? (await this.translationService.translateAsync('@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.actions.add-item.title')) || 'Add Component'
|
|
1695
|
+
: (await this.translationService.translateAsync('@general:actions.edit.title')) || 'Edit';
|
|
1696
|
+
const formDefinition = this.buildItemFormDefinition();
|
|
1697
|
+
const result = await this.layoutBuilder
|
|
1698
|
+
.create()
|
|
1699
|
+
.dialog((dialog) => {
|
|
1700
|
+
dialog
|
|
1701
|
+
.setTitle(title)
|
|
1702
|
+
.setSize('sm')
|
|
1703
|
+
.setCloseButton(true)
|
|
1704
|
+
.setContext({ ...defaultSeed })
|
|
1705
|
+
.content((layout) => {
|
|
1706
|
+
layout.mode('edit');
|
|
1707
|
+
layout.dynamicForm(formDefinition);
|
|
1708
|
+
})
|
|
1709
|
+
.setActions((actions) => {
|
|
1710
|
+
actions.cancel('@general:actions.cancel.title').submit('@general:actions.save.title');
|
|
1711
|
+
})
|
|
1712
|
+
.onAction((dialogRef) => {
|
|
1713
|
+
if (dialogRef.action() === 'cancel') {
|
|
1714
|
+
return { success: false };
|
|
1715
|
+
}
|
|
1716
|
+
const context = dialogRef.context();
|
|
1717
|
+
const assetTypeId = String(context.assetTypeId ?? '').trim();
|
|
1718
|
+
const assetType = context.assetType;
|
|
1719
|
+
const roleName = String(context.roleName ?? '').trim();
|
|
1720
|
+
const count = Number(context.count ?? 0);
|
|
1721
|
+
const hasMaintenance = context.hasMaintenance === true;
|
|
1722
|
+
if (!assetTypeId) {
|
|
1723
|
+
return { success: false };
|
|
1724
|
+
}
|
|
1725
|
+
return { success: true, kind: 'object', value: {
|
|
1726
|
+
assetTypeId,
|
|
1727
|
+
assetType: {
|
|
1728
|
+
id: String(assetType?.id ?? assetTypeId),
|
|
1729
|
+
name: String(assetType?.name ?? ''),
|
|
1730
|
+
},
|
|
1731
|
+
roleName,
|
|
1732
|
+
count: Number.isFinite(count) && count > 0 ? count : 1,
|
|
1733
|
+
hasMaintenance,
|
|
1734
|
+
},
|
|
1735
|
+
};
|
|
1736
|
+
});
|
|
1737
|
+
})
|
|
1738
|
+
.show();
|
|
1739
|
+
return result?.success && result.value ? result.value : null;
|
|
1740
|
+
}
|
|
1741
|
+
buildItemFormDefinition() {
|
|
1742
|
+
const excludedAssetTypeId = this.assetTypeId();
|
|
1743
|
+
const group = {
|
|
1744
|
+
name: 'component',
|
|
1745
|
+
title: '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.title',
|
|
1746
|
+
parameters: [
|
|
1747
|
+
{
|
|
1748
|
+
path: 'assetTypeId',
|
|
1749
|
+
title: '@asset-management:assetTypes.entities.assetType.title',
|
|
1750
|
+
widget: {
|
|
1751
|
+
path: 'assetTypeId',
|
|
1752
|
+
type: AXPWidgetsCatalog.lookup,
|
|
1753
|
+
options: {
|
|
1754
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.assetType.name}`,
|
|
1755
|
+
textField: 'title',
|
|
1756
|
+
valueField: 'id',
|
|
1757
|
+
look: 'select',
|
|
1758
|
+
multiple: false,
|
|
1759
|
+
expose: [
|
|
1760
|
+
{ source: 'id', target: 'assetType.id' },
|
|
1761
|
+
{ source: 'title', target: 'assetType.name' },
|
|
1762
|
+
{ source: 'hasMaintenance', target: 'hasMaintenance' },
|
|
1763
|
+
],
|
|
1764
|
+
...(excludedAssetTypeId
|
|
1765
|
+
? {
|
|
1766
|
+
filter: { field: 'id', operator: { type: 'notEqual' }, value: excludedAssetTypeId },
|
|
1767
|
+
}
|
|
1768
|
+
: {}),
|
|
1769
|
+
validations: [{ rule: 'required' }],
|
|
1770
|
+
},
|
|
1771
|
+
},
|
|
1772
|
+
},
|
|
1773
|
+
this.toFieldDefinition('hasMaintenance', '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.fields.hasMaintenance.title', AXPWidgetsCatalog.toggle),
|
|
1774
|
+
this.toFieldDefinition('count', '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.fields.count.title', AXPWidgetsCatalog.number, [{ rule: 'required' }]),
|
|
1775
|
+
this.toFieldDefinition('roleName', '@asset-management:assetTypeSectionComponents.entities.assetTypeSectionComponent.fields.roleName.title', AXPWidgetsCatalog.largeText),
|
|
1776
|
+
],
|
|
1777
|
+
};
|
|
1778
|
+
return { groups: [group] };
|
|
1779
|
+
}
|
|
1780
|
+
buildSectionFormDefinition() {
|
|
1781
|
+
const group = {
|
|
1782
|
+
name: 'section',
|
|
1783
|
+
title: '@asset-management:assetTypeSections.entities.assetTypeSection.title',
|
|
1784
|
+
parameters: [
|
|
1785
|
+
this.toFieldDefinition('code', '@asset-management:assetTypeSections.entities.assetTypeSection.fields.code.title', AXPWidgetsCatalog.number, [{ rule: 'required' }]),
|
|
1786
|
+
this.toFieldDefinition('title', '@asset-management:assetTypeSections.entities.assetTypeSection.fields.title.title', AXPWidgetsCatalog.text, [{ rule: 'required' }]),
|
|
1787
|
+
this.toFieldDefinition('description', '@asset-management:assetTypeSections.entities.assetTypeSection.fields.description.title', AXPWidgetsCatalog.largeText),
|
|
1788
|
+
],
|
|
1789
|
+
};
|
|
1790
|
+
return { groups: [group] };
|
|
1791
|
+
}
|
|
1792
|
+
buildLinkAssetFormDefinition(requiredAssetTypeId) {
|
|
1793
|
+
const currentAssetId = this.options()['mainAssetId'];
|
|
1794
|
+
const assetTypeFilterValue = typeof requiredAssetTypeId === 'string' && requiredAssetTypeId.trim()
|
|
1795
|
+
? requiredAssetTypeId.trim()
|
|
1796
|
+
: "{{ context.eval('assetTypeId') }}";
|
|
1797
|
+
const filters = [
|
|
1798
|
+
...(typeof currentAssetId === 'string' && currentAssetId
|
|
1799
|
+
? [{ field: 'id', operator: { type: 'notEqual' }, value: currentAssetId }]
|
|
1800
|
+
: []),
|
|
1801
|
+
{
|
|
1802
|
+
field: 'assetTypeId',
|
|
1803
|
+
operator: { type: 'equal' },
|
|
1804
|
+
value: assetTypeFilterValue,
|
|
1805
|
+
},
|
|
1806
|
+
];
|
|
1807
|
+
const group = {
|
|
1808
|
+
name: 'asset-link',
|
|
1809
|
+
title: '@asset-management:assets.entities.asset.title',
|
|
1810
|
+
parameters: [
|
|
1811
|
+
{
|
|
1812
|
+
path: 'assetId',
|
|
1813
|
+
title: '@asset-management:assets.entities.asset.title',
|
|
1814
|
+
widget: {
|
|
1815
|
+
path: 'assetId',
|
|
1816
|
+
type: AXPWidgetsCatalog.lookup,
|
|
1817
|
+
options: {
|
|
1818
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.asset.name}`,
|
|
1819
|
+
textField: 'title',
|
|
1820
|
+
valueField: 'id',
|
|
1821
|
+
look: 'lookup',
|
|
1822
|
+
allowSearch: true,
|
|
1823
|
+
hasClearButton: true,
|
|
1824
|
+
columns: ['code', 'title', 'assetTypeId', 'statusId', 'locationId'],
|
|
1825
|
+
expose: [
|
|
1826
|
+
{ source: 'id', target: 'asset.id' },
|
|
1827
|
+
{ source: 'code', target: 'asset.code' },
|
|
1828
|
+
{ source: 'title', target: 'asset.title' },
|
|
1829
|
+
],
|
|
1830
|
+
filter: filters.length === 1 ? filters[0] : { logic: 'and', filters },
|
|
1831
|
+
validations: [{ rule: 'required' }],
|
|
1832
|
+
},
|
|
1833
|
+
},
|
|
1834
|
+
},
|
|
1835
|
+
],
|
|
1836
|
+
};
|
|
1837
|
+
return { groups: [group] };
|
|
1838
|
+
}
|
|
1839
|
+
toFieldDefinition(path, title, widgetType, validations = []) {
|
|
1840
|
+
return {
|
|
1841
|
+
path,
|
|
1842
|
+
title,
|
|
1843
|
+
widget: {
|
|
1844
|
+
path,
|
|
1845
|
+
type: widgetType,
|
|
1846
|
+
...(validations.length > 0 ? { options: { validations } } : {}),
|
|
1847
|
+
},
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
toBuilderValue(value) {
|
|
1851
|
+
return {
|
|
1852
|
+
sections: value.sections.map((section) => ({
|
|
1853
|
+
id: section.id,
|
|
1854
|
+
order: section.code - 1,
|
|
1855
|
+
name: section.id,
|
|
1856
|
+
code: section.code,
|
|
1857
|
+
title: section.title,
|
|
1858
|
+
description: section.description,
|
|
1859
|
+
items: section.items.map((item, itemIndex) => ({
|
|
1860
|
+
id: item.id,
|
|
1861
|
+
order: itemIndex,
|
|
1862
|
+
name: this.resolveLocalizedTextForDialog(item.assetType?.name ?? ''),
|
|
1863
|
+
assetType: item.assetType,
|
|
1864
|
+
roleName: item.roleName,
|
|
1865
|
+
count: item.count,
|
|
1866
|
+
hasMaintenance: item.hasMaintenance,
|
|
1867
|
+
assetTypeId: item.assetTypeId,
|
|
1868
|
+
assetTypeSectionId: item.assetTypeSectionId || section.id,
|
|
1869
|
+
assetTypeSectionComponentId: item.assetTypeSectionComponentId || item.id,
|
|
1870
|
+
assetId: item.assetId,
|
|
1871
|
+
asset: item.asset,
|
|
1872
|
+
})),
|
|
1873
|
+
})),
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
fromBuilderValue(value) {
|
|
1877
|
+
const assetTypeId = this.assetTypeId() ?? '';
|
|
1878
|
+
return {
|
|
1879
|
+
sections: value.sections.map((section, sectionIndex) => {
|
|
1880
|
+
const sectionId = section.id || AXPDataGenerator.uuid();
|
|
1881
|
+
const sectionCodeRaw = Number(section['code'] ?? sectionIndex + 1);
|
|
1882
|
+
const sectionCode = Number.isFinite(sectionCodeRaw) && sectionCodeRaw > 0 ? sectionCodeRaw : sectionIndex + 1;
|
|
1883
|
+
return {
|
|
1884
|
+
id: sectionId,
|
|
1885
|
+
code: sectionCode,
|
|
1886
|
+
title: normalizeAssetTypeBuilderLocalizedField(section['title'], `Section ${sectionCode}`),
|
|
1887
|
+
assetTypeId,
|
|
1888
|
+
description: normalizeAssetTypeBuilderLocalizedField(section['description'], ''),
|
|
1889
|
+
items: section.items.map((item) => this.mapBuilderItemToDomain(item, sectionId, assetTypeId)),
|
|
1890
|
+
};
|
|
1891
|
+
}),
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
mapBuilderItemToDomain(item, sectionId, assetTypeId) {
|
|
1895
|
+
const rawAt = item['assetType'];
|
|
1896
|
+
const normalizedAssetTypeId = (() => {
|
|
1897
|
+
const fromField = typeof item['assetTypeId'] === 'string' ? String(item['assetTypeId']).trim() : '';
|
|
1898
|
+
if (fromField)
|
|
1899
|
+
return fromField;
|
|
1900
|
+
const fromRef = typeof rawAt?.id === 'string' ? String(rawAt.id).trim() : '';
|
|
1901
|
+
if (fromRef)
|
|
1902
|
+
return fromRef;
|
|
1903
|
+
return String(assetTypeId ?? '');
|
|
1904
|
+
})();
|
|
1905
|
+
return {
|
|
1906
|
+
id: item.id || AXPDataGenerator.uuid(),
|
|
1907
|
+
assetTypeSectionId: String(item['assetTypeSectionId'] ?? sectionId),
|
|
1908
|
+
assetTypeId: normalizedAssetTypeId,
|
|
1909
|
+
assetType: {
|
|
1910
|
+
id: String(rawAt?.id ?? normalizedAssetTypeId),
|
|
1911
|
+
name: normalizeAssetTypeBuilderLocalizedField(rawAt?.name, ''),
|
|
1912
|
+
},
|
|
1913
|
+
roleName: normalizeAssetTypeBuilderLocalizedField(item['roleName'], ''),
|
|
1914
|
+
count: Number(item['count'] ?? 1),
|
|
1915
|
+
hasMaintenance: item['hasMaintenance'] === true,
|
|
1916
|
+
assetTypeSectionComponentId: String(item['assetTypeSectionComponentId'] ?? ''),
|
|
1917
|
+
assetId: typeof item['assetId'] === 'string' ? item['assetId'] : undefined,
|
|
1918
|
+
asset: item['asset'] && typeof item['asset'] === 'object'
|
|
1919
|
+
? {
|
|
1920
|
+
id: String(item['asset'].id ?? ''),
|
|
1921
|
+
code: typeof item['asset'].code === 'string'
|
|
1922
|
+
? (item['asset'].code ?? '')
|
|
1923
|
+
: undefined,
|
|
1924
|
+
title: normalizeAssetTypeBuilderLocalizedField(item['asset'].title, ''),
|
|
1925
|
+
}
|
|
1926
|
+
: undefined,
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
resolveLocalizedTextForDialog(value) {
|
|
1930
|
+
if (value == null || value === '') {
|
|
1931
|
+
return '';
|
|
1932
|
+
}
|
|
1933
|
+
if (typeof value === 'string') {
|
|
1934
|
+
return value;
|
|
1935
|
+
}
|
|
1936
|
+
return resolveMultiLanguageString(value, this.translationService.getActiveLang());
|
|
1937
|
+
}
|
|
1938
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeSectionBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1939
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAssetTypeSectionBuilderComponent, isStandalone: true, selector: "axm-asset-type-section-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, assetTypeId: { classPropertyName: "assetTypeId", publicName: "assetTypeId", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "standardRef", first: true, predicate: AXPStandardSectionItemsBuilderComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"axm-asset-type-section-builder\">\n @if (!readonly() && !hideHeaderActions() && allowAddSection()) {\n <div class=\"__header\">\n <div class=\"__header-left\"></div>\n <div class=\"__header-right\">\n <ax-button\n class=\"ax-sm\"\n [text]=\"'@asset-management:assetTypeSections.entities.assetTypeSection.actions.add-section.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"addSection()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n\n <axp-standard-section-items-builder\n class=\"block min-h-[200px]\"\n [value]=\"builderValue()\"\n [config]=\"standardConfig()\"\n [readonly]=\"readonly()\"\n (valueChange)=\"onBuilderValueChange($event)\" />\n</div>\n", styles: [".axm-asset-type-section-builder .__header{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;justify-content:space-between}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "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.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStandardSectionItemsBuilderComponent, selector: "axp-standard-section-items-builder", inputs: ["value", "config", "readonly"], outputs: ["valueChange"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1940
|
+
}
|
|
1941
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeSectionBuilderComponent, decorators: [{
|
|
1942
|
+
type: Component,
|
|
1943
|
+
args: [{ selector: 'axm-asset-type-section-builder', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1944
|
+
CommonModule,
|
|
1945
|
+
AXButtonModule,
|
|
1946
|
+
AXDecoratorModule,
|
|
1947
|
+
AXTranslationModule,
|
|
1948
|
+
AXPStandardSectionItemsBuilderComponent,
|
|
1949
|
+
], template: "<div class=\"axm-asset-type-section-builder\">\n @if (!readonly() && !hideHeaderActions() && allowAddSection()) {\n <div class=\"__header\">\n <div class=\"__header-left\"></div>\n <div class=\"__header-right\">\n <ax-button\n class=\"ax-sm\"\n [text]=\"'@asset-management:assetTypeSections.entities.assetTypeSection.actions.add-section.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"addSection()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-layer-group\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n\n <axp-standard-section-items-builder\n class=\"block min-h-[200px]\"\n [value]=\"builderValue()\"\n [config]=\"standardConfig()\"\n [readonly]=\"readonly()\"\n (valueChange)=\"onBuilderValueChange($event)\" />\n</div>\n", styles: [".axm-asset-type-section-builder .__header{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;justify-content:space-between}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
1950
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], assetTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "assetTypeId", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], standardRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPStandardSectionItemsBuilderComponent), { isSignal: true }] }] } });
|
|
1951
|
+
|
|
1952
|
+
const ASSET_TYPE_COMPONENTS_SAVE_COMMAND = 'AssetType:Components:Save';
|
|
1953
|
+
class AXMSaveAssetTypeComponentsCommand {
|
|
1954
|
+
constructor() {
|
|
1955
|
+
this.entityService = inject(AXPEntityService);
|
|
1956
|
+
this.translationService = inject(AXTranslationService);
|
|
1957
|
+
}
|
|
1958
|
+
async execute(input) {
|
|
1959
|
+
const id = input?.id;
|
|
1960
|
+
const entityRef = input?.entity || `${RootConfig.module.name}.${RootConfig.entities.assetType.name}`;
|
|
1961
|
+
const field = input?.field || 'components';
|
|
1962
|
+
const value = input?.value ?? { sections: [] };
|
|
1963
|
+
if (!id) {
|
|
1964
|
+
return {
|
|
1965
|
+
success: false,
|
|
1966
|
+
message: {
|
|
1967
|
+
text: await this.translationService.translateAsync('@general:messages.entity.invalid-data'),
|
|
1968
|
+
},
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
try {
|
|
1972
|
+
const payload = { [field]: value };
|
|
1973
|
+
const isAssetTypeComponentsUpdate = entityRef === `${RootConfig.module.name}.${RootConfig.entities.assetType.name}` && field === 'components';
|
|
1974
|
+
if (isAssetTypeComponentsUpdate) {
|
|
1975
|
+
payload['name'] = this.ensureLatinName(input.name, {
|
|
1976
|
+
fallback: input.title,
|
|
1977
|
+
id,
|
|
1978
|
+
});
|
|
1979
|
+
}
|
|
1980
|
+
await this.entityService.withEntity(entityRef).data().update(id, payload);
|
|
1981
|
+
return { success: true, kind: 'object',
|
|
1982
|
+
data: { id, field, value },
|
|
1983
|
+
message: {
|
|
1984
|
+
text: await this.translationService.translateAsync('@general:messages.generic.success.description'),
|
|
1985
|
+
},
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
catch (error) {
|
|
1989
|
+
const message = error instanceof Error
|
|
1990
|
+
? error.message
|
|
1991
|
+
: await this.translationService.translateAsync('@general:messages.generic.error.description');
|
|
1992
|
+
return {
|
|
1993
|
+
success: false,
|
|
1994
|
+
message: {
|
|
1995
|
+
text: message,
|
|
1996
|
+
},
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
ensureLatinName(raw, context) {
|
|
2001
|
+
const fromRaw = this.toLatinIdentifier(raw);
|
|
2002
|
+
if (fromRaw) {
|
|
2003
|
+
return fromRaw;
|
|
2004
|
+
}
|
|
2005
|
+
const fromTitle = this.toLatinIdentifier(context?.fallback);
|
|
2006
|
+
if (fromTitle) {
|
|
2007
|
+
return fromTitle;
|
|
2008
|
+
}
|
|
2009
|
+
const fromId = this.toLatinIdentifier(context?.id);
|
|
2010
|
+
if (fromId) {
|
|
2011
|
+
return fromId;
|
|
2012
|
+
}
|
|
2013
|
+
return 'asset_type';
|
|
2014
|
+
}
|
|
2015
|
+
toLatinIdentifier(value) {
|
|
2016
|
+
if (typeof value !== 'string') {
|
|
2017
|
+
return '';
|
|
2018
|
+
}
|
|
2019
|
+
return value
|
|
2020
|
+
.replace(/[^A-Za-z0-9_-]+/g, '_')
|
|
2021
|
+
.replace(/^_+|_+$/g, '')
|
|
2022
|
+
.replace(/_{2,}/g, '_');
|
|
2023
|
+
}
|
|
2024
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSaveAssetTypeComponentsCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2025
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSaveAssetTypeComponentsCommand, providedIn: 'root' }); }
|
|
2026
|
+
}
|
|
2027
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMSaveAssetTypeComponentsCommand, decorators: [{
|
|
2028
|
+
type: Injectable,
|
|
2029
|
+
args: [{
|
|
2030
|
+
providedIn: 'root',
|
|
2031
|
+
}]
|
|
2032
|
+
}] });
|
|
2033
|
+
|
|
2034
|
+
var saveAssetTypeComponents_command = /*#__PURE__*/Object.freeze({
|
|
2035
|
+
__proto__: null,
|
|
2036
|
+
ASSET_TYPE_COMPONENTS_SAVE_COMMAND: ASSET_TYPE_COMPONENTS_SAVE_COMMAND,
|
|
2037
|
+
AXMSaveAssetTypeComponentsCommand: AXMSaveAssetTypeComponentsCommand
|
|
2038
|
+
});
|
|
2039
|
+
|
|
2040
|
+
const ASSET_TYPE_SECTIONS_ADD_SECTION_COMMAND = 'AssetType:Sections:AddSection';
|
|
2041
|
+
const ASSET_TYPE_SECTIONS_DISCARD_COMMAND = 'AssetType:Sections:Discard';
|
|
2042
|
+
const ASSET_TYPE_SECTIONS_SAVE_COMMAND = 'AssetType:Sections:Save';
|
|
2043
|
+
class AXMAssetTypeSectionBuilderPageComponent extends AXPPageLayoutBaseComponent {
|
|
2044
|
+
constructor() {
|
|
2045
|
+
super(...arguments);
|
|
2046
|
+
/** Default `{}`: required inputs throw (NG0950) if read before `AXPPageComponentRendererDirective` calls `setInput` after `createComponent`. */
|
|
2047
|
+
this.rootContext = input({}, /* @ts-ignore */
|
|
2048
|
+
...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
|
|
2049
|
+
this.pageConfig = input(/* @ts-ignore */
|
|
2050
|
+
...(ngDevMode ? [undefined, { debugName: "pageConfig" }] : /* istanbul ignore next */ []));
|
|
2051
|
+
this.options = input({}, /* @ts-ignore */
|
|
2052
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2053
|
+
this.builderRef = viewChild('builderRef', /* @ts-ignore */
|
|
2054
|
+
...(ngDevMode ? [{ debugName: "builderRef" }] : /* istanbul ignore next */ []));
|
|
2055
|
+
this.commandService = inject(AXPCommandService);
|
|
2056
|
+
this.entityService = inject(AXPEntityService);
|
|
2057
|
+
this.hostPageLayout = inject(AXPPageLayoutBase, { optional: true, skipSelf: true });
|
|
2058
|
+
this.baselineValue = signal(null, /* @ts-ignore */
|
|
2059
|
+
...(ngDevMode ? [{ debugName: "baselineValue" }] : /* istanbul ignore next */ []));
|
|
2060
|
+
this.committedValue = signal(null, /* @ts-ignore */
|
|
2061
|
+
...(ngDevMode ? [{ debugName: "committedValue" }] : /* istanbul ignore next */ []));
|
|
2062
|
+
this.config = computed(() => ({
|
|
2063
|
+
...(this.pageConfig() ?? {}),
|
|
2064
|
+
...(this.options() ?? {}),
|
|
2065
|
+
}), /* @ts-ignore */
|
|
2066
|
+
...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
2067
|
+
this.fieldName = computed(() => {
|
|
2068
|
+
const field = this.readStringConfig('field');
|
|
2069
|
+
return field || 'components';
|
|
2070
|
+
}, /* @ts-ignore */
|
|
2071
|
+
...(ngDevMode ? [{ debugName: "fieldName" }] : /* istanbul ignore next */ []));
|
|
2072
|
+
this.sourceFieldName = computed(() => {
|
|
2073
|
+
const field = this.readStringConfig('sourceField');
|
|
2074
|
+
return field || this.fieldName();
|
|
2075
|
+
}, /* @ts-ignore */
|
|
2076
|
+
...(ngDevMode ? [{ debugName: "sourceFieldName" }] : /* istanbul ignore next */ []));
|
|
2077
|
+
this.sourceIdPath = computed(() => {
|
|
2078
|
+
const path = this.readStringConfig('sourceIdPath');
|
|
2079
|
+
return path || 'id';
|
|
2080
|
+
}, /* @ts-ignore */
|
|
2081
|
+
...(ngDevMode ? [{ debugName: "sourceIdPath" }] : /* istanbul ignore next */ []));
|
|
2082
|
+
this.targetIdPath = computed(() => {
|
|
2083
|
+
const path = this.readStringConfig('targetIdPath');
|
|
2084
|
+
return path || this.sourceIdPath();
|
|
2085
|
+
}, /* @ts-ignore */
|
|
2086
|
+
...(ngDevMode ? [{ debugName: "targetIdPath" }] : /* istanbul ignore next */ []));
|
|
2087
|
+
this.sourceEntityRef = computed(() => {
|
|
2088
|
+
const entity = this.readStringConfig('sourceEntity');
|
|
2089
|
+
return entity || `${RootConfig.module.name}.${RootConfig.entities.assetType.name}`;
|
|
2090
|
+
}, /* @ts-ignore */
|
|
2091
|
+
...(ngDevMode ? [{ debugName: "sourceEntityRef" }] : /* istanbul ignore next */ []));
|
|
2092
|
+
this.targetEntityRef = computed(() => {
|
|
2093
|
+
const entity = this.readStringConfig('targetEntity');
|
|
2094
|
+
return entity || this.sourceEntityRef();
|
|
2095
|
+
}, /* @ts-ignore */
|
|
2096
|
+
...(ngDevMode ? [{ debugName: "targetEntityRef" }] : /* istanbul ignore next */ []));
|
|
2097
|
+
this.context = computed(() => this.rootContext(), /* @ts-ignore */
|
|
2098
|
+
...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2099
|
+
this.sourceRecordId = computed(() => {
|
|
2100
|
+
const ctx = this.context();
|
|
2101
|
+
const id = get(ctx, this.sourceIdPath());
|
|
2102
|
+
if (typeof id === 'string' && id.length > 0) {
|
|
2103
|
+
return id;
|
|
2104
|
+
}
|
|
2105
|
+
// Lookup expose often hydrates nested `assetType.id` before/without top-level assetTypeId.
|
|
2106
|
+
if (this.sourceIdPath() === 'assetTypeId') {
|
|
2107
|
+
const nested = get(ctx, 'assetType.id');
|
|
2108
|
+
if (typeof nested === 'string' && nested.length > 0) {
|
|
2109
|
+
return nested;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
return undefined;
|
|
2113
|
+
}, /* @ts-ignore */
|
|
2114
|
+
...(ngDevMode ? [{ debugName: "sourceRecordId" }] : /* istanbul ignore next */ []));
|
|
2115
|
+
this.targetRecordId = computed(() => {
|
|
2116
|
+
const id = get(this.context(), this.targetIdPath());
|
|
2117
|
+
return typeof id === 'string' ? id : undefined;
|
|
2118
|
+
}, /* @ts-ignore */
|
|
2119
|
+
...(ngDevMode ? [{ debugName: "targetRecordId" }] : /* istanbul ignore next */ []));
|
|
2120
|
+
this.readonly = computed(() => this.readBooleanConfig('readonly'), /* @ts-ignore */
|
|
2121
|
+
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
2122
|
+
this.linkAssetMode = computed(() => this.readBooleanConfig('linkAssetMode'), /* @ts-ignore */
|
|
2123
|
+
...(ngDevMode ? [{ debugName: "linkAssetMode" }] : /* istanbul ignore next */ []));
|
|
2124
|
+
this.allowAddSection = computed(() => this.readBooleanConfig('allowAddSection', true), /* @ts-ignore */
|
|
2125
|
+
...(ngDevMode ? [{ debugName: "allowAddSection" }] : /* istanbul ignore next */ []));
|
|
2126
|
+
this.allowAddItems = computed(() => this.readBooleanConfig('allowAddItems', true), /* @ts-ignore */
|
|
2127
|
+
...(ngDevMode ? [{ debugName: "allowAddItems" }] : /* istanbul ignore next */ []));
|
|
2128
|
+
this.allowEditSection = computed(() => this.readBooleanConfig('allowEditSection', true), /* @ts-ignore */
|
|
2129
|
+
...(ngDevMode ? [{ debugName: "allowEditSection" }] : /* istanbul ignore next */ []));
|
|
2130
|
+
this.allowReorderSections = computed(() => this.readBooleanConfig('allowReorderSections', true), /* @ts-ignore */
|
|
2131
|
+
...(ngDevMode ? [{ debugName: "allowReorderSections" }] : /* istanbul ignore next */ []));
|
|
2132
|
+
this.builderOptions = computed(() => ({
|
|
2133
|
+
hideHeaderActions: true,
|
|
2134
|
+
readonly: this.readonly(),
|
|
2135
|
+
linkAssetMode: this.linkAssetMode(),
|
|
2136
|
+
mainAssetId: this.targetRecordId(),
|
|
2137
|
+
allowAddSection: this.allowAddSection(),
|
|
2138
|
+
allowEditSection: this.allowEditSection(),
|
|
2139
|
+
allowAddItems: this.allowAddItems(),
|
|
2140
|
+
allowReorderSections: this.allowReorderSections(),
|
|
2141
|
+
}), /* @ts-ignore */
|
|
2142
|
+
...(ngDevMode ? [{ debugName: "builderOptions" }] : /* istanbul ignore next */ []));
|
|
2143
|
+
this.isDirty = computed(() => {
|
|
2144
|
+
const baseline = this.baselineValue();
|
|
2145
|
+
const committed = this.committedValue();
|
|
2146
|
+
return !isEqual(baseline ?? null, committed ?? null);
|
|
2147
|
+
}, /* @ts-ignore */
|
|
2148
|
+
...(ngDevMode ? [{ debugName: "isDirty" }] : /* istanbul ignore next */ []));
|
|
2149
|
+
this.#syncFromContext = effect((onCleanup) => {
|
|
2150
|
+
const ctx = this.context();
|
|
2151
|
+
const id = this.sourceRecordId();
|
|
2152
|
+
const linkMode = this.linkAssetMode();
|
|
2153
|
+
const fieldName = this.fieldName();
|
|
2154
|
+
const sourceField = this.sourceFieldName();
|
|
2155
|
+
const value = get(ctx, fieldName);
|
|
2156
|
+
const linkedFromContext = get(ctx, fieldName);
|
|
2157
|
+
if (!linkMode) {
|
|
2158
|
+
const immediateValue = (value ?? null);
|
|
2159
|
+
this.baselineValue.set(immediateValue);
|
|
2160
|
+
this.committedValue.set(immediateValue);
|
|
2161
|
+
untracked(() => this.recompute());
|
|
2162
|
+
if (!id) {
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
let cancelled = false;
|
|
2166
|
+
const sourceEntityRef = this.sourceEntityRef();
|
|
2167
|
+
const load = async () => {
|
|
2168
|
+
try {
|
|
2169
|
+
const sourceRecord = await this.entityService.withEntity(sourceEntityRef).data().byKey(id);
|
|
2170
|
+
if (cancelled)
|
|
2171
|
+
return;
|
|
2172
|
+
const fallbackValue = get(sourceRecord, sourceField);
|
|
2173
|
+
const resolved = this.hasSections(value) ? value : (fallbackValue ?? null);
|
|
2174
|
+
this.baselineValue.set(resolved);
|
|
2175
|
+
this.committedValue.set(resolved);
|
|
2176
|
+
untracked(() => this.recompute());
|
|
2177
|
+
}
|
|
2178
|
+
catch {
|
|
2179
|
+
if (cancelled)
|
|
2180
|
+
return;
|
|
2181
|
+
this.baselineValue.set(immediateValue);
|
|
2182
|
+
this.committedValue.set(immediateValue);
|
|
2183
|
+
untracked(() => this.recompute());
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
void load();
|
|
2187
|
+
onCleanup(() => {
|
|
2188
|
+
cancelled = true;
|
|
2189
|
+
});
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
// ----- linkAssetMode: template from source entity (AssetType), links on target (Asset) -----
|
|
2193
|
+
// Never use target context's `components` (or empty defaults) as the structure template.
|
|
2194
|
+
if (!id) {
|
|
2195
|
+
const empty = this.buildLinkedAssetValue(null, this.pickPersistedComponentLinks(linkedFromContext, undefined));
|
|
2196
|
+
this.baselineValue.set(empty);
|
|
2197
|
+
this.committedValue.set(empty);
|
|
2198
|
+
untracked(() => this.recompute());
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
let cancelled = false;
|
|
2202
|
+
const sourceEntityRef = this.sourceEntityRef();
|
|
2203
|
+
const targetEntityRef = this.targetEntityRef();
|
|
2204
|
+
const targetRecordId = this.targetRecordId();
|
|
2205
|
+
const shouldFetchPersistedLinksFromTarget = typeof targetRecordId === 'string' &&
|
|
2206
|
+
targetRecordId.length > 0 &&
|
|
2207
|
+
targetEntityRef !== sourceEntityRef;
|
|
2208
|
+
const load = async () => {
|
|
2209
|
+
try {
|
|
2210
|
+
const [sourceRecord, targetRecord] = await Promise.all([
|
|
2211
|
+
this.entityService.withEntity(sourceEntityRef).data().byKey(id),
|
|
2212
|
+
shouldFetchPersistedLinksFromTarget
|
|
2213
|
+
? this.entityService.withEntity(targetEntityRef).data().byKey(targetRecordId)
|
|
2214
|
+
: Promise.resolve(null),
|
|
2215
|
+
]);
|
|
2216
|
+
if (cancelled)
|
|
2217
|
+
return;
|
|
2218
|
+
const template = get(sourceRecord, sourceField);
|
|
2219
|
+
const recordLinksUnknown = shouldFetchPersistedLinksFromTarget
|
|
2220
|
+
? get(targetRecord, fieldName)
|
|
2221
|
+
: get(sourceRecord, fieldName);
|
|
2222
|
+
const resolved = this.buildLinkedAssetValue(this.hasSections(template) ? (template ?? null) : null, this.pickPersistedComponentLinks(linkedFromContext, recordLinksUnknown));
|
|
2223
|
+
this.baselineValue.set(resolved);
|
|
2224
|
+
this.committedValue.set(resolved);
|
|
2225
|
+
untracked(() => this.recompute());
|
|
2226
|
+
}
|
|
2227
|
+
catch {
|
|
2228
|
+
if (cancelled)
|
|
2229
|
+
return;
|
|
2230
|
+
// Keep whatever is already shown; do not wipe with an empty target-context template.
|
|
2231
|
+
untracked(() => this.recompute());
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
void load();
|
|
2235
|
+
onCleanup(() => {
|
|
2236
|
+
cancelled = true;
|
|
2237
|
+
});
|
|
2238
|
+
}, /* @ts-ignore */
|
|
2239
|
+
...(ngDevMode ? [{ debugName: "#syncFromContext" }] : /* istanbul ignore next */ []));
|
|
2240
|
+
}
|
|
2241
|
+
#syncFromContext;
|
|
2242
|
+
onValueChange(value) {
|
|
2243
|
+
this.committedValue.set(value);
|
|
2244
|
+
this.updateRootContextField(this.fieldName(), this.linkAssetMode() ? this.toAssetComponentValue(value) : value);
|
|
2245
|
+
this.recompute();
|
|
2246
|
+
}
|
|
2247
|
+
getWizardStepContext() {
|
|
2248
|
+
const field = this.fieldName();
|
|
2249
|
+
const value = this.committedValue();
|
|
2250
|
+
if (!field || value == null) {
|
|
2251
|
+
return null;
|
|
2252
|
+
}
|
|
2253
|
+
const ctxValue = this.linkAssetMode() ? this.toAssetComponentValue(value) : value;
|
|
2254
|
+
return { [field]: cloneDeep(ctxValue) };
|
|
2255
|
+
}
|
|
2256
|
+
hasUnsavedChanges() {
|
|
2257
|
+
return this.isDirty();
|
|
2258
|
+
}
|
|
2259
|
+
async getPrimaryMenuItems() {
|
|
2260
|
+
if (this.readonly()) {
|
|
2261
|
+
return [];
|
|
2262
|
+
}
|
|
2263
|
+
const addSectionTitle = (await this.translateService.translateAsync('@asset-management:assetTypeSections.entities.assetTypeSection.actions.add-section.title')) || 'Add Section';
|
|
2264
|
+
const discardTitle = (await this.translateService.translateAsync('@general:actions.discard.title')) || 'Discard';
|
|
2265
|
+
const saveTitle = (await this.translateService.translateAsync('@general:actions.save.title')) || 'Save';
|
|
2266
|
+
return [
|
|
2267
|
+
...(this.allowAddSection()
|
|
2268
|
+
? [
|
|
2269
|
+
{
|
|
2270
|
+
title: addSectionTitle,
|
|
2271
|
+
icon: 'fa-light fa-layer-group',
|
|
2272
|
+
zone: 'header',
|
|
2273
|
+
priority: 'primary',
|
|
2274
|
+
color: 'primary',
|
|
2275
|
+
command: { name: ASSET_TYPE_SECTIONS_ADD_SECTION_COMMAND, options: {} },
|
|
2276
|
+
},
|
|
2277
|
+
]
|
|
2278
|
+
: []),
|
|
2279
|
+
{
|
|
2280
|
+
title: discardTitle,
|
|
2281
|
+
icon: 'fa-light fa-rotate-left',
|
|
2282
|
+
zone: 'footer',
|
|
2283
|
+
priority: 'secondary',
|
|
2284
|
+
color: 'default',
|
|
2285
|
+
visible: this.isDirty(),
|
|
2286
|
+
command: { name: ASSET_TYPE_SECTIONS_DISCARD_COMMAND, options: {} },
|
|
2287
|
+
},
|
|
2288
|
+
{
|
|
2289
|
+
title: saveTitle,
|
|
2290
|
+
icon: 'fa-light fa-floppy-disk',
|
|
2291
|
+
zone: 'footer',
|
|
2292
|
+
priority: 'primary',
|
|
2293
|
+
color: 'primary',
|
|
2294
|
+
visible: this.isDirty(),
|
|
2295
|
+
command: { name: ASSET_TYPE_SECTIONS_SAVE_COMMAND, options: {} },
|
|
2296
|
+
},
|
|
2297
|
+
];
|
|
2298
|
+
}
|
|
2299
|
+
async execute(command) {
|
|
2300
|
+
if (command.name === ASSET_TYPE_SECTIONS_ADD_SECTION_COMMAND) {
|
|
2301
|
+
await this.builderRef()?.addSection();
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
if (command.name === ASSET_TYPE_SECTIONS_DISCARD_COMMAND) {
|
|
2305
|
+
this.handleDiscard();
|
|
2306
|
+
return;
|
|
2307
|
+
}
|
|
2308
|
+
if (command.name !== ASSET_TYPE_SECTIONS_SAVE_COMMAND)
|
|
2309
|
+
return;
|
|
2310
|
+
await this.handleSave({ silent: false });
|
|
2311
|
+
}
|
|
2312
|
+
async handleSave(options) {
|
|
2313
|
+
const silent = options?.silent === true;
|
|
2314
|
+
const id = this.targetRecordId();
|
|
2315
|
+
const entity = this.targetEntityRef();
|
|
2316
|
+
const field = this.fieldName();
|
|
2317
|
+
const value = this.committedValue();
|
|
2318
|
+
if (!id || !entity || !field) {
|
|
2319
|
+
if (!silent) {
|
|
2320
|
+
this.toastService.show({
|
|
2321
|
+
color: 'danger',
|
|
2322
|
+
title: await this.translateService.translateAsync('@general:messages.error.title'),
|
|
2323
|
+
content: await this.translateService.translateAsync('@general:messages.entity.invalid-data'),
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
const root = (this.rootContext() ?? {});
|
|
2329
|
+
const result = await this.commandService.execute(ASSET_TYPE_COMPONENTS_SAVE_COMMAND, {
|
|
2330
|
+
id,
|
|
2331
|
+
entity,
|
|
2332
|
+
field,
|
|
2333
|
+
value: this.linkAssetMode() ? this.toAssetComponentValue(value ?? { sections: [] }) : (value ?? { sections: [] }),
|
|
2334
|
+
name: root['name'],
|
|
2335
|
+
title: root['title'],
|
|
2336
|
+
});
|
|
2337
|
+
if (result?.success) {
|
|
2338
|
+
const saved = value ?? { sections: [] };
|
|
2339
|
+
this.baselineValue.set(saved);
|
|
2340
|
+
this.committedValue.set(saved);
|
|
2341
|
+
this.updateRootContextField(field, this.linkAssetMode() ? this.toAssetComponentValue(saved) : saved);
|
|
2342
|
+
this.builderRef()?.syncAfterSave(saved);
|
|
2343
|
+
this.recompute();
|
|
2344
|
+
if (!silent) {
|
|
2345
|
+
this.toastService.show({
|
|
2346
|
+
color: 'success',
|
|
2347
|
+
title: await this.translateService.translateAsync('@general:messages.generic.success.title'),
|
|
2348
|
+
content: await this.translateService.translateAsync('@general:messages.generic.success.description'),
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
this.toastService.show({
|
|
2354
|
+
color: 'danger',
|
|
2355
|
+
title: await this.translateService.translateAsync('@general:messages.error.title'),
|
|
2356
|
+
content: await this.translateService.translateAsync('@general:messages.entity.update-failed'),
|
|
2357
|
+
});
|
|
2358
|
+
}
|
|
2359
|
+
recompute() {
|
|
2360
|
+
super.recompute();
|
|
2361
|
+
const layout = this.hostPageLayout;
|
|
2362
|
+
layout?.recompute?.();
|
|
2363
|
+
}
|
|
2364
|
+
handleDiscard() {
|
|
2365
|
+
const baseline = this.baselineValue() ?? { sections: [] };
|
|
2366
|
+
const field = this.fieldName();
|
|
2367
|
+
this.committedValue.set(baseline);
|
|
2368
|
+
this.updateRootContextField(field, this.linkAssetMode() ? this.toAssetComponentValue(baseline) : baseline);
|
|
2369
|
+
this.builderRef()?.resetAfterDiscard();
|
|
2370
|
+
this.recompute();
|
|
2371
|
+
}
|
|
2372
|
+
/** Keeps details-view `rootContext` in sync so sidebar navigation remounts with latest data. */
|
|
2373
|
+
updateRootContextField(field, value) {
|
|
2374
|
+
const ctx = this.rootContext();
|
|
2375
|
+
if (!ctx || typeof ctx !== 'object') {
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
ctx[field] = cloneDeep(value);
|
|
2379
|
+
}
|
|
2380
|
+
buildLinkedAssetValue(source, links) {
|
|
2381
|
+
if (!source || !Array.isArray(source.sections)) {
|
|
2382
|
+
return { sections: [] };
|
|
2383
|
+
}
|
|
2384
|
+
const groupedLinks = new Map();
|
|
2385
|
+
for (const link of links ?? []) {
|
|
2386
|
+
const key = String(link.assetTypeSectionComponentId ?? '');
|
|
2387
|
+
if (!key)
|
|
2388
|
+
continue;
|
|
2389
|
+
if (!groupedLinks.has(key))
|
|
2390
|
+
groupedLinks.set(key, []);
|
|
2391
|
+
groupedLinks.get(key).push(link);
|
|
2392
|
+
}
|
|
2393
|
+
return {
|
|
2394
|
+
sections: source.sections.map((section) => ({
|
|
2395
|
+
...section,
|
|
2396
|
+
items: (section.items ?? []).flatMap((item) => {
|
|
2397
|
+
const componentId = String(item.id ?? '');
|
|
2398
|
+
const count = Math.max(1, Number(item.count ?? 1));
|
|
2399
|
+
const existing = groupedLinks.get(componentId) ?? [];
|
|
2400
|
+
return Array.from({ length: count }).map((_, index) => {
|
|
2401
|
+
const linked = existing[index];
|
|
2402
|
+
return {
|
|
2403
|
+
...item,
|
|
2404
|
+
id: `${componentId}__slot_${index + 1}`,
|
|
2405
|
+
count: 1,
|
|
2406
|
+
assetTypeSectionComponentId: componentId,
|
|
2407
|
+
roleName: this.withSlotSuffix(item.roleName, index + 1),
|
|
2408
|
+
assetId: linked?.assetId,
|
|
2409
|
+
asset: linked?.asset
|
|
2410
|
+
? {
|
|
2411
|
+
id: linked.asset.id,
|
|
2412
|
+
code: linked.asset.code,
|
|
2413
|
+
title: linked.asset.title,
|
|
2414
|
+
}
|
|
2415
|
+
: undefined,
|
|
2416
|
+
};
|
|
2417
|
+
});
|
|
2418
|
+
}),
|
|
2419
|
+
})),
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
withSlotSuffix(value, slotIndex) {
|
|
2423
|
+
const normalized = normalizeAssetTypeBuilderLocalizedField(value, '');
|
|
2424
|
+
const suffix = `#${slotIndex}`;
|
|
2425
|
+
if (typeof normalized === 'string') {
|
|
2426
|
+
const base = normalized.trim();
|
|
2427
|
+
return base ? `${base} ${suffix}` : suffix;
|
|
2428
|
+
}
|
|
2429
|
+
return Object.fromEntries(Object.entries(normalized).map(([locale, text]) => {
|
|
2430
|
+
const trimmed = typeof text === 'string' ? text.trim() : '';
|
|
2431
|
+
return [locale, trimmed ? `${trimmed} ${suffix}` : suffix];
|
|
2432
|
+
}));
|
|
2433
|
+
}
|
|
2434
|
+
toAssetComponentValue(value) {
|
|
2435
|
+
const mainAssetId = this.targetRecordId() ?? '';
|
|
2436
|
+
return value.sections.flatMap((section) => (section.items ?? [])
|
|
2437
|
+
.filter((item) => typeof item.assetId === 'string' && item.assetId)
|
|
2438
|
+
.map((item) => ({
|
|
2439
|
+
id: item.id,
|
|
2440
|
+
assetId: String(item.assetId),
|
|
2441
|
+
asset: {
|
|
2442
|
+
id: String(item.asset?.id ?? item.assetId),
|
|
2443
|
+
code: String(item.asset?.code ?? ''),
|
|
2444
|
+
title: String(item.asset?.title ?? ''),
|
|
2445
|
+
},
|
|
2446
|
+
mainAssetId,
|
|
2447
|
+
mainAsset: {
|
|
2448
|
+
id: mainAssetId,
|
|
2449
|
+
code: '',
|
|
2450
|
+
title: '',
|
|
2451
|
+
},
|
|
2452
|
+
assetTypeSectionComponentId: String(item.assetTypeSectionComponentId ?? ''),
|
|
2453
|
+
assetTypeSectionComponent: {
|
|
2454
|
+
id: String(item.assetTypeSectionComponentId ?? ''),
|
|
2455
|
+
code: String(item.assetTypeSectionId ?? ''),
|
|
2456
|
+
title: String(item.roleName ?? ''),
|
|
2457
|
+
assetTypeId: String(item.assetTypeId ?? ''),
|
|
2458
|
+
assetType: {
|
|
2459
|
+
id: String(item.assetType?.id ?? String(item.assetTypeId ?? '')),
|
|
2460
|
+
name: item.assetType?.name ?? '',
|
|
2461
|
+
},
|
|
2462
|
+
},
|
|
2463
|
+
})));
|
|
2464
|
+
}
|
|
2465
|
+
readStringConfig(key) {
|
|
2466
|
+
const rootValue = this.config()[key];
|
|
2467
|
+
if (typeof rootValue === 'string') {
|
|
2468
|
+
return rootValue;
|
|
2469
|
+
}
|
|
2470
|
+
return '';
|
|
2471
|
+
}
|
|
2472
|
+
readBooleanConfig(key, defaultValue = false) {
|
|
2473
|
+
const rootValue = this.config()[key];
|
|
2474
|
+
if (typeof rootValue === 'boolean') {
|
|
2475
|
+
return rootValue;
|
|
2476
|
+
}
|
|
2477
|
+
return defaultValue;
|
|
2478
|
+
}
|
|
2479
|
+
hasSections(value) {
|
|
2480
|
+
return !!value && Array.isArray(value.sections) && value.sections.length > 0;
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Prefer links loaded with the record (`byKey`). Context often holds `assetComponents: []` from a
|
|
2484
|
+
* partial row merge; `[] ?? serverLinks` would keep the empty array and hide persisted assignments.
|
|
2485
|
+
*/
|
|
2486
|
+
pickPersistedComponentLinks(contextLinks, recordLinks) {
|
|
2487
|
+
if (recordLinks !== undefined) {
|
|
2488
|
+
return Array.isArray(recordLinks) ? recordLinks : [];
|
|
2489
|
+
}
|
|
2490
|
+
return Array.isArray(contextLinks) ? contextLinks : null;
|
|
2491
|
+
}
|
|
2492
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeSectionBuilderPageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2493
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.8", type: AXMAssetTypeSectionBuilderPageComponent, isStandalone: true, selector: "axm-asset-type-section-builder-page", inputs: { rootContext: { classPropertyName: "rootContext", publicName: "rootContext", isSignal: true, isRequired: false, transformFunction: null }, pageConfig: { classPropertyName: "pageConfig", publicName: "pageConfig", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.axp-page-layout-base": "true" } }, providers: [
|
|
2494
|
+
{
|
|
2495
|
+
provide: AXPPageLayoutBase,
|
|
2496
|
+
useExisting: AXMAssetTypeSectionBuilderPageComponent,
|
|
2497
|
+
},
|
|
2498
|
+
], viewQueries: [{ propertyName: "builderRef", first: true, predicate: ["builderRef"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
2499
|
+
<axm-asset-type-section-builder
|
|
2500
|
+
#builderRef
|
|
2501
|
+
[value]="committedValue()"
|
|
2502
|
+
[assetTypeId]="sourceRecordId()"
|
|
2503
|
+
[options]="builderOptions()"
|
|
2504
|
+
(valueChange)="onValueChange($event)"
|
|
2505
|
+
/>
|
|
2506
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AXMAssetTypeSectionBuilderComponent, selector: "axm-asset-type-section-builder", inputs: ["value", "assetTypeId", "options"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2507
|
+
}
|
|
2508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeSectionBuilderPageComponent, decorators: [{
|
|
2509
|
+
type: Component,
|
|
2510
|
+
args: [{
|
|
2511
|
+
selector: 'axm-asset-type-section-builder-page',
|
|
2512
|
+
standalone: true,
|
|
2513
|
+
imports: [AXMAssetTypeSectionBuilderComponent],
|
|
2514
|
+
providers: [
|
|
2515
|
+
{
|
|
2516
|
+
provide: AXPPageLayoutBase,
|
|
2517
|
+
useExisting: AXMAssetTypeSectionBuilderPageComponent,
|
|
2518
|
+
},
|
|
2519
|
+
],
|
|
2520
|
+
template: `
|
|
2521
|
+
<axm-asset-type-section-builder
|
|
2522
|
+
#builderRef
|
|
2523
|
+
[value]="committedValue()"
|
|
2524
|
+
[assetTypeId]="sourceRecordId()"
|
|
2525
|
+
[options]="builderOptions()"
|
|
2526
|
+
(valueChange)="onValueChange($event)"
|
|
2527
|
+
/>
|
|
2528
|
+
`,
|
|
2529
|
+
host: {
|
|
2530
|
+
'[class.axp-page-layout-base]': 'true',
|
|
2531
|
+
},
|
|
2532
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2533
|
+
}]
|
|
2534
|
+
}], propDecorators: { rootContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootContext", required: false }] }], pageConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageConfig", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], builderRef: [{ type: i0.ViewChild, args: ['builderRef', { isSignal: true }] }] } });
|
|
2535
|
+
|
|
2536
|
+
var assetTypeSectionBuilderPage_component = /*#__PURE__*/Object.freeze({
|
|
2537
|
+
__proto__: null,
|
|
2538
|
+
AXMAssetTypeSectionBuilderPageComponent: AXMAssetTypeSectionBuilderPageComponent
|
|
2539
|
+
});
|
|
2540
|
+
|
|
2541
|
+
class AXMAssetTypeComponentsPageComponentProvider {
|
|
2542
|
+
async components() {
|
|
2543
|
+
return [
|
|
2544
|
+
{
|
|
2545
|
+
key: ASSET_TYPE_COMPONENTS_PAGE_COMPONENT_KEY,
|
|
2546
|
+
loader: () => Promise.resolve().then(function () { return assetTypeSectionBuilderPage_component; }).then((m) => m.AXMAssetTypeSectionBuilderPageComponent),
|
|
2547
|
+
},
|
|
2548
|
+
];
|
|
2549
|
+
}
|
|
2550
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeComponentsPageComponentProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2551
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeComponentsPageComponentProvider }); }
|
|
2552
|
+
}
|
|
2553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetTypeComponentsPageComponentProvider, decorators: [{
|
|
2554
|
+
type: Injectable
|
|
2555
|
+
}] });
|
|
2556
|
+
|
|
2557
|
+
var index = /*#__PURE__*/_mergeNamespaces({
|
|
2558
|
+
__proto__: null,
|
|
2559
|
+
ASSET_TYPE_COMPONENTS_SAVE_COMMAND: ASSET_TYPE_COMPONENTS_SAVE_COMMAND,
|
|
2560
|
+
AXMAssetTypeComponentsPageComponentProvider: AXMAssetTypeComponentsPageComponentProvider,
|
|
2561
|
+
AXMAssetTypeSectionBuilderComponent: AXMAssetTypeSectionBuilderComponent,
|
|
2562
|
+
AXMAssetTypeSectionBuilderPageComponent: AXMAssetTypeSectionBuilderPageComponent,
|
|
2563
|
+
AXMSaveAssetTypeComponentsCommand: AXMSaveAssetTypeComponentsCommand,
|
|
2564
|
+
createAssetTypeSectionBuilderDefaultValue: createAssetTypeSectionBuilderDefaultValue,
|
|
2565
|
+
normalizeAssetTypeBuilderLocalizedField: normalizeAssetTypeBuilderLocalizedField,
|
|
2566
|
+
normalizeAssetTypeSectionBuilderValue: normalizeAssetTypeSectionBuilderValue
|
|
2567
|
+
}, [contracts]);
|
|
2568
|
+
|
|
2569
|
+
//#region ---- Imports ----
|
|
2570
|
+
//#endregion
|
|
2571
|
+
//#region ---- Constants ----
|
|
2572
|
+
const BLOCKING_WORK_ORDER_STATUSES = new Set(['in-progress', 'completed']);
|
|
2573
|
+
const PROTECTED_LIFECYCLE_STATUSES = new Set([AXMAssetLifecycleStatus.Retired, AXMAssetLifecycleStatus.Disposed]);
|
|
2574
|
+
const PROTECTED_OPERATIONAL_STATUSES = new Set([AXMAssetStatus.Lost]);
|
|
2575
|
+
//#endregion
|
|
2576
|
+
/**
|
|
2577
|
+
* Central policy for asset operational status changes driven by maintenance work orders.
|
|
2578
|
+
* Callers must not set `Asset.statusId` directly from workflows — use {@link recalculate} only.
|
|
2579
|
+
*/
|
|
2580
|
+
class AXMAssetOperationalStatusService {
|
|
2581
|
+
constructor() {
|
|
2582
|
+
//#region ---- Services & Dependencies ----
|
|
2583
|
+
this.entityService = inject(AXPEntityService);
|
|
2584
|
+
}
|
|
2585
|
+
//#endregion
|
|
2586
|
+
//#region ---- Public API ----
|
|
2587
|
+
async recalculate(assetIdRaw, trigger, context = {}) {
|
|
2588
|
+
const assetId = assetIdRaw?.trim();
|
|
2589
|
+
if (!assetId) {
|
|
2590
|
+
return {
|
|
2591
|
+
assetId: '',
|
|
2592
|
+
previousStatusId: null,
|
|
2593
|
+
statusId: null,
|
|
2594
|
+
changed: false,
|
|
2595
|
+
reason: 'assetId is required',
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
2598
|
+
const asset = (await this.entityService.withEntity('AssetManagement', 'Asset').data().byKey(assetId));
|
|
2599
|
+
if (!asset?.id) {
|
|
2600
|
+
return {
|
|
2601
|
+
assetId,
|
|
2602
|
+
previousStatusId: null,
|
|
2603
|
+
statusId: null,
|
|
2604
|
+
changed: false,
|
|
2605
|
+
reason: 'Asset not found',
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
const previousStatusId = isString(asset.statusId) ? asset.statusId.trim() : null;
|
|
2609
|
+
const lifecycleStatusId = isString(asset.lifecycleStatusId) ? asset.lifecycleStatusId.trim() : null;
|
|
2610
|
+
if (lifecycleStatusId && PROTECTED_LIFECYCLE_STATUSES.has(lifecycleStatusId)) {
|
|
2611
|
+
return {
|
|
2612
|
+
assetId,
|
|
2613
|
+
previousStatusId,
|
|
2614
|
+
statusId: previousStatusId,
|
|
2615
|
+
changed: false,
|
|
2616
|
+
reason: `${trigger}: asset lifecycle is protected`,
|
|
2617
|
+
};
|
|
2618
|
+
}
|
|
2619
|
+
if (previousStatusId && PROTECTED_OPERATIONAL_STATUSES.has(previousStatusId)) {
|
|
2620
|
+
return {
|
|
2621
|
+
assetId,
|
|
2622
|
+
previousStatusId,
|
|
2623
|
+
statusId: previousStatusId,
|
|
2624
|
+
changed: false,
|
|
2625
|
+
reason: `${trigger}: asset status is protected`,
|
|
2626
|
+
};
|
|
2627
|
+
}
|
|
2628
|
+
const maintenanceTypeId = await this.resolveMaintenanceTypeId(assetId, context);
|
|
2629
|
+
const shouldBlock = await this.shouldBlockAssetForMaintenance(assetId, maintenanceTypeId);
|
|
2630
|
+
let nextStatusId = previousStatusId;
|
|
2631
|
+
const update = {};
|
|
2632
|
+
if (trigger === 'work-started') {
|
|
2633
|
+
if (shouldBlock) {
|
|
2634
|
+
nextStatusId = AXMAssetStatus.UnderMaintenanceInspection;
|
|
2635
|
+
if (previousStatusId === AXMAssetStatus.Available || previousStatusId === AXMAssetStatus.Assigned) {
|
|
2636
|
+
update.statusBeforeInterruptionId = previousStatusId;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
if (trigger === 'work-completed') {
|
|
2641
|
+
const hasBlockingWork = await this.hasBlockingWorkOrders(assetId);
|
|
2642
|
+
if (hasBlockingWork) {
|
|
2643
|
+
nextStatusId = AXMAssetStatus.UnderMaintenanceInspection;
|
|
2644
|
+
}
|
|
2645
|
+
// Do not release the asset here — completed work still awaits sign-off.
|
|
2646
|
+
}
|
|
2647
|
+
if (trigger === 'work-signed-off') {
|
|
2648
|
+
const hasBlockingWork = await this.hasBlockingWorkOrders(assetId);
|
|
2649
|
+
if (hasBlockingWork) {
|
|
2650
|
+
nextStatusId = AXMAssetStatus.UnderMaintenanceInspection;
|
|
2651
|
+
}
|
|
2652
|
+
else {
|
|
2653
|
+
nextStatusId = this.resolveRestoredStatus(asset);
|
|
2654
|
+
update.statusBeforeInterruptionId = null;
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
const changed = !!nextStatusId && nextStatusId !== previousStatusId;
|
|
2658
|
+
const hasFieldUpdates = update.statusBeforeInterruptionId !== undefined;
|
|
2659
|
+
if ((changed && nextStatusId) || hasFieldUpdates) {
|
|
2660
|
+
await this.entityService
|
|
2661
|
+
.withEntity('AssetManagement', 'Asset')
|
|
2662
|
+
.data()
|
|
2663
|
+
.update(assetId, {
|
|
2664
|
+
...update,
|
|
2665
|
+
...(changed && nextStatusId ? { statusId: nextStatusId } : {}),
|
|
2666
|
+
});
|
|
2667
|
+
}
|
|
2668
|
+
return {
|
|
2669
|
+
assetId,
|
|
2670
|
+
previousStatusId,
|
|
2671
|
+
statusId: nextStatusId,
|
|
2672
|
+
changed,
|
|
2673
|
+
reason: changed ? `${trigger}: status recalculated` : `${trigger}: status unchanged`,
|
|
2674
|
+
};
|
|
2675
|
+
}
|
|
2676
|
+
//#endregion
|
|
2677
|
+
//#region ---- Policy helpers ----
|
|
2678
|
+
async resolveMaintenanceTypeId(assetId, context) {
|
|
2679
|
+
const fromContext = context.maintenanceTypeId?.trim();
|
|
2680
|
+
if (fromContext) {
|
|
2681
|
+
return fromContext;
|
|
2682
|
+
}
|
|
2683
|
+
const workOrderId = context.workOrderId?.trim();
|
|
2684
|
+
if (workOrderId) {
|
|
2685
|
+
const workOrder = (await this.entityService
|
|
2686
|
+
.withEntity('MaintenanceManagement', 'WorkOrder')
|
|
2687
|
+
.data()
|
|
2688
|
+
.byKey(workOrderId));
|
|
2689
|
+
const fromWorkOrder = workOrder?.maintenanceTypeId?.trim();
|
|
2690
|
+
if (fromWorkOrder) {
|
|
2691
|
+
return fromWorkOrder;
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
const page = await this.entityService
|
|
2695
|
+
.withEntity('MaintenanceManagement', 'WorkOrder')
|
|
2696
|
+
.data()
|
|
2697
|
+
.query({
|
|
2698
|
+
skip: 0,
|
|
2699
|
+
take: 1,
|
|
2700
|
+
filter: {
|
|
2701
|
+
logic: 'and',
|
|
2702
|
+
filters: [
|
|
2703
|
+
{ field: 'assetId', operator: { type: 'equal' }, value: assetId },
|
|
2704
|
+
{ field: 'statusId', operator: { type: 'equal' }, value: 'in-progress' },
|
|
2705
|
+
],
|
|
2706
|
+
},
|
|
2707
|
+
});
|
|
2708
|
+
const row = defaultTo(get(page, 'items[0]'), null);
|
|
2709
|
+
return row?.maintenanceTypeId?.trim() ?? '';
|
|
2710
|
+
}
|
|
2711
|
+
/**
|
|
2712
|
+
* Inspection-like maintenance types keep the asset blocked under the combined operational status.
|
|
2713
|
+
* TODO: replace title/code heuristic with an explicit MaintenanceType classification field when available.
|
|
2714
|
+
*/
|
|
2715
|
+
async shouldBlockAssetForMaintenance(_assetId, maintenanceTypeId) {
|
|
2716
|
+
if (!maintenanceTypeId) {
|
|
2717
|
+
return true;
|
|
2718
|
+
}
|
|
2719
|
+
const maintenanceType = (await this.entityService
|
|
2720
|
+
.withEntity('MaintenanceManagement', 'MaintenanceType')
|
|
2721
|
+
.data()
|
|
2722
|
+
.byKey(maintenanceTypeId));
|
|
2723
|
+
if (!maintenanceType) {
|
|
2724
|
+
return true;
|
|
2725
|
+
}
|
|
2726
|
+
const code = maintenanceType.code?.toLowerCase() ?? '';
|
|
2727
|
+
const titleText = this.resolveDisplayText(maintenanceType.title).toLowerCase();
|
|
2728
|
+
const isInspection = code.includes('inspect') || titleText.includes('inspect');
|
|
2729
|
+
if (isInspection) {
|
|
2730
|
+
return true;
|
|
2731
|
+
}
|
|
2732
|
+
// Non-inspection maintenance that does not block the asset is not modeled yet.
|
|
2733
|
+
// TODO: honor MaintenanceType.blocksAsset (or equivalent) when introduced.
|
|
2734
|
+
return true;
|
|
2735
|
+
}
|
|
2736
|
+
async hasBlockingWorkOrders(assetId) {
|
|
2737
|
+
const page = await this.entityService
|
|
2738
|
+
.withEntity('MaintenanceManagement', 'WorkOrder')
|
|
2739
|
+
.data()
|
|
2740
|
+
.query({
|
|
2741
|
+
skip: 0,
|
|
2742
|
+
take: 100,
|
|
2743
|
+
filter: {
|
|
2744
|
+
logic: 'and',
|
|
2745
|
+
filters: [{ field: 'assetId', operator: { type: 'equal' }, value: assetId }],
|
|
2746
|
+
},
|
|
2747
|
+
});
|
|
2748
|
+
const items = defaultTo(get(page, 'items'), []);
|
|
2749
|
+
return items.some((row) => {
|
|
2750
|
+
const statusId = row.statusId?.trim();
|
|
2751
|
+
return !!statusId && BLOCKING_WORK_ORDER_STATUSES.has(statusId);
|
|
2752
|
+
});
|
|
2753
|
+
}
|
|
2754
|
+
resolveRestoredStatus(asset) {
|
|
2755
|
+
const saved = isString(asset.statusBeforeInterruptionId) ? asset.statusBeforeInterruptionId.trim() : null;
|
|
2756
|
+
if (saved) {
|
|
2757
|
+
return saved;
|
|
2758
|
+
}
|
|
2759
|
+
return AXMAssetStatus.Available;
|
|
2760
|
+
}
|
|
2761
|
+
resolveDisplayText(value) {
|
|
2762
|
+
if (isString(value)) {
|
|
2763
|
+
return value;
|
|
2764
|
+
}
|
|
2765
|
+
if (value && typeof value === 'object') {
|
|
2766
|
+
const record = value;
|
|
2767
|
+
return record['en-US'] ?? record['fa-IR'] ?? Object.values(record)[0] ?? '';
|
|
2768
|
+
}
|
|
2769
|
+
return '';
|
|
2770
|
+
}
|
|
2771
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetOperationalStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2772
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetOperationalStatusService, providedIn: 'root' }); }
|
|
2773
|
+
}
|
|
2774
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetOperationalStatusService, decorators: [{
|
|
2775
|
+
type: Injectable,
|
|
2776
|
+
args: [{ providedIn: 'root' }]
|
|
2777
|
+
}] });
|
|
2778
|
+
|
|
2779
|
+
//#region ---- Types ----
|
|
2780
|
+
//#endregion
|
|
2781
|
+
|
|
2782
|
+
// export * from './asset-status.provider';
|
|
2783
|
+
|
|
2784
|
+
/**
|
|
2785
|
+
* Generated bundle index. Do not edit.
|
|
2786
|
+
*/
|
|
2787
|
+
|
|
2788
|
+
export { AXMAssetOperationalStatusService as A, USAGE_UNIT_LABEL_KEYS as U, AXM_ASSET_USAGE_I18N as a, USAGE_KIND_LABEL_KEYS as b, USAGE_METER_KIND_ORDER as c, ASSET_TYPE_COMPONENTS_SAVE_COMMAND as d, AXMAssetManagementAssetStatusProvider as e, AXMAssetManagementFeatureDefinitionProvider as f, AXMAssetManagementMenuProvider as g, AXMAssetManagementModule as h, isUsageMeterKind as i, AXMAssetManagementPermissionDefinitionProvider as j, AXMAssetManagementSearchCommandProvider as k, AXMAssetTypeComponentsPageComponentProvider as l, AXMAssetTypeSectionBuilderComponent as m, AXMAssetTypeSectionBuilderPageComponent as n, orderedUsageMeterKinds as o, AXMCreateAssetRentalHistoryRentFromCommand as p, AXMCreateAssetRentalHistoryRentToCommand as q, readAssetUsageIntervalKinds as r, AXMSaveAssetTypeComponentsCommand as s, assertRentalPartyForDirection as t, createAssetTypeSectionBuilderDefaultValue as u, normalizeAssetTypeBuilderLocalizedField as v, normalizeAssetTypeSectionBuilderValue as w };
|
|
2789
|
+
//# sourceMappingURL=acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs.map
|