myio-js-library 0.1.214 → 0.1.217
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/dist/index.cjs +1103 -6
- package/dist/index.d.cts +160 -3
- package/dist/index.js +1096 -6
- package/dist/myio-js-library.umd.js +1096 -6
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -578,14 +578,17 @@ __export(index_exports, {
|
|
|
578
578
|
CONSUMPTION_THEME_COLORS: () => THEME_COLORS,
|
|
579
579
|
ConnectionStatusType: () => ConnectionStatusType,
|
|
580
580
|
ContractSummaryTooltip: () => ContractSummaryTooltip,
|
|
581
|
+
DECIMAL_OPTIONS: () => DECIMAL_OPTIONS,
|
|
581
582
|
DEFAULT_CLAMP_RANGE: () => DEFAULT_CLAMP_RANGE,
|
|
582
583
|
DEFAULT_ENERGY_GROUP_COLORS: () => DEFAULT_ENERGY_GROUP_COLORS,
|
|
583
584
|
DEFAULT_GAS_GROUP_COLORS: () => DEFAULT_GAS_GROUP_COLORS,
|
|
585
|
+
DEFAULT_MEASUREMENT_SETTINGS: () => DEFAULT_SETTINGS,
|
|
584
586
|
DEFAULT_SHOPPING_COLORS: () => DEFAULT_SHOPPING_COLORS,
|
|
585
587
|
DEFAULT_WATER_GROUP_COLORS: () => DEFAULT_WATER_GROUP_COLORS,
|
|
586
588
|
DEVICE_COUNT_KEYS: () => DEVICE_COUNT_KEYS,
|
|
587
589
|
DeviceComparisonTooltip: () => DeviceComparisonTooltip,
|
|
588
590
|
DeviceStatusType: () => DeviceStatusType,
|
|
591
|
+
ENERGY_UNITS: () => ENERGY_UNITS,
|
|
589
592
|
EXPORT_DEFAULT_COLORS: () => EXPORT_DEFAULT_COLORS,
|
|
590
593
|
EXPORT_DOMAIN_ICONS: () => EXPORT_DOMAIN_ICONS,
|
|
591
594
|
EXPORT_DOMAIN_LABELS: () => EXPORT_DOMAIN_LABELS,
|
|
@@ -596,6 +599,7 @@ __export(index_exports, {
|
|
|
596
599
|
IMPORTANCE_LABELS: () => IMPORTANCE_LABELS,
|
|
597
600
|
IMPORTANCE_LABELS_EN: () => IMPORTANCE_LABELS_EN,
|
|
598
601
|
InfoTooltip: () => InfoTooltip,
|
|
602
|
+
MEASUREMENT_DOMAIN_CONFIG: () => DOMAIN_CONFIG5,
|
|
599
603
|
MyIOChartModal: () => MyIOChartModal,
|
|
600
604
|
MyIODraggableCard: () => MyIODraggableCard,
|
|
601
605
|
MyIOSelectionStore: () => MyIOSelectionStore,
|
|
@@ -607,9 +611,11 @@ __export(index_exports, {
|
|
|
607
611
|
STATUS_COLORS: () => STATUS_COLORS,
|
|
608
612
|
STATUS_LABELS: () => STATUS_LABELS,
|
|
609
613
|
STATUS_LABELS_EN: () => STATUS_LABELS_EN,
|
|
614
|
+
TEMPERATURE_UNITS: () => TEMPERATURE_UNITS,
|
|
610
615
|
TempComparisonTooltip: () => TempComparisonTooltip,
|
|
611
616
|
TempRangeTooltip: () => TempRangeTooltip,
|
|
612
617
|
TempSensorSummaryTooltip: () => TempSensorSummaryTooltip,
|
|
618
|
+
WATER_UNITS: () => WATER_UNITS,
|
|
613
619
|
WaterSummaryTooltip: () => WaterSummaryTooltip,
|
|
614
620
|
addDetectionContext: () => addDetectionContext,
|
|
615
621
|
addNamespace: () => addNamespace,
|
|
@@ -715,6 +721,7 @@ __export(index_exports, {
|
|
|
715
721
|
openDashboardPopupWaterTank: () => openDashboardPopupWaterTank,
|
|
716
722
|
openDemandModal: () => openDemandModal,
|
|
717
723
|
openGoalsPanel: () => openGoalsPanel,
|
|
724
|
+
openMeasurementSetupModal: () => openMeasurementSetupModal,
|
|
718
725
|
openPowerLimitsSetupModal: () => openPowerLimitsSetupModal,
|
|
719
726
|
openRealTimeTelemetryModal: () => openRealTimeTelemetryModal,
|
|
720
727
|
openTemperatureComparisonModal: () => openTemperatureComparisonModal,
|
|
@@ -29206,13 +29213,31 @@ var DefaultSettingsPersister = class {
|
|
|
29206
29213
|
};
|
|
29207
29214
|
|
|
29208
29215
|
// src/components/premium-modals/settings/SettingsFetcher.ts
|
|
29209
|
-
var DefaultSettingsFetcher = class {
|
|
29216
|
+
var DefaultSettingsFetcher = class _DefaultSettingsFetcher {
|
|
29210
29217
|
jwtToken;
|
|
29211
29218
|
tbBaseUrl;
|
|
29219
|
+
static FETCH_TIMEOUT_MS = 8e3;
|
|
29220
|
+
// 8 second timeout
|
|
29212
29221
|
constructor(jwtToken, apiConfig) {
|
|
29213
29222
|
this.jwtToken = jwtToken;
|
|
29214
29223
|
this.tbBaseUrl = apiConfig?.tbBaseUrl || window.location.origin;
|
|
29215
29224
|
}
|
|
29225
|
+
/**
|
|
29226
|
+
* Fetch with timeout to prevent hanging requests from blocking modal render
|
|
29227
|
+
*/
|
|
29228
|
+
async fetchWithTimeout(url, options, timeoutMs = _DefaultSettingsFetcher.FETCH_TIMEOUT_MS) {
|
|
29229
|
+
const controller = new AbortController();
|
|
29230
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
29231
|
+
try {
|
|
29232
|
+
const response = await fetch(url, {
|
|
29233
|
+
...options,
|
|
29234
|
+
signal: controller.signal
|
|
29235
|
+
});
|
|
29236
|
+
return response;
|
|
29237
|
+
} finally {
|
|
29238
|
+
clearTimeout(timeoutId);
|
|
29239
|
+
}
|
|
29240
|
+
}
|
|
29216
29241
|
async fetchCurrentSettings(deviceId, jwtToken, scope = "SERVER_SCOPE") {
|
|
29217
29242
|
try {
|
|
29218
29243
|
const [entityResult, attributesResult] = await Promise.allSettled([
|
|
@@ -29246,9 +29271,12 @@ var DefaultSettingsFetcher = class {
|
|
|
29246
29271
|
}
|
|
29247
29272
|
}
|
|
29248
29273
|
async fetchDeviceEntity(deviceId) {
|
|
29249
|
-
const response = await
|
|
29250
|
-
|
|
29251
|
-
|
|
29274
|
+
const response = await this.fetchWithTimeout(
|
|
29275
|
+
`${this.tbBaseUrl}/api/device/${deviceId}`,
|
|
29276
|
+
{
|
|
29277
|
+
headers: { "X-Authorization": `Bearer ${this.jwtToken}` }
|
|
29278
|
+
}
|
|
29279
|
+
);
|
|
29252
29280
|
if (!response.ok) {
|
|
29253
29281
|
throw new Error(
|
|
29254
29282
|
`Failed to fetch device entity: ${response.status} ${response.statusText}`
|
|
@@ -29260,7 +29288,7 @@ var DefaultSettingsFetcher = class {
|
|
|
29260
29288
|
};
|
|
29261
29289
|
}
|
|
29262
29290
|
async fetchDeviceAttributes(deviceId, scope) {
|
|
29263
|
-
const response = await
|
|
29291
|
+
const response = await this.fetchWithTimeout(
|
|
29264
29292
|
`${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/values/attributes/${scope}`,
|
|
29265
29293
|
{
|
|
29266
29294
|
headers: { "X-Authorization": `Bearer ${this.jwtToken}` }
|
|
@@ -29469,12 +29497,16 @@ var SettingsController = class {
|
|
|
29469
29497
|
const tbBaseUrl = this.params.api?.tbBaseUrl || window.location.origin;
|
|
29470
29498
|
const url = `${tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE?keys=mapInstantaneousPower`;
|
|
29471
29499
|
console.log("[SettingsModal] RFC-0080: Fetching GLOBAL from:", url);
|
|
29500
|
+
const controller = new AbortController();
|
|
29501
|
+
const timeoutId = setTimeout(() => controller.abort(), 8e3);
|
|
29472
29502
|
const response = await fetch(url, {
|
|
29473
29503
|
headers: {
|
|
29474
29504
|
"X-Authorization": `Bearer ${jwtToken}`,
|
|
29475
29505
|
"Content-Type": "application/json"
|
|
29476
|
-
}
|
|
29506
|
+
},
|
|
29507
|
+
signal: controller.signal
|
|
29477
29508
|
});
|
|
29509
|
+
clearTimeout(timeoutId);
|
|
29478
29510
|
if (!response.ok) {
|
|
29479
29511
|
throw new Error(`HTTP ${response.status}`);
|
|
29480
29512
|
}
|
|
@@ -43715,6 +43747,1064 @@ async function openContractDevicesModal(params) {
|
|
|
43715
43747
|
throw error;
|
|
43716
43748
|
}
|
|
43717
43749
|
}
|
|
43750
|
+
|
|
43751
|
+
// src/components/premium-modals/measurement-setup/types.ts
|
|
43752
|
+
var WATER_UNITS = [
|
|
43753
|
+
{ value: "m3", label: "Metros C\xFAbicos (m\xB3)" },
|
|
43754
|
+
{ value: "liters", label: "Litros (L)" }
|
|
43755
|
+
];
|
|
43756
|
+
var ENERGY_UNITS = [
|
|
43757
|
+
{ value: "auto", label: "Autom\xE1tico (kWh/MWh)" },
|
|
43758
|
+
{ value: "kwh", label: "Quilowatt-hora (kWh)" },
|
|
43759
|
+
{ value: "mwh", label: "Megawatt-hora (MWh)" }
|
|
43760
|
+
];
|
|
43761
|
+
var TEMPERATURE_UNITS = [
|
|
43762
|
+
{ value: "celsius", label: "Celsius (\xB0C)" },
|
|
43763
|
+
{ value: "fahrenheit", label: "Fahrenheit (\xB0F)" }
|
|
43764
|
+
];
|
|
43765
|
+
var DECIMAL_OPTIONS = [
|
|
43766
|
+
{ value: 0, label: "0 casas" },
|
|
43767
|
+
{ value: 1, label: "1 casa" },
|
|
43768
|
+
{ value: 2, label: "2 casas" },
|
|
43769
|
+
{ value: 3, label: "3 casas" },
|
|
43770
|
+
{ value: 4, label: "4 casas" },
|
|
43771
|
+
{ value: 5, label: "5 casas" },
|
|
43772
|
+
{ value: 6, label: "6 casas" }
|
|
43773
|
+
];
|
|
43774
|
+
var DOMAIN_CONFIG5 = {
|
|
43775
|
+
water: {
|
|
43776
|
+
icon: "\u{1F4A7}",
|
|
43777
|
+
label: "\xC1gua",
|
|
43778
|
+
color: "#3b82f6",
|
|
43779
|
+
bgColor: "rgba(59, 130, 246, 0.1)"
|
|
43780
|
+
},
|
|
43781
|
+
energy: {
|
|
43782
|
+
icon: "\u26A1",
|
|
43783
|
+
label: "Energia",
|
|
43784
|
+
color: "#f59e0b",
|
|
43785
|
+
bgColor: "rgba(245, 158, 11, 0.1)"
|
|
43786
|
+
},
|
|
43787
|
+
temperature: {
|
|
43788
|
+
icon: "\u{1F321}\uFE0F",
|
|
43789
|
+
label: "Temperatura",
|
|
43790
|
+
color: "#ef4444",
|
|
43791
|
+
bgColor: "rgba(239, 68, 68, 0.1)"
|
|
43792
|
+
}
|
|
43793
|
+
};
|
|
43794
|
+
var DEFAULT_SETTINGS = {
|
|
43795
|
+
version: "1.0.0",
|
|
43796
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43797
|
+
water: {
|
|
43798
|
+
unit: "m3",
|
|
43799
|
+
decimalPlaces: 3,
|
|
43800
|
+
autoScale: true
|
|
43801
|
+
},
|
|
43802
|
+
energy: {
|
|
43803
|
+
unit: "auto",
|
|
43804
|
+
decimalPlaces: 3,
|
|
43805
|
+
forceUnit: false
|
|
43806
|
+
},
|
|
43807
|
+
temperature: {
|
|
43808
|
+
unit: "celsius",
|
|
43809
|
+
decimalPlaces: 1
|
|
43810
|
+
}
|
|
43811
|
+
};
|
|
43812
|
+
|
|
43813
|
+
// src/components/premium-modals/measurement-setup/MeasurementSetupView.ts
|
|
43814
|
+
var MeasurementSetupView = class {
|
|
43815
|
+
container = null;
|
|
43816
|
+
overlayEl = null;
|
|
43817
|
+
config;
|
|
43818
|
+
formData;
|
|
43819
|
+
isLoading = false;
|
|
43820
|
+
isSaving = false;
|
|
43821
|
+
constructor(config) {
|
|
43822
|
+
this.config = config;
|
|
43823
|
+
this.formData = {
|
|
43824
|
+
water: { ...DEFAULT_SETTINGS.water },
|
|
43825
|
+
energy: { ...DEFAULT_SETTINGS.energy },
|
|
43826
|
+
temperature: { ...DEFAULT_SETTINGS.temperature }
|
|
43827
|
+
};
|
|
43828
|
+
}
|
|
43829
|
+
render(targetContainer) {
|
|
43830
|
+
this.overlayEl = document.createElement("div");
|
|
43831
|
+
this.overlayEl.className = "myio-measurement-setup-overlay";
|
|
43832
|
+
this.overlayEl.innerHTML = `
|
|
43833
|
+
<style>${this.getStyles()}</style>
|
|
43834
|
+
<div class="myio-measurement-setup-card">
|
|
43835
|
+
${this.renderHeader()}
|
|
43836
|
+
<div class="myio-measurement-setup-body">
|
|
43837
|
+
${this.renderWaterSection()}
|
|
43838
|
+
${this.renderEnergySection()}
|
|
43839
|
+
${this.renderTemperatureSection()}
|
|
43840
|
+
</div>
|
|
43841
|
+
${this.renderToolbar()}
|
|
43842
|
+
${this.renderLoadingState()}
|
|
43843
|
+
${this.renderErrorState()}
|
|
43844
|
+
${this.renderSuccessState()}
|
|
43845
|
+
</div>
|
|
43846
|
+
`;
|
|
43847
|
+
const target = targetContainer || document.body;
|
|
43848
|
+
target.appendChild(this.overlayEl);
|
|
43849
|
+
this.container = this.overlayEl.querySelector(".myio-measurement-setup-card");
|
|
43850
|
+
this.setupEventListeners();
|
|
43851
|
+
requestAnimationFrame(() => {
|
|
43852
|
+
this.overlayEl?.classList.add("active");
|
|
43853
|
+
});
|
|
43854
|
+
return this.overlayEl;
|
|
43855
|
+
}
|
|
43856
|
+
renderHeader() {
|
|
43857
|
+
return `
|
|
43858
|
+
<div class="myio-modal-header">
|
|
43859
|
+
<h2 class="myio-modal-title">\u{1F4D0} Configura\xE7\xE3o de Medidas</h2>
|
|
43860
|
+
<button class="myio-modal-close" id="msm-close-btn" type="button" aria-label="Fechar modal">\xD7</button>
|
|
43861
|
+
</div>
|
|
43862
|
+
`;
|
|
43863
|
+
}
|
|
43864
|
+
renderWaterSection() {
|
|
43865
|
+
const cfg = DOMAIN_CONFIG5.water;
|
|
43866
|
+
return `
|
|
43867
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43868
|
+
<div class="myio-section-header">
|
|
43869
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43870
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43871
|
+
</div>
|
|
43872
|
+
<div class="myio-section-content">
|
|
43873
|
+
<div class="myio-form-group">
|
|
43874
|
+
<label for="msm-water-unit">Unidade</label>
|
|
43875
|
+
<select id="msm-water-unit" class="myio-select">
|
|
43876
|
+
${WATER_UNITS.map((u) => `
|
|
43877
|
+
<option value="${u.value}" ${u.value === this.formData.water.unit ? "selected" : ""}>
|
|
43878
|
+
${u.label}
|
|
43879
|
+
</option>
|
|
43880
|
+
`).join("")}
|
|
43881
|
+
</select>
|
|
43882
|
+
</div>
|
|
43883
|
+
<div class="myio-form-group">
|
|
43884
|
+
<label for="msm-water-decimals">Casas Decimais</label>
|
|
43885
|
+
<select id="msm-water-decimals" class="myio-select">
|
|
43886
|
+
${DECIMAL_OPTIONS.map((d) => `
|
|
43887
|
+
<option value="${d.value}" ${d.value === this.formData.water.decimalPlaces ? "selected" : ""}>
|
|
43888
|
+
${d.label}
|
|
43889
|
+
</option>
|
|
43890
|
+
`).join("")}
|
|
43891
|
+
</select>
|
|
43892
|
+
</div>
|
|
43893
|
+
<div class="myio-form-group myio-checkbox-group">
|
|
43894
|
+
<label class="myio-checkbox-label">
|
|
43895
|
+
<input type="checkbox" id="msm-water-autoscale" ${this.formData.water.autoScale ? "checked" : ""}>
|
|
43896
|
+
<span class="myio-checkbox-text">Escala autom\xE1tica (L\u2194m\xB3)</span>
|
|
43897
|
+
</label>
|
|
43898
|
+
<span class="myio-form-hint">Converte automaticamente entre unidades</span>
|
|
43899
|
+
</div>
|
|
43900
|
+
</div>
|
|
43901
|
+
<div class="myio-section-preview">
|
|
43902
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43903
|
+
<span class="myio-preview-value" id="msm-water-preview">1.234,567 m\xB3</span>
|
|
43904
|
+
</div>
|
|
43905
|
+
</div>
|
|
43906
|
+
`;
|
|
43907
|
+
}
|
|
43908
|
+
renderEnergySection() {
|
|
43909
|
+
const cfg = DOMAIN_CONFIG5.energy;
|
|
43910
|
+
return `
|
|
43911
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43912
|
+
<div class="myio-section-header">
|
|
43913
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43914
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43915
|
+
</div>
|
|
43916
|
+
<div class="myio-section-content">
|
|
43917
|
+
<div class="myio-form-group">
|
|
43918
|
+
<label for="msm-energy-unit">Unidade</label>
|
|
43919
|
+
<select id="msm-energy-unit" class="myio-select">
|
|
43920
|
+
${ENERGY_UNITS.map((u) => `
|
|
43921
|
+
<option value="${u.value}" ${u.value === this.formData.energy.unit ? "selected" : ""}>
|
|
43922
|
+
${u.label}
|
|
43923
|
+
</option>
|
|
43924
|
+
`).join("")}
|
|
43925
|
+
</select>
|
|
43926
|
+
</div>
|
|
43927
|
+
<div class="myio-form-group">
|
|
43928
|
+
<label for="msm-energy-decimals">Casas Decimais</label>
|
|
43929
|
+
<select id="msm-energy-decimals" class="myio-select">
|
|
43930
|
+
${DECIMAL_OPTIONS.filter((d) => d.value <= 4).map((d) => `
|
|
43931
|
+
<option value="${d.value}" ${d.value === this.formData.energy.decimalPlaces ? "selected" : ""}>
|
|
43932
|
+
${d.label}
|
|
43933
|
+
</option>
|
|
43934
|
+
`).join("")}
|
|
43935
|
+
</select>
|
|
43936
|
+
</div>
|
|
43937
|
+
<div class="myio-form-group myio-checkbox-group">
|
|
43938
|
+
<label class="myio-checkbox-label">
|
|
43939
|
+
<input type="checkbox" id="msm-energy-forceunit" ${this.formData.energy.forceUnit ? "checked" : ""}>
|
|
43940
|
+
<span class="myio-checkbox-text">For\xE7ar unidade selecionada</span>
|
|
43941
|
+
</label>
|
|
43942
|
+
<span class="myio-form-hint">Quando ativo, n\xE3o converte automaticamente kWh\u2194MWh</span>
|
|
43943
|
+
</div>
|
|
43944
|
+
</div>
|
|
43945
|
+
<div class="myio-section-preview">
|
|
43946
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43947
|
+
<span class="myio-preview-value" id="msm-energy-preview">1.234,567 kWh</span>
|
|
43948
|
+
</div>
|
|
43949
|
+
</div>
|
|
43950
|
+
`;
|
|
43951
|
+
}
|
|
43952
|
+
renderTemperatureSection() {
|
|
43953
|
+
const cfg = DOMAIN_CONFIG5.temperature;
|
|
43954
|
+
return `
|
|
43955
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43956
|
+
<div class="myio-section-header">
|
|
43957
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43958
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43959
|
+
</div>
|
|
43960
|
+
<div class="myio-section-content">
|
|
43961
|
+
<div class="myio-form-group">
|
|
43962
|
+
<label for="msm-temp-unit">Unidade</label>
|
|
43963
|
+
<select id="msm-temp-unit" class="myio-select">
|
|
43964
|
+
${TEMPERATURE_UNITS.map((u) => `
|
|
43965
|
+
<option value="${u.value}" ${u.value === this.formData.temperature.unit ? "selected" : ""}>
|
|
43966
|
+
${u.label}
|
|
43967
|
+
</option>
|
|
43968
|
+
`).join("")}
|
|
43969
|
+
</select>
|
|
43970
|
+
</div>
|
|
43971
|
+
<div class="myio-form-group">
|
|
43972
|
+
<label for="msm-temp-decimals">Casas Decimais</label>
|
|
43973
|
+
<select id="msm-temp-decimals" class="myio-select">
|
|
43974
|
+
${DECIMAL_OPTIONS.filter((d) => d.value <= 3).map((d) => `
|
|
43975
|
+
<option value="${d.value}" ${d.value === this.formData.temperature.decimalPlaces ? "selected" : ""}>
|
|
43976
|
+
${d.label}
|
|
43977
|
+
</option>
|
|
43978
|
+
`).join("")}
|
|
43979
|
+
</select>
|
|
43980
|
+
</div>
|
|
43981
|
+
</div>
|
|
43982
|
+
<div class="myio-section-preview">
|
|
43983
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43984
|
+
<span class="myio-preview-value" id="msm-temp-preview">23,5 \xB0C</span>
|
|
43985
|
+
</div>
|
|
43986
|
+
</div>
|
|
43987
|
+
`;
|
|
43988
|
+
}
|
|
43989
|
+
renderToolbar() {
|
|
43990
|
+
return `
|
|
43991
|
+
<div class="myio-measurement-setup-toolbar">
|
|
43992
|
+
<div class="myio-toolbar-actions">
|
|
43993
|
+
<button class="myio-btn myio-btn-secondary" id="msm-reset-btn" type="button">
|
|
43994
|
+
Restaurar Padr\xE3o
|
|
43995
|
+
</button>
|
|
43996
|
+
<button class="myio-btn myio-btn-primary" id="msm-save-btn" type="button">
|
|
43997
|
+
<span class="myio-btn-text">Salvar</span>
|
|
43998
|
+
<span class="myio-btn-spinner" style="display: none;"></span>
|
|
43999
|
+
</button>
|
|
44000
|
+
</div>
|
|
44001
|
+
</div>
|
|
44002
|
+
`;
|
|
44003
|
+
}
|
|
44004
|
+
renderLoadingState() {
|
|
44005
|
+
return `
|
|
44006
|
+
<div class="myio-measurement-setup-loading" id="msm-loading" style="display: none;">
|
|
44007
|
+
<div class="myio-spinner"></div>
|
|
44008
|
+
<span>Carregando configura\xE7\xE3o...</span>
|
|
44009
|
+
</div>
|
|
44010
|
+
`;
|
|
44011
|
+
}
|
|
44012
|
+
renderErrorState() {
|
|
44013
|
+
return `
|
|
44014
|
+
<div class="myio-measurement-setup-error" id="msm-error" style="display: none;">
|
|
44015
|
+
<span class="myio-error-icon">⚠</span>
|
|
44016
|
+
<span class="myio-error-message" id="msm-error-msg"></span>
|
|
44017
|
+
</div>
|
|
44018
|
+
`;
|
|
44019
|
+
}
|
|
44020
|
+
renderSuccessState() {
|
|
44021
|
+
return `
|
|
44022
|
+
<div class="myio-measurement-setup-success" id="msm-success" style="display: none;">
|
|
44023
|
+
<span class="myio-success-icon">✓</span>
|
|
44024
|
+
<span class="myio-success-message">Configura\xE7\xE3o salva com sucesso!</span>
|
|
44025
|
+
</div>
|
|
44026
|
+
`;
|
|
44027
|
+
}
|
|
44028
|
+
setupEventListeners() {
|
|
44029
|
+
if (!this.overlayEl) return;
|
|
44030
|
+
const closeBtn = this.overlayEl.querySelector("#msm-close-btn");
|
|
44031
|
+
closeBtn?.addEventListener("click", () => this.close());
|
|
44032
|
+
this.overlayEl.addEventListener("click", (e) => {
|
|
44033
|
+
if (e.target === this.overlayEl) {
|
|
44034
|
+
this.close();
|
|
44035
|
+
}
|
|
44036
|
+
});
|
|
44037
|
+
document.addEventListener("keydown", this.handleKeyDown);
|
|
44038
|
+
const saveBtn = this.overlayEl.querySelector("#msm-save-btn");
|
|
44039
|
+
saveBtn?.addEventListener("click", () => this.handleSave());
|
|
44040
|
+
const resetBtn = this.overlayEl.querySelector("#msm-reset-btn");
|
|
44041
|
+
resetBtn?.addEventListener("click", () => this.handleReset());
|
|
44042
|
+
const waterUnit = this.overlayEl.querySelector("#msm-water-unit");
|
|
44043
|
+
const waterDecimals = this.overlayEl.querySelector("#msm-water-decimals");
|
|
44044
|
+
const waterAutoScale = this.overlayEl.querySelector("#msm-water-autoscale");
|
|
44045
|
+
waterUnit?.addEventListener("change", (e) => {
|
|
44046
|
+
this.formData.water.unit = e.target.value;
|
|
44047
|
+
this.updatePreviews();
|
|
44048
|
+
});
|
|
44049
|
+
waterDecimals?.addEventListener("change", (e) => {
|
|
44050
|
+
this.formData.water.decimalPlaces = parseInt(e.target.value, 10);
|
|
44051
|
+
this.updatePreviews();
|
|
44052
|
+
});
|
|
44053
|
+
waterAutoScale?.addEventListener("change", (e) => {
|
|
44054
|
+
this.formData.water.autoScale = e.target.checked;
|
|
44055
|
+
});
|
|
44056
|
+
const energyUnit = this.overlayEl.querySelector("#msm-energy-unit");
|
|
44057
|
+
const energyDecimals = this.overlayEl.querySelector("#msm-energy-decimals");
|
|
44058
|
+
const energyForceUnit = this.overlayEl.querySelector("#msm-energy-forceunit");
|
|
44059
|
+
energyUnit?.addEventListener("change", (e) => {
|
|
44060
|
+
this.formData.energy.unit = e.target.value;
|
|
44061
|
+
this.updatePreviews();
|
|
44062
|
+
});
|
|
44063
|
+
energyDecimals?.addEventListener("change", (e) => {
|
|
44064
|
+
this.formData.energy.decimalPlaces = parseInt(e.target.value, 10);
|
|
44065
|
+
this.updatePreviews();
|
|
44066
|
+
});
|
|
44067
|
+
energyForceUnit?.addEventListener("change", (e) => {
|
|
44068
|
+
this.formData.energy.forceUnit = e.target.checked;
|
|
44069
|
+
});
|
|
44070
|
+
const tempUnit = this.overlayEl.querySelector("#msm-temp-unit");
|
|
44071
|
+
const tempDecimals = this.overlayEl.querySelector("#msm-temp-decimals");
|
|
44072
|
+
tempUnit?.addEventListener("change", (e) => {
|
|
44073
|
+
this.formData.temperature.unit = e.target.value;
|
|
44074
|
+
this.updatePreviews();
|
|
44075
|
+
});
|
|
44076
|
+
tempDecimals?.addEventListener("change", (e) => {
|
|
44077
|
+
this.formData.temperature.decimalPlaces = parseInt(e.target.value, 10);
|
|
44078
|
+
this.updatePreviews();
|
|
44079
|
+
});
|
|
44080
|
+
this.updatePreviews();
|
|
44081
|
+
}
|
|
44082
|
+
updatePreviews() {
|
|
44083
|
+
const waterPreview = this.overlayEl?.querySelector("#msm-water-preview");
|
|
44084
|
+
if (waterPreview) {
|
|
44085
|
+
const sampleValue = 1234.567;
|
|
44086
|
+
const unit = this.formData.water.unit === "liters" ? "L" : "m\xB3";
|
|
44087
|
+
const displayValue = this.formData.water.unit === "liters" ? sampleValue * 1e3 : sampleValue;
|
|
44088
|
+
waterPreview.textContent = this.formatNumber(displayValue, this.formData.water.decimalPlaces) + " " + unit;
|
|
44089
|
+
}
|
|
44090
|
+
const energyPreview = this.overlayEl?.querySelector("#msm-energy-preview");
|
|
44091
|
+
if (energyPreview) {
|
|
44092
|
+
const sampleValueKwh = 1234.567;
|
|
44093
|
+
let displayValue = sampleValueKwh;
|
|
44094
|
+
let unit = "kWh";
|
|
44095
|
+
if (this.formData.energy.unit === "mwh") {
|
|
44096
|
+
displayValue = sampleValueKwh / 1e3;
|
|
44097
|
+
unit = "MWh";
|
|
44098
|
+
} else if (this.formData.energy.unit === "auto" && sampleValueKwh > 1e3) {
|
|
44099
|
+
displayValue = sampleValueKwh / 1e3;
|
|
44100
|
+
unit = "MWh";
|
|
44101
|
+
}
|
|
44102
|
+
energyPreview.textContent = this.formatNumber(displayValue, this.formData.energy.decimalPlaces) + " " + unit;
|
|
44103
|
+
}
|
|
44104
|
+
const tempPreview = this.overlayEl?.querySelector("#msm-temp-preview");
|
|
44105
|
+
if (tempPreview) {
|
|
44106
|
+
const sampleCelsius = 23.5;
|
|
44107
|
+
let displayValue = sampleCelsius;
|
|
44108
|
+
let unit = "\xB0C";
|
|
44109
|
+
if (this.formData.temperature.unit === "fahrenheit") {
|
|
44110
|
+
displayValue = sampleCelsius * 9 / 5 + 32;
|
|
44111
|
+
unit = "\xB0F";
|
|
44112
|
+
}
|
|
44113
|
+
tempPreview.textContent = this.formatNumber(displayValue, this.formData.temperature.decimalPlaces) + " " + unit;
|
|
44114
|
+
}
|
|
44115
|
+
}
|
|
44116
|
+
formatNumber(value, decimals) {
|
|
44117
|
+
const parts = value.toFixed(decimals).split(".");
|
|
44118
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
44119
|
+
return decimals > 0 ? parts.join(",") : parts[0];
|
|
44120
|
+
}
|
|
44121
|
+
handleKeyDown = (e) => {
|
|
44122
|
+
if (e.key === "Escape") {
|
|
44123
|
+
this.close();
|
|
44124
|
+
}
|
|
44125
|
+
};
|
|
44126
|
+
async handleSave() {
|
|
44127
|
+
if (this.isSaving) return;
|
|
44128
|
+
this.isSaving = true;
|
|
44129
|
+
this.showSaveLoading(true);
|
|
44130
|
+
this.hideError();
|
|
44131
|
+
this.hideSuccess();
|
|
44132
|
+
try {
|
|
44133
|
+
await this.config.onSave();
|
|
44134
|
+
this.showSuccess();
|
|
44135
|
+
setTimeout(() => this.hideSuccess(), 3e3);
|
|
44136
|
+
} catch (error) {
|
|
44137
|
+
this.showError(error.message || "Falha ao salvar configura\xE7\xE3o");
|
|
44138
|
+
} finally {
|
|
44139
|
+
this.isSaving = false;
|
|
44140
|
+
this.showSaveLoading(false);
|
|
44141
|
+
}
|
|
44142
|
+
}
|
|
44143
|
+
handleReset() {
|
|
44144
|
+
this.formData = {
|
|
44145
|
+
water: { ...DEFAULT_SETTINGS.water },
|
|
44146
|
+
energy: { ...DEFAULT_SETTINGS.energy },
|
|
44147
|
+
temperature: { ...DEFAULT_SETTINGS.temperature }
|
|
44148
|
+
};
|
|
44149
|
+
this.updateFormInputs();
|
|
44150
|
+
this.updatePreviews();
|
|
44151
|
+
this.hideError();
|
|
44152
|
+
this.hideSuccess();
|
|
44153
|
+
}
|
|
44154
|
+
updateFormInputs() {
|
|
44155
|
+
const waterUnit = this.overlayEl?.querySelector("#msm-water-unit");
|
|
44156
|
+
const waterDecimals = this.overlayEl?.querySelector("#msm-water-decimals");
|
|
44157
|
+
const waterAutoScale = this.overlayEl?.querySelector("#msm-water-autoscale");
|
|
44158
|
+
if (waterUnit) waterUnit.value = this.formData.water.unit;
|
|
44159
|
+
if (waterDecimals) waterDecimals.value = String(this.formData.water.decimalPlaces);
|
|
44160
|
+
if (waterAutoScale) waterAutoScale.checked = this.formData.water.autoScale;
|
|
44161
|
+
const energyUnit = this.overlayEl?.querySelector("#msm-energy-unit");
|
|
44162
|
+
const energyDecimals = this.overlayEl?.querySelector("#msm-energy-decimals");
|
|
44163
|
+
const energyForceUnit = this.overlayEl?.querySelector("#msm-energy-forceunit");
|
|
44164
|
+
if (energyUnit) energyUnit.value = this.formData.energy.unit;
|
|
44165
|
+
if (energyDecimals) energyDecimals.value = String(this.formData.energy.decimalPlaces);
|
|
44166
|
+
if (energyForceUnit) energyForceUnit.checked = this.formData.energy.forceUnit;
|
|
44167
|
+
const tempUnit = this.overlayEl?.querySelector("#msm-temp-unit");
|
|
44168
|
+
const tempDecimals = this.overlayEl?.querySelector("#msm-temp-decimals");
|
|
44169
|
+
if (tempUnit) tempUnit.value = this.formData.temperature.unit;
|
|
44170
|
+
if (tempDecimals) tempDecimals.value = String(this.formData.temperature.decimalPlaces);
|
|
44171
|
+
}
|
|
44172
|
+
close() {
|
|
44173
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
44174
|
+
if (this.overlayEl) {
|
|
44175
|
+
this.overlayEl.classList.remove("active");
|
|
44176
|
+
setTimeout(() => {
|
|
44177
|
+
this.overlayEl?.remove();
|
|
44178
|
+
this.overlayEl = null;
|
|
44179
|
+
this.container = null;
|
|
44180
|
+
this.config.onClose();
|
|
44181
|
+
}, 300);
|
|
44182
|
+
}
|
|
44183
|
+
}
|
|
44184
|
+
destroy() {
|
|
44185
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
44186
|
+
this.overlayEl?.remove();
|
|
44187
|
+
this.overlayEl = null;
|
|
44188
|
+
this.container = null;
|
|
44189
|
+
}
|
|
44190
|
+
showLoading() {
|
|
44191
|
+
this.isLoading = true;
|
|
44192
|
+
const loadingEl = this.overlayEl?.querySelector("#msm-loading");
|
|
44193
|
+
const bodyEl = this.overlayEl?.querySelector(".myio-measurement-setup-body");
|
|
44194
|
+
if (loadingEl) loadingEl.style.display = "flex";
|
|
44195
|
+
if (bodyEl) bodyEl.style.opacity = "0.5";
|
|
44196
|
+
}
|
|
44197
|
+
hideLoading() {
|
|
44198
|
+
this.isLoading = false;
|
|
44199
|
+
const loadingEl = this.overlayEl?.querySelector("#msm-loading");
|
|
44200
|
+
const bodyEl = this.overlayEl?.querySelector(".myio-measurement-setup-body");
|
|
44201
|
+
if (loadingEl) loadingEl.style.display = "none";
|
|
44202
|
+
if (bodyEl) bodyEl.style.opacity = "1";
|
|
44203
|
+
}
|
|
44204
|
+
showSaveLoading(show) {
|
|
44205
|
+
const saveBtn = this.overlayEl?.querySelector("#msm-save-btn");
|
|
44206
|
+
const btnText = saveBtn?.querySelector(".myio-btn-text");
|
|
44207
|
+
const btnSpinner = saveBtn?.querySelector(".myio-btn-spinner");
|
|
44208
|
+
if (saveBtn) saveBtn.disabled = show;
|
|
44209
|
+
if (btnText) btnText.style.display = show ? "none" : "inline";
|
|
44210
|
+
if (btnSpinner) btnSpinner.style.display = show ? "inline-block" : "none";
|
|
44211
|
+
}
|
|
44212
|
+
showError(message) {
|
|
44213
|
+
const errorEl = this.overlayEl?.querySelector("#msm-error");
|
|
44214
|
+
const errorMsg = this.overlayEl?.querySelector("#msm-error-msg");
|
|
44215
|
+
if (errorEl) errorEl.style.display = "flex";
|
|
44216
|
+
if (errorMsg) errorMsg.textContent = message;
|
|
44217
|
+
}
|
|
44218
|
+
hideError() {
|
|
44219
|
+
const errorEl = this.overlayEl?.querySelector("#msm-error");
|
|
44220
|
+
if (errorEl) errorEl.style.display = "none";
|
|
44221
|
+
}
|
|
44222
|
+
showSuccess() {
|
|
44223
|
+
const successEl = this.overlayEl?.querySelector("#msm-success");
|
|
44224
|
+
if (successEl) successEl.style.display = "flex";
|
|
44225
|
+
}
|
|
44226
|
+
hideSuccess() {
|
|
44227
|
+
const successEl = this.overlayEl?.querySelector("#msm-success");
|
|
44228
|
+
if (successEl) successEl.style.display = "none";
|
|
44229
|
+
}
|
|
44230
|
+
getFormData() {
|
|
44231
|
+
return {
|
|
44232
|
+
water: { ...this.formData.water },
|
|
44233
|
+
energy: { ...this.formData.energy },
|
|
44234
|
+
temperature: { ...this.formData.temperature }
|
|
44235
|
+
};
|
|
44236
|
+
}
|
|
44237
|
+
setFormData(data) {
|
|
44238
|
+
if (data.water) this.formData.water = { ...data.water };
|
|
44239
|
+
if (data.energy) this.formData.energy = { ...data.energy };
|
|
44240
|
+
if (data.temperature) this.formData.temperature = { ...data.temperature };
|
|
44241
|
+
this.updateFormInputs();
|
|
44242
|
+
this.updatePreviews();
|
|
44243
|
+
}
|
|
44244
|
+
getStyles() {
|
|
44245
|
+
const styles = this.config.styles || {};
|
|
44246
|
+
const primaryColor = styles.primaryColor || "#4A148C";
|
|
44247
|
+
const successColor = styles.successColor || "#22c55e";
|
|
44248
|
+
const dangerColor = styles.dangerColor || "#ef4444";
|
|
44249
|
+
return `
|
|
44250
|
+
.myio-measurement-setup-overlay {
|
|
44251
|
+
position: fixed;
|
|
44252
|
+
top: 0;
|
|
44253
|
+
left: 0;
|
|
44254
|
+
right: 0;
|
|
44255
|
+
bottom: 0;
|
|
44256
|
+
background: rgba(0, 0, 0, 0.6);
|
|
44257
|
+
display: flex;
|
|
44258
|
+
align-items: center;
|
|
44259
|
+
justify-content: center;
|
|
44260
|
+
z-index: ${styles.zIndex || 1e4};
|
|
44261
|
+
opacity: 0;
|
|
44262
|
+
visibility: hidden;
|
|
44263
|
+
transition: all 0.3s ease;
|
|
44264
|
+
font-family: ${styles.fontFamily || "'Roboto', Arial, sans-serif"};
|
|
44265
|
+
}
|
|
44266
|
+
|
|
44267
|
+
.myio-measurement-setup-overlay.active {
|
|
44268
|
+
opacity: 1;
|
|
44269
|
+
visibility: visible;
|
|
44270
|
+
}
|
|
44271
|
+
|
|
44272
|
+
.myio-measurement-setup-card {
|
|
44273
|
+
background: ${styles.backgroundColor || "#ffffff"};
|
|
44274
|
+
border-radius: ${styles.borderRadius || "8px"};
|
|
44275
|
+
width: 90%;
|
|
44276
|
+
max-width: 580px;
|
|
44277
|
+
max-height: 90vh;
|
|
44278
|
+
overflow-y: auto;
|
|
44279
|
+
transform: scale(0.9);
|
|
44280
|
+
transition: transform 0.3s ease;
|
|
44281
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
44282
|
+
}
|
|
44283
|
+
|
|
44284
|
+
.myio-measurement-setup-overlay.active .myio-measurement-setup-card {
|
|
44285
|
+
transform: scale(1);
|
|
44286
|
+
}
|
|
44287
|
+
|
|
44288
|
+
/* Header */
|
|
44289
|
+
.myio-modal-header {
|
|
44290
|
+
display: flex;
|
|
44291
|
+
align-items: center;
|
|
44292
|
+
justify-content: space-between;
|
|
44293
|
+
padding: 6px 12px;
|
|
44294
|
+
background: ${primaryColor};
|
|
44295
|
+
border-radius: 8px 8px 0 0;
|
|
44296
|
+
min-height: 18px;
|
|
44297
|
+
}
|
|
44298
|
+
|
|
44299
|
+
.myio-modal-title {
|
|
44300
|
+
margin: 4px;
|
|
44301
|
+
font-size: 14px;
|
|
44302
|
+
font-weight: 600;
|
|
44303
|
+
color: white;
|
|
44304
|
+
line-height: 1.5;
|
|
44305
|
+
}
|
|
44306
|
+
|
|
44307
|
+
.myio-modal-close {
|
|
44308
|
+
background: none;
|
|
44309
|
+
border: none;
|
|
44310
|
+
font-size: 18px;
|
|
44311
|
+
cursor: pointer;
|
|
44312
|
+
padding: 2px 8px;
|
|
44313
|
+
border-radius: 4px;
|
|
44314
|
+
color: rgba(255, 255, 255, 0.8);
|
|
44315
|
+
transition: background-color 0.2s, color 0.2s;
|
|
44316
|
+
line-height: 1;
|
|
44317
|
+
}
|
|
44318
|
+
|
|
44319
|
+
.myio-modal-close:hover {
|
|
44320
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
44321
|
+
color: white;
|
|
44322
|
+
}
|
|
44323
|
+
|
|
44324
|
+
/* Body */
|
|
44325
|
+
.myio-measurement-setup-body {
|
|
44326
|
+
padding: 12px 16px;
|
|
44327
|
+
display: flex;
|
|
44328
|
+
flex-direction: column;
|
|
44329
|
+
gap: 10px;
|
|
44330
|
+
transition: opacity 0.3s;
|
|
44331
|
+
}
|
|
44332
|
+
|
|
44333
|
+
/* Section cards */
|
|
44334
|
+
.myio-measurement-section {
|
|
44335
|
+
background: var(--section-bg);
|
|
44336
|
+
border: 1px solid var(--section-color);
|
|
44337
|
+
border-radius: 6px;
|
|
44338
|
+
padding: 10px 12px;
|
|
44339
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
44340
|
+
}
|
|
44341
|
+
|
|
44342
|
+
.myio-measurement-section:hover {
|
|
44343
|
+
transform: translateY(-1px);
|
|
44344
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
44345
|
+
}
|
|
44346
|
+
|
|
44347
|
+
.myio-section-header {
|
|
44348
|
+
display: flex;
|
|
44349
|
+
align-items: center;
|
|
44350
|
+
gap: 6px;
|
|
44351
|
+
margin-bottom: 8px;
|
|
44352
|
+
padding-bottom: 6px;
|
|
44353
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
44354
|
+
}
|
|
44355
|
+
|
|
44356
|
+
.myio-section-icon {
|
|
44357
|
+
font-size: 16px;
|
|
44358
|
+
line-height: 1;
|
|
44359
|
+
}
|
|
44360
|
+
|
|
44361
|
+
.myio-section-title {
|
|
44362
|
+
font-weight: 600;
|
|
44363
|
+
font-size: 13px;
|
|
44364
|
+
color: #1f2937;
|
|
44365
|
+
}
|
|
44366
|
+
|
|
44367
|
+
.myio-section-content {
|
|
44368
|
+
display: grid;
|
|
44369
|
+
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
|
44370
|
+
gap: 10px;
|
|
44371
|
+
}
|
|
44372
|
+
|
|
44373
|
+
.myio-section-preview {
|
|
44374
|
+
margin-top: 8px;
|
|
44375
|
+
padding-top: 6px;
|
|
44376
|
+
border-top: 1px dashed rgba(0, 0, 0, 0.08);
|
|
44377
|
+
display: flex;
|
|
44378
|
+
align-items: center;
|
|
44379
|
+
gap: 6px;
|
|
44380
|
+
}
|
|
44381
|
+
|
|
44382
|
+
.myio-preview-label {
|
|
44383
|
+
font-size: 11px;
|
|
44384
|
+
color: #6b7280;
|
|
44385
|
+
}
|
|
44386
|
+
|
|
44387
|
+
.myio-preview-value {
|
|
44388
|
+
font-size: 13px;
|
|
44389
|
+
font-weight: 600;
|
|
44390
|
+
color: var(--section-color);
|
|
44391
|
+
font-family: 'Consolas', 'Monaco', monospace;
|
|
44392
|
+
}
|
|
44393
|
+
|
|
44394
|
+
/* Form elements */
|
|
44395
|
+
.myio-form-group {
|
|
44396
|
+
display: flex;
|
|
44397
|
+
flex-direction: column;
|
|
44398
|
+
gap: 3px;
|
|
44399
|
+
}
|
|
44400
|
+
|
|
44401
|
+
.myio-form-group label {
|
|
44402
|
+
font-size: 11px;
|
|
44403
|
+
font-weight: 500;
|
|
44404
|
+
color: #374151;
|
|
44405
|
+
}
|
|
44406
|
+
|
|
44407
|
+
.myio-select {
|
|
44408
|
+
padding: 6px 8px;
|
|
44409
|
+
border: 1px solid #d1d5db;
|
|
44410
|
+
border-radius: 4px;
|
|
44411
|
+
font-size: 12px;
|
|
44412
|
+
background: white;
|
|
44413
|
+
color: #1f2937;
|
|
44414
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
44415
|
+
cursor: pointer;
|
|
44416
|
+
}
|
|
44417
|
+
|
|
44418
|
+
.myio-select:focus {
|
|
44419
|
+
outline: none;
|
|
44420
|
+
border-color: ${primaryColor};
|
|
44421
|
+
box-shadow: 0 0 0 2px ${this.hexToRgba(primaryColor, 0.1)};
|
|
44422
|
+
}
|
|
44423
|
+
|
|
44424
|
+
.myio-checkbox-group {
|
|
44425
|
+
grid-column: 1 / -1;
|
|
44426
|
+
}
|
|
44427
|
+
|
|
44428
|
+
.myio-checkbox-label {
|
|
44429
|
+
display: flex;
|
|
44430
|
+
align-items: center;
|
|
44431
|
+
gap: 6px;
|
|
44432
|
+
cursor: pointer;
|
|
44433
|
+
}
|
|
44434
|
+
|
|
44435
|
+
.myio-checkbox-label input[type="checkbox"] {
|
|
44436
|
+
width: 14px;
|
|
44437
|
+
height: 14px;
|
|
44438
|
+
accent-color: ${primaryColor};
|
|
44439
|
+
cursor: pointer;
|
|
44440
|
+
}
|
|
44441
|
+
|
|
44442
|
+
.myio-checkbox-text {
|
|
44443
|
+
font-size: 12px;
|
|
44444
|
+
color: #374151;
|
|
44445
|
+
}
|
|
44446
|
+
|
|
44447
|
+
.myio-form-hint {
|
|
44448
|
+
font-size: 10px;
|
|
44449
|
+
color: #9ca3af;
|
|
44450
|
+
margin-top: 2px;
|
|
44451
|
+
}
|
|
44452
|
+
|
|
44453
|
+
/* Toolbar */
|
|
44454
|
+
.myio-measurement-setup-toolbar {
|
|
44455
|
+
display: flex;
|
|
44456
|
+
justify-content: flex-end;
|
|
44457
|
+
padding: 10px 16px;
|
|
44458
|
+
background: #f9fafb;
|
|
44459
|
+
border-top: 1px solid #e5e7eb;
|
|
44460
|
+
border-radius: 0 0 8px 8px;
|
|
44461
|
+
}
|
|
44462
|
+
|
|
44463
|
+
.myio-toolbar-actions {
|
|
44464
|
+
display: flex;
|
|
44465
|
+
align-items: center;
|
|
44466
|
+
gap: 8px;
|
|
44467
|
+
}
|
|
44468
|
+
|
|
44469
|
+
.myio-btn {
|
|
44470
|
+
padding: 6px 14px;
|
|
44471
|
+
border-radius: ${styles.buttonRadius || "4px"};
|
|
44472
|
+
font-size: 12px;
|
|
44473
|
+
font-weight: 500;
|
|
44474
|
+
cursor: pointer;
|
|
44475
|
+
border: none;
|
|
44476
|
+
transition: all 0.2s;
|
|
44477
|
+
display: inline-flex;
|
|
44478
|
+
align-items: center;
|
|
44479
|
+
gap: 4px;
|
|
44480
|
+
}
|
|
44481
|
+
|
|
44482
|
+
.myio-btn:disabled {
|
|
44483
|
+
opacity: 0.6;
|
|
44484
|
+
cursor: not-allowed;
|
|
44485
|
+
}
|
|
44486
|
+
|
|
44487
|
+
.myio-btn-primary {
|
|
44488
|
+
background: ${primaryColor};
|
|
44489
|
+
color: white;
|
|
44490
|
+
}
|
|
44491
|
+
|
|
44492
|
+
.myio-btn-primary:hover:not(:disabled) {
|
|
44493
|
+
background: ${this.lightenColor(primaryColor, -10)};
|
|
44494
|
+
}
|
|
44495
|
+
|
|
44496
|
+
.myio-btn-secondary {
|
|
44497
|
+
background: #e5e7eb;
|
|
44498
|
+
color: #374151;
|
|
44499
|
+
}
|
|
44500
|
+
|
|
44501
|
+
.myio-btn-secondary:hover:not(:disabled) {
|
|
44502
|
+
background: #d1d5db;
|
|
44503
|
+
}
|
|
44504
|
+
|
|
44505
|
+
.myio-btn-spinner {
|
|
44506
|
+
width: 12px;
|
|
44507
|
+
height: 12px;
|
|
44508
|
+
border: 2px solid white;
|
|
44509
|
+
border-top-color: transparent;
|
|
44510
|
+
border-radius: 50%;
|
|
44511
|
+
animation: spin 0.8s linear infinite;
|
|
44512
|
+
}
|
|
44513
|
+
|
|
44514
|
+
@keyframes spin {
|
|
44515
|
+
to { transform: rotate(360deg); }
|
|
44516
|
+
}
|
|
44517
|
+
|
|
44518
|
+
/* Loading, Error, Success states */
|
|
44519
|
+
.myio-measurement-setup-loading,
|
|
44520
|
+
.myio-measurement-setup-error,
|
|
44521
|
+
.myio-measurement-setup-success {
|
|
44522
|
+
display: flex;
|
|
44523
|
+
align-items: center;
|
|
44524
|
+
justify-content: center;
|
|
44525
|
+
gap: 8px;
|
|
44526
|
+
padding: 8px 12px;
|
|
44527
|
+
margin: 0 16px 12px;
|
|
44528
|
+
border-radius: 4px;
|
|
44529
|
+
font-size: 12px;
|
|
44530
|
+
}
|
|
44531
|
+
|
|
44532
|
+
.myio-measurement-setup-loading {
|
|
44533
|
+
background: #f3f4f6;
|
|
44534
|
+
color: #6b7280;
|
|
44535
|
+
}
|
|
44536
|
+
|
|
44537
|
+
.myio-measurement-setup-error {
|
|
44538
|
+
background: #fef2f2;
|
|
44539
|
+
color: ${dangerColor};
|
|
44540
|
+
border: 1px solid ${dangerColor};
|
|
44541
|
+
}
|
|
44542
|
+
|
|
44543
|
+
.myio-measurement-setup-success {
|
|
44544
|
+
background: #f0fdf4;
|
|
44545
|
+
color: ${successColor};
|
|
44546
|
+
border: 1px solid ${successColor};
|
|
44547
|
+
}
|
|
44548
|
+
|
|
44549
|
+
.myio-spinner {
|
|
44550
|
+
width: 16px;
|
|
44551
|
+
height: 16px;
|
|
44552
|
+
border: 2px solid #e5e7eb;
|
|
44553
|
+
border-top-color: ${primaryColor};
|
|
44554
|
+
border-radius: 50%;
|
|
44555
|
+
animation: spin 0.8s linear infinite;
|
|
44556
|
+
}
|
|
44557
|
+
|
|
44558
|
+
.myio-error-icon, .myio-success-icon {
|
|
44559
|
+
font-size: 14px;
|
|
44560
|
+
}
|
|
44561
|
+
|
|
44562
|
+
@media (max-width: 500px) {
|
|
44563
|
+
.myio-section-content {
|
|
44564
|
+
grid-template-columns: 1fr;
|
|
44565
|
+
}
|
|
44566
|
+
|
|
44567
|
+
.myio-toolbar-actions {
|
|
44568
|
+
flex-direction: column;
|
|
44569
|
+
width: 100%;
|
|
44570
|
+
}
|
|
44571
|
+
|
|
44572
|
+
.myio-btn {
|
|
44573
|
+
width: 100%;
|
|
44574
|
+
justify-content: center;
|
|
44575
|
+
}
|
|
44576
|
+
}
|
|
44577
|
+
`;
|
|
44578
|
+
}
|
|
44579
|
+
lightenColor(hex, percent) {
|
|
44580
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
44581
|
+
const amt = Math.round(2.55 * percent);
|
|
44582
|
+
const R = (num >> 16) + amt;
|
|
44583
|
+
const G = (num >> 8 & 255) + amt;
|
|
44584
|
+
const B = (num & 255) + amt;
|
|
44585
|
+
return "#" + (16777216 + (R < 255 ? R < 1 ? 0 : R : 255) * 65536 + (G < 255 ? G < 1 ? 0 : G : 255) * 256 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
|
|
44586
|
+
}
|
|
44587
|
+
hexToRgba(hex, alpha) {
|
|
44588
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
44589
|
+
const R = num >> 16;
|
|
44590
|
+
const G = num >> 8 & 255;
|
|
44591
|
+
const B = num & 255;
|
|
44592
|
+
return `rgba(${R}, ${G}, ${B}, ${alpha})`;
|
|
44593
|
+
}
|
|
44594
|
+
};
|
|
44595
|
+
|
|
44596
|
+
// src/components/premium-modals/measurement-setup/MeasurementSetupPersister.ts
|
|
44597
|
+
var MeasurementSetupPersister = class _MeasurementSetupPersister {
|
|
44598
|
+
token;
|
|
44599
|
+
tbBaseUrl;
|
|
44600
|
+
static ATTRIBUTE_KEY = "measurementDisplaySettings";
|
|
44601
|
+
static FETCH_TIMEOUT_MS = 8e3;
|
|
44602
|
+
constructor(token, tbBaseUrl) {
|
|
44603
|
+
this.token = token;
|
|
44604
|
+
this.tbBaseUrl = tbBaseUrl || window.location.origin;
|
|
44605
|
+
}
|
|
44606
|
+
/**
|
|
44607
|
+
* Fetch with timeout to prevent hanging requests
|
|
44608
|
+
*/
|
|
44609
|
+
async fetchWithTimeout(url, options, timeoutMs = _MeasurementSetupPersister.FETCH_TIMEOUT_MS) {
|
|
44610
|
+
const controller = new AbortController();
|
|
44611
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
44612
|
+
try {
|
|
44613
|
+
const response = await fetch(url, {
|
|
44614
|
+
...options,
|
|
44615
|
+
signal: controller.signal
|
|
44616
|
+
});
|
|
44617
|
+
return response;
|
|
44618
|
+
} finally {
|
|
44619
|
+
clearTimeout(timeoutId);
|
|
44620
|
+
}
|
|
44621
|
+
}
|
|
44622
|
+
/**
|
|
44623
|
+
* Load measurement settings from customer SERVER_SCOPE
|
|
44624
|
+
*/
|
|
44625
|
+
async loadSettings(customerId) {
|
|
44626
|
+
try {
|
|
44627
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE?keys=${_MeasurementSetupPersister.ATTRIBUTE_KEY}`;
|
|
44628
|
+
console.log("[MeasurementSetupPersister] Loading settings from:", url);
|
|
44629
|
+
const response = await this.fetchWithTimeout(url, {
|
|
44630
|
+
headers: {
|
|
44631
|
+
"X-Authorization": `Bearer ${this.token}`,
|
|
44632
|
+
"Content-Type": "application/json"
|
|
44633
|
+
}
|
|
44634
|
+
});
|
|
44635
|
+
if (!response.ok) {
|
|
44636
|
+
console.warn(`[MeasurementSetupPersister] HTTP ${response.status}: ${response.statusText}`);
|
|
44637
|
+
return null;
|
|
44638
|
+
}
|
|
44639
|
+
const attrs = await response.json();
|
|
44640
|
+
const settingsAttr = attrs.find((a) => a.key === _MeasurementSetupPersister.ATTRIBUTE_KEY);
|
|
44641
|
+
if (!settingsAttr) {
|
|
44642
|
+
console.log("[MeasurementSetupPersister] No existing settings found, using defaults");
|
|
44643
|
+
return null;
|
|
44644
|
+
}
|
|
44645
|
+
const value = typeof settingsAttr.value === "string" ? JSON.parse(settingsAttr.value) : settingsAttr.value;
|
|
44646
|
+
console.log("[MeasurementSetupPersister] Loaded settings:", value);
|
|
44647
|
+
return this.validateAndMergeSettings(value);
|
|
44648
|
+
} catch (error) {
|
|
44649
|
+
console.error("[MeasurementSetupPersister] Failed to load settings:", error);
|
|
44650
|
+
return null;
|
|
44651
|
+
}
|
|
44652
|
+
}
|
|
44653
|
+
/**
|
|
44654
|
+
* Save measurement settings to customer SERVER_SCOPE
|
|
44655
|
+
*/
|
|
44656
|
+
async saveSettings(customerId, settings) {
|
|
44657
|
+
try {
|
|
44658
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/attributes/SERVER_SCOPE`;
|
|
44659
|
+
console.log("[MeasurementSetupPersister] Saving settings to:", url);
|
|
44660
|
+
const payload = {
|
|
44661
|
+
[_MeasurementSetupPersister.ATTRIBUTE_KEY]: JSON.stringify(settings)
|
|
44662
|
+
};
|
|
44663
|
+
const response = await this.fetchWithTimeout(url, {
|
|
44664
|
+
method: "POST",
|
|
44665
|
+
headers: {
|
|
44666
|
+
"X-Authorization": `Bearer ${this.token}`,
|
|
44667
|
+
"Content-Type": "application/json"
|
|
44668
|
+
},
|
|
44669
|
+
body: JSON.stringify(payload)
|
|
44670
|
+
});
|
|
44671
|
+
if (!response.ok) {
|
|
44672
|
+
const errorText = await response.text();
|
|
44673
|
+
console.error("[MeasurementSetupPersister] Save failed:", response.status, errorText);
|
|
44674
|
+
return {
|
|
44675
|
+
ok: false,
|
|
44676
|
+
error: {
|
|
44677
|
+
code: response.status === 401 ? "AUTH_ERROR" : "NETWORK_ERROR",
|
|
44678
|
+
message: `Failed to save settings: HTTP ${response.status}`,
|
|
44679
|
+
cause: errorText
|
|
44680
|
+
}
|
|
44681
|
+
};
|
|
44682
|
+
}
|
|
44683
|
+
console.log("[MeasurementSetupPersister] Settings saved successfully");
|
|
44684
|
+
return { ok: true, settings };
|
|
44685
|
+
} catch (error) {
|
|
44686
|
+
console.error("[MeasurementSetupPersister] Save error:", error);
|
|
44687
|
+
return {
|
|
44688
|
+
ok: false,
|
|
44689
|
+
error: {
|
|
44690
|
+
code: "UNKNOWN_ERROR",
|
|
44691
|
+
message: error.message || "Failed to save settings",
|
|
44692
|
+
cause: error
|
|
44693
|
+
}
|
|
44694
|
+
};
|
|
44695
|
+
}
|
|
44696
|
+
}
|
|
44697
|
+
/**
|
|
44698
|
+
* Validate and merge settings with defaults to ensure all fields exist
|
|
44699
|
+
*/
|
|
44700
|
+
validateAndMergeSettings(settings) {
|
|
44701
|
+
return {
|
|
44702
|
+
version: settings.version || DEFAULT_SETTINGS.version,
|
|
44703
|
+
updatedAt: settings.updatedAt || DEFAULT_SETTINGS.updatedAt,
|
|
44704
|
+
updatedBy: settings.updatedBy,
|
|
44705
|
+
water: {
|
|
44706
|
+
unit: settings.water?.unit || DEFAULT_SETTINGS.water.unit,
|
|
44707
|
+
decimalPlaces: settings.water?.decimalPlaces ?? DEFAULT_SETTINGS.water.decimalPlaces,
|
|
44708
|
+
autoScale: settings.water?.autoScale ?? DEFAULT_SETTINGS.water.autoScale
|
|
44709
|
+
},
|
|
44710
|
+
energy: {
|
|
44711
|
+
unit: settings.energy?.unit || DEFAULT_SETTINGS.energy.unit,
|
|
44712
|
+
decimalPlaces: settings.energy?.decimalPlaces ?? DEFAULT_SETTINGS.energy.decimalPlaces,
|
|
44713
|
+
forceUnit: settings.energy?.forceUnit ?? DEFAULT_SETTINGS.energy.forceUnit
|
|
44714
|
+
},
|
|
44715
|
+
temperature: {
|
|
44716
|
+
unit: settings.temperature?.unit || DEFAULT_SETTINGS.temperature.unit,
|
|
44717
|
+
decimalPlaces: settings.temperature?.decimalPlaces ?? DEFAULT_SETTINGS.temperature.decimalPlaces
|
|
44718
|
+
}
|
|
44719
|
+
};
|
|
44720
|
+
}
|
|
44721
|
+
/**
|
|
44722
|
+
* Convert form data to full settings object for persistence
|
|
44723
|
+
*/
|
|
44724
|
+
formDataToSettings(formData, existingSettings) {
|
|
44725
|
+
return {
|
|
44726
|
+
version: existingSettings?.version || DEFAULT_SETTINGS.version,
|
|
44727
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44728
|
+
updatedBy: existingSettings?.updatedBy,
|
|
44729
|
+
water: { ...formData.water },
|
|
44730
|
+
energy: { ...formData.energy },
|
|
44731
|
+
temperature: { ...formData.temperature }
|
|
44732
|
+
};
|
|
44733
|
+
}
|
|
44734
|
+
/**
|
|
44735
|
+
* Extract form data from settings
|
|
44736
|
+
*/
|
|
44737
|
+
settingsToFormData(settings) {
|
|
44738
|
+
const s = settings || DEFAULT_SETTINGS;
|
|
44739
|
+
return {
|
|
44740
|
+
water: { ...s.water },
|
|
44741
|
+
energy: { ...s.energy },
|
|
44742
|
+
temperature: { ...s.temperature }
|
|
44743
|
+
};
|
|
44744
|
+
}
|
|
44745
|
+
};
|
|
44746
|
+
|
|
44747
|
+
// src/components/premium-modals/measurement-setup/openMeasurementSetupModal.ts
|
|
44748
|
+
async function openMeasurementSetupModal(params) {
|
|
44749
|
+
if (!params.token) {
|
|
44750
|
+
throw new Error("[MeasurementSetupModal] token is required");
|
|
44751
|
+
}
|
|
44752
|
+
if (!params.customerId) {
|
|
44753
|
+
throw new Error("[MeasurementSetupModal] customerId is required");
|
|
44754
|
+
}
|
|
44755
|
+
const persister = new MeasurementSetupPersister(params.token, params.tbBaseUrl);
|
|
44756
|
+
let existingSettings = params.existingSettings || null;
|
|
44757
|
+
const view = new MeasurementSetupView({
|
|
44758
|
+
styles: params.styles,
|
|
44759
|
+
onSave: async () => {
|
|
44760
|
+
const formData = view.getFormData();
|
|
44761
|
+
const settings = persister.formDataToSettings(formData, existingSettings);
|
|
44762
|
+
const result = await persister.saveSettings(params.customerId, settings);
|
|
44763
|
+
if (!result.ok) {
|
|
44764
|
+
throw new Error(result.error?.message || "Failed to save configuration");
|
|
44765
|
+
}
|
|
44766
|
+
existingSettings = settings;
|
|
44767
|
+
if (params.onSave) {
|
|
44768
|
+
params.onSave(settings);
|
|
44769
|
+
}
|
|
44770
|
+
},
|
|
44771
|
+
onClose: () => {
|
|
44772
|
+
if (params.onClose) {
|
|
44773
|
+
params.onClose();
|
|
44774
|
+
}
|
|
44775
|
+
}
|
|
44776
|
+
});
|
|
44777
|
+
async function loadFormData() {
|
|
44778
|
+
view.showLoading();
|
|
44779
|
+
try {
|
|
44780
|
+
if (!existingSettings) {
|
|
44781
|
+
existingSettings = await persister.loadSettings(params.customerId);
|
|
44782
|
+
}
|
|
44783
|
+
const formData = persister.settingsToFormData(existingSettings);
|
|
44784
|
+
view.setFormData(formData);
|
|
44785
|
+
} catch (error) {
|
|
44786
|
+
console.error("[MeasurementSetupModal] Error loading form data:", error);
|
|
44787
|
+
view.showError(error.message || "Failed to load configuration");
|
|
44788
|
+
} finally {
|
|
44789
|
+
view.hideLoading();
|
|
44790
|
+
}
|
|
44791
|
+
}
|
|
44792
|
+
let container;
|
|
44793
|
+
if (params.container) {
|
|
44794
|
+
if (typeof params.container === "string") {
|
|
44795
|
+
container = document.querySelector(params.container);
|
|
44796
|
+
} else {
|
|
44797
|
+
container = params.container;
|
|
44798
|
+
}
|
|
44799
|
+
}
|
|
44800
|
+
view.render(container);
|
|
44801
|
+
await loadFormData();
|
|
44802
|
+
return {
|
|
44803
|
+
destroy: () => view.destroy(),
|
|
44804
|
+
getFormData: () => view.getFormData(),
|
|
44805
|
+
setFormData: (data) => view.setFormData(data)
|
|
44806
|
+
};
|
|
44807
|
+
}
|
|
43718
44808
|
// Annotate the CommonJS export names for ESM import in node:
|
|
43719
44809
|
0 && (module.exports = {
|
|
43720
44810
|
ANNOTATION_TYPE_COLORS,
|
|
@@ -43727,14 +44817,17 @@ async function openContractDevicesModal(params) {
|
|
|
43727
44817
|
CONSUMPTION_THEME_COLORS,
|
|
43728
44818
|
ConnectionStatusType,
|
|
43729
44819
|
ContractSummaryTooltip,
|
|
44820
|
+
DECIMAL_OPTIONS,
|
|
43730
44821
|
DEFAULT_CLAMP_RANGE,
|
|
43731
44822
|
DEFAULT_ENERGY_GROUP_COLORS,
|
|
43732
44823
|
DEFAULT_GAS_GROUP_COLORS,
|
|
44824
|
+
DEFAULT_MEASUREMENT_SETTINGS,
|
|
43733
44825
|
DEFAULT_SHOPPING_COLORS,
|
|
43734
44826
|
DEFAULT_WATER_GROUP_COLORS,
|
|
43735
44827
|
DEVICE_COUNT_KEYS,
|
|
43736
44828
|
DeviceComparisonTooltip,
|
|
43737
44829
|
DeviceStatusType,
|
|
44830
|
+
ENERGY_UNITS,
|
|
43738
44831
|
EXPORT_DEFAULT_COLORS,
|
|
43739
44832
|
EXPORT_DOMAIN_ICONS,
|
|
43740
44833
|
EXPORT_DOMAIN_LABELS,
|
|
@@ -43745,6 +44838,7 @@ async function openContractDevicesModal(params) {
|
|
|
43745
44838
|
IMPORTANCE_LABELS,
|
|
43746
44839
|
IMPORTANCE_LABELS_EN,
|
|
43747
44840
|
InfoTooltip,
|
|
44841
|
+
MEASUREMENT_DOMAIN_CONFIG,
|
|
43748
44842
|
MyIOChartModal,
|
|
43749
44843
|
MyIODraggableCard,
|
|
43750
44844
|
MyIOSelectionStore,
|
|
@@ -43756,9 +44850,11 @@ async function openContractDevicesModal(params) {
|
|
|
43756
44850
|
STATUS_COLORS,
|
|
43757
44851
|
STATUS_LABELS,
|
|
43758
44852
|
STATUS_LABELS_EN,
|
|
44853
|
+
TEMPERATURE_UNITS,
|
|
43759
44854
|
TempComparisonTooltip,
|
|
43760
44855
|
TempRangeTooltip,
|
|
43761
44856
|
TempSensorSummaryTooltip,
|
|
44857
|
+
WATER_UNITS,
|
|
43762
44858
|
WaterSummaryTooltip,
|
|
43763
44859
|
addDetectionContext,
|
|
43764
44860
|
addNamespace,
|
|
@@ -43864,6 +44960,7 @@ async function openContractDevicesModal(params) {
|
|
|
43864
44960
|
openDashboardPopupWaterTank,
|
|
43865
44961
|
openDemandModal,
|
|
43866
44962
|
openGoalsPanel,
|
|
44963
|
+
openMeasurementSetupModal,
|
|
43867
44964
|
openPowerLimitsSetupModal,
|
|
43868
44965
|
openRealTimeTelemetryModal,
|
|
43869
44966
|
openTemperatureComparisonModal,
|