@acorex-platform/module-asset-management-client 0.0.56 → 0.0.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/fesm2022/acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs +2789 -0
  2. package/fesm2022/acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs +276 -0
  4. package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs +55 -0
  6. package/fesm2022/acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset-type.mjs +105 -1
  8. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset-type.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset.mjs +290 -5
  10. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entities-asset.mjs.map +1 -1
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-BO3otOO_.mjs.map +1 -0
  27. 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
  28. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-CvCBkNVZ.mjs.map +1 -0
  29. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.interval-kind-nMKvWqpx.mjs +45 -0
  30. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.interval-kind-nMKvWqpx.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog.mjs +1 -1
  32. package/fesm2022/acorex-platform-module-asset-management-client-contracts.mjs +241 -1
  33. package/fesm2022/acorex-platform-module-asset-management-client-contracts.mjs.map +1 -1
  34. 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
  35. 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
  36. package/fesm2022/acorex-platform-module-asset-management-client.mjs +1 -2496
  37. package/fesm2022/acorex-platform-module-asset-management-client.mjs.map +1 -1
  38. package/i18n/en-AU/asset-management.json +44 -0
  39. package/i18n/en-US/asset-management.json +44 -0
  40. package/i18n/fa-IR/asset-management.json +44 -0
  41. package/package.json +2 -2
  42. package/types/acorex-platform-module-asset-management-client-contracts.d.ts +72 -2
  43. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset-type.entity-CUZ1xIl3.mjs.map +0 -1
  44. package/fesm2022/acorex-platform-module-asset-management-client-contracts-entity-catalog-asset.entity-Ckx8fhZ-.mjs.map +0 -1
@@ -0,0 +1,276 @@
1
+ import { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';
2
+ import { AXMAssetIntervalKind, AXMAssetIntervalUnit, readAssetUsageValues, isAXMAssetUsageUnitForKind } from '@acorex-platform/module-asset-management-client/contracts';
3
+ import * as i0 from '@angular/core';
4
+ import { input, output, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
5
+ import { AXLabelComponent } from '@acorex/components/label';
6
+ import * as i2 from '@acorex/components/number-box';
7
+ import { AXNumberBoxModule } from '@acorex/components/number-box';
8
+ import * as i3 from '@acorex/components/selection-list';
9
+ import { AXSelectionListModule } from '@acorex/components/selection-list';
10
+ import * as i4 from '@acorex/core/translation';
11
+ import { AXTranslationModule } from '@acorex/core/translation';
12
+ import { AsyncPipe } from '@angular/common';
13
+ import * as i1 from '@angular/forms';
14
+ import { FormsModule } from '@angular/forms';
15
+ import { c as USAGE_METER_KIND_ORDER, a as AXM_ASSET_USAGE_I18N, U as USAGE_UNIT_LABEL_KEYS, b as USAGE_KIND_LABEL_KEYS, i as isUsageMeterKind, r as readAssetUsageIntervalKinds } from './acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs';
16
+
17
+ //#endregion
18
+ //#region ----- Helpers -----
19
+ function defaultUnit(kind) {
20
+ switch (kind) {
21
+ case AXMAssetIntervalKind.Distance:
22
+ return AXMAssetIntervalUnit.Kilometer;
23
+ case AXMAssetIntervalKind.OperatingHours:
24
+ return AXMAssetIntervalUnit.Hour;
25
+ case AXMAssetIntervalKind.OperationCount:
26
+ return AXMAssetIntervalUnit.Operation;
27
+ }
28
+ }
29
+ function stable(value) {
30
+ return JSON.stringify(value);
31
+ }
32
+ function readChoiceId(value) {
33
+ if (typeof value === 'string') {
34
+ return value;
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return readChoiceId(value[0]);
38
+ }
39
+ if (value && typeof value === 'object' && 'id' in value && typeof value.id === 'string') {
40
+ return value.id;
41
+ }
42
+ return '';
43
+ }
44
+ function kindsToShow(supported, stored) {
45
+ const supportedMeters = USAGE_METER_KIND_ORDER.filter((kind) => supported.includes(kind));
46
+ if (supportedMeters.length > 0) {
47
+ return supportedMeters;
48
+ }
49
+ return USAGE_METER_KIND_ORDER.filter((kind) => stored.some((item) => item.kind === kind));
50
+ }
51
+ function buildDraft(kinds, stored) {
52
+ const byKind = new Map(stored.map((item) => [item.kind, item]));
53
+ const draft = {};
54
+ for (const kind of kinds) {
55
+ const existing = byKind.get(kind);
56
+ draft[kind] = {
57
+ currentValue: existing?.currentValue ?? null,
58
+ unit: existing?.unit ?? defaultUnit(kind),
59
+ lastReadingAt: existing?.lastReadingAt,
60
+ unitLocked: existing != null,
61
+ baseline: existing?.currentValue ?? null,
62
+ };
63
+ }
64
+ return draft;
65
+ }
66
+ function toUsageValues(draft) {
67
+ const values = [];
68
+ for (const kind of USAGE_METER_KIND_ORDER) {
69
+ const item = draft[kind];
70
+ if (!item || item.currentValue == null || !Number.isFinite(item.currentValue)) {
71
+ continue;
72
+ }
73
+ const currentValue = kind === AXMAssetIntervalKind.OperationCount ? Math.trunc(item.currentValue) : item.currentValue;
74
+ if (currentValue < 0 || (item.baseline != null && currentValue < item.baseline)) {
75
+ continue;
76
+ }
77
+ const reading = { kind, currentValue, unit: item.unit };
78
+ const changed = item.baseline == null || currentValue !== item.baseline;
79
+ if (changed) {
80
+ reading.lastReadingAt = new Date().toISOString();
81
+ }
82
+ else if (item.lastReadingAt) {
83
+ reading.lastReadingAt = item.lastReadingAt;
84
+ }
85
+ values.push(reading);
86
+ }
87
+ return values;
88
+ }
89
+ //#endregion
90
+ //#region ----- Component -----
91
+ class AXMAssetUsageValuesComponent {
92
+ //#endregion
93
+ //#region ----- Lifecycle -----
94
+ constructor() {
95
+ //#region ----- Inputs -----
96
+ this.supportedIntervalKinds = input([], /* @ts-ignore */
97
+ ...(ngDevMode ? [{ debugName: "supportedIntervalKinds" }] : /* istanbul ignore next */ []));
98
+ this.value = input(undefined, /* @ts-ignore */
99
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
100
+ this.disabled = input(false, /* @ts-ignore */
101
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
102
+ /** Existing assets keep the stored unit. Create can still choose kilometre or mile. */
103
+ this.lockUnits = input(false, /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "lockUnits" }] : /* istanbul ignore next */ []));
105
+ //#endregion
106
+ //#region ----- Outputs -----
107
+ this.valueChange = output();
108
+ //#endregion
109
+ //#region ----- Constants -----
110
+ this.emptyKey = `${AXM_ASSET_USAGE_I18N}.empty`;
111
+ this.dateNoteKey = `${AXM_ASSET_USAGE_I18N}.date-note`;
112
+ this.distanceUnits = [
113
+ { id: AXMAssetIntervalUnit.Kilometer, text: USAGE_UNIT_LABEL_KEYS[AXMAssetIntervalUnit.Kilometer] },
114
+ { id: AXMAssetIntervalUnit.Mile, text: USAGE_UNIT_LABEL_KEYS[AXMAssetIntervalUnit.Mile] },
115
+ ];
116
+ //#endregion
117
+ //#region ----- State Signals -----
118
+ this.draft = signal({}, /* @ts-ignore */
119
+ ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
120
+ this.lastEmitted = '';
121
+ this.lastSupportedKey = '';
122
+ this.lastHydrated = '';
123
+ //#endregion
124
+ //#region ----- Computed Properties -----
125
+ this.showDateNote = computed(() => this.supportedIntervalKinds().includes(AXMAssetIntervalKind.Date), /* @ts-ignore */
126
+ ...(ngDevMode ? [{ debugName: "showDateNote" }] : /* istanbul ignore next */ []));
127
+ this.fields = computed(() => {
128
+ const draft = this.draft();
129
+ const fields = [];
130
+ for (const kind of USAGE_METER_KIND_ORDER) {
131
+ const item = draft[kind];
132
+ if (!item) {
133
+ continue;
134
+ }
135
+ fields.push({
136
+ kind,
137
+ labelKey: USAGE_KIND_LABEL_KEYS[kind],
138
+ currentValue: item.currentValue,
139
+ unit: item.unit,
140
+ unitSelectable: kind === AXMAssetIntervalKind.Distance && !item.unitLocked && !this.lockUnits(),
141
+ minValue: item.baseline ?? 0,
142
+ decimals: kind === AXMAssetIntervalKind.OperationCount ? 0 : 2,
143
+ unitLabelKey: USAGE_UNIT_LABEL_KEYS[item.unit],
144
+ });
145
+ }
146
+ return fields;
147
+ }, /* @ts-ignore */
148
+ ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
149
+ this.showEmpty = computed(() => this.fields().length === 0 && !this.showDateNote(), /* @ts-ignore */
150
+ ...(ngDevMode ? [{ debugName: "showEmpty" }] : /* istanbul ignore next */ []));
151
+ effect(() => {
152
+ const supported = this.supportedIntervalKinds();
153
+ const stored = readAssetUsageValues(this.value());
154
+ const supportedKey = [...supported].sort().join('|');
155
+ const token = `${supportedKey}::${stable(stored)}`;
156
+ if (this.lastEmitted && stable(stored) === this.lastEmitted && supportedKey === this.lastSupportedKey) {
157
+ return;
158
+ }
159
+ if (token === this.lastHydrated) {
160
+ return;
161
+ }
162
+ this.lastHydrated = token;
163
+ this.lastSupportedKey = supportedKey;
164
+ this.draft.set(buildDraft(kindsToShow(supported, stored), stored));
165
+ });
166
+ }
167
+ //#endregion
168
+ //#region ----- Event Handlers -----
169
+ onValue(kind, event) {
170
+ if (!event.isUserInteraction || this.disabled() || !isUsageMeterKind(kind)) {
171
+ return;
172
+ }
173
+ const currentValue = typeof event.value === 'number' && Number.isFinite(event.value) ? event.value : null;
174
+ const draft = this.draft();
175
+ const item = draft[kind];
176
+ if (!item || item.currentValue === currentValue) {
177
+ return;
178
+ }
179
+ this.commit({ ...draft, [kind]: { ...item, currentValue } });
180
+ }
181
+ onDistanceUnit(event) {
182
+ if (!event.isUserInteraction || this.disabled()) {
183
+ return;
184
+ }
185
+ const unit = readChoiceId(event.value);
186
+ if (!isAXMAssetUsageUnitForKind(AXMAssetIntervalKind.Distance, unit)) {
187
+ return;
188
+ }
189
+ const draft = this.draft();
190
+ const item = draft[AXMAssetIntervalKind.Distance];
191
+ if (!item || item.unitLocked || this.lockUnits() || item.unit === unit) {
192
+ return;
193
+ }
194
+ this.commit({
195
+ ...draft,
196
+ [AXMAssetIntervalKind.Distance]: { ...item, unit: unit },
197
+ });
198
+ }
199
+ //#endregion
200
+ //#region ----- Draft -----
201
+ commit(draft) {
202
+ this.draft.set(draft);
203
+ const values = toUsageValues(draft);
204
+ this.lastEmitted = stable(values);
205
+ this.valueChange.emit(values);
206
+ }
207
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
208
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAssetUsageValuesComponent, isStandalone: true, selector: "axm-asset-usage-values", inputs: { supportedIntervalKinds: { classPropertyName: "supportedIntervalKinds", publicName: "supportedIntervalKinds", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, lockUnits: { classPropertyName: "lockUnits", publicName: "lockUnits", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { classAttribute: "block" }, ngImport: i0, template: "<!-- ----- No meter kinds and no date interval on the asset type ----- -->\n@if (showEmpty()) {\n <p class=\"ax-text-muted\">{{ emptyKey | translate | async }}</p>\n}\n\n<!-- ----- Date is shown as a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (field of fields(); track field.kind) {\n <div class=\"mt-3 flex flex-col gap-2\">\n <ax-label>{{ field.labelKey | translate | async }}</ax-label>\n <div class=\"flex flex-wrap items-center gap-3\">\n <ax-number-box\n class=\"w-36\"\n [minValue]=\"field.minValue\"\n [decimals]=\"field.decimals\"\n [ngModel]=\"field.currentValue\"\n [disabled]=\"disabled()\"\n [showSpinButtons]=\"false\"\n (onValueChanged)=\"onValue(field.kind, $event)\"\n ></ax-number-box>\n <!-- ----- Distance unit can be chosen only before a reading is stored ----- -->\n @if (field.unitSelectable) {\n <ax-selection-list\n [items]=\"distanceUnits\"\n [ngModel]=\"field.unit\"\n [disabled]=\"disabled()\"\n direction=\"horizontal\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n (onValueChanged)=\"onDistanceUnit($event)\"\n >\n <ng-template #itemTemplate let-item>\n <span>{{ item.text | translate | async }}</span>\n </ng-template>\n </ax-selection-list>\n }\n <!-- ----- Saved or fixed unit stays beside the number and is not part of the input ----- -->\n @else {\n <span class=\"ax-text-muted\">({{ field.unitLabelKey | translate | async }})</span>\n }\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXNumberBoxModule }, { kind: "component", type: i2.AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "component", type: i3.AXSelectionListComponent, selector: "ax-selection-list", inputs: ["id", "name", "disabled", "readonly", "tabIndex", "value", "valueField", "textField", "disabledField", "readonlyField", "multiple", "direction", "customTemplate", "showControl", "items", "look"], outputs: ["onValueChanged", "onBlur", "onFocus"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
209
+ }
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesComponent, decorators: [{
211
+ type: Component,
212
+ args: [{ selector: 'axm-asset-usage-values', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
213
+ AsyncPipe,
214
+ FormsModule,
215
+ AXTranslationModule,
216
+ AXLabelComponent,
217
+ AXNumberBoxModule,
218
+ AXSelectionListModule,
219
+ ], host: { class: 'block' }, template: "<!-- ----- No meter kinds and no date interval on the asset type ----- -->\n@if (showEmpty()) {\n <p class=\"ax-text-muted\">{{ emptyKey | translate | async }}</p>\n}\n\n<!-- ----- Date is shown as a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (field of fields(); track field.kind) {\n <div class=\"mt-3 flex flex-col gap-2\">\n <ax-label>{{ field.labelKey | translate | async }}</ax-label>\n <div class=\"flex flex-wrap items-center gap-3\">\n <ax-number-box\n class=\"w-36\"\n [minValue]=\"field.minValue\"\n [decimals]=\"field.decimals\"\n [ngModel]=\"field.currentValue\"\n [disabled]=\"disabled()\"\n [showSpinButtons]=\"false\"\n (onValueChanged)=\"onValue(field.kind, $event)\"\n ></ax-number-box>\n <!-- ----- Distance unit can be chosen only before a reading is stored ----- -->\n @if (field.unitSelectable) {\n <ax-selection-list\n [items]=\"distanceUnits\"\n [ngModel]=\"field.unit\"\n [disabled]=\"disabled()\"\n direction=\"horizontal\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n (onValueChanged)=\"onDistanceUnit($event)\"\n >\n <ng-template #itemTemplate let-item>\n <span>{{ item.text | translate | async }}</span>\n </ng-template>\n </ax-selection-list>\n }\n <!-- ----- Saved or fixed unit stays beside the number and is not part of the input ----- -->\n @else {\n <span class=\"ax-text-muted\">({{ field.unitLabelKey | translate | async }})</span>\n }\n </div>\n </div>\n}\n" }]
220
+ }], ctorParameters: () => [], propDecorators: { supportedIntervalKinds: [{ type: i0.Input, args: [{ isSignal: true, alias: "supportedIntervalKinds", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], lockUnits: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockUnits", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
221
+
222
+ //#region ----- Imports -----
223
+ //#endregion
224
+ //#region ----- Component -----
225
+ class AXMAssetUsageValuesWidgetEditComponent extends AXPValueWidgetComponent {
226
+ constructor() {
227
+ super(...arguments);
228
+ //#region ----- Computed Properties -----
229
+ this.supportedKinds = computed(() => readAssetUsageIntervalKinds(this.options(), (path) => this.contextService.getValue(path)), /* @ts-ignore */
230
+ ...(ngDevMode ? [{ debugName: "supportedKinds" }] : /* istanbul ignore next */ []));
231
+ this.currentValue = computed(() => readAssetUsageValues(this.getValue()), /* @ts-ignore */
232
+ ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
233
+ this.isDisabled = computed(() => Boolean(this.options()['disabled']), /* @ts-ignore */
234
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
235
+ this.lockUnits = computed(() => {
236
+ const id = this.contextService.getValue('id');
237
+ return id != null && id !== '';
238
+ }, /* @ts-ignore */
239
+ ...(ngDevMode ? [{ debugName: "lockUnits" }] : /* istanbul ignore next */ []));
240
+ }
241
+ //#endregion
242
+ //#region ----- Event Handlers -----
243
+ onUsageValuesChange(values) {
244
+ this.setValue(values);
245
+ }
246
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
247
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXMAssetUsageValuesWidgetEditComponent, isStandalone: true, selector: "axm-asset-usage-values-widget-edit", usesInheritance: true, ngImport: i0, template: `
248
+ <axm-asset-usage-values
249
+ [supportedIntervalKinds]="supportedKinds()"
250
+ [value]="currentValue()"
251
+ [disabled]="isDisabled()"
252
+ [lockUnits]="lockUnits()"
253
+ (valueChange)="onUsageValuesChange($event)"
254
+ />
255
+ `, isInline: true, dependencies: [{ kind: "component", type: AXMAssetUsageValuesComponent, selector: "axm-asset-usage-values", inputs: ["supportedIntervalKinds", "value", "disabled", "lockUnits"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
256
+ }
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetEditComponent, decorators: [{
258
+ type: Component,
259
+ args: [{
260
+ selector: 'axm-asset-usage-values-widget-edit',
261
+ template: `
262
+ <axm-asset-usage-values
263
+ [supportedIntervalKinds]="supportedKinds()"
264
+ [value]="currentValue()"
265
+ [disabled]="isDisabled()"
266
+ [lockUnits]="lockUnits()"
267
+ (valueChange)="onUsageValuesChange($event)"
268
+ />
269
+ `,
270
+ changeDetection: ChangeDetectionStrategy.OnPush,
271
+ imports: [AXMAssetUsageValuesComponent],
272
+ }]
273
+ }] });
274
+
275
+ export { AXMAssetUsageValuesWidgetEditComponent };
276
+ //# sourceMappingURL=acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-asset-management-client-asset-usage-values-widget-edit.component-qauvpIMv.mjs","sources":["../../../../libs/modules/asset-management/client/src/lib/features/asset-usage-values/asset-usage-values.component.ts","../../../../libs/modules/asset-management/client/src/lib/features/asset-usage-values/asset-usage-values.component.html","../../../../libs/modules/asset-management/client/src/lib/features/asset-usage-values/asset-usage-values-widget-edit.component.ts"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport { AXLabelComponent } from '@acorex/components/label';\nimport { AXNumberBoxModule } from '@acorex/components/number-box';\nimport { AXSelectionListModule } from '@acorex/components/selection-list';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport {\n AXMAssetIntervalKind,\n AXMAssetIntervalUnit,\n isAXMAssetUsageUnitForKind,\n readAssetUsageValues,\n type AXMAssetUsageKind,\n type AXMAssetUsageValue,\n} from '@acorex-platform/module-asset-management-client/contracts';\nimport { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, effect, input, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport {\n AXM_ASSET_USAGE_I18N,\n USAGE_KIND_LABEL_KEYS,\n USAGE_METER_KIND_ORDER,\n USAGE_UNIT_LABEL_KEYS,\n isUsageMeterKind,\n} from './asset-usage-values.kinds';\n\n//#endregion\n\n//#region ----- Types -----\n\ninterface UsageDraftItem {\n currentValue: number | null;\n unit: AXMAssetIntervalUnit;\n lastReadingAt?: string;\n unitLocked: boolean;\n baseline: number | null;\n}\n\ninterface UsageField {\n kind: AXMAssetUsageKind;\n labelKey: string;\n currentValue: number | null;\n unit: AXMAssetIntervalUnit;\n unitSelectable: boolean;\n minValue: number;\n decimals: number;\n unitLabelKey: string;\n}\n\ninterface UsageChoice {\n id: string;\n text: string;\n}\n\n//#endregion\n\n//#region ----- Helpers -----\n\nfunction defaultUnit(kind: AXMAssetUsageKind): AXMAssetIntervalUnit {\n switch (kind) {\n case AXMAssetIntervalKind.Distance:\n return AXMAssetIntervalUnit.Kilometer;\n case AXMAssetIntervalKind.OperatingHours:\n return AXMAssetIntervalUnit.Hour;\n case AXMAssetIntervalKind.OperationCount:\n return AXMAssetIntervalUnit.Operation;\n }\n}\n\nfunction stable(value: unknown): string {\n return JSON.stringify(value);\n}\n\nfunction readChoiceId(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n if (Array.isArray(value)) {\n return readChoiceId(value[0]);\n }\n if (value && typeof value === 'object' && 'id' in value && typeof (value as { id: unknown }).id === 'string') {\n return (value as { id: string }).id;\n }\n return '';\n}\n\nfunction kindsToShow(supported: readonly string[], stored: readonly AXMAssetUsageValue[]): AXMAssetUsageKind[] {\n const supportedMeters = USAGE_METER_KIND_ORDER.filter((kind) => supported.includes(kind));\n if (supportedMeters.length > 0) {\n return supportedMeters;\n }\n return USAGE_METER_KIND_ORDER.filter((kind) => stored.some((item) => item.kind === kind));\n}\n\nfunction buildDraft(kinds: readonly AXMAssetUsageKind[], stored: readonly AXMAssetUsageValue[]): Record<string, UsageDraftItem> {\n const byKind = new Map(stored.map((item) => [item.kind, item]));\n const draft: Record<string, UsageDraftItem> = {};\n for (const kind of kinds) {\n const existing = byKind.get(kind);\n draft[kind] = {\n currentValue: existing?.currentValue ?? null,\n unit: existing?.unit ?? defaultUnit(kind),\n lastReadingAt: existing?.lastReadingAt,\n unitLocked: existing != null,\n baseline: existing?.currentValue ?? null,\n };\n }\n return draft;\n}\n\nfunction toUsageValues(draft: Record<string, UsageDraftItem>): AXMAssetUsageValue[] {\n const values: AXMAssetUsageValue[] = [];\n for (const kind of USAGE_METER_KIND_ORDER) {\n const item = draft[kind];\n if (!item || item.currentValue == null || !Number.isFinite(item.currentValue)) {\n continue;\n }\n const currentValue =\n kind === AXMAssetIntervalKind.OperationCount ? Math.trunc(item.currentValue) : item.currentValue;\n if (currentValue < 0 || (item.baseline != null && currentValue < item.baseline)) {\n continue;\n }\n const reading: AXMAssetUsageValue = { kind, currentValue, unit: item.unit };\n const changed = item.baseline == null || currentValue !== item.baseline;\n if (changed) {\n reading.lastReadingAt = new Date().toISOString();\n } else if (item.lastReadingAt) {\n reading.lastReadingAt = item.lastReadingAt;\n }\n values.push(reading);\n }\n return values;\n}\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axm-asset-usage-values',\n templateUrl: './asset-usage-values.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n AsyncPipe,\n FormsModule,\n AXTranslationModule,\n AXLabelComponent,\n AXNumberBoxModule,\n AXSelectionListModule,\n ],\n host: { class: 'block' },\n})\nexport class AXMAssetUsageValuesComponent {\n //#region ----- Inputs -----\n\n readonly supportedIntervalKinds = input<readonly string[]>([]);\n readonly value = input<AXMAssetUsageValue[] | null | undefined>(undefined);\n readonly disabled = input(false);\n /** Existing assets keep the stored unit. Create can still choose kilometre or mile. */\n readonly lockUnits = input(false);\n\n //#endregion\n\n //#region ----- Outputs -----\n\n readonly valueChange = output<AXMAssetUsageValue[]>();\n\n //#endregion\n\n //#region ----- Constants -----\n\n protected readonly emptyKey = `${AXM_ASSET_USAGE_I18N}.empty`;\n protected readonly dateNoteKey = `${AXM_ASSET_USAGE_I18N}.date-note`;\n protected readonly distanceUnits: UsageChoice[] = [\n { id: AXMAssetIntervalUnit.Kilometer, text: USAGE_UNIT_LABEL_KEYS[AXMAssetIntervalUnit.Kilometer] },\n { id: AXMAssetIntervalUnit.Mile, text: USAGE_UNIT_LABEL_KEYS[AXMAssetIntervalUnit.Mile] },\n ];\n\n //#endregion\n\n //#region ----- State Signals -----\n\n private readonly draft = signal<Record<string, UsageDraftItem>>({});\n private lastEmitted = '';\n private lastSupportedKey = '';\n private lastHydrated = '';\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n protected readonly showDateNote = computed(() => this.supportedIntervalKinds().includes(AXMAssetIntervalKind.Date));\n\n protected readonly fields = computed<UsageField[]>(() => {\n const draft = this.draft();\n const fields: UsageField[] = [];\n for (const kind of USAGE_METER_KIND_ORDER) {\n const item = draft[kind];\n if (!item) {\n continue;\n }\n fields.push({\n kind,\n labelKey: USAGE_KIND_LABEL_KEYS[kind],\n currentValue: item.currentValue,\n unit: item.unit,\n unitSelectable:\n kind === AXMAssetIntervalKind.Distance && !item.unitLocked && !this.lockUnits(),\n minValue: item.baseline ?? 0,\n decimals: kind === AXMAssetIntervalKind.OperationCount ? 0 : 2,\n unitLabelKey: USAGE_UNIT_LABEL_KEYS[item.unit],\n });\n }\n return fields;\n });\n\n protected readonly showEmpty = computed(() => this.fields().length === 0 && !this.showDateNote());\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n constructor() {\n effect(() => {\n const supported = this.supportedIntervalKinds();\n const stored = readAssetUsageValues(this.value());\n const supportedKey = [...supported].sort().join('|');\n const token = `${supportedKey}::${stable(stored)}`;\n if (this.lastEmitted && stable(stored) === this.lastEmitted && supportedKey === this.lastSupportedKey) {\n return;\n }\n if (token === this.lastHydrated) {\n return;\n }\n this.lastHydrated = token;\n this.lastSupportedKey = supportedKey;\n this.draft.set(buildDraft(kindsToShow(supported, stored), stored));\n });\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected onValue(kind: AXMAssetUsageKind, event: AXValueChangedEvent): void {\n if (!event.isUserInteraction || this.disabled() || !isUsageMeterKind(kind)) {\n return;\n }\n const currentValue = typeof event.value === 'number' && Number.isFinite(event.value) ? event.value : null;\n const draft = this.draft();\n const item = draft[kind];\n if (!item || item.currentValue === currentValue) {\n return;\n }\n this.commit({ ...draft, [kind]: { ...item, currentValue } });\n }\n\n protected onDistanceUnit(event: AXValueChangedEvent): void {\n if (!event.isUserInteraction || this.disabled()) {\n return;\n }\n const unit = readChoiceId(event.value);\n if (!isAXMAssetUsageUnitForKind(AXMAssetIntervalKind.Distance, unit as AXMAssetIntervalUnit)) {\n return;\n }\n const draft = this.draft();\n const item = draft[AXMAssetIntervalKind.Distance];\n if (!item || item.unitLocked || this.lockUnits() || item.unit === unit) {\n return;\n }\n this.commit({\n ...draft,\n [AXMAssetIntervalKind.Distance]: { ...item, unit: unit as AXMAssetIntervalUnit },\n });\n }\n\n //#endregion\n\n //#region ----- Draft -----\n\n private commit(draft: Record<string, UsageDraftItem>): void {\n this.draft.set(draft);\n const values = toUsageValues(draft);\n this.lastEmitted = stable(values);\n this.valueChange.emit(values);\n }\n\n //#endregion\n}\n\n//#endregion\n","<!-- ----- No meter kinds and no date interval on the asset type ----- -->\n@if (showEmpty()) {\n <p class=\"ax-text-muted\">{{ emptyKey | translate | async }}</p>\n}\n\n<!-- ----- Date is shown as a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (field of fields(); track field.kind) {\n <div class=\"mt-3 flex flex-col gap-2\">\n <ax-label>{{ field.labelKey | translate | async }}</ax-label>\n <div class=\"flex flex-wrap items-center gap-3\">\n <ax-number-box\n class=\"w-36\"\n [minValue]=\"field.minValue\"\n [decimals]=\"field.decimals\"\n [ngModel]=\"field.currentValue\"\n [disabled]=\"disabled()\"\n [showSpinButtons]=\"false\"\n (onValueChanged)=\"onValue(field.kind, $event)\"\n ></ax-number-box>\n <!-- ----- Distance unit can be chosen only before a reading is stored ----- -->\n @if (field.unitSelectable) {\n <ax-selection-list\n [items]=\"distanceUnits\"\n [ngModel]=\"field.unit\"\n [disabled]=\"disabled()\"\n direction=\"horizontal\"\n [multiple]=\"false\"\n [showControl]=\"true\"\n valueField=\"id\"\n textField=\"text\"\n (onValueChanged)=\"onDistanceUnit($event)\"\n >\n <ng-template #itemTemplate let-item>\n <span>{{ item.text | translate | async }}</span>\n </ng-template>\n </ax-selection-list>\n }\n <!-- ----- Saved or fixed unit stays beside the number and is not part of the input ----- -->\n @else {\n <span class=\"ax-text-muted\">({{ field.unitLabelKey | translate | async }})</span>\n }\n </div>\n </div>\n}\n","//#region ----- Imports -----\n\nimport { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';\nimport { readAssetUsageValues, type AXMAssetUsageValue } from '@acorex-platform/module-asset-management-client/contracts';\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\n\nimport { AXMAssetUsageValuesComponent } from './asset-usage-values.component';\nimport { readAssetUsageIntervalKinds } from './asset-usage-values.kinds';\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axm-asset-usage-values-widget-edit',\n template: `\n <axm-asset-usage-values\n [supportedIntervalKinds]=\"supportedKinds()\"\n [value]=\"currentValue()\"\n [disabled]=\"isDisabled()\"\n [lockUnits]=\"lockUnits()\"\n (valueChange)=\"onUsageValuesChange($event)\"\n />\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AXMAssetUsageValuesComponent],\n})\nexport class AXMAssetUsageValuesWidgetEditComponent extends AXPValueWidgetComponent<AXMAssetUsageValue[] | null> {\n //#region ----- Computed Properties -----\n\n protected readonly supportedKinds = computed(() =>\n readAssetUsageIntervalKinds(this.options(), (path) => this.contextService.getValue(path)),\n );\n\n protected readonly currentValue = computed(() => readAssetUsageValues(this.getValue()));\n\n protected readonly isDisabled = computed(() => Boolean(this.options()['disabled']));\n\n protected readonly lockUnits = computed(() => {\n const id = this.contextService.getValue('id');\n return id != null && id !== '';\n });\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected onUsageValuesChange(values: AXMAssetUsageValue[]): void {\n this.setValue(values);\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { AXLabelComponent } from '@acorex/components/label';
2
+ import * as i4 from '@acorex/core/translation';
3
+ import { AXTranslationModule } from '@acorex/core/translation';
4
+ import { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';
5
+ import { AXMAssetIntervalKind, readAssetUsageValues } from '@acorex-platform/module-asset-management-client/contracts';
6
+ import { AsyncPipe } from '@angular/common';
7
+ import * as i0 from '@angular/core';
8
+ import { computed, ChangeDetectionStrategy, Component } from '@angular/core';
9
+ import { a as AXM_ASSET_USAGE_I18N, r as readAssetUsageIntervalKinds, o as orderedUsageMeterKinds, U as USAGE_UNIT_LABEL_KEYS, b as USAGE_KIND_LABEL_KEYS } from './acorex-platform-module-asset-management-client-acorex-platform-module-asset-management-client-B7YXKaeh.mjs';
10
+
11
+ //#region ----- Imports -----
12
+ //#endregion
13
+ //#region ----- Component -----
14
+ class AXMAssetUsageValuesWidgetViewComponent extends AXPValueWidgetComponent {
15
+ constructor() {
16
+ super(...arguments);
17
+ //#region ----- Constants -----
18
+ this.emptyKey = `${AXM_ASSET_USAGE_I18N}.empty`;
19
+ this.dateNoteKey = `${AXM_ASSET_USAGE_I18N}.date-note`;
20
+ this.noReadingKey = `${AXM_ASSET_USAGE_I18N}.no-reading`;
21
+ //#endregion
22
+ //#region ----- Computed Properties -----
23
+ this.supportedKinds = computed(() => readAssetUsageIntervalKinds(this.options(), (path) => this.contextService.getValue(path)), /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "supportedKinds" }] : /* istanbul ignore next */ []));
25
+ this.showDateNote = computed(() => this.supportedKinds().includes(AXMAssetIntervalKind.Date), /* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "showDateNote" }] : /* istanbul ignore next */ []));
27
+ this.rows = computed(() => {
28
+ const stored = readAssetUsageValues(this.getValue());
29
+ const byKind = new Map(stored.map((item) => [item.kind, item]));
30
+ const supportedMeters = orderedUsageMeterKinds(this.supportedKinds());
31
+ const kinds = supportedMeters.length > 0 ? supportedMeters : stored.map((item) => item.kind);
32
+ return kinds.map((kind) => {
33
+ const reading = byKind.get(kind);
34
+ return {
35
+ kind,
36
+ labelKey: USAGE_KIND_LABEL_KEYS[kind] ?? '',
37
+ currentValue: reading?.currentValue ?? null,
38
+ unitKey: reading ? USAGE_UNIT_LABEL_KEYS[reading.unit] : '',
39
+ };
40
+ });
41
+ }, /* @ts-ignore */
42
+ ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
43
+ this.showEmpty = computed(() => this.rows().length === 0 && !this.showDateNote(), /* @ts-ignore */
44
+ ...(ngDevMode ? [{ debugName: "showEmpty" }] : /* istanbul ignore next */ []));
45
+ }
46
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
47
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAssetUsageValuesWidgetViewComponent, isStandalone: true, selector: "axm-asset-usage-values-widget-view", usesInheritance: true, ngImport: i0, template: "<!-- ----- Asset type has no meter readings and no date interval ----- -->\n@if (showEmpty()) {\n <span class=\"ax-text-muted\">{{ emptyKey | translate | async }}</span>\n}\n\n<!-- ----- Date is a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (row of rows(); track row.kind) {\n <div class=\"mt-2\">\n <ax-label>{{ row.labelKey | translate | async }}</ax-label>\n <!-- ----- Stored cumulative reading ----- -->\n @if (row.currentValue != null) {\n <span class=\"ms-2\">{{ row.currentValue }}</span>\n <span class=\"ms-2 ax-text-muted\">({{ row.unitKey | translate | async }})</span>\n }\n <!-- ----- Supported kind with no reading yet ----- -->\n @else {\n <span class=\"ms-2 ax-text-muted\">{{ noReadingKey | translate | async }}</span>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
48
+ }
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAssetUsageValuesWidgetViewComponent, decorators: [{
50
+ type: Component,
51
+ args: [{ selector: 'axm-asset-usage-values-widget-view', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AsyncPipe, AXTranslationModule, AXLabelComponent], template: "<!-- ----- Asset type has no meter readings and no date interval ----- -->\n@if (showEmpty()) {\n <span class=\"ax-text-muted\">{{ emptyKey | translate | async }}</span>\n}\n\n<!-- ----- Date is a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (row of rows(); track row.kind) {\n <div class=\"mt-2\">\n <ax-label>{{ row.labelKey | translate | async }}</ax-label>\n <!-- ----- Stored cumulative reading ----- -->\n @if (row.currentValue != null) {\n <span class=\"ms-2\">{{ row.currentValue }}</span>\n <span class=\"ms-2 ax-text-muted\">({{ row.unitKey | translate | async }})</span>\n }\n <!-- ----- Supported kind with no reading yet ----- -->\n @else {\n <span class=\"ms-2 ax-text-muted\">{{ noReadingKey | translate | async }}</span>\n }\n </div>\n}\n" }]
52
+ }] });
53
+
54
+ export { AXMAssetUsageValuesWidgetViewComponent };
55
+ //# sourceMappingURL=acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-asset-management-client-asset-usage-values-widget-view.component-5psJebph.mjs","sources":["../../../../libs/modules/asset-management/client/src/lib/features/asset-usage-values/asset-usage-values-widget-view.component.ts","../../../../libs/modules/asset-management/client/src/lib/features/asset-usage-values/asset-usage-values-widget-view.component.html"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXLabelComponent } from '@acorex/components/label';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { AXPValueWidgetComponent } from '@acorex-platform/framework-client/layout/widget-core';\nimport {\n AXMAssetIntervalKind,\n readAssetUsageValues,\n type AXMAssetUsageValue,\n} from '@acorex-platform/module-asset-management-client/contracts';\nimport { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\n\nimport {\n AXM_ASSET_USAGE_I18N,\n USAGE_KIND_LABEL_KEYS,\n USAGE_UNIT_LABEL_KEYS,\n orderedUsageMeterKinds,\n readAssetUsageIntervalKinds,\n} from './asset-usage-values.kinds';\n\n//#endregion\n\n//#region ----- Types -----\n\ninterface UsageViewRow {\n kind: string;\n labelKey: string;\n currentValue: number | null;\n unitKey: string;\n}\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axm-asset-usage-values-widget-view',\n templateUrl: './asset-usage-values-widget-view.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe, AXTranslationModule, AXLabelComponent],\n})\nexport class AXMAssetUsageValuesWidgetViewComponent extends AXPValueWidgetComponent<AXMAssetUsageValue[] | null> {\n //#region ----- Constants -----\n\n protected readonly emptyKey = `${AXM_ASSET_USAGE_I18N}.empty`;\n protected readonly dateNoteKey = `${AXM_ASSET_USAGE_I18N}.date-note`;\n protected readonly noReadingKey = `${AXM_ASSET_USAGE_I18N}.no-reading`;\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n private readonly supportedKinds = computed(() =>\n readAssetUsageIntervalKinds(this.options(), (path) => this.contextService.getValue(path)),\n );\n\n protected readonly showDateNote = computed(() => this.supportedKinds().includes(AXMAssetIntervalKind.Date));\n\n protected readonly rows = computed<UsageViewRow[]>(() => {\n const stored = readAssetUsageValues(this.getValue());\n const byKind = new Map(stored.map((item) => [item.kind, item]));\n const supportedMeters = orderedUsageMeterKinds(this.supportedKinds());\n const kinds = supportedMeters.length > 0 ? supportedMeters : stored.map((item) => item.kind);\n return kinds.map((kind) => {\n const reading = byKind.get(kind);\n return {\n kind,\n labelKey: USAGE_KIND_LABEL_KEYS[kind] ?? '',\n currentValue: reading?.currentValue ?? null,\n unitKey: reading ? USAGE_UNIT_LABEL_KEYS[reading.unit] : '',\n };\n });\n });\n\n protected readonly showEmpty = computed(() => this.rows().length === 0 && !this.showDateNote());\n\n //#endregion\n}\n\n//#endregion\n","<!-- ----- Asset type has no meter readings and no date interval ----- -->\n@if (showEmpty()) {\n <span class=\"ax-text-muted\">{{ emptyKey | translate | async }}</span>\n}\n\n<!-- ----- Date is a note because it is not stored on the asset ----- -->\n@if (showDateNote()) {\n <p class=\"ax-text-muted\">{{ dateNoteKey | translate | async }}</p>\n}\n\n@for (row of rows(); track row.kind) {\n <div class=\"mt-2\">\n <ax-label>{{ row.labelKey | translate | async }}</ax-label>\n <!-- ----- Stored cumulative reading ----- -->\n @if (row.currentValue != null) {\n <span class=\"ms-2\">{{ row.currentValue }}</span>\n <span class=\"ms-2 ax-text-muted\">({{ row.unitKey | translate | async }})</span>\n }\n <!-- ----- Supported kind with no reading yet ----- -->\n @else {\n <span class=\"ms-2 ax-text-muted\">{{ noReadingKey | translate | async }}</span>\n }\n </div>\n}\n"],"names":["i1"],"mappings":"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"}
@@ -1,6 +1,49 @@
1
1
  import { AXPWidgetsCatalog, AXPSystemActionType } from '@acorex-platform/framework-shared/core';
2
2
  import { createAllQueryView, entityMasterCrudActions, entityMasterRecordActions, AXPEntityCommandScope, entityDetailsCrudActions, entityDetailsSimpleCondition } from '@acorex-platform/framework-shared/entity';
3
3
 
4
+ //#region ---- Interval kind ----
5
+ /** Measurement capabilities an asset type can use for maintenance intervals. Combinations are multiple values, not extra enum members. */
6
+ var AXMAssetIntervalKind;
7
+ (function (AXMAssetIntervalKind) {
8
+ AXMAssetIntervalKind["Date"] = "date";
9
+ AXMAssetIntervalKind["Distance"] = "distance";
10
+ AXMAssetIntervalKind["OperatingHours"] = "operating-hours";
11
+ AXMAssetIntervalKind["OperationCount"] = "operation-count";
12
+ })(AXMAssetIntervalKind || (AXMAssetIntervalKind = {}));
13
+ const ASSET_INTERVAL_KINDS = new Set(Object.values(AXMAssetIntervalKind));
14
+ function isAXMAssetIntervalKind(value) {
15
+ return ASSET_INTERVAL_KINDS.has(value);
16
+ }
17
+ /**
18
+ * Reads `supportedIntervalKinds` from a stored row or a select-editor value.
19
+ * Missing or empty input is `[]`. A non-array, or any item that is not a known kind, is invalid.
20
+ * Select rows `{ id }` are accepted and reduced to the id.
21
+ */
22
+ function resolveSupportedIntervalKinds(value) {
23
+ if (value == null || value === '') {
24
+ return { kinds: [], invalid: false };
25
+ }
26
+ if (!Array.isArray(value)) {
27
+ return { kinds: [], invalid: true };
28
+ }
29
+ const kinds = [];
30
+ for (const item of value) {
31
+ const raw = typeof item === 'string'
32
+ ? item
33
+ : item && typeof item === 'object' && 'id' in item && typeof item.id === 'string'
34
+ ? item.id
35
+ : '';
36
+ if (!isAXMAssetIntervalKind(raw)) {
37
+ return { kinds: [], invalid: true };
38
+ }
39
+ if (!kinds.includes(raw)) {
40
+ kinds.push(raw);
41
+ }
42
+ }
43
+ return { kinds, invalid: false };
44
+ }
45
+ //#endregion
46
+
4
47
  //#region ---- Root Configuration ----
5
48
  const config = {
6
49
  i18n: 'asset-management',
@@ -106,6 +149,25 @@ const RootConfig = {
106
149
  /** Registry key for the asset type Components custom page tab. */
107
150
  const ASSET_TYPE_COMPONENTS_PAGE_COMPONENT_KEY = 'asset-type-components-page';
108
151
 
152
+ const supportedIntervalKindDataSource = [
153
+ {
154
+ id: AXMAssetIntervalKind.Date,
155
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.options.date',
156
+ },
157
+ {
158
+ id: AXMAssetIntervalKind.Distance,
159
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.options.distance',
160
+ },
161
+ {
162
+ id: AXMAssetIntervalKind.OperatingHours,
163
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.options.operating-hours',
164
+ },
165
+ {
166
+ id: AXMAssetIntervalKind.OperationCount,
167
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.options.operation-count',
168
+ },
169
+ ];
170
+ const maintenanceFieldVisible = `{{ [true, "true"].includes(context.eval("hasMaintenance")) }}`;
109
171
  //#endregion
110
172
  //#region ---- Entity Factory ----
111
173
  /**
@@ -314,7 +376,7 @@ async function factoryAssetType() {
314
376
  dataType: 'array',
315
377
  nullable: true,
316
378
  defaultValue: [],
317
- visible: `{{ [true, "true"].includes(context.eval("hasMaintenance")) }}`,
379
+ visible: maintenanceFieldVisible,
318
380
  interface: {
319
381
  type: AXPWidgetsCatalog.lookup,
320
382
  options: {
@@ -331,6 +393,31 @@ async function factoryAssetType() {
331
393
  filter: { advance: { enabled: false }, inline: { enabled: false } },
332
394
  },
333
395
  },
396
+ {
397
+ name: 'supportedIntervalKinds',
398
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.title',
399
+ groupId: 'maintenance-info',
400
+ schema: {
401
+ dataType: 'array',
402
+ nullable: true,
403
+ defaultValue: [],
404
+ visible: maintenanceFieldVisible,
405
+ interface: {
406
+ type: AXPWidgetsCatalog.select,
407
+ options: {
408
+ valueField: 'id',
409
+ textField: 'title',
410
+ multiple: true,
411
+ allowSearch: false,
412
+ dataSource: supportedIntervalKindDataSource,
413
+ },
414
+ },
415
+ },
416
+ options: {
417
+ sort: { enabled: false },
418
+ filter: { advance: { enabled: false }, inline: { enabled: false } },
419
+ },
420
+ },
334
421
  {
335
422
  name: 'description',
336
423
  title: '@asset-management:assetTypes.entities.assetType.fields.description.title',
@@ -379,6 +466,11 @@ async function factoryAssetType() {
379
466
  title: '@asset-management:assetTypes.entities.assetType.fields.maintenanceTypeIds.gridTitle',
380
467
  options: { order: 5 },
381
468
  },
469
+ {
470
+ name: 'supportedIntervalKinds',
471
+ title: '@asset-management:assetTypes.entities.assetType.fields.supported-interval-kinds.gridTitle',
472
+ options: { order: 6 },
473
+ },
382
474
  ],
383
475
  queries: {},
384
476
  interfaces: {
@@ -409,6 +501,10 @@ async function factoryAssetType() {
409
501
  name: 'maintenanceTypeIds',
410
502
  layout: { positions: { lg: { colSpan: 12, order: 6 } } },
411
503
  },
504
+ {
505
+ name: 'supportedIntervalKinds',
506
+ layout: { positions: { lg: { colSpan: 12, order: 7 } } },
507
+ },
412
508
  ],
413
509
  },
414
510
  update: {
@@ -437,6 +533,10 @@ async function factoryAssetType() {
437
533
  name: 'maintenanceTypeIds',
438
534
  layout: { positions: { lg: { colSpan: 12, order: 6 } } },
439
535
  },
536
+ {
537
+ name: 'supportedIntervalKinds',
538
+ layout: { positions: { lg: { colSpan: 12, order: 7 } } },
539
+ },
440
540
  ],
441
541
  },
442
542
  single: {
@@ -467,6 +567,10 @@ async function factoryAssetType() {
467
567
  name: 'maintenanceTypeIds',
468
568
  layout: { positions: { lg: { colSpan: 12, order: 6 } } },
469
569
  },
570
+ {
571
+ name: 'supportedIntervalKinds',
572
+ layout: { positions: { lg: { colSpan: 12, order: 7 } } },
573
+ },
470
574
  ],
471
575
  actions: [...entityMasterRecordActions()],
472
576
  },