@c8y/ngx-components 1024.21.3 → 1024.21.5
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/c8y-ngx-components-ai-agents-scada.mjs +82 -19
- package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-1WsTSnO_.mjs → c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-B0EYpohd.mjs} +31 -17
- package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-B0EYpohd.mjs.map +1 -0
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-C3KZGqlc.mjs → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-BqbzREl7.mjs} +2 -2
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-C3KZGqlc.mjs.map → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-BqbzREl7.mjs.map} +1 -1
- package/fesm2022/c8y-ngx-components-computed-asset-properties-last-measurement-config.component-d3JeKEr4.mjs +108 -0
- package/fesm2022/c8y-ngx-components-computed-asset-properties-last-measurement-config.component-d3JeKEr4.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-computed-asset-properties.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +93 -9
- package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
- package/locales/de.po +0 -3
- package/locales/es.po +0 -3
- package/locales/fr.po +0 -3
- package/locales/ja_JP.po +0 -3
- package/locales/ko.po +0 -3
- package/locales/locales.pot +9 -0
- package/locales/nl.po +0 -3
- package/locales/pl.po +0 -3
- package/locales/pt_BR.po +0 -3
- package/locales/zh_CN.po +0 -3
- package/locales/zh_TW.po +0 -3
- package/package.json +1 -1
- package/types/c8y-ngx-components-ai-agents-scada.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-scada.d.ts +28 -2
- package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-1WsTSnO_.mjs.map +0 -1
- package/fesm2022/c8y-ngx-components-computed-asset-properties-last-measurement-config.component-DOmwNU6m.mjs +0 -86
- package/fesm2022/c8y-ngx-components-computed-asset-properties-last-measurement-config.component-DOmwNU6m.mjs.map +0 -1
|
@@ -189,13 +189,13 @@ const INITIAL_SVG_CODE = `<?xml version="1.0" encoding="utf-8"?>
|
|
|
189
189
|
<text x="60" y="495" class="label">Examples:</text>
|
|
190
190
|
|
|
191
191
|
<text x="60" y="525" class="label">Device name:</text>
|
|
192
|
-
<text x="180" y="525" class="placeholder">\${this.c8yScadaValues?.deviceName
|
|
192
|
+
<text x="180" y="525" class="placeholder">\${this.c8yScadaValues?.deviceName ?? '-'}</text>
|
|
193
193
|
|
|
194
194
|
<text x="60" y="550" class="label">Temperature:</text>
|
|
195
|
-
<text x="180" y="550" class="placeholder">\${this.c8yScadaValues?.temperature
|
|
195
|
+
<text x="180" y="550" class="placeholder">\${this.c8yScadaValues?.temperature ?? '-'} °C</text>
|
|
196
196
|
|
|
197
197
|
<text x="60" y="575" class="label">Status:</text>
|
|
198
|
-
<text x="180" y="575" class="placeholder">\${this.c8yScadaValues?.status
|
|
198
|
+
<text x="180" y="575" class="placeholder">\${this.c8yScadaValues?.status ?? '-'}</text>
|
|
199
199
|
|
|
200
200
|
<!-- STEP 4: Advanced Customization -->
|
|
201
201
|
<circle cx="55" cy="630" r="15" class="step-circle" />
|
|
@@ -453,6 +453,13 @@ function restoreLitExpressions(svg, litExpressions) {
|
|
|
453
453
|
return `\${${expr}}`;
|
|
454
454
|
});
|
|
455
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* The expression inserted for a text turned into a placeholder. It shows `[name]` until the
|
|
458
|
+
* placeholder has a value; `??` keeps a value of `0` visible.
|
|
459
|
+
*/
|
|
460
|
+
function placeholderExpressionWithFallback(placeholderName) {
|
|
461
|
+
return `\${this.c8yScadaValues?.${placeholderName} ?? '[${placeholderName}]'}`;
|
|
462
|
+
}
|
|
456
463
|
/**
|
|
457
464
|
* Generates Lit web component code for rendering SCADA SVG elements.
|
|
458
465
|
*
|
|
@@ -600,6 +607,7 @@ export default class ScadaElement extends LitElement {
|
|
|
600
607
|
}`;
|
|
601
608
|
}
|
|
602
609
|
|
|
610
|
+
const LAST_MEASUREMENT = 'lastMeasurement';
|
|
603
611
|
class ScadaWidgetConfigService {
|
|
604
612
|
constructor() {
|
|
605
613
|
this.widgetConfigService = inject(WidgetConfigService);
|
|
@@ -618,6 +626,8 @@ class ScadaWidgetConfigService {
|
|
|
618
626
|
if (!migratedConfig.config?.htmlWidgetConfig) {
|
|
619
627
|
migratedConfig = await this.updateConfigWithSvgCode(migratedConfig, INITIAL_SVG_CODE);
|
|
620
628
|
}
|
|
629
|
+
this.addKeyPathToSavedLegacyMappings(migratedConfig);
|
|
630
|
+
this.addRawValueToSavedLegacyLastMeasurements(migratedConfig);
|
|
621
631
|
return migratedConfig;
|
|
622
632
|
}
|
|
623
633
|
save(config) {
|
|
@@ -740,6 +750,65 @@ class ScadaWidgetConfigService {
|
|
|
740
750
|
}
|
|
741
751
|
config.config.mappings = newMappings;
|
|
742
752
|
}
|
|
753
|
+
/**
|
|
754
|
+
* A widget migrated and saved before the migration set `keyPath` is never migrated again, so
|
|
755
|
+
* its nested property mappings get it on load. It comes from the stored 1.0 mapping, or from
|
|
756
|
+
* splitting the dotted `name` the migration built from it.
|
|
757
|
+
*/
|
|
758
|
+
addKeyPathToSavedLegacyMappings(config) {
|
|
759
|
+
if (!config.config?.htmlWidgetConfig?.config?.legacy) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
for (const [placeholder, mapping] of Object.entries(config.config.mappings || {})) {
|
|
763
|
+
const property = mapping?.assetProperty;
|
|
764
|
+
const isNestedPropertyWithoutKeyPath = property && !property.computed && !('keyPath' in property) && property.name?.includes('.');
|
|
765
|
+
if (!isNestedPropertyWithoutKeyPath) {
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
const legacyKeyPath = config.mapping?.[placeholder]?.keyPath;
|
|
769
|
+
const keyPath = Array.isArray(legacyKeyPath) && legacyKeyPath.join('.') === property.name
|
|
770
|
+
? [...legacyKeyPath]
|
|
771
|
+
: property.name.split('.');
|
|
772
|
+
mapping.assetProperty = { ...property, keyPath };
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* A widget migrated and saved before the migration set `rawValue` is never migrated again,
|
|
777
|
+
* so its "Last measurement" mappings get it on load.
|
|
778
|
+
*/
|
|
779
|
+
addRawValueToSavedLegacyLastMeasurements(config) {
|
|
780
|
+
if (!config.config?.htmlWidgetConfig?.config?.legacy) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
for (const [placeholder, mapping] of Object.entries(config.config.mappings || {})) {
|
|
784
|
+
const legacyMapping = config.mapping?.[placeholder];
|
|
785
|
+
if (this.isUnchangedMigratedLastMeasurement(mapping?.assetProperty, legacyMapping)) {
|
|
786
|
+
mapping.assetProperty = {
|
|
787
|
+
...mapping.assetProperty,
|
|
788
|
+
config: { ...mapping.assetProperty.config, rawValue: true }
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* True while the mapping still holds the "Last measurement" it was migrated from, and nobody
|
|
795
|
+
* has chosen its formatting since.
|
|
796
|
+
*/
|
|
797
|
+
isUnchangedMigratedLastMeasurement(property, legacyMapping) {
|
|
798
|
+
const propertyConfig = property?.config;
|
|
799
|
+
return (!!property?.computed &&
|
|
800
|
+
property.name === LAST_MEASUREMENT &&
|
|
801
|
+
!!propertyConfig?._id &&
|
|
802
|
+
propertyConfig._id === legacyMapping?.config?._id &&
|
|
803
|
+
!('rawValue' in propertyConfig));
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* SCADA 1.0 drawings compare the measured value as the device sent it. A rounded string
|
|
807
|
+
* reads differently: `"0.00"` is truthy in `ng-if="LangHL"`, where `0` is not.
|
|
808
|
+
*/
|
|
809
|
+
withRawValueForLastMeasurement(computedPropertyName, config) {
|
|
810
|
+
return computedPropertyName === LAST_MEASUREMENT ? { ...config, rawValue: true } : config;
|
|
811
|
+
}
|
|
743
812
|
/**
|
|
744
813
|
* Removes hardcoded width and height attributes from the root SVG element.
|
|
745
814
|
*
|
|
@@ -866,9 +935,13 @@ class ScadaWidgetConfigService {
|
|
|
866
935
|
const binary = await this.inventoryBinary.download(binaryId);
|
|
867
936
|
const svgCode = await binary.text();
|
|
868
937
|
const mappings = {};
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
938
|
+
const legacyMappings = config.mapping;
|
|
939
|
+
for (const [placeholder, legacyProperty] of Object.entries(legacyMappings)) {
|
|
940
|
+
const isUnmapped = !legacyProperty;
|
|
941
|
+
mappings[placeholder] = {
|
|
942
|
+
assetProperty: isUnmapped
|
|
943
|
+
? null
|
|
944
|
+
: await this.migrateProperty(legacyProperty, config.deviceIds[placeholder])
|
|
872
945
|
};
|
|
873
946
|
}
|
|
874
947
|
return {
|
|
@@ -915,7 +988,7 @@ class ScadaWidgetConfigService {
|
|
|
915
988
|
active: true,
|
|
916
989
|
temporary: true,
|
|
917
990
|
contextAssetId: assetId,
|
|
918
|
-
config: legacyProperty.config,
|
|
991
|
+
config: this.withRawValueForLastMeasurement(computedPropertyName, legacyProperty.config),
|
|
919
992
|
asset: {
|
|
920
993
|
id: asset.id,
|
|
921
994
|
name: asset.name
|
|
@@ -947,6 +1020,8 @@ class ScadaWidgetConfigService {
|
|
|
947
1020
|
c8y_JsonSchema: {
|
|
948
1021
|
properties: buildJsonSchema(legacyProperty.keyPath, legacyProperty.label, legacyProperty.type)
|
|
949
1022
|
},
|
|
1023
|
+
// Without `keyPath`, the dotted `name` is looked up as a single top-level key.
|
|
1024
|
+
keyPath: legacyProperty.keyPath,
|
|
950
1025
|
name: legacyProperty.keyPath.join('.'),
|
|
951
1026
|
active: true,
|
|
952
1027
|
label: legacyProperty.label,
|
|
@@ -1543,7 +1618,7 @@ class ScadaWidgetViewComponent {
|
|
|
1543
1618
|
this.scadaWidgetService.getSvgComputedStyling(this.svgDisplaySettings());
|
|
1544
1619
|
}
|
|
1545
1620
|
if (this.legacyScopeRef) {
|
|
1546
|
-
Object.assign(this.legacyScopeRef, scadaValues);
|
|
1621
|
+
Object.assign(this.legacyScopeRef, this.withEmptyStringForMissingValues(scadaValues));
|
|
1547
1622
|
Object.assign(this.legacyScopeRef, scadaFunctions);
|
|
1548
1623
|
}
|
|
1549
1624
|
},
|
|
@@ -1558,6 +1633,15 @@ class ScadaWidgetViewComponent {
|
|
|
1558
1633
|
}
|
|
1559
1634
|
});
|
|
1560
1635
|
}
|
|
1636
|
+
/**
|
|
1637
|
+
* SCADA 1.0 resolved a placeholder without a value to `''`, and its drawings rely on it:
|
|
1638
|
+
* `ng-if="state==0"` matches `''` but not `undefined`. Lit drawings keep `undefined`.
|
|
1639
|
+
*/
|
|
1640
|
+
withEmptyStringForMissingValues(values) {
|
|
1641
|
+
const placeholders = Object.keys(this.effectiveConfig()?.config?.mappings ?? {});
|
|
1642
|
+
const emptyValues = Object.fromEntries(placeholders.map(placeholder => [placeholder, '']));
|
|
1643
|
+
return { ...emptyValues, ...values };
|
|
1644
|
+
}
|
|
1561
1645
|
handleFetchError(err) {
|
|
1562
1646
|
this.alerts?.addAlerts(new DynamicComponentAlert({
|
|
1563
1647
|
type: 'warning',
|
|
@@ -1639,7 +1723,7 @@ class ScadaWidgetAdvancedEditorComponent {
|
|
|
1639
1723
|
const proposedName = textContent && textContent.trim() ? camelCase(textContent) : '';
|
|
1640
1724
|
try {
|
|
1641
1725
|
const placeholderName = await this.confirmPlaceholderName(proposedName);
|
|
1642
|
-
node.textContent =
|
|
1726
|
+
node.textContent = placeholderExpressionWithFallback(placeholderName);
|
|
1643
1727
|
node.classList.remove('potential-placeholder');
|
|
1644
1728
|
}
|
|
1645
1729
|
catch (e) {
|