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.js
CHANGED
|
@@ -29034,13 +29034,31 @@ var DefaultSettingsPersister = class {
|
|
|
29034
29034
|
};
|
|
29035
29035
|
|
|
29036
29036
|
// src/components/premium-modals/settings/SettingsFetcher.ts
|
|
29037
|
-
var DefaultSettingsFetcher = class {
|
|
29037
|
+
var DefaultSettingsFetcher = class _DefaultSettingsFetcher {
|
|
29038
29038
|
jwtToken;
|
|
29039
29039
|
tbBaseUrl;
|
|
29040
|
+
static FETCH_TIMEOUT_MS = 8e3;
|
|
29041
|
+
// 8 second timeout
|
|
29040
29042
|
constructor(jwtToken, apiConfig) {
|
|
29041
29043
|
this.jwtToken = jwtToken;
|
|
29042
29044
|
this.tbBaseUrl = apiConfig?.tbBaseUrl || window.location.origin;
|
|
29043
29045
|
}
|
|
29046
|
+
/**
|
|
29047
|
+
* Fetch with timeout to prevent hanging requests from blocking modal render
|
|
29048
|
+
*/
|
|
29049
|
+
async fetchWithTimeout(url, options, timeoutMs = _DefaultSettingsFetcher.FETCH_TIMEOUT_MS) {
|
|
29050
|
+
const controller = new AbortController();
|
|
29051
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
29052
|
+
try {
|
|
29053
|
+
const response = await fetch(url, {
|
|
29054
|
+
...options,
|
|
29055
|
+
signal: controller.signal
|
|
29056
|
+
});
|
|
29057
|
+
return response;
|
|
29058
|
+
} finally {
|
|
29059
|
+
clearTimeout(timeoutId);
|
|
29060
|
+
}
|
|
29061
|
+
}
|
|
29044
29062
|
async fetchCurrentSettings(deviceId, jwtToken, scope = "SERVER_SCOPE") {
|
|
29045
29063
|
try {
|
|
29046
29064
|
const [entityResult, attributesResult] = await Promise.allSettled([
|
|
@@ -29074,9 +29092,12 @@ var DefaultSettingsFetcher = class {
|
|
|
29074
29092
|
}
|
|
29075
29093
|
}
|
|
29076
29094
|
async fetchDeviceEntity(deviceId) {
|
|
29077
|
-
const response = await
|
|
29078
|
-
|
|
29079
|
-
|
|
29095
|
+
const response = await this.fetchWithTimeout(
|
|
29096
|
+
`${this.tbBaseUrl}/api/device/${deviceId}`,
|
|
29097
|
+
{
|
|
29098
|
+
headers: { "X-Authorization": `Bearer ${this.jwtToken}` }
|
|
29099
|
+
}
|
|
29100
|
+
);
|
|
29080
29101
|
if (!response.ok) {
|
|
29081
29102
|
throw new Error(
|
|
29082
29103
|
`Failed to fetch device entity: ${response.status} ${response.statusText}`
|
|
@@ -29088,7 +29109,7 @@ var DefaultSettingsFetcher = class {
|
|
|
29088
29109
|
};
|
|
29089
29110
|
}
|
|
29090
29111
|
async fetchDeviceAttributes(deviceId, scope) {
|
|
29091
|
-
const response = await
|
|
29112
|
+
const response = await this.fetchWithTimeout(
|
|
29092
29113
|
`${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/values/attributes/${scope}`,
|
|
29093
29114
|
{
|
|
29094
29115
|
headers: { "X-Authorization": `Bearer ${this.jwtToken}` }
|
|
@@ -29297,12 +29318,16 @@ var SettingsController = class {
|
|
|
29297
29318
|
const tbBaseUrl = this.params.api?.tbBaseUrl || window.location.origin;
|
|
29298
29319
|
const url = `${tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE?keys=mapInstantaneousPower`;
|
|
29299
29320
|
console.log("[SettingsModal] RFC-0080: Fetching GLOBAL from:", url);
|
|
29321
|
+
const controller = new AbortController();
|
|
29322
|
+
const timeoutId = setTimeout(() => controller.abort(), 8e3);
|
|
29300
29323
|
const response = await fetch(url, {
|
|
29301
29324
|
headers: {
|
|
29302
29325
|
"X-Authorization": `Bearer ${jwtToken}`,
|
|
29303
29326
|
"Content-Type": "application/json"
|
|
29304
|
-
}
|
|
29327
|
+
},
|
|
29328
|
+
signal: controller.signal
|
|
29305
29329
|
});
|
|
29330
|
+
clearTimeout(timeoutId);
|
|
29306
29331
|
if (!response.ok) {
|
|
29307
29332
|
throw new Error(`HTTP ${response.status}`);
|
|
29308
29333
|
}
|
|
@@ -43543,6 +43568,1064 @@ async function openContractDevicesModal(params) {
|
|
|
43543
43568
|
throw error;
|
|
43544
43569
|
}
|
|
43545
43570
|
}
|
|
43571
|
+
|
|
43572
|
+
// src/components/premium-modals/measurement-setup/types.ts
|
|
43573
|
+
var WATER_UNITS = [
|
|
43574
|
+
{ value: "m3", label: "Metros C\xFAbicos (m\xB3)" },
|
|
43575
|
+
{ value: "liters", label: "Litros (L)" }
|
|
43576
|
+
];
|
|
43577
|
+
var ENERGY_UNITS = [
|
|
43578
|
+
{ value: "auto", label: "Autom\xE1tico (kWh/MWh)" },
|
|
43579
|
+
{ value: "kwh", label: "Quilowatt-hora (kWh)" },
|
|
43580
|
+
{ value: "mwh", label: "Megawatt-hora (MWh)" }
|
|
43581
|
+
];
|
|
43582
|
+
var TEMPERATURE_UNITS = [
|
|
43583
|
+
{ value: "celsius", label: "Celsius (\xB0C)" },
|
|
43584
|
+
{ value: "fahrenheit", label: "Fahrenheit (\xB0F)" }
|
|
43585
|
+
];
|
|
43586
|
+
var DECIMAL_OPTIONS = [
|
|
43587
|
+
{ value: 0, label: "0 casas" },
|
|
43588
|
+
{ value: 1, label: "1 casa" },
|
|
43589
|
+
{ value: 2, label: "2 casas" },
|
|
43590
|
+
{ value: 3, label: "3 casas" },
|
|
43591
|
+
{ value: 4, label: "4 casas" },
|
|
43592
|
+
{ value: 5, label: "5 casas" },
|
|
43593
|
+
{ value: 6, label: "6 casas" }
|
|
43594
|
+
];
|
|
43595
|
+
var DOMAIN_CONFIG5 = {
|
|
43596
|
+
water: {
|
|
43597
|
+
icon: "\u{1F4A7}",
|
|
43598
|
+
label: "\xC1gua",
|
|
43599
|
+
color: "#3b82f6",
|
|
43600
|
+
bgColor: "rgba(59, 130, 246, 0.1)"
|
|
43601
|
+
},
|
|
43602
|
+
energy: {
|
|
43603
|
+
icon: "\u26A1",
|
|
43604
|
+
label: "Energia",
|
|
43605
|
+
color: "#f59e0b",
|
|
43606
|
+
bgColor: "rgba(245, 158, 11, 0.1)"
|
|
43607
|
+
},
|
|
43608
|
+
temperature: {
|
|
43609
|
+
icon: "\u{1F321}\uFE0F",
|
|
43610
|
+
label: "Temperatura",
|
|
43611
|
+
color: "#ef4444",
|
|
43612
|
+
bgColor: "rgba(239, 68, 68, 0.1)"
|
|
43613
|
+
}
|
|
43614
|
+
};
|
|
43615
|
+
var DEFAULT_SETTINGS = {
|
|
43616
|
+
version: "1.0.0",
|
|
43617
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43618
|
+
water: {
|
|
43619
|
+
unit: "m3",
|
|
43620
|
+
decimalPlaces: 3,
|
|
43621
|
+
autoScale: true
|
|
43622
|
+
},
|
|
43623
|
+
energy: {
|
|
43624
|
+
unit: "auto",
|
|
43625
|
+
decimalPlaces: 3,
|
|
43626
|
+
forceUnit: false
|
|
43627
|
+
},
|
|
43628
|
+
temperature: {
|
|
43629
|
+
unit: "celsius",
|
|
43630
|
+
decimalPlaces: 1
|
|
43631
|
+
}
|
|
43632
|
+
};
|
|
43633
|
+
|
|
43634
|
+
// src/components/premium-modals/measurement-setup/MeasurementSetupView.ts
|
|
43635
|
+
var MeasurementSetupView = class {
|
|
43636
|
+
container = null;
|
|
43637
|
+
overlayEl = null;
|
|
43638
|
+
config;
|
|
43639
|
+
formData;
|
|
43640
|
+
isLoading = false;
|
|
43641
|
+
isSaving = false;
|
|
43642
|
+
constructor(config) {
|
|
43643
|
+
this.config = config;
|
|
43644
|
+
this.formData = {
|
|
43645
|
+
water: { ...DEFAULT_SETTINGS.water },
|
|
43646
|
+
energy: { ...DEFAULT_SETTINGS.energy },
|
|
43647
|
+
temperature: { ...DEFAULT_SETTINGS.temperature }
|
|
43648
|
+
};
|
|
43649
|
+
}
|
|
43650
|
+
render(targetContainer) {
|
|
43651
|
+
this.overlayEl = document.createElement("div");
|
|
43652
|
+
this.overlayEl.className = "myio-measurement-setup-overlay";
|
|
43653
|
+
this.overlayEl.innerHTML = `
|
|
43654
|
+
<style>${this.getStyles()}</style>
|
|
43655
|
+
<div class="myio-measurement-setup-card">
|
|
43656
|
+
${this.renderHeader()}
|
|
43657
|
+
<div class="myio-measurement-setup-body">
|
|
43658
|
+
${this.renderWaterSection()}
|
|
43659
|
+
${this.renderEnergySection()}
|
|
43660
|
+
${this.renderTemperatureSection()}
|
|
43661
|
+
</div>
|
|
43662
|
+
${this.renderToolbar()}
|
|
43663
|
+
${this.renderLoadingState()}
|
|
43664
|
+
${this.renderErrorState()}
|
|
43665
|
+
${this.renderSuccessState()}
|
|
43666
|
+
</div>
|
|
43667
|
+
`;
|
|
43668
|
+
const target = targetContainer || document.body;
|
|
43669
|
+
target.appendChild(this.overlayEl);
|
|
43670
|
+
this.container = this.overlayEl.querySelector(".myio-measurement-setup-card");
|
|
43671
|
+
this.setupEventListeners();
|
|
43672
|
+
requestAnimationFrame(() => {
|
|
43673
|
+
this.overlayEl?.classList.add("active");
|
|
43674
|
+
});
|
|
43675
|
+
return this.overlayEl;
|
|
43676
|
+
}
|
|
43677
|
+
renderHeader() {
|
|
43678
|
+
return `
|
|
43679
|
+
<div class="myio-modal-header">
|
|
43680
|
+
<h2 class="myio-modal-title">\u{1F4D0} Configura\xE7\xE3o de Medidas</h2>
|
|
43681
|
+
<button class="myio-modal-close" id="msm-close-btn" type="button" aria-label="Fechar modal">\xD7</button>
|
|
43682
|
+
</div>
|
|
43683
|
+
`;
|
|
43684
|
+
}
|
|
43685
|
+
renderWaterSection() {
|
|
43686
|
+
const cfg = DOMAIN_CONFIG5.water;
|
|
43687
|
+
return `
|
|
43688
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43689
|
+
<div class="myio-section-header">
|
|
43690
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43691
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43692
|
+
</div>
|
|
43693
|
+
<div class="myio-section-content">
|
|
43694
|
+
<div class="myio-form-group">
|
|
43695
|
+
<label for="msm-water-unit">Unidade</label>
|
|
43696
|
+
<select id="msm-water-unit" class="myio-select">
|
|
43697
|
+
${WATER_UNITS.map((u) => `
|
|
43698
|
+
<option value="${u.value}" ${u.value === this.formData.water.unit ? "selected" : ""}>
|
|
43699
|
+
${u.label}
|
|
43700
|
+
</option>
|
|
43701
|
+
`).join("")}
|
|
43702
|
+
</select>
|
|
43703
|
+
</div>
|
|
43704
|
+
<div class="myio-form-group">
|
|
43705
|
+
<label for="msm-water-decimals">Casas Decimais</label>
|
|
43706
|
+
<select id="msm-water-decimals" class="myio-select">
|
|
43707
|
+
${DECIMAL_OPTIONS.map((d) => `
|
|
43708
|
+
<option value="${d.value}" ${d.value === this.formData.water.decimalPlaces ? "selected" : ""}>
|
|
43709
|
+
${d.label}
|
|
43710
|
+
</option>
|
|
43711
|
+
`).join("")}
|
|
43712
|
+
</select>
|
|
43713
|
+
</div>
|
|
43714
|
+
<div class="myio-form-group myio-checkbox-group">
|
|
43715
|
+
<label class="myio-checkbox-label">
|
|
43716
|
+
<input type="checkbox" id="msm-water-autoscale" ${this.formData.water.autoScale ? "checked" : ""}>
|
|
43717
|
+
<span class="myio-checkbox-text">Escala autom\xE1tica (L\u2194m\xB3)</span>
|
|
43718
|
+
</label>
|
|
43719
|
+
<span class="myio-form-hint">Converte automaticamente entre unidades</span>
|
|
43720
|
+
</div>
|
|
43721
|
+
</div>
|
|
43722
|
+
<div class="myio-section-preview">
|
|
43723
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43724
|
+
<span class="myio-preview-value" id="msm-water-preview">1.234,567 m\xB3</span>
|
|
43725
|
+
</div>
|
|
43726
|
+
</div>
|
|
43727
|
+
`;
|
|
43728
|
+
}
|
|
43729
|
+
renderEnergySection() {
|
|
43730
|
+
const cfg = DOMAIN_CONFIG5.energy;
|
|
43731
|
+
return `
|
|
43732
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43733
|
+
<div class="myio-section-header">
|
|
43734
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43735
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43736
|
+
</div>
|
|
43737
|
+
<div class="myio-section-content">
|
|
43738
|
+
<div class="myio-form-group">
|
|
43739
|
+
<label for="msm-energy-unit">Unidade</label>
|
|
43740
|
+
<select id="msm-energy-unit" class="myio-select">
|
|
43741
|
+
${ENERGY_UNITS.map((u) => `
|
|
43742
|
+
<option value="${u.value}" ${u.value === this.formData.energy.unit ? "selected" : ""}>
|
|
43743
|
+
${u.label}
|
|
43744
|
+
</option>
|
|
43745
|
+
`).join("")}
|
|
43746
|
+
</select>
|
|
43747
|
+
</div>
|
|
43748
|
+
<div class="myio-form-group">
|
|
43749
|
+
<label for="msm-energy-decimals">Casas Decimais</label>
|
|
43750
|
+
<select id="msm-energy-decimals" class="myio-select">
|
|
43751
|
+
${DECIMAL_OPTIONS.filter((d) => d.value <= 4).map((d) => `
|
|
43752
|
+
<option value="${d.value}" ${d.value === this.formData.energy.decimalPlaces ? "selected" : ""}>
|
|
43753
|
+
${d.label}
|
|
43754
|
+
</option>
|
|
43755
|
+
`).join("")}
|
|
43756
|
+
</select>
|
|
43757
|
+
</div>
|
|
43758
|
+
<div class="myio-form-group myio-checkbox-group">
|
|
43759
|
+
<label class="myio-checkbox-label">
|
|
43760
|
+
<input type="checkbox" id="msm-energy-forceunit" ${this.formData.energy.forceUnit ? "checked" : ""}>
|
|
43761
|
+
<span class="myio-checkbox-text">For\xE7ar unidade selecionada</span>
|
|
43762
|
+
</label>
|
|
43763
|
+
<span class="myio-form-hint">Quando ativo, n\xE3o converte automaticamente kWh\u2194MWh</span>
|
|
43764
|
+
</div>
|
|
43765
|
+
</div>
|
|
43766
|
+
<div class="myio-section-preview">
|
|
43767
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43768
|
+
<span class="myio-preview-value" id="msm-energy-preview">1.234,567 kWh</span>
|
|
43769
|
+
</div>
|
|
43770
|
+
</div>
|
|
43771
|
+
`;
|
|
43772
|
+
}
|
|
43773
|
+
renderTemperatureSection() {
|
|
43774
|
+
const cfg = DOMAIN_CONFIG5.temperature;
|
|
43775
|
+
return `
|
|
43776
|
+
<div class="myio-measurement-section" style="--section-color: ${cfg.color}; --section-bg: ${cfg.bgColor};">
|
|
43777
|
+
<div class="myio-section-header">
|
|
43778
|
+
<span class="myio-section-icon">${cfg.icon}</span>
|
|
43779
|
+
<span class="myio-section-title">${cfg.label}</span>
|
|
43780
|
+
</div>
|
|
43781
|
+
<div class="myio-section-content">
|
|
43782
|
+
<div class="myio-form-group">
|
|
43783
|
+
<label for="msm-temp-unit">Unidade</label>
|
|
43784
|
+
<select id="msm-temp-unit" class="myio-select">
|
|
43785
|
+
${TEMPERATURE_UNITS.map((u) => `
|
|
43786
|
+
<option value="${u.value}" ${u.value === this.formData.temperature.unit ? "selected" : ""}>
|
|
43787
|
+
${u.label}
|
|
43788
|
+
</option>
|
|
43789
|
+
`).join("")}
|
|
43790
|
+
</select>
|
|
43791
|
+
</div>
|
|
43792
|
+
<div class="myio-form-group">
|
|
43793
|
+
<label for="msm-temp-decimals">Casas Decimais</label>
|
|
43794
|
+
<select id="msm-temp-decimals" class="myio-select">
|
|
43795
|
+
${DECIMAL_OPTIONS.filter((d) => d.value <= 3).map((d) => `
|
|
43796
|
+
<option value="${d.value}" ${d.value === this.formData.temperature.decimalPlaces ? "selected" : ""}>
|
|
43797
|
+
${d.label}
|
|
43798
|
+
</option>
|
|
43799
|
+
`).join("")}
|
|
43800
|
+
</select>
|
|
43801
|
+
</div>
|
|
43802
|
+
</div>
|
|
43803
|
+
<div class="myio-section-preview">
|
|
43804
|
+
<span class="myio-preview-label">Exemplo:</span>
|
|
43805
|
+
<span class="myio-preview-value" id="msm-temp-preview">23,5 \xB0C</span>
|
|
43806
|
+
</div>
|
|
43807
|
+
</div>
|
|
43808
|
+
`;
|
|
43809
|
+
}
|
|
43810
|
+
renderToolbar() {
|
|
43811
|
+
return `
|
|
43812
|
+
<div class="myio-measurement-setup-toolbar">
|
|
43813
|
+
<div class="myio-toolbar-actions">
|
|
43814
|
+
<button class="myio-btn myio-btn-secondary" id="msm-reset-btn" type="button">
|
|
43815
|
+
Restaurar Padr\xE3o
|
|
43816
|
+
</button>
|
|
43817
|
+
<button class="myio-btn myio-btn-primary" id="msm-save-btn" type="button">
|
|
43818
|
+
<span class="myio-btn-text">Salvar</span>
|
|
43819
|
+
<span class="myio-btn-spinner" style="display: none;"></span>
|
|
43820
|
+
</button>
|
|
43821
|
+
</div>
|
|
43822
|
+
</div>
|
|
43823
|
+
`;
|
|
43824
|
+
}
|
|
43825
|
+
renderLoadingState() {
|
|
43826
|
+
return `
|
|
43827
|
+
<div class="myio-measurement-setup-loading" id="msm-loading" style="display: none;">
|
|
43828
|
+
<div class="myio-spinner"></div>
|
|
43829
|
+
<span>Carregando configura\xE7\xE3o...</span>
|
|
43830
|
+
</div>
|
|
43831
|
+
`;
|
|
43832
|
+
}
|
|
43833
|
+
renderErrorState() {
|
|
43834
|
+
return `
|
|
43835
|
+
<div class="myio-measurement-setup-error" id="msm-error" style="display: none;">
|
|
43836
|
+
<span class="myio-error-icon">⚠</span>
|
|
43837
|
+
<span class="myio-error-message" id="msm-error-msg"></span>
|
|
43838
|
+
</div>
|
|
43839
|
+
`;
|
|
43840
|
+
}
|
|
43841
|
+
renderSuccessState() {
|
|
43842
|
+
return `
|
|
43843
|
+
<div class="myio-measurement-setup-success" id="msm-success" style="display: none;">
|
|
43844
|
+
<span class="myio-success-icon">✓</span>
|
|
43845
|
+
<span class="myio-success-message">Configura\xE7\xE3o salva com sucesso!</span>
|
|
43846
|
+
</div>
|
|
43847
|
+
`;
|
|
43848
|
+
}
|
|
43849
|
+
setupEventListeners() {
|
|
43850
|
+
if (!this.overlayEl) return;
|
|
43851
|
+
const closeBtn = this.overlayEl.querySelector("#msm-close-btn");
|
|
43852
|
+
closeBtn?.addEventListener("click", () => this.close());
|
|
43853
|
+
this.overlayEl.addEventListener("click", (e) => {
|
|
43854
|
+
if (e.target === this.overlayEl) {
|
|
43855
|
+
this.close();
|
|
43856
|
+
}
|
|
43857
|
+
});
|
|
43858
|
+
document.addEventListener("keydown", this.handleKeyDown);
|
|
43859
|
+
const saveBtn = this.overlayEl.querySelector("#msm-save-btn");
|
|
43860
|
+
saveBtn?.addEventListener("click", () => this.handleSave());
|
|
43861
|
+
const resetBtn = this.overlayEl.querySelector("#msm-reset-btn");
|
|
43862
|
+
resetBtn?.addEventListener("click", () => this.handleReset());
|
|
43863
|
+
const waterUnit = this.overlayEl.querySelector("#msm-water-unit");
|
|
43864
|
+
const waterDecimals = this.overlayEl.querySelector("#msm-water-decimals");
|
|
43865
|
+
const waterAutoScale = this.overlayEl.querySelector("#msm-water-autoscale");
|
|
43866
|
+
waterUnit?.addEventListener("change", (e) => {
|
|
43867
|
+
this.formData.water.unit = e.target.value;
|
|
43868
|
+
this.updatePreviews();
|
|
43869
|
+
});
|
|
43870
|
+
waterDecimals?.addEventListener("change", (e) => {
|
|
43871
|
+
this.formData.water.decimalPlaces = parseInt(e.target.value, 10);
|
|
43872
|
+
this.updatePreviews();
|
|
43873
|
+
});
|
|
43874
|
+
waterAutoScale?.addEventListener("change", (e) => {
|
|
43875
|
+
this.formData.water.autoScale = e.target.checked;
|
|
43876
|
+
});
|
|
43877
|
+
const energyUnit = this.overlayEl.querySelector("#msm-energy-unit");
|
|
43878
|
+
const energyDecimals = this.overlayEl.querySelector("#msm-energy-decimals");
|
|
43879
|
+
const energyForceUnit = this.overlayEl.querySelector("#msm-energy-forceunit");
|
|
43880
|
+
energyUnit?.addEventListener("change", (e) => {
|
|
43881
|
+
this.formData.energy.unit = e.target.value;
|
|
43882
|
+
this.updatePreviews();
|
|
43883
|
+
});
|
|
43884
|
+
energyDecimals?.addEventListener("change", (e) => {
|
|
43885
|
+
this.formData.energy.decimalPlaces = parseInt(e.target.value, 10);
|
|
43886
|
+
this.updatePreviews();
|
|
43887
|
+
});
|
|
43888
|
+
energyForceUnit?.addEventListener("change", (e) => {
|
|
43889
|
+
this.formData.energy.forceUnit = e.target.checked;
|
|
43890
|
+
});
|
|
43891
|
+
const tempUnit = this.overlayEl.querySelector("#msm-temp-unit");
|
|
43892
|
+
const tempDecimals = this.overlayEl.querySelector("#msm-temp-decimals");
|
|
43893
|
+
tempUnit?.addEventListener("change", (e) => {
|
|
43894
|
+
this.formData.temperature.unit = e.target.value;
|
|
43895
|
+
this.updatePreviews();
|
|
43896
|
+
});
|
|
43897
|
+
tempDecimals?.addEventListener("change", (e) => {
|
|
43898
|
+
this.formData.temperature.decimalPlaces = parseInt(e.target.value, 10);
|
|
43899
|
+
this.updatePreviews();
|
|
43900
|
+
});
|
|
43901
|
+
this.updatePreviews();
|
|
43902
|
+
}
|
|
43903
|
+
updatePreviews() {
|
|
43904
|
+
const waterPreview = this.overlayEl?.querySelector("#msm-water-preview");
|
|
43905
|
+
if (waterPreview) {
|
|
43906
|
+
const sampleValue = 1234.567;
|
|
43907
|
+
const unit = this.formData.water.unit === "liters" ? "L" : "m\xB3";
|
|
43908
|
+
const displayValue = this.formData.water.unit === "liters" ? sampleValue * 1e3 : sampleValue;
|
|
43909
|
+
waterPreview.textContent = this.formatNumber(displayValue, this.formData.water.decimalPlaces) + " " + unit;
|
|
43910
|
+
}
|
|
43911
|
+
const energyPreview = this.overlayEl?.querySelector("#msm-energy-preview");
|
|
43912
|
+
if (energyPreview) {
|
|
43913
|
+
const sampleValueKwh = 1234.567;
|
|
43914
|
+
let displayValue = sampleValueKwh;
|
|
43915
|
+
let unit = "kWh";
|
|
43916
|
+
if (this.formData.energy.unit === "mwh") {
|
|
43917
|
+
displayValue = sampleValueKwh / 1e3;
|
|
43918
|
+
unit = "MWh";
|
|
43919
|
+
} else if (this.formData.energy.unit === "auto" && sampleValueKwh > 1e3) {
|
|
43920
|
+
displayValue = sampleValueKwh / 1e3;
|
|
43921
|
+
unit = "MWh";
|
|
43922
|
+
}
|
|
43923
|
+
energyPreview.textContent = this.formatNumber(displayValue, this.formData.energy.decimalPlaces) + " " + unit;
|
|
43924
|
+
}
|
|
43925
|
+
const tempPreview = this.overlayEl?.querySelector("#msm-temp-preview");
|
|
43926
|
+
if (tempPreview) {
|
|
43927
|
+
const sampleCelsius = 23.5;
|
|
43928
|
+
let displayValue = sampleCelsius;
|
|
43929
|
+
let unit = "\xB0C";
|
|
43930
|
+
if (this.formData.temperature.unit === "fahrenheit") {
|
|
43931
|
+
displayValue = sampleCelsius * 9 / 5 + 32;
|
|
43932
|
+
unit = "\xB0F";
|
|
43933
|
+
}
|
|
43934
|
+
tempPreview.textContent = this.formatNumber(displayValue, this.formData.temperature.decimalPlaces) + " " + unit;
|
|
43935
|
+
}
|
|
43936
|
+
}
|
|
43937
|
+
formatNumber(value, decimals) {
|
|
43938
|
+
const parts = value.toFixed(decimals).split(".");
|
|
43939
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
43940
|
+
return decimals > 0 ? parts.join(",") : parts[0];
|
|
43941
|
+
}
|
|
43942
|
+
handleKeyDown = (e) => {
|
|
43943
|
+
if (e.key === "Escape") {
|
|
43944
|
+
this.close();
|
|
43945
|
+
}
|
|
43946
|
+
};
|
|
43947
|
+
async handleSave() {
|
|
43948
|
+
if (this.isSaving) return;
|
|
43949
|
+
this.isSaving = true;
|
|
43950
|
+
this.showSaveLoading(true);
|
|
43951
|
+
this.hideError();
|
|
43952
|
+
this.hideSuccess();
|
|
43953
|
+
try {
|
|
43954
|
+
await this.config.onSave();
|
|
43955
|
+
this.showSuccess();
|
|
43956
|
+
setTimeout(() => this.hideSuccess(), 3e3);
|
|
43957
|
+
} catch (error) {
|
|
43958
|
+
this.showError(error.message || "Falha ao salvar configura\xE7\xE3o");
|
|
43959
|
+
} finally {
|
|
43960
|
+
this.isSaving = false;
|
|
43961
|
+
this.showSaveLoading(false);
|
|
43962
|
+
}
|
|
43963
|
+
}
|
|
43964
|
+
handleReset() {
|
|
43965
|
+
this.formData = {
|
|
43966
|
+
water: { ...DEFAULT_SETTINGS.water },
|
|
43967
|
+
energy: { ...DEFAULT_SETTINGS.energy },
|
|
43968
|
+
temperature: { ...DEFAULT_SETTINGS.temperature }
|
|
43969
|
+
};
|
|
43970
|
+
this.updateFormInputs();
|
|
43971
|
+
this.updatePreviews();
|
|
43972
|
+
this.hideError();
|
|
43973
|
+
this.hideSuccess();
|
|
43974
|
+
}
|
|
43975
|
+
updateFormInputs() {
|
|
43976
|
+
const waterUnit = this.overlayEl?.querySelector("#msm-water-unit");
|
|
43977
|
+
const waterDecimals = this.overlayEl?.querySelector("#msm-water-decimals");
|
|
43978
|
+
const waterAutoScale = this.overlayEl?.querySelector("#msm-water-autoscale");
|
|
43979
|
+
if (waterUnit) waterUnit.value = this.formData.water.unit;
|
|
43980
|
+
if (waterDecimals) waterDecimals.value = String(this.formData.water.decimalPlaces);
|
|
43981
|
+
if (waterAutoScale) waterAutoScale.checked = this.formData.water.autoScale;
|
|
43982
|
+
const energyUnit = this.overlayEl?.querySelector("#msm-energy-unit");
|
|
43983
|
+
const energyDecimals = this.overlayEl?.querySelector("#msm-energy-decimals");
|
|
43984
|
+
const energyForceUnit = this.overlayEl?.querySelector("#msm-energy-forceunit");
|
|
43985
|
+
if (energyUnit) energyUnit.value = this.formData.energy.unit;
|
|
43986
|
+
if (energyDecimals) energyDecimals.value = String(this.formData.energy.decimalPlaces);
|
|
43987
|
+
if (energyForceUnit) energyForceUnit.checked = this.formData.energy.forceUnit;
|
|
43988
|
+
const tempUnit = this.overlayEl?.querySelector("#msm-temp-unit");
|
|
43989
|
+
const tempDecimals = this.overlayEl?.querySelector("#msm-temp-decimals");
|
|
43990
|
+
if (tempUnit) tempUnit.value = this.formData.temperature.unit;
|
|
43991
|
+
if (tempDecimals) tempDecimals.value = String(this.formData.temperature.decimalPlaces);
|
|
43992
|
+
}
|
|
43993
|
+
close() {
|
|
43994
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
43995
|
+
if (this.overlayEl) {
|
|
43996
|
+
this.overlayEl.classList.remove("active");
|
|
43997
|
+
setTimeout(() => {
|
|
43998
|
+
this.overlayEl?.remove();
|
|
43999
|
+
this.overlayEl = null;
|
|
44000
|
+
this.container = null;
|
|
44001
|
+
this.config.onClose();
|
|
44002
|
+
}, 300);
|
|
44003
|
+
}
|
|
44004
|
+
}
|
|
44005
|
+
destroy() {
|
|
44006
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
44007
|
+
this.overlayEl?.remove();
|
|
44008
|
+
this.overlayEl = null;
|
|
44009
|
+
this.container = null;
|
|
44010
|
+
}
|
|
44011
|
+
showLoading() {
|
|
44012
|
+
this.isLoading = true;
|
|
44013
|
+
const loadingEl = this.overlayEl?.querySelector("#msm-loading");
|
|
44014
|
+
const bodyEl = this.overlayEl?.querySelector(".myio-measurement-setup-body");
|
|
44015
|
+
if (loadingEl) loadingEl.style.display = "flex";
|
|
44016
|
+
if (bodyEl) bodyEl.style.opacity = "0.5";
|
|
44017
|
+
}
|
|
44018
|
+
hideLoading() {
|
|
44019
|
+
this.isLoading = false;
|
|
44020
|
+
const loadingEl = this.overlayEl?.querySelector("#msm-loading");
|
|
44021
|
+
const bodyEl = this.overlayEl?.querySelector(".myio-measurement-setup-body");
|
|
44022
|
+
if (loadingEl) loadingEl.style.display = "none";
|
|
44023
|
+
if (bodyEl) bodyEl.style.opacity = "1";
|
|
44024
|
+
}
|
|
44025
|
+
showSaveLoading(show) {
|
|
44026
|
+
const saveBtn = this.overlayEl?.querySelector("#msm-save-btn");
|
|
44027
|
+
const btnText = saveBtn?.querySelector(".myio-btn-text");
|
|
44028
|
+
const btnSpinner = saveBtn?.querySelector(".myio-btn-spinner");
|
|
44029
|
+
if (saveBtn) saveBtn.disabled = show;
|
|
44030
|
+
if (btnText) btnText.style.display = show ? "none" : "inline";
|
|
44031
|
+
if (btnSpinner) btnSpinner.style.display = show ? "inline-block" : "none";
|
|
44032
|
+
}
|
|
44033
|
+
showError(message) {
|
|
44034
|
+
const errorEl = this.overlayEl?.querySelector("#msm-error");
|
|
44035
|
+
const errorMsg = this.overlayEl?.querySelector("#msm-error-msg");
|
|
44036
|
+
if (errorEl) errorEl.style.display = "flex";
|
|
44037
|
+
if (errorMsg) errorMsg.textContent = message;
|
|
44038
|
+
}
|
|
44039
|
+
hideError() {
|
|
44040
|
+
const errorEl = this.overlayEl?.querySelector("#msm-error");
|
|
44041
|
+
if (errorEl) errorEl.style.display = "none";
|
|
44042
|
+
}
|
|
44043
|
+
showSuccess() {
|
|
44044
|
+
const successEl = this.overlayEl?.querySelector("#msm-success");
|
|
44045
|
+
if (successEl) successEl.style.display = "flex";
|
|
44046
|
+
}
|
|
44047
|
+
hideSuccess() {
|
|
44048
|
+
const successEl = this.overlayEl?.querySelector("#msm-success");
|
|
44049
|
+
if (successEl) successEl.style.display = "none";
|
|
44050
|
+
}
|
|
44051
|
+
getFormData() {
|
|
44052
|
+
return {
|
|
44053
|
+
water: { ...this.formData.water },
|
|
44054
|
+
energy: { ...this.formData.energy },
|
|
44055
|
+
temperature: { ...this.formData.temperature }
|
|
44056
|
+
};
|
|
44057
|
+
}
|
|
44058
|
+
setFormData(data) {
|
|
44059
|
+
if (data.water) this.formData.water = { ...data.water };
|
|
44060
|
+
if (data.energy) this.formData.energy = { ...data.energy };
|
|
44061
|
+
if (data.temperature) this.formData.temperature = { ...data.temperature };
|
|
44062
|
+
this.updateFormInputs();
|
|
44063
|
+
this.updatePreviews();
|
|
44064
|
+
}
|
|
44065
|
+
getStyles() {
|
|
44066
|
+
const styles = this.config.styles || {};
|
|
44067
|
+
const primaryColor = styles.primaryColor || "#4A148C";
|
|
44068
|
+
const successColor = styles.successColor || "#22c55e";
|
|
44069
|
+
const dangerColor = styles.dangerColor || "#ef4444";
|
|
44070
|
+
return `
|
|
44071
|
+
.myio-measurement-setup-overlay {
|
|
44072
|
+
position: fixed;
|
|
44073
|
+
top: 0;
|
|
44074
|
+
left: 0;
|
|
44075
|
+
right: 0;
|
|
44076
|
+
bottom: 0;
|
|
44077
|
+
background: rgba(0, 0, 0, 0.6);
|
|
44078
|
+
display: flex;
|
|
44079
|
+
align-items: center;
|
|
44080
|
+
justify-content: center;
|
|
44081
|
+
z-index: ${styles.zIndex || 1e4};
|
|
44082
|
+
opacity: 0;
|
|
44083
|
+
visibility: hidden;
|
|
44084
|
+
transition: all 0.3s ease;
|
|
44085
|
+
font-family: ${styles.fontFamily || "'Roboto', Arial, sans-serif"};
|
|
44086
|
+
}
|
|
44087
|
+
|
|
44088
|
+
.myio-measurement-setup-overlay.active {
|
|
44089
|
+
opacity: 1;
|
|
44090
|
+
visibility: visible;
|
|
44091
|
+
}
|
|
44092
|
+
|
|
44093
|
+
.myio-measurement-setup-card {
|
|
44094
|
+
background: ${styles.backgroundColor || "#ffffff"};
|
|
44095
|
+
border-radius: ${styles.borderRadius || "8px"};
|
|
44096
|
+
width: 90%;
|
|
44097
|
+
max-width: 580px;
|
|
44098
|
+
max-height: 90vh;
|
|
44099
|
+
overflow-y: auto;
|
|
44100
|
+
transform: scale(0.9);
|
|
44101
|
+
transition: transform 0.3s ease;
|
|
44102
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
44103
|
+
}
|
|
44104
|
+
|
|
44105
|
+
.myio-measurement-setup-overlay.active .myio-measurement-setup-card {
|
|
44106
|
+
transform: scale(1);
|
|
44107
|
+
}
|
|
44108
|
+
|
|
44109
|
+
/* Header */
|
|
44110
|
+
.myio-modal-header {
|
|
44111
|
+
display: flex;
|
|
44112
|
+
align-items: center;
|
|
44113
|
+
justify-content: space-between;
|
|
44114
|
+
padding: 6px 12px;
|
|
44115
|
+
background: ${primaryColor};
|
|
44116
|
+
border-radius: 8px 8px 0 0;
|
|
44117
|
+
min-height: 18px;
|
|
44118
|
+
}
|
|
44119
|
+
|
|
44120
|
+
.myio-modal-title {
|
|
44121
|
+
margin: 4px;
|
|
44122
|
+
font-size: 14px;
|
|
44123
|
+
font-weight: 600;
|
|
44124
|
+
color: white;
|
|
44125
|
+
line-height: 1.5;
|
|
44126
|
+
}
|
|
44127
|
+
|
|
44128
|
+
.myio-modal-close {
|
|
44129
|
+
background: none;
|
|
44130
|
+
border: none;
|
|
44131
|
+
font-size: 18px;
|
|
44132
|
+
cursor: pointer;
|
|
44133
|
+
padding: 2px 8px;
|
|
44134
|
+
border-radius: 4px;
|
|
44135
|
+
color: rgba(255, 255, 255, 0.8);
|
|
44136
|
+
transition: background-color 0.2s, color 0.2s;
|
|
44137
|
+
line-height: 1;
|
|
44138
|
+
}
|
|
44139
|
+
|
|
44140
|
+
.myio-modal-close:hover {
|
|
44141
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
44142
|
+
color: white;
|
|
44143
|
+
}
|
|
44144
|
+
|
|
44145
|
+
/* Body */
|
|
44146
|
+
.myio-measurement-setup-body {
|
|
44147
|
+
padding: 12px 16px;
|
|
44148
|
+
display: flex;
|
|
44149
|
+
flex-direction: column;
|
|
44150
|
+
gap: 10px;
|
|
44151
|
+
transition: opacity 0.3s;
|
|
44152
|
+
}
|
|
44153
|
+
|
|
44154
|
+
/* Section cards */
|
|
44155
|
+
.myio-measurement-section {
|
|
44156
|
+
background: var(--section-bg);
|
|
44157
|
+
border: 1px solid var(--section-color);
|
|
44158
|
+
border-radius: 6px;
|
|
44159
|
+
padding: 10px 12px;
|
|
44160
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
44161
|
+
}
|
|
44162
|
+
|
|
44163
|
+
.myio-measurement-section:hover {
|
|
44164
|
+
transform: translateY(-1px);
|
|
44165
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
44166
|
+
}
|
|
44167
|
+
|
|
44168
|
+
.myio-section-header {
|
|
44169
|
+
display: flex;
|
|
44170
|
+
align-items: center;
|
|
44171
|
+
gap: 6px;
|
|
44172
|
+
margin-bottom: 8px;
|
|
44173
|
+
padding-bottom: 6px;
|
|
44174
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
44175
|
+
}
|
|
44176
|
+
|
|
44177
|
+
.myio-section-icon {
|
|
44178
|
+
font-size: 16px;
|
|
44179
|
+
line-height: 1;
|
|
44180
|
+
}
|
|
44181
|
+
|
|
44182
|
+
.myio-section-title {
|
|
44183
|
+
font-weight: 600;
|
|
44184
|
+
font-size: 13px;
|
|
44185
|
+
color: #1f2937;
|
|
44186
|
+
}
|
|
44187
|
+
|
|
44188
|
+
.myio-section-content {
|
|
44189
|
+
display: grid;
|
|
44190
|
+
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
|
44191
|
+
gap: 10px;
|
|
44192
|
+
}
|
|
44193
|
+
|
|
44194
|
+
.myio-section-preview {
|
|
44195
|
+
margin-top: 8px;
|
|
44196
|
+
padding-top: 6px;
|
|
44197
|
+
border-top: 1px dashed rgba(0, 0, 0, 0.08);
|
|
44198
|
+
display: flex;
|
|
44199
|
+
align-items: center;
|
|
44200
|
+
gap: 6px;
|
|
44201
|
+
}
|
|
44202
|
+
|
|
44203
|
+
.myio-preview-label {
|
|
44204
|
+
font-size: 11px;
|
|
44205
|
+
color: #6b7280;
|
|
44206
|
+
}
|
|
44207
|
+
|
|
44208
|
+
.myio-preview-value {
|
|
44209
|
+
font-size: 13px;
|
|
44210
|
+
font-weight: 600;
|
|
44211
|
+
color: var(--section-color);
|
|
44212
|
+
font-family: 'Consolas', 'Monaco', monospace;
|
|
44213
|
+
}
|
|
44214
|
+
|
|
44215
|
+
/* Form elements */
|
|
44216
|
+
.myio-form-group {
|
|
44217
|
+
display: flex;
|
|
44218
|
+
flex-direction: column;
|
|
44219
|
+
gap: 3px;
|
|
44220
|
+
}
|
|
44221
|
+
|
|
44222
|
+
.myio-form-group label {
|
|
44223
|
+
font-size: 11px;
|
|
44224
|
+
font-weight: 500;
|
|
44225
|
+
color: #374151;
|
|
44226
|
+
}
|
|
44227
|
+
|
|
44228
|
+
.myio-select {
|
|
44229
|
+
padding: 6px 8px;
|
|
44230
|
+
border: 1px solid #d1d5db;
|
|
44231
|
+
border-radius: 4px;
|
|
44232
|
+
font-size: 12px;
|
|
44233
|
+
background: white;
|
|
44234
|
+
color: #1f2937;
|
|
44235
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
44236
|
+
cursor: pointer;
|
|
44237
|
+
}
|
|
44238
|
+
|
|
44239
|
+
.myio-select:focus {
|
|
44240
|
+
outline: none;
|
|
44241
|
+
border-color: ${primaryColor};
|
|
44242
|
+
box-shadow: 0 0 0 2px ${this.hexToRgba(primaryColor, 0.1)};
|
|
44243
|
+
}
|
|
44244
|
+
|
|
44245
|
+
.myio-checkbox-group {
|
|
44246
|
+
grid-column: 1 / -1;
|
|
44247
|
+
}
|
|
44248
|
+
|
|
44249
|
+
.myio-checkbox-label {
|
|
44250
|
+
display: flex;
|
|
44251
|
+
align-items: center;
|
|
44252
|
+
gap: 6px;
|
|
44253
|
+
cursor: pointer;
|
|
44254
|
+
}
|
|
44255
|
+
|
|
44256
|
+
.myio-checkbox-label input[type="checkbox"] {
|
|
44257
|
+
width: 14px;
|
|
44258
|
+
height: 14px;
|
|
44259
|
+
accent-color: ${primaryColor};
|
|
44260
|
+
cursor: pointer;
|
|
44261
|
+
}
|
|
44262
|
+
|
|
44263
|
+
.myio-checkbox-text {
|
|
44264
|
+
font-size: 12px;
|
|
44265
|
+
color: #374151;
|
|
44266
|
+
}
|
|
44267
|
+
|
|
44268
|
+
.myio-form-hint {
|
|
44269
|
+
font-size: 10px;
|
|
44270
|
+
color: #9ca3af;
|
|
44271
|
+
margin-top: 2px;
|
|
44272
|
+
}
|
|
44273
|
+
|
|
44274
|
+
/* Toolbar */
|
|
44275
|
+
.myio-measurement-setup-toolbar {
|
|
44276
|
+
display: flex;
|
|
44277
|
+
justify-content: flex-end;
|
|
44278
|
+
padding: 10px 16px;
|
|
44279
|
+
background: #f9fafb;
|
|
44280
|
+
border-top: 1px solid #e5e7eb;
|
|
44281
|
+
border-radius: 0 0 8px 8px;
|
|
44282
|
+
}
|
|
44283
|
+
|
|
44284
|
+
.myio-toolbar-actions {
|
|
44285
|
+
display: flex;
|
|
44286
|
+
align-items: center;
|
|
44287
|
+
gap: 8px;
|
|
44288
|
+
}
|
|
44289
|
+
|
|
44290
|
+
.myio-btn {
|
|
44291
|
+
padding: 6px 14px;
|
|
44292
|
+
border-radius: ${styles.buttonRadius || "4px"};
|
|
44293
|
+
font-size: 12px;
|
|
44294
|
+
font-weight: 500;
|
|
44295
|
+
cursor: pointer;
|
|
44296
|
+
border: none;
|
|
44297
|
+
transition: all 0.2s;
|
|
44298
|
+
display: inline-flex;
|
|
44299
|
+
align-items: center;
|
|
44300
|
+
gap: 4px;
|
|
44301
|
+
}
|
|
44302
|
+
|
|
44303
|
+
.myio-btn:disabled {
|
|
44304
|
+
opacity: 0.6;
|
|
44305
|
+
cursor: not-allowed;
|
|
44306
|
+
}
|
|
44307
|
+
|
|
44308
|
+
.myio-btn-primary {
|
|
44309
|
+
background: ${primaryColor};
|
|
44310
|
+
color: white;
|
|
44311
|
+
}
|
|
44312
|
+
|
|
44313
|
+
.myio-btn-primary:hover:not(:disabled) {
|
|
44314
|
+
background: ${this.lightenColor(primaryColor, -10)};
|
|
44315
|
+
}
|
|
44316
|
+
|
|
44317
|
+
.myio-btn-secondary {
|
|
44318
|
+
background: #e5e7eb;
|
|
44319
|
+
color: #374151;
|
|
44320
|
+
}
|
|
44321
|
+
|
|
44322
|
+
.myio-btn-secondary:hover:not(:disabled) {
|
|
44323
|
+
background: #d1d5db;
|
|
44324
|
+
}
|
|
44325
|
+
|
|
44326
|
+
.myio-btn-spinner {
|
|
44327
|
+
width: 12px;
|
|
44328
|
+
height: 12px;
|
|
44329
|
+
border: 2px solid white;
|
|
44330
|
+
border-top-color: transparent;
|
|
44331
|
+
border-radius: 50%;
|
|
44332
|
+
animation: spin 0.8s linear infinite;
|
|
44333
|
+
}
|
|
44334
|
+
|
|
44335
|
+
@keyframes spin {
|
|
44336
|
+
to { transform: rotate(360deg); }
|
|
44337
|
+
}
|
|
44338
|
+
|
|
44339
|
+
/* Loading, Error, Success states */
|
|
44340
|
+
.myio-measurement-setup-loading,
|
|
44341
|
+
.myio-measurement-setup-error,
|
|
44342
|
+
.myio-measurement-setup-success {
|
|
44343
|
+
display: flex;
|
|
44344
|
+
align-items: center;
|
|
44345
|
+
justify-content: center;
|
|
44346
|
+
gap: 8px;
|
|
44347
|
+
padding: 8px 12px;
|
|
44348
|
+
margin: 0 16px 12px;
|
|
44349
|
+
border-radius: 4px;
|
|
44350
|
+
font-size: 12px;
|
|
44351
|
+
}
|
|
44352
|
+
|
|
44353
|
+
.myio-measurement-setup-loading {
|
|
44354
|
+
background: #f3f4f6;
|
|
44355
|
+
color: #6b7280;
|
|
44356
|
+
}
|
|
44357
|
+
|
|
44358
|
+
.myio-measurement-setup-error {
|
|
44359
|
+
background: #fef2f2;
|
|
44360
|
+
color: ${dangerColor};
|
|
44361
|
+
border: 1px solid ${dangerColor};
|
|
44362
|
+
}
|
|
44363
|
+
|
|
44364
|
+
.myio-measurement-setup-success {
|
|
44365
|
+
background: #f0fdf4;
|
|
44366
|
+
color: ${successColor};
|
|
44367
|
+
border: 1px solid ${successColor};
|
|
44368
|
+
}
|
|
44369
|
+
|
|
44370
|
+
.myio-spinner {
|
|
44371
|
+
width: 16px;
|
|
44372
|
+
height: 16px;
|
|
44373
|
+
border: 2px solid #e5e7eb;
|
|
44374
|
+
border-top-color: ${primaryColor};
|
|
44375
|
+
border-radius: 50%;
|
|
44376
|
+
animation: spin 0.8s linear infinite;
|
|
44377
|
+
}
|
|
44378
|
+
|
|
44379
|
+
.myio-error-icon, .myio-success-icon {
|
|
44380
|
+
font-size: 14px;
|
|
44381
|
+
}
|
|
44382
|
+
|
|
44383
|
+
@media (max-width: 500px) {
|
|
44384
|
+
.myio-section-content {
|
|
44385
|
+
grid-template-columns: 1fr;
|
|
44386
|
+
}
|
|
44387
|
+
|
|
44388
|
+
.myio-toolbar-actions {
|
|
44389
|
+
flex-direction: column;
|
|
44390
|
+
width: 100%;
|
|
44391
|
+
}
|
|
44392
|
+
|
|
44393
|
+
.myio-btn {
|
|
44394
|
+
width: 100%;
|
|
44395
|
+
justify-content: center;
|
|
44396
|
+
}
|
|
44397
|
+
}
|
|
44398
|
+
`;
|
|
44399
|
+
}
|
|
44400
|
+
lightenColor(hex, percent) {
|
|
44401
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
44402
|
+
const amt = Math.round(2.55 * percent);
|
|
44403
|
+
const R = (num >> 16) + amt;
|
|
44404
|
+
const G = (num >> 8 & 255) + amt;
|
|
44405
|
+
const B = (num & 255) + amt;
|
|
44406
|
+
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);
|
|
44407
|
+
}
|
|
44408
|
+
hexToRgba(hex, alpha) {
|
|
44409
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
44410
|
+
const R = num >> 16;
|
|
44411
|
+
const G = num >> 8 & 255;
|
|
44412
|
+
const B = num & 255;
|
|
44413
|
+
return `rgba(${R}, ${G}, ${B}, ${alpha})`;
|
|
44414
|
+
}
|
|
44415
|
+
};
|
|
44416
|
+
|
|
44417
|
+
// src/components/premium-modals/measurement-setup/MeasurementSetupPersister.ts
|
|
44418
|
+
var MeasurementSetupPersister = class _MeasurementSetupPersister {
|
|
44419
|
+
token;
|
|
44420
|
+
tbBaseUrl;
|
|
44421
|
+
static ATTRIBUTE_KEY = "measurementDisplaySettings";
|
|
44422
|
+
static FETCH_TIMEOUT_MS = 8e3;
|
|
44423
|
+
constructor(token, tbBaseUrl) {
|
|
44424
|
+
this.token = token;
|
|
44425
|
+
this.tbBaseUrl = tbBaseUrl || window.location.origin;
|
|
44426
|
+
}
|
|
44427
|
+
/**
|
|
44428
|
+
* Fetch with timeout to prevent hanging requests
|
|
44429
|
+
*/
|
|
44430
|
+
async fetchWithTimeout(url, options, timeoutMs = _MeasurementSetupPersister.FETCH_TIMEOUT_MS) {
|
|
44431
|
+
const controller = new AbortController();
|
|
44432
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
44433
|
+
try {
|
|
44434
|
+
const response = await fetch(url, {
|
|
44435
|
+
...options,
|
|
44436
|
+
signal: controller.signal
|
|
44437
|
+
});
|
|
44438
|
+
return response;
|
|
44439
|
+
} finally {
|
|
44440
|
+
clearTimeout(timeoutId);
|
|
44441
|
+
}
|
|
44442
|
+
}
|
|
44443
|
+
/**
|
|
44444
|
+
* Load measurement settings from customer SERVER_SCOPE
|
|
44445
|
+
*/
|
|
44446
|
+
async loadSettings(customerId) {
|
|
44447
|
+
try {
|
|
44448
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE?keys=${_MeasurementSetupPersister.ATTRIBUTE_KEY}`;
|
|
44449
|
+
console.log("[MeasurementSetupPersister] Loading settings from:", url);
|
|
44450
|
+
const response = await this.fetchWithTimeout(url, {
|
|
44451
|
+
headers: {
|
|
44452
|
+
"X-Authorization": `Bearer ${this.token}`,
|
|
44453
|
+
"Content-Type": "application/json"
|
|
44454
|
+
}
|
|
44455
|
+
});
|
|
44456
|
+
if (!response.ok) {
|
|
44457
|
+
console.warn(`[MeasurementSetupPersister] HTTP ${response.status}: ${response.statusText}`);
|
|
44458
|
+
return null;
|
|
44459
|
+
}
|
|
44460
|
+
const attrs = await response.json();
|
|
44461
|
+
const settingsAttr = attrs.find((a) => a.key === _MeasurementSetupPersister.ATTRIBUTE_KEY);
|
|
44462
|
+
if (!settingsAttr) {
|
|
44463
|
+
console.log("[MeasurementSetupPersister] No existing settings found, using defaults");
|
|
44464
|
+
return null;
|
|
44465
|
+
}
|
|
44466
|
+
const value = typeof settingsAttr.value === "string" ? JSON.parse(settingsAttr.value) : settingsAttr.value;
|
|
44467
|
+
console.log("[MeasurementSetupPersister] Loaded settings:", value);
|
|
44468
|
+
return this.validateAndMergeSettings(value);
|
|
44469
|
+
} catch (error) {
|
|
44470
|
+
console.error("[MeasurementSetupPersister] Failed to load settings:", error);
|
|
44471
|
+
return null;
|
|
44472
|
+
}
|
|
44473
|
+
}
|
|
44474
|
+
/**
|
|
44475
|
+
* Save measurement settings to customer SERVER_SCOPE
|
|
44476
|
+
*/
|
|
44477
|
+
async saveSettings(customerId, settings) {
|
|
44478
|
+
try {
|
|
44479
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/attributes/SERVER_SCOPE`;
|
|
44480
|
+
console.log("[MeasurementSetupPersister] Saving settings to:", url);
|
|
44481
|
+
const payload = {
|
|
44482
|
+
[_MeasurementSetupPersister.ATTRIBUTE_KEY]: JSON.stringify(settings)
|
|
44483
|
+
};
|
|
44484
|
+
const response = await this.fetchWithTimeout(url, {
|
|
44485
|
+
method: "POST",
|
|
44486
|
+
headers: {
|
|
44487
|
+
"X-Authorization": `Bearer ${this.token}`,
|
|
44488
|
+
"Content-Type": "application/json"
|
|
44489
|
+
},
|
|
44490
|
+
body: JSON.stringify(payload)
|
|
44491
|
+
});
|
|
44492
|
+
if (!response.ok) {
|
|
44493
|
+
const errorText = await response.text();
|
|
44494
|
+
console.error("[MeasurementSetupPersister] Save failed:", response.status, errorText);
|
|
44495
|
+
return {
|
|
44496
|
+
ok: false,
|
|
44497
|
+
error: {
|
|
44498
|
+
code: response.status === 401 ? "AUTH_ERROR" : "NETWORK_ERROR",
|
|
44499
|
+
message: `Failed to save settings: HTTP ${response.status}`,
|
|
44500
|
+
cause: errorText
|
|
44501
|
+
}
|
|
44502
|
+
};
|
|
44503
|
+
}
|
|
44504
|
+
console.log("[MeasurementSetupPersister] Settings saved successfully");
|
|
44505
|
+
return { ok: true, settings };
|
|
44506
|
+
} catch (error) {
|
|
44507
|
+
console.error("[MeasurementSetupPersister] Save error:", error);
|
|
44508
|
+
return {
|
|
44509
|
+
ok: false,
|
|
44510
|
+
error: {
|
|
44511
|
+
code: "UNKNOWN_ERROR",
|
|
44512
|
+
message: error.message || "Failed to save settings",
|
|
44513
|
+
cause: error
|
|
44514
|
+
}
|
|
44515
|
+
};
|
|
44516
|
+
}
|
|
44517
|
+
}
|
|
44518
|
+
/**
|
|
44519
|
+
* Validate and merge settings with defaults to ensure all fields exist
|
|
44520
|
+
*/
|
|
44521
|
+
validateAndMergeSettings(settings) {
|
|
44522
|
+
return {
|
|
44523
|
+
version: settings.version || DEFAULT_SETTINGS.version,
|
|
44524
|
+
updatedAt: settings.updatedAt || DEFAULT_SETTINGS.updatedAt,
|
|
44525
|
+
updatedBy: settings.updatedBy,
|
|
44526
|
+
water: {
|
|
44527
|
+
unit: settings.water?.unit || DEFAULT_SETTINGS.water.unit,
|
|
44528
|
+
decimalPlaces: settings.water?.decimalPlaces ?? DEFAULT_SETTINGS.water.decimalPlaces,
|
|
44529
|
+
autoScale: settings.water?.autoScale ?? DEFAULT_SETTINGS.water.autoScale
|
|
44530
|
+
},
|
|
44531
|
+
energy: {
|
|
44532
|
+
unit: settings.energy?.unit || DEFAULT_SETTINGS.energy.unit,
|
|
44533
|
+
decimalPlaces: settings.energy?.decimalPlaces ?? DEFAULT_SETTINGS.energy.decimalPlaces,
|
|
44534
|
+
forceUnit: settings.energy?.forceUnit ?? DEFAULT_SETTINGS.energy.forceUnit
|
|
44535
|
+
},
|
|
44536
|
+
temperature: {
|
|
44537
|
+
unit: settings.temperature?.unit || DEFAULT_SETTINGS.temperature.unit,
|
|
44538
|
+
decimalPlaces: settings.temperature?.decimalPlaces ?? DEFAULT_SETTINGS.temperature.decimalPlaces
|
|
44539
|
+
}
|
|
44540
|
+
};
|
|
44541
|
+
}
|
|
44542
|
+
/**
|
|
44543
|
+
* Convert form data to full settings object for persistence
|
|
44544
|
+
*/
|
|
44545
|
+
formDataToSettings(formData, existingSettings) {
|
|
44546
|
+
return {
|
|
44547
|
+
version: existingSettings?.version || DEFAULT_SETTINGS.version,
|
|
44548
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44549
|
+
updatedBy: existingSettings?.updatedBy,
|
|
44550
|
+
water: { ...formData.water },
|
|
44551
|
+
energy: { ...formData.energy },
|
|
44552
|
+
temperature: { ...formData.temperature }
|
|
44553
|
+
};
|
|
44554
|
+
}
|
|
44555
|
+
/**
|
|
44556
|
+
* Extract form data from settings
|
|
44557
|
+
*/
|
|
44558
|
+
settingsToFormData(settings) {
|
|
44559
|
+
const s = settings || DEFAULT_SETTINGS;
|
|
44560
|
+
return {
|
|
44561
|
+
water: { ...s.water },
|
|
44562
|
+
energy: { ...s.energy },
|
|
44563
|
+
temperature: { ...s.temperature }
|
|
44564
|
+
};
|
|
44565
|
+
}
|
|
44566
|
+
};
|
|
44567
|
+
|
|
44568
|
+
// src/components/premium-modals/measurement-setup/openMeasurementSetupModal.ts
|
|
44569
|
+
async function openMeasurementSetupModal(params) {
|
|
44570
|
+
if (!params.token) {
|
|
44571
|
+
throw new Error("[MeasurementSetupModal] token is required");
|
|
44572
|
+
}
|
|
44573
|
+
if (!params.customerId) {
|
|
44574
|
+
throw new Error("[MeasurementSetupModal] customerId is required");
|
|
44575
|
+
}
|
|
44576
|
+
const persister = new MeasurementSetupPersister(params.token, params.tbBaseUrl);
|
|
44577
|
+
let existingSettings = params.existingSettings || null;
|
|
44578
|
+
const view = new MeasurementSetupView({
|
|
44579
|
+
styles: params.styles,
|
|
44580
|
+
onSave: async () => {
|
|
44581
|
+
const formData = view.getFormData();
|
|
44582
|
+
const settings = persister.formDataToSettings(formData, existingSettings);
|
|
44583
|
+
const result = await persister.saveSettings(params.customerId, settings);
|
|
44584
|
+
if (!result.ok) {
|
|
44585
|
+
throw new Error(result.error?.message || "Failed to save configuration");
|
|
44586
|
+
}
|
|
44587
|
+
existingSettings = settings;
|
|
44588
|
+
if (params.onSave) {
|
|
44589
|
+
params.onSave(settings);
|
|
44590
|
+
}
|
|
44591
|
+
},
|
|
44592
|
+
onClose: () => {
|
|
44593
|
+
if (params.onClose) {
|
|
44594
|
+
params.onClose();
|
|
44595
|
+
}
|
|
44596
|
+
}
|
|
44597
|
+
});
|
|
44598
|
+
async function loadFormData() {
|
|
44599
|
+
view.showLoading();
|
|
44600
|
+
try {
|
|
44601
|
+
if (!existingSettings) {
|
|
44602
|
+
existingSettings = await persister.loadSettings(params.customerId);
|
|
44603
|
+
}
|
|
44604
|
+
const formData = persister.settingsToFormData(existingSettings);
|
|
44605
|
+
view.setFormData(formData);
|
|
44606
|
+
} catch (error) {
|
|
44607
|
+
console.error("[MeasurementSetupModal] Error loading form data:", error);
|
|
44608
|
+
view.showError(error.message || "Failed to load configuration");
|
|
44609
|
+
} finally {
|
|
44610
|
+
view.hideLoading();
|
|
44611
|
+
}
|
|
44612
|
+
}
|
|
44613
|
+
let container;
|
|
44614
|
+
if (params.container) {
|
|
44615
|
+
if (typeof params.container === "string") {
|
|
44616
|
+
container = document.querySelector(params.container);
|
|
44617
|
+
} else {
|
|
44618
|
+
container = params.container;
|
|
44619
|
+
}
|
|
44620
|
+
}
|
|
44621
|
+
view.render(container);
|
|
44622
|
+
await loadFormData();
|
|
44623
|
+
return {
|
|
44624
|
+
destroy: () => view.destroy(),
|
|
44625
|
+
getFormData: () => view.getFormData(),
|
|
44626
|
+
setFormData: (data) => view.setFormData(data)
|
|
44627
|
+
};
|
|
44628
|
+
}
|
|
43546
44629
|
export {
|
|
43547
44630
|
ANNOTATION_TYPE_COLORS,
|
|
43548
44631
|
ANNOTATION_TYPE_LABELS,
|
|
@@ -43554,14 +44637,17 @@ export {
|
|
|
43554
44637
|
THEME_COLORS as CONSUMPTION_THEME_COLORS,
|
|
43555
44638
|
ConnectionStatusType,
|
|
43556
44639
|
ContractSummaryTooltip,
|
|
44640
|
+
DECIMAL_OPTIONS,
|
|
43557
44641
|
DEFAULT_CLAMP_RANGE,
|
|
43558
44642
|
DEFAULT_ENERGY_GROUP_COLORS,
|
|
43559
44643
|
DEFAULT_GAS_GROUP_COLORS,
|
|
44644
|
+
DEFAULT_SETTINGS as DEFAULT_MEASUREMENT_SETTINGS,
|
|
43560
44645
|
DEFAULT_SHOPPING_COLORS,
|
|
43561
44646
|
DEFAULT_WATER_GROUP_COLORS,
|
|
43562
44647
|
DEVICE_COUNT_KEYS,
|
|
43563
44648
|
DeviceComparisonTooltip,
|
|
43564
44649
|
DeviceStatusType,
|
|
44650
|
+
ENERGY_UNITS,
|
|
43565
44651
|
EXPORT_DEFAULT_COLORS,
|
|
43566
44652
|
EXPORT_DOMAIN_ICONS,
|
|
43567
44653
|
EXPORT_DOMAIN_LABELS,
|
|
@@ -43572,6 +44658,7 @@ export {
|
|
|
43572
44658
|
IMPORTANCE_LABELS,
|
|
43573
44659
|
IMPORTANCE_LABELS_EN,
|
|
43574
44660
|
InfoTooltip,
|
|
44661
|
+
DOMAIN_CONFIG5 as MEASUREMENT_DOMAIN_CONFIG,
|
|
43575
44662
|
MyIOChartModal,
|
|
43576
44663
|
MyIODraggableCard,
|
|
43577
44664
|
MyIOSelectionStore,
|
|
@@ -43583,9 +44670,11 @@ export {
|
|
|
43583
44670
|
STATUS_COLORS,
|
|
43584
44671
|
STATUS_LABELS,
|
|
43585
44672
|
STATUS_LABELS_EN,
|
|
44673
|
+
TEMPERATURE_UNITS,
|
|
43586
44674
|
TempComparisonTooltip,
|
|
43587
44675
|
TempRangeTooltip,
|
|
43588
44676
|
TempSensorSummaryTooltip,
|
|
44677
|
+
WATER_UNITS,
|
|
43589
44678
|
WaterSummaryTooltip,
|
|
43590
44679
|
addDetectionContext,
|
|
43591
44680
|
addNamespace,
|
|
@@ -43691,6 +44780,7 @@ export {
|
|
|
43691
44780
|
openDashboardPopupWaterTank,
|
|
43692
44781
|
openDemandModal,
|
|
43693
44782
|
openGoalsPanel,
|
|
44783
|
+
openMeasurementSetupModal,
|
|
43694
44784
|
openPowerLimitsSetupModal,
|
|
43695
44785
|
openRealTimeTelemetryModal,
|
|
43696
44786
|
openTemperatureComparisonModal,
|