myio-js-library 0.1.172 → 0.1.174
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 +1004 -0
- package/dist/index.d.cts +199 -1
- package/dist/index.js +1000 -0
- package/dist/myio-js-library.umd.js +1000 -0
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16639,6 +16639,1002 @@ function validateOptions2(options) {
|
|
|
16639
16639
|
}
|
|
16640
16640
|
}
|
|
16641
16641
|
|
|
16642
|
+
// src/components/premium-modals/power-limits/types.ts
|
|
16643
|
+
var DEVICE_TYPES = [
|
|
16644
|
+
{ value: "ELEVADOR", label: "Elevator" },
|
|
16645
|
+
{ value: "ESCADA_ROLANTE", label: "Escalator" },
|
|
16646
|
+
{ value: "MOTOR", label: "Motor" },
|
|
16647
|
+
{ value: "BOMBA", label: "Pump" },
|
|
16648
|
+
{ value: "CHILLER", label: "Chiller" },
|
|
16649
|
+
{ value: "AR_CONDICIONADO", label: "Air Conditioner" },
|
|
16650
|
+
{ value: "HVAC", label: "HVAC" },
|
|
16651
|
+
{ value: "FANCOIL", label: "Fancoil" },
|
|
16652
|
+
{ value: "3F_MEDIDOR", label: "Three-phase Meter" }
|
|
16653
|
+
];
|
|
16654
|
+
var TELEMETRY_TYPES2 = [
|
|
16655
|
+
{ value: "consumption", label: "Consumption (kW)", unit: "kW" },
|
|
16656
|
+
{ value: "voltage_a", label: "Voltage A (V)", unit: "V" },
|
|
16657
|
+
{ value: "voltage_b", label: "Voltage B (V)", unit: "V" },
|
|
16658
|
+
{ value: "voltage_c", label: "Voltage C (V)", unit: "V" },
|
|
16659
|
+
{ value: "current_a", label: "Current A (A)", unit: "A" },
|
|
16660
|
+
{ value: "current_b", label: "Current B (A)", unit: "A" },
|
|
16661
|
+
{ value: "current_c", label: "Current C (A)", unit: "A" },
|
|
16662
|
+
{ value: "total_current", label: "Total Current (A)", unit: "A" },
|
|
16663
|
+
{ value: "fp_a", label: "Power Factor A", unit: "" },
|
|
16664
|
+
{ value: "fp_b", label: "Power Factor B", unit: "" },
|
|
16665
|
+
{ value: "fp_c", label: "Power Factor C", unit: "" }
|
|
16666
|
+
];
|
|
16667
|
+
var STATUS_CONFIG = {
|
|
16668
|
+
standBy: { label: "StandBy", color: "#22c55e", bgColor: "rgba(34, 197, 94, 0.1)" },
|
|
16669
|
+
normal: { label: "Normal", color: "#3b82f6", bgColor: "rgba(59, 130, 246, 0.1)" },
|
|
16670
|
+
alert: { label: "Alert", color: "#f59e0b", bgColor: "rgba(245, 158, 11, 0.1)" },
|
|
16671
|
+
failure: { label: "Failure", color: "#ef4444", bgColor: "rgba(239, 68, 68, 0.1)" }
|
|
16672
|
+
};
|
|
16673
|
+
|
|
16674
|
+
// src/components/premium-modals/power-limits/PowerLimitsModalView.ts
|
|
16675
|
+
var PowerLimitsModalView = class {
|
|
16676
|
+
container = null;
|
|
16677
|
+
overlayEl = null;
|
|
16678
|
+
config;
|
|
16679
|
+
formData;
|
|
16680
|
+
isLoading = false;
|
|
16681
|
+
isSaving = false;
|
|
16682
|
+
constructor(config) {
|
|
16683
|
+
this.config = config;
|
|
16684
|
+
this.formData = {
|
|
16685
|
+
deviceType: config.deviceType,
|
|
16686
|
+
telemetryType: config.telemetryType,
|
|
16687
|
+
standby: { baseValue: null, topValue: null },
|
|
16688
|
+
normal: { baseValue: null, topValue: null },
|
|
16689
|
+
alert: { baseValue: null, topValue: null },
|
|
16690
|
+
failure: { baseValue: null, topValue: null }
|
|
16691
|
+
};
|
|
16692
|
+
}
|
|
16693
|
+
render(targetContainer) {
|
|
16694
|
+
this.overlayEl = document.createElement("div");
|
|
16695
|
+
this.overlayEl.className = "myio-power-limits-overlay";
|
|
16696
|
+
this.overlayEl.innerHTML = `
|
|
16697
|
+
<style>${this.getStyles()}</style>
|
|
16698
|
+
<div class="myio-power-limits-card">
|
|
16699
|
+
${this.renderHeader()}
|
|
16700
|
+
${this.renderSelectors()}
|
|
16701
|
+
${this.renderStatusCards()}
|
|
16702
|
+
${this.renderLoadingState()}
|
|
16703
|
+
${this.renderErrorState()}
|
|
16704
|
+
${this.renderSuccessState()}
|
|
16705
|
+
</div>
|
|
16706
|
+
`;
|
|
16707
|
+
const target = targetContainer || document.body;
|
|
16708
|
+
target.appendChild(this.overlayEl);
|
|
16709
|
+
this.container = this.overlayEl.querySelector(".myio-power-limits-card");
|
|
16710
|
+
this.setupEventListeners();
|
|
16711
|
+
requestAnimationFrame(() => {
|
|
16712
|
+
this.overlayEl?.classList.add("active");
|
|
16713
|
+
});
|
|
16714
|
+
return this.overlayEl;
|
|
16715
|
+
}
|
|
16716
|
+
renderHeader() {
|
|
16717
|
+
return `
|
|
16718
|
+
<div class="myio-power-limits-header">
|
|
16719
|
+
<div class="myio-power-limits-title-section">
|
|
16720
|
+
<span class="myio-power-limits-icon">⚙</span>
|
|
16721
|
+
<h2 class="myio-power-limits-title">Power Limits Setup</h2>
|
|
16722
|
+
</div>
|
|
16723
|
+
<div class="myio-power-limits-actions">
|
|
16724
|
+
<button class="myio-btn myio-btn-primary" id="plm-save-btn" type="button">
|
|
16725
|
+
<span class="myio-btn-text">Save</span>
|
|
16726
|
+
<span class="myio-btn-spinner" style="display: none;"></span>
|
|
16727
|
+
</button>
|
|
16728
|
+
<button class="myio-btn myio-btn-secondary" id="plm-reset-btn" type="button">Reset</button>
|
|
16729
|
+
<button class="myio-btn myio-btn-close" id="plm-close-btn" type="button" aria-label="Close">×</button>
|
|
16730
|
+
</div>
|
|
16731
|
+
</div>
|
|
16732
|
+
`;
|
|
16733
|
+
}
|
|
16734
|
+
renderSelectors() {
|
|
16735
|
+
const deviceOptions = DEVICE_TYPES.map(
|
|
16736
|
+
(dt) => `<option value="${dt.value}" ${dt.value === this.config.deviceType ? "selected" : ""}>${dt.label}</option>`
|
|
16737
|
+
).join("");
|
|
16738
|
+
const telemetryOptions = TELEMETRY_TYPES2.map(
|
|
16739
|
+
(tt) => `<option value="${tt.value}" ${tt.value === this.config.telemetryType ? "selected" : ""}>${tt.label}</option>`
|
|
16740
|
+
).join("");
|
|
16741
|
+
return `
|
|
16742
|
+
<div class="myio-power-limits-selectors">
|
|
16743
|
+
<div class="myio-form-group">
|
|
16744
|
+
<label for="plm-device-type">Device Type</label>
|
|
16745
|
+
<select id="plm-device-type" class="myio-select">
|
|
16746
|
+
${deviceOptions}
|
|
16747
|
+
</select>
|
|
16748
|
+
</div>
|
|
16749
|
+
<div class="myio-form-group">
|
|
16750
|
+
<label for="plm-telemetry-type">Telemetry Type</label>
|
|
16751
|
+
<select id="plm-telemetry-type" class="myio-select">
|
|
16752
|
+
${telemetryOptions}
|
|
16753
|
+
</select>
|
|
16754
|
+
</div>
|
|
16755
|
+
</div>
|
|
16756
|
+
`;
|
|
16757
|
+
}
|
|
16758
|
+
renderStatusCards() {
|
|
16759
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
16760
|
+
const cards = statuses.map((status) => {
|
|
16761
|
+
const config = STATUS_CONFIG[status === "standby" ? "standBy" : status];
|
|
16762
|
+
const formValues = this.formData[status];
|
|
16763
|
+
return `
|
|
16764
|
+
<div class="myio-power-limits-card-item myio-status-${status}" style="--status-color: ${config.color}; --status-bg: ${config.bgColor};">
|
|
16765
|
+
<div class="myio-card-header">
|
|
16766
|
+
<span class="myio-status-indicator"></span>
|
|
16767
|
+
<span class="myio-status-label">${config.label}</span>
|
|
16768
|
+
</div>
|
|
16769
|
+
<div class="myio-card-inputs">
|
|
16770
|
+
<div class="myio-input-group">
|
|
16771
|
+
<label for="plm-${status}-base">Base Value</label>
|
|
16772
|
+
<input
|
|
16773
|
+
type="number"
|
|
16774
|
+
id="plm-${status}-base"
|
|
16775
|
+
class="myio-input"
|
|
16776
|
+
min="0"
|
|
16777
|
+
step="0.01"
|
|
16778
|
+
value="${formValues.baseValue ?? ""}"
|
|
16779
|
+
placeholder="0"
|
|
16780
|
+
>
|
|
16781
|
+
</div>
|
|
16782
|
+
<div class="myio-input-group">
|
|
16783
|
+
<label for="plm-${status}-top">Top Value</label>
|
|
16784
|
+
<input
|
|
16785
|
+
type="number"
|
|
16786
|
+
id="plm-${status}-top"
|
|
16787
|
+
class="myio-input"
|
|
16788
|
+
min="0"
|
|
16789
|
+
step="0.01"
|
|
16790
|
+
value="${formValues.topValue ?? ""}"
|
|
16791
|
+
placeholder="0"
|
|
16792
|
+
>
|
|
16793
|
+
</div>
|
|
16794
|
+
</div>
|
|
16795
|
+
</div>
|
|
16796
|
+
`;
|
|
16797
|
+
}).join("");
|
|
16798
|
+
return `
|
|
16799
|
+
<div class="myio-power-limits-grid" id="plm-grid">
|
|
16800
|
+
${cards}
|
|
16801
|
+
</div>
|
|
16802
|
+
`;
|
|
16803
|
+
}
|
|
16804
|
+
renderLoadingState() {
|
|
16805
|
+
return `
|
|
16806
|
+
<div class="myio-power-limits-loading" id="plm-loading" style="display: none;">
|
|
16807
|
+
<div class="myio-spinner"></div>
|
|
16808
|
+
<span>Loading configuration...</span>
|
|
16809
|
+
</div>
|
|
16810
|
+
`;
|
|
16811
|
+
}
|
|
16812
|
+
renderErrorState() {
|
|
16813
|
+
return `
|
|
16814
|
+
<div class="myio-power-limits-error" id="plm-error" style="display: none;">
|
|
16815
|
+
<span class="myio-error-icon">⚠</span>
|
|
16816
|
+
<span class="myio-error-message" id="plm-error-msg"></span>
|
|
16817
|
+
</div>
|
|
16818
|
+
`;
|
|
16819
|
+
}
|
|
16820
|
+
renderSuccessState() {
|
|
16821
|
+
return `
|
|
16822
|
+
<div class="myio-power-limits-success" id="plm-success" style="display: none;">
|
|
16823
|
+
<span class="myio-success-icon">✓</span>
|
|
16824
|
+
<span class="myio-success-message">Configuration saved successfully!</span>
|
|
16825
|
+
</div>
|
|
16826
|
+
`;
|
|
16827
|
+
}
|
|
16828
|
+
setupEventListeners() {
|
|
16829
|
+
if (!this.overlayEl) return;
|
|
16830
|
+
const closeBtn = this.overlayEl.querySelector("#plm-close-btn");
|
|
16831
|
+
closeBtn?.addEventListener("click", () => this.close());
|
|
16832
|
+
this.overlayEl.addEventListener("click", (e) => {
|
|
16833
|
+
if (e.target === this.overlayEl) {
|
|
16834
|
+
this.close();
|
|
16835
|
+
}
|
|
16836
|
+
});
|
|
16837
|
+
document.addEventListener("keydown", this.handleKeyDown);
|
|
16838
|
+
const saveBtn = this.overlayEl.querySelector("#plm-save-btn");
|
|
16839
|
+
saveBtn?.addEventListener("click", () => this.handleSave());
|
|
16840
|
+
const resetBtn = this.overlayEl.querySelector("#plm-reset-btn");
|
|
16841
|
+
resetBtn?.addEventListener("click", () => this.handleReset());
|
|
16842
|
+
const deviceSelect = this.overlayEl.querySelector("#plm-device-type");
|
|
16843
|
+
deviceSelect?.addEventListener("change", (e) => {
|
|
16844
|
+
const value = e.target.value;
|
|
16845
|
+
this.formData.deviceType = value;
|
|
16846
|
+
this.config.onDeviceTypeChange(value);
|
|
16847
|
+
});
|
|
16848
|
+
const telemetrySelect = this.overlayEl.querySelector("#plm-telemetry-type");
|
|
16849
|
+
telemetrySelect?.addEventListener("change", (e) => {
|
|
16850
|
+
const value = e.target.value;
|
|
16851
|
+
this.formData.telemetryType = value;
|
|
16852
|
+
this.config.onTelemetryTypeChange(value);
|
|
16853
|
+
});
|
|
16854
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
16855
|
+
statuses.forEach((status) => {
|
|
16856
|
+
const baseInput = this.overlayEl?.querySelector(`#plm-${status}-base`);
|
|
16857
|
+
const topInput = this.overlayEl?.querySelector(`#plm-${status}-top`);
|
|
16858
|
+
baseInput?.addEventListener("input", (e) => {
|
|
16859
|
+
const value = e.target.value;
|
|
16860
|
+
this.formData[status].baseValue = value ? parseFloat(value) : null;
|
|
16861
|
+
});
|
|
16862
|
+
topInput?.addEventListener("input", (e) => {
|
|
16863
|
+
const value = e.target.value;
|
|
16864
|
+
this.formData[status].topValue = value ? parseFloat(value) : null;
|
|
16865
|
+
});
|
|
16866
|
+
});
|
|
16867
|
+
}
|
|
16868
|
+
handleKeyDown = (e) => {
|
|
16869
|
+
if (e.key === "Escape") {
|
|
16870
|
+
this.close();
|
|
16871
|
+
}
|
|
16872
|
+
};
|
|
16873
|
+
async handleSave() {
|
|
16874
|
+
if (this.isSaving) return;
|
|
16875
|
+
const validationError = this.validateForm();
|
|
16876
|
+
if (validationError) {
|
|
16877
|
+
this.showError(validationError);
|
|
16878
|
+
return;
|
|
16879
|
+
}
|
|
16880
|
+
this.isSaving = true;
|
|
16881
|
+
this.showSaveLoading(true);
|
|
16882
|
+
this.hideError();
|
|
16883
|
+
this.hideSuccess();
|
|
16884
|
+
try {
|
|
16885
|
+
await this.config.onSave();
|
|
16886
|
+
this.showSuccess();
|
|
16887
|
+
setTimeout(() => this.hideSuccess(), 3e3);
|
|
16888
|
+
} catch (error) {
|
|
16889
|
+
this.showError(error.message || "Failed to save configuration");
|
|
16890
|
+
} finally {
|
|
16891
|
+
this.isSaving = false;
|
|
16892
|
+
this.showSaveLoading(false);
|
|
16893
|
+
}
|
|
16894
|
+
}
|
|
16895
|
+
handleReset() {
|
|
16896
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
16897
|
+
statuses.forEach((status) => {
|
|
16898
|
+
const baseInput = this.overlayEl?.querySelector(`#plm-${status}-base`);
|
|
16899
|
+
const topInput = this.overlayEl?.querySelector(`#plm-${status}-top`);
|
|
16900
|
+
if (baseInput) baseInput.value = "";
|
|
16901
|
+
if (topInput) topInput.value = "";
|
|
16902
|
+
this.formData[status] = { baseValue: null, topValue: null };
|
|
16903
|
+
});
|
|
16904
|
+
this.hideError();
|
|
16905
|
+
this.hideSuccess();
|
|
16906
|
+
}
|
|
16907
|
+
validateForm() {
|
|
16908
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
16909
|
+
for (const status of statuses) {
|
|
16910
|
+
const base = this.formData[status].baseValue;
|
|
16911
|
+
const top = this.formData[status].topValue;
|
|
16912
|
+
if (base !== null && base < 0) {
|
|
16913
|
+
return `${STATUS_CONFIG[status === "standby" ? "standBy" : status].label}: Base value cannot be negative`;
|
|
16914
|
+
}
|
|
16915
|
+
if (top !== null && top < 0) {
|
|
16916
|
+
return `${STATUS_CONFIG[status === "standby" ? "standBy" : status].label}: Top value cannot be negative`;
|
|
16917
|
+
}
|
|
16918
|
+
if (base !== null && top !== null && base > top) {
|
|
16919
|
+
return `${STATUS_CONFIG[status === "standby" ? "standBy" : status].label}: Base value should not exceed top value`;
|
|
16920
|
+
}
|
|
16921
|
+
}
|
|
16922
|
+
return null;
|
|
16923
|
+
}
|
|
16924
|
+
close() {
|
|
16925
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
16926
|
+
if (this.overlayEl) {
|
|
16927
|
+
this.overlayEl.classList.remove("active");
|
|
16928
|
+
setTimeout(() => {
|
|
16929
|
+
this.overlayEl?.remove();
|
|
16930
|
+
this.overlayEl = null;
|
|
16931
|
+
this.container = null;
|
|
16932
|
+
this.config.onClose();
|
|
16933
|
+
}, 300);
|
|
16934
|
+
}
|
|
16935
|
+
}
|
|
16936
|
+
destroy() {
|
|
16937
|
+
document.removeEventListener("keydown", this.handleKeyDown);
|
|
16938
|
+
this.overlayEl?.remove();
|
|
16939
|
+
this.overlayEl = null;
|
|
16940
|
+
this.container = null;
|
|
16941
|
+
}
|
|
16942
|
+
showLoading() {
|
|
16943
|
+
this.isLoading = true;
|
|
16944
|
+
const loadingEl = this.overlayEl?.querySelector("#plm-loading");
|
|
16945
|
+
const gridEl = this.overlayEl?.querySelector("#plm-grid");
|
|
16946
|
+
if (loadingEl) loadingEl.style.display = "flex";
|
|
16947
|
+
if (gridEl) gridEl.style.opacity = "0.5";
|
|
16948
|
+
}
|
|
16949
|
+
hideLoading() {
|
|
16950
|
+
this.isLoading = false;
|
|
16951
|
+
const loadingEl = this.overlayEl?.querySelector("#plm-loading");
|
|
16952
|
+
const gridEl = this.overlayEl?.querySelector("#plm-grid");
|
|
16953
|
+
if (loadingEl) loadingEl.style.display = "none";
|
|
16954
|
+
if (gridEl) gridEl.style.opacity = "1";
|
|
16955
|
+
}
|
|
16956
|
+
showSaveLoading(show) {
|
|
16957
|
+
const saveBtn = this.overlayEl?.querySelector("#plm-save-btn");
|
|
16958
|
+
const btnText = saveBtn?.querySelector(".myio-btn-text");
|
|
16959
|
+
const btnSpinner = saveBtn?.querySelector(".myio-btn-spinner");
|
|
16960
|
+
if (saveBtn) saveBtn.disabled = show;
|
|
16961
|
+
if (btnText) btnText.style.display = show ? "none" : "inline";
|
|
16962
|
+
if (btnSpinner) btnSpinner.style.display = show ? "inline-block" : "none";
|
|
16963
|
+
}
|
|
16964
|
+
showError(message) {
|
|
16965
|
+
const errorEl = this.overlayEl?.querySelector("#plm-error");
|
|
16966
|
+
const errorMsg = this.overlayEl?.querySelector("#plm-error-msg");
|
|
16967
|
+
if (errorEl) errorEl.style.display = "flex";
|
|
16968
|
+
if (errorMsg) errorMsg.textContent = message;
|
|
16969
|
+
}
|
|
16970
|
+
hideError() {
|
|
16971
|
+
const errorEl = this.overlayEl?.querySelector("#plm-error");
|
|
16972
|
+
if (errorEl) errorEl.style.display = "none";
|
|
16973
|
+
}
|
|
16974
|
+
showSuccess() {
|
|
16975
|
+
const successEl = this.overlayEl?.querySelector("#plm-success");
|
|
16976
|
+
if (successEl) successEl.style.display = "flex";
|
|
16977
|
+
}
|
|
16978
|
+
hideSuccess() {
|
|
16979
|
+
const successEl = this.overlayEl?.querySelector("#plm-success");
|
|
16980
|
+
if (successEl) successEl.style.display = "none";
|
|
16981
|
+
}
|
|
16982
|
+
getFormData() {
|
|
16983
|
+
return { ...this.formData };
|
|
16984
|
+
}
|
|
16985
|
+
setFormData(data) {
|
|
16986
|
+
if (data.deviceType) this.formData.deviceType = data.deviceType;
|
|
16987
|
+
if (data.telemetryType) this.formData.telemetryType = data.telemetryType;
|
|
16988
|
+
if (data.standby) this.formData.standby = { ...data.standby };
|
|
16989
|
+
if (data.normal) this.formData.normal = { ...data.normal };
|
|
16990
|
+
if (data.alert) this.formData.alert = { ...data.alert };
|
|
16991
|
+
if (data.failure) this.formData.failure = { ...data.failure };
|
|
16992
|
+
this.updateInputValues();
|
|
16993
|
+
}
|
|
16994
|
+
updateInputValues() {
|
|
16995
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
16996
|
+
statuses.forEach((status) => {
|
|
16997
|
+
const baseInput = this.overlayEl?.querySelector(`#plm-${status}-base`);
|
|
16998
|
+
const topInput = this.overlayEl?.querySelector(`#plm-${status}-top`);
|
|
16999
|
+
if (baseInput) {
|
|
17000
|
+
baseInput.value = this.formData[status].baseValue?.toString() ?? "";
|
|
17001
|
+
}
|
|
17002
|
+
if (topInput) {
|
|
17003
|
+
topInput.value = this.formData[status].topValue?.toString() ?? "";
|
|
17004
|
+
}
|
|
17005
|
+
});
|
|
17006
|
+
const deviceSelect = this.overlayEl?.querySelector("#plm-device-type");
|
|
17007
|
+
const telemetrySelect = this.overlayEl?.querySelector("#plm-telemetry-type");
|
|
17008
|
+
if (deviceSelect) deviceSelect.value = this.formData.deviceType;
|
|
17009
|
+
if (telemetrySelect) telemetrySelect.value = this.formData.telemetryType;
|
|
17010
|
+
}
|
|
17011
|
+
getStyles() {
|
|
17012
|
+
const styles = this.config.styles || {};
|
|
17013
|
+
const primaryColor = styles.primaryColor || "#4A148C";
|
|
17014
|
+
const successColor = styles.successColor || "#22c55e";
|
|
17015
|
+
const warningColor = styles.warningColor || "#f59e0b";
|
|
17016
|
+
const dangerColor = styles.dangerColor || "#ef4444";
|
|
17017
|
+
const infoColor = styles.infoColor || "#3b82f6";
|
|
17018
|
+
return `
|
|
17019
|
+
.myio-power-limits-overlay {
|
|
17020
|
+
position: fixed;
|
|
17021
|
+
top: 0;
|
|
17022
|
+
left: 0;
|
|
17023
|
+
right: 0;
|
|
17024
|
+
bottom: 0;
|
|
17025
|
+
background: rgba(0, 0, 0, 0.6);
|
|
17026
|
+
display: flex;
|
|
17027
|
+
align-items: center;
|
|
17028
|
+
justify-content: center;
|
|
17029
|
+
z-index: ${styles.zIndex || 1e4};
|
|
17030
|
+
opacity: 0;
|
|
17031
|
+
visibility: hidden;
|
|
17032
|
+
transition: all 0.3s ease;
|
|
17033
|
+
font-family: ${styles.fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'};
|
|
17034
|
+
}
|
|
17035
|
+
|
|
17036
|
+
.myio-power-limits-overlay.active {
|
|
17037
|
+
opacity: 1;
|
|
17038
|
+
visibility: visible;
|
|
17039
|
+
}
|
|
17040
|
+
|
|
17041
|
+
.myio-power-limits-card {
|
|
17042
|
+
background: ${styles.backgroundColor || "#ffffff"};
|
|
17043
|
+
border-radius: ${styles.borderRadius || "12px"};
|
|
17044
|
+
width: 90%;
|
|
17045
|
+
max-width: 875px;
|
|
17046
|
+
max-height: 90vh;
|
|
17047
|
+
overflow-y: auto;
|
|
17048
|
+
transform: scale(0.9);
|
|
17049
|
+
transition: transform 0.3s ease;
|
|
17050
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
17051
|
+
}
|
|
17052
|
+
|
|
17053
|
+
.myio-power-limits-overlay.active .myio-power-limits-card {
|
|
17054
|
+
transform: scale(1);
|
|
17055
|
+
}
|
|
17056
|
+
|
|
17057
|
+
.myio-power-limits-header {
|
|
17058
|
+
display: flex;
|
|
17059
|
+
align-items: center;
|
|
17060
|
+
justify-content: space-between;
|
|
17061
|
+
padding: 20px 24px;
|
|
17062
|
+
background: linear-gradient(135deg, ${primaryColor}, ${this.lightenColor(primaryColor, 20)});
|
|
17063
|
+
color: white;
|
|
17064
|
+
border-radius: 12px 12px 0 0;
|
|
17065
|
+
}
|
|
17066
|
+
|
|
17067
|
+
.myio-power-limits-title-section {
|
|
17068
|
+
display: flex;
|
|
17069
|
+
align-items: center;
|
|
17070
|
+
gap: 12px;
|
|
17071
|
+
}
|
|
17072
|
+
|
|
17073
|
+
.myio-power-limits-icon {
|
|
17074
|
+
font-size: 24px;
|
|
17075
|
+
}
|
|
17076
|
+
|
|
17077
|
+
.myio-power-limits-title {
|
|
17078
|
+
font-size: 1.25rem;
|
|
17079
|
+
font-weight: 600;
|
|
17080
|
+
margin: 0;
|
|
17081
|
+
}
|
|
17082
|
+
|
|
17083
|
+
.myio-power-limits-actions {
|
|
17084
|
+
display: flex;
|
|
17085
|
+
align-items: center;
|
|
17086
|
+
gap: 8px;
|
|
17087
|
+
}
|
|
17088
|
+
|
|
17089
|
+
.myio-btn {
|
|
17090
|
+
padding: 8px 16px;
|
|
17091
|
+
border-radius: ${styles.buttonRadius || "6px"};
|
|
17092
|
+
font-size: 14px;
|
|
17093
|
+
font-weight: 500;
|
|
17094
|
+
cursor: pointer;
|
|
17095
|
+
border: none;
|
|
17096
|
+
transition: all 0.2s;
|
|
17097
|
+
display: inline-flex;
|
|
17098
|
+
align-items: center;
|
|
17099
|
+
gap: 6px;
|
|
17100
|
+
}
|
|
17101
|
+
|
|
17102
|
+
.myio-btn:disabled {
|
|
17103
|
+
opacity: 0.6;
|
|
17104
|
+
cursor: not-allowed;
|
|
17105
|
+
}
|
|
17106
|
+
|
|
17107
|
+
.myio-btn-primary {
|
|
17108
|
+
background: white;
|
|
17109
|
+
color: ${primaryColor};
|
|
17110
|
+
}
|
|
17111
|
+
|
|
17112
|
+
.myio-btn-primary:hover:not(:disabled) {
|
|
17113
|
+
background: #f3f4f6;
|
|
17114
|
+
}
|
|
17115
|
+
|
|
17116
|
+
.myio-btn-secondary {
|
|
17117
|
+
background: rgba(255, 255, 255, 0.2);
|
|
17118
|
+
color: white;
|
|
17119
|
+
}
|
|
17120
|
+
|
|
17121
|
+
.myio-btn-secondary:hover:not(:disabled) {
|
|
17122
|
+
background: rgba(255, 255, 255, 0.3);
|
|
17123
|
+
}
|
|
17124
|
+
|
|
17125
|
+
.myio-btn-close {
|
|
17126
|
+
background: transparent;
|
|
17127
|
+
color: white;
|
|
17128
|
+
font-size: 24px;
|
|
17129
|
+
padding: 4px 8px;
|
|
17130
|
+
line-height: 1;
|
|
17131
|
+
}
|
|
17132
|
+
|
|
17133
|
+
.myio-btn-close:hover {
|
|
17134
|
+
background: rgba(255, 255, 255, 0.1);
|
|
17135
|
+
}
|
|
17136
|
+
|
|
17137
|
+
.myio-btn-spinner {
|
|
17138
|
+
width: 16px;
|
|
17139
|
+
height: 16px;
|
|
17140
|
+
border: 2px solid ${primaryColor};
|
|
17141
|
+
border-top-color: transparent;
|
|
17142
|
+
border-radius: 50%;
|
|
17143
|
+
animation: spin 0.8s linear infinite;
|
|
17144
|
+
}
|
|
17145
|
+
|
|
17146
|
+
@keyframes spin {
|
|
17147
|
+
to { transform: rotate(360deg); }
|
|
17148
|
+
}
|
|
17149
|
+
|
|
17150
|
+
.myio-power-limits-selectors {
|
|
17151
|
+
display: grid;
|
|
17152
|
+
grid-template-columns: 1fr 1fr;
|
|
17153
|
+
gap: 16px;
|
|
17154
|
+
padding: 20px 24px;
|
|
17155
|
+
background: #f9fafb;
|
|
17156
|
+
border-bottom: 1px solid #e5e7eb;
|
|
17157
|
+
}
|
|
17158
|
+
|
|
17159
|
+
.myio-form-group {
|
|
17160
|
+
display: flex;
|
|
17161
|
+
flex-direction: column;
|
|
17162
|
+
gap: 6px;
|
|
17163
|
+
}
|
|
17164
|
+
|
|
17165
|
+
.myio-form-group label {
|
|
17166
|
+
font-size: 13px;
|
|
17167
|
+
font-weight: 500;
|
|
17168
|
+
color: #374151;
|
|
17169
|
+
}
|
|
17170
|
+
|
|
17171
|
+
.myio-select, .myio-input {
|
|
17172
|
+
padding: 10px 12px;
|
|
17173
|
+
border: 1px solid #d1d5db;
|
|
17174
|
+
border-radius: 6px;
|
|
17175
|
+
font-size: 14px;
|
|
17176
|
+
background: white;
|
|
17177
|
+
color: #1f2937;
|
|
17178
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
17179
|
+
}
|
|
17180
|
+
|
|
17181
|
+
.myio-select:focus, .myio-input:focus {
|
|
17182
|
+
outline: none;
|
|
17183
|
+
border-color: ${primaryColor};
|
|
17184
|
+
box-shadow: 0 0 0 3px ${this.hexToRgba(primaryColor, 0.1)};
|
|
17185
|
+
}
|
|
17186
|
+
|
|
17187
|
+
.myio-power-limits-grid {
|
|
17188
|
+
display: grid;
|
|
17189
|
+
grid-template-columns: repeat(2, 1fr);
|
|
17190
|
+
gap: 16px;
|
|
17191
|
+
padding: 24px;
|
|
17192
|
+
transition: opacity 0.3s;
|
|
17193
|
+
}
|
|
17194
|
+
|
|
17195
|
+
.myio-power-limits-card-item {
|
|
17196
|
+
background: var(--status-bg);
|
|
17197
|
+
border: 1px solid var(--status-color);
|
|
17198
|
+
border-radius: 8px;
|
|
17199
|
+
padding: 16px;
|
|
17200
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
17201
|
+
}
|
|
17202
|
+
|
|
17203
|
+
.myio-power-limits-card-item:hover {
|
|
17204
|
+
transform: translateY(-2px);
|
|
17205
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
17206
|
+
}
|
|
17207
|
+
|
|
17208
|
+
.myio-card-header {
|
|
17209
|
+
display: flex;
|
|
17210
|
+
align-items: center;
|
|
17211
|
+
gap: 8px;
|
|
17212
|
+
margin-bottom: 12px;
|
|
17213
|
+
}
|
|
17214
|
+
|
|
17215
|
+
.myio-status-indicator {
|
|
17216
|
+
width: 12px;
|
|
17217
|
+
height: 12px;
|
|
17218
|
+
border-radius: 50%;
|
|
17219
|
+
background: var(--status-color);
|
|
17220
|
+
}
|
|
17221
|
+
|
|
17222
|
+
.myio-status-label {
|
|
17223
|
+
font-weight: 600;
|
|
17224
|
+
font-size: 14px;
|
|
17225
|
+
color: #1f2937;
|
|
17226
|
+
}
|
|
17227
|
+
|
|
17228
|
+
.myio-card-inputs {
|
|
17229
|
+
display: grid;
|
|
17230
|
+
grid-template-columns: 1fr 1fr;
|
|
17231
|
+
gap: 12px;
|
|
17232
|
+
}
|
|
17233
|
+
|
|
17234
|
+
.myio-input-group {
|
|
17235
|
+
display: flex;
|
|
17236
|
+
flex-direction: column;
|
|
17237
|
+
gap: 4px;
|
|
17238
|
+
}
|
|
17239
|
+
|
|
17240
|
+
.myio-input-group label {
|
|
17241
|
+
font-size: 11px;
|
|
17242
|
+
font-weight: 500;
|
|
17243
|
+
color: #6b7280;
|
|
17244
|
+
text-transform: uppercase;
|
|
17245
|
+
}
|
|
17246
|
+
|
|
17247
|
+
.myio-power-limits-loading,
|
|
17248
|
+
.myio-power-limits-error,
|
|
17249
|
+
.myio-power-limits-success {
|
|
17250
|
+
display: flex;
|
|
17251
|
+
align-items: center;
|
|
17252
|
+
justify-content: center;
|
|
17253
|
+
gap: 12px;
|
|
17254
|
+
padding: 16px 24px;
|
|
17255
|
+
margin: 0 24px 24px;
|
|
17256
|
+
border-radius: 8px;
|
|
17257
|
+
}
|
|
17258
|
+
|
|
17259
|
+
.myio-power-limits-loading {
|
|
17260
|
+
background: #f3f4f6;
|
|
17261
|
+
color: #6b7280;
|
|
17262
|
+
}
|
|
17263
|
+
|
|
17264
|
+
.myio-power-limits-error {
|
|
17265
|
+
background: #fef2f2;
|
|
17266
|
+
color: ${dangerColor};
|
|
17267
|
+
border: 1px solid ${dangerColor};
|
|
17268
|
+
}
|
|
17269
|
+
|
|
17270
|
+
.myio-power-limits-success {
|
|
17271
|
+
background: #f0fdf4;
|
|
17272
|
+
color: ${successColor};
|
|
17273
|
+
border: 1px solid ${successColor};
|
|
17274
|
+
}
|
|
17275
|
+
|
|
17276
|
+
.myio-spinner {
|
|
17277
|
+
width: 24px;
|
|
17278
|
+
height: 24px;
|
|
17279
|
+
border: 3px solid #e5e7eb;
|
|
17280
|
+
border-top-color: ${primaryColor};
|
|
17281
|
+
border-radius: 50%;
|
|
17282
|
+
animation: spin 0.8s linear infinite;
|
|
17283
|
+
}
|
|
17284
|
+
|
|
17285
|
+
.myio-error-icon, .myio-success-icon {
|
|
17286
|
+
font-size: 20px;
|
|
17287
|
+
}
|
|
17288
|
+
|
|
17289
|
+
@media (max-width: 600px) {
|
|
17290
|
+
.myio-power-limits-selectors,
|
|
17291
|
+
.myio-power-limits-grid {
|
|
17292
|
+
grid-template-columns: 1fr;
|
|
17293
|
+
}
|
|
17294
|
+
|
|
17295
|
+
.myio-power-limits-header {
|
|
17296
|
+
flex-direction: column;
|
|
17297
|
+
gap: 12px;
|
|
17298
|
+
text-align: center;
|
|
17299
|
+
}
|
|
17300
|
+
|
|
17301
|
+
.myio-power-limits-actions {
|
|
17302
|
+
width: 100%;
|
|
17303
|
+
justify-content: center;
|
|
17304
|
+
}
|
|
17305
|
+
}
|
|
17306
|
+
`;
|
|
17307
|
+
}
|
|
17308
|
+
lightenColor(hex, percent) {
|
|
17309
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
17310
|
+
const amt = Math.round(2.55 * percent);
|
|
17311
|
+
const R = (num >> 16) + amt;
|
|
17312
|
+
const G = (num >> 8 & 255) + amt;
|
|
17313
|
+
const B = (num & 255) + amt;
|
|
17314
|
+
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);
|
|
17315
|
+
}
|
|
17316
|
+
hexToRgba(hex, alpha) {
|
|
17317
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
17318
|
+
const R = num >> 16;
|
|
17319
|
+
const G = num >> 8 & 255;
|
|
17320
|
+
const B = num & 255;
|
|
17321
|
+
return `rgba(${R}, ${G}, ${B}, ${alpha})`;
|
|
17322
|
+
}
|
|
17323
|
+
};
|
|
17324
|
+
|
|
17325
|
+
// src/components/premium-modals/power-limits/PowerLimitsPersister.ts
|
|
17326
|
+
var PowerLimitsPersister = class {
|
|
17327
|
+
jwtToken;
|
|
17328
|
+
tbBaseUrl;
|
|
17329
|
+
constructor(jwtToken, tbBaseUrl) {
|
|
17330
|
+
this.jwtToken = jwtToken;
|
|
17331
|
+
this.tbBaseUrl = tbBaseUrl || window.location.origin;
|
|
17332
|
+
}
|
|
17333
|
+
/**
|
|
17334
|
+
* Load existing mapInstantaneousPower from customer server_scope attributes
|
|
17335
|
+
*/
|
|
17336
|
+
async loadCustomerPowerLimits(customerId) {
|
|
17337
|
+
try {
|
|
17338
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE?keys=mapInstantaneousPower`;
|
|
17339
|
+
const response = await fetch(url, {
|
|
17340
|
+
method: "GET",
|
|
17341
|
+
headers: {
|
|
17342
|
+
"X-Authorization": `Bearer ${this.jwtToken}`,
|
|
17343
|
+
"Content-Type": "application/json"
|
|
17344
|
+
}
|
|
17345
|
+
});
|
|
17346
|
+
if (!response.ok) {
|
|
17347
|
+
if (response.status === 404) {
|
|
17348
|
+
console.log("[PowerLimitsPersister] No existing mapInstantaneousPower found");
|
|
17349
|
+
return null;
|
|
17350
|
+
}
|
|
17351
|
+
throw this.createHttpError(response.status, await response.text().catch(() => ""));
|
|
17352
|
+
}
|
|
17353
|
+
const data = await response.json();
|
|
17354
|
+
if (!data || data.length === 0) {
|
|
17355
|
+
console.log("[PowerLimitsPersister] No mapInstantaneousPower attribute found");
|
|
17356
|
+
return null;
|
|
17357
|
+
}
|
|
17358
|
+
const attr = data.find((item) => item.key === "mapInstantaneousPower");
|
|
17359
|
+
if (!attr || !attr.value) {
|
|
17360
|
+
return null;
|
|
17361
|
+
}
|
|
17362
|
+
const parsedValue = typeof attr.value === "string" ? JSON.parse(attr.value) : attr.value;
|
|
17363
|
+
console.log("[PowerLimitsPersister] Loaded mapInstantaneousPower:", parsedValue);
|
|
17364
|
+
return parsedValue;
|
|
17365
|
+
} catch (error) {
|
|
17366
|
+
console.error("[PowerLimitsPersister] Error loading power limits:", error);
|
|
17367
|
+
throw this.mapError(error);
|
|
17368
|
+
}
|
|
17369
|
+
}
|
|
17370
|
+
/**
|
|
17371
|
+
* Save mapInstantaneousPower to customer server_scope attributes
|
|
17372
|
+
*/
|
|
17373
|
+
async saveCustomerPowerLimits(customerId, limits) {
|
|
17374
|
+
try {
|
|
17375
|
+
const url = `${this.tbBaseUrl}/api/plugins/telemetry/CUSTOMER/${customerId}/attributes/SERVER_SCOPE`;
|
|
17376
|
+
const payload = {
|
|
17377
|
+
mapInstantaneousPower: limits
|
|
17378
|
+
};
|
|
17379
|
+
console.log("[PowerLimitsPersister] Saving power limits:", payload);
|
|
17380
|
+
const response = await fetch(url, {
|
|
17381
|
+
method: "POST",
|
|
17382
|
+
headers: {
|
|
17383
|
+
"X-Authorization": `Bearer ${this.jwtToken}`,
|
|
17384
|
+
"Content-Type": "application/json"
|
|
17385
|
+
},
|
|
17386
|
+
body: JSON.stringify(payload)
|
|
17387
|
+
});
|
|
17388
|
+
if (!response.ok) {
|
|
17389
|
+
throw this.createHttpError(response.status, await response.text().catch(() => ""));
|
|
17390
|
+
}
|
|
17391
|
+
console.log("[PowerLimitsPersister] Successfully saved power limits");
|
|
17392
|
+
return { ok: true };
|
|
17393
|
+
} catch (error) {
|
|
17394
|
+
console.error("[PowerLimitsPersister] Error saving power limits:", error);
|
|
17395
|
+
return { ok: false, error: this.mapError(error) };
|
|
17396
|
+
}
|
|
17397
|
+
}
|
|
17398
|
+
/**
|
|
17399
|
+
* Extract form data for a specific device type and telemetry type
|
|
17400
|
+
*/
|
|
17401
|
+
extractFormData(limits, deviceType, telemetryType) {
|
|
17402
|
+
const defaultFormData = {
|
|
17403
|
+
deviceType,
|
|
17404
|
+
telemetryType,
|
|
17405
|
+
standby: { baseValue: null, topValue: null },
|
|
17406
|
+
normal: { baseValue: null, topValue: null },
|
|
17407
|
+
alert: { baseValue: null, topValue: null },
|
|
17408
|
+
failure: { baseValue: null, topValue: null }
|
|
17409
|
+
};
|
|
17410
|
+
if (!limits || !limits.limitsByInstantaneoustPowerType) {
|
|
17411
|
+
return defaultFormData;
|
|
17412
|
+
}
|
|
17413
|
+
const telemetryEntry = limits.limitsByInstantaneoustPowerType.find(
|
|
17414
|
+
(t) => t.telemetryType === telemetryType
|
|
17415
|
+
);
|
|
17416
|
+
if (!telemetryEntry || !telemetryEntry.itemsByDeviceType) {
|
|
17417
|
+
return defaultFormData;
|
|
17418
|
+
}
|
|
17419
|
+
const deviceEntry = telemetryEntry.itemsByDeviceType.find(
|
|
17420
|
+
(d) => d.deviceType === deviceType
|
|
17421
|
+
);
|
|
17422
|
+
if (!deviceEntry || !deviceEntry.limitsByDeviceStatus) {
|
|
17423
|
+
return defaultFormData;
|
|
17424
|
+
}
|
|
17425
|
+
const statusMap = {
|
|
17426
|
+
"standBy": "standby",
|
|
17427
|
+
"normal": "normal",
|
|
17428
|
+
"alert": "alert",
|
|
17429
|
+
"failure": "failure"
|
|
17430
|
+
};
|
|
17431
|
+
deviceEntry.limitsByDeviceStatus.forEach((status) => {
|
|
17432
|
+
const formKey = statusMap[status.deviceStatusName];
|
|
17433
|
+
if (formKey && defaultFormData[formKey]) {
|
|
17434
|
+
defaultFormData[formKey] = {
|
|
17435
|
+
baseValue: status.limitsValues.baseValue,
|
|
17436
|
+
topValue: status.limitsValues.topValue
|
|
17437
|
+
};
|
|
17438
|
+
}
|
|
17439
|
+
});
|
|
17440
|
+
return defaultFormData;
|
|
17441
|
+
}
|
|
17442
|
+
/**
|
|
17443
|
+
* Merge form data into existing limits JSON
|
|
17444
|
+
* Creates new entries if they don't exist
|
|
17445
|
+
*/
|
|
17446
|
+
mergeFormDataIntoLimits(existingLimits, formData) {
|
|
17447
|
+
const result = existingLimits ? JSON.parse(JSON.stringify(existingLimits)) : { version: "1.0.0", limitsByInstantaneoustPowerType: [] };
|
|
17448
|
+
const statusLimits = [
|
|
17449
|
+
{
|
|
17450
|
+
deviceStatusName: "standBy",
|
|
17451
|
+
limitsValues: {
|
|
17452
|
+
baseValue: formData.standby.baseValue ?? 0,
|
|
17453
|
+
topValue: formData.standby.topValue ?? 0
|
|
17454
|
+
}
|
|
17455
|
+
},
|
|
17456
|
+
{
|
|
17457
|
+
deviceStatusName: "normal",
|
|
17458
|
+
limitsValues: {
|
|
17459
|
+
baseValue: formData.normal.baseValue ?? 0,
|
|
17460
|
+
topValue: formData.normal.topValue ?? 0
|
|
17461
|
+
}
|
|
17462
|
+
},
|
|
17463
|
+
{
|
|
17464
|
+
deviceStatusName: "alert",
|
|
17465
|
+
limitsValues: {
|
|
17466
|
+
baseValue: formData.alert.baseValue ?? 0,
|
|
17467
|
+
topValue: formData.alert.topValue ?? 0
|
|
17468
|
+
}
|
|
17469
|
+
},
|
|
17470
|
+
{
|
|
17471
|
+
deviceStatusName: "failure",
|
|
17472
|
+
limitsValues: {
|
|
17473
|
+
baseValue: formData.failure.baseValue ?? 0,
|
|
17474
|
+
topValue: formData.failure.topValue ?? 0
|
|
17475
|
+
}
|
|
17476
|
+
}
|
|
17477
|
+
];
|
|
17478
|
+
let telemetryEntry = result.limitsByInstantaneoustPowerType.find(
|
|
17479
|
+
(t) => t.telemetryType === formData.telemetryType
|
|
17480
|
+
);
|
|
17481
|
+
if (!telemetryEntry) {
|
|
17482
|
+
telemetryEntry = {
|
|
17483
|
+
telemetryType: formData.telemetryType,
|
|
17484
|
+
itemsByDeviceType: []
|
|
17485
|
+
};
|
|
17486
|
+
result.limitsByInstantaneoustPowerType.push(telemetryEntry);
|
|
17487
|
+
}
|
|
17488
|
+
let deviceEntry = telemetryEntry.itemsByDeviceType.find(
|
|
17489
|
+
(d) => d.deviceType === formData.deviceType
|
|
17490
|
+
);
|
|
17491
|
+
if (!deviceEntry) {
|
|
17492
|
+
deviceEntry = {
|
|
17493
|
+
deviceType: formData.deviceType,
|
|
17494
|
+
name: `mapInstantaneousPower${this.formatDeviceTypeName(formData.deviceType)}`,
|
|
17495
|
+
description: `Power limits for ${formData.deviceType}`,
|
|
17496
|
+
limitsByDeviceStatus: []
|
|
17497
|
+
};
|
|
17498
|
+
telemetryEntry.itemsByDeviceType.push(deviceEntry);
|
|
17499
|
+
}
|
|
17500
|
+
deviceEntry.limitsByDeviceStatus = statusLimits;
|
|
17501
|
+
deviceEntry.name = `mapInstantaneousPower${this.formatDeviceTypeName(formData.deviceType)}`;
|
|
17502
|
+
deviceEntry.description = `Power limits for ${formData.deviceType} - ${formData.telemetryType}`;
|
|
17503
|
+
return result;
|
|
17504
|
+
}
|
|
17505
|
+
/**
|
|
17506
|
+
* Format device type name for the JSON name field
|
|
17507
|
+
*/
|
|
17508
|
+
formatDeviceTypeName(deviceType) {
|
|
17509
|
+
if (!deviceType) return "";
|
|
17510
|
+
return deviceType.toLowerCase().split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
17511
|
+
}
|
|
17512
|
+
createHttpError(status, body) {
|
|
17513
|
+
const error = new Error(`HTTP ${status}: ${body}`);
|
|
17514
|
+
error.status = status;
|
|
17515
|
+
error.body = body;
|
|
17516
|
+
return error;
|
|
17517
|
+
}
|
|
17518
|
+
mapError(error) {
|
|
17519
|
+
const status = error.status;
|
|
17520
|
+
if (status === 400) {
|
|
17521
|
+
return {
|
|
17522
|
+
code: "VALIDATION_ERROR",
|
|
17523
|
+
message: "Invalid input data",
|
|
17524
|
+
cause: error
|
|
17525
|
+
};
|
|
17526
|
+
}
|
|
17527
|
+
if (status === 401) {
|
|
17528
|
+
return {
|
|
17529
|
+
code: "TOKEN_EXPIRED",
|
|
17530
|
+
message: "Authentication token has expired",
|
|
17531
|
+
cause: error
|
|
17532
|
+
};
|
|
17533
|
+
}
|
|
17534
|
+
if (status === 403) {
|
|
17535
|
+
return {
|
|
17536
|
+
code: "AUTH_ERROR",
|
|
17537
|
+
message: "Insufficient permissions",
|
|
17538
|
+
cause: error
|
|
17539
|
+
};
|
|
17540
|
+
}
|
|
17541
|
+
if (status === 404) {
|
|
17542
|
+
return {
|
|
17543
|
+
code: "NETWORK_ERROR",
|
|
17544
|
+
message: "Customer not found",
|
|
17545
|
+
cause: error
|
|
17546
|
+
};
|
|
17547
|
+
}
|
|
17548
|
+
if (status >= 500) {
|
|
17549
|
+
return {
|
|
17550
|
+
code: "NETWORK_ERROR",
|
|
17551
|
+
message: "Server error occurred",
|
|
17552
|
+
cause: error
|
|
17553
|
+
};
|
|
17554
|
+
}
|
|
17555
|
+
return {
|
|
17556
|
+
code: "UNKNOWN_ERROR",
|
|
17557
|
+
message: error.message || "Unknown error occurred",
|
|
17558
|
+
cause: error
|
|
17559
|
+
};
|
|
17560
|
+
}
|
|
17561
|
+
};
|
|
17562
|
+
|
|
17563
|
+
// src/components/premium-modals/power-limits/openPowerLimitsSetupModal.ts
|
|
17564
|
+
async function openPowerLimitsSetupModal(params) {
|
|
17565
|
+
if (!params.token) {
|
|
17566
|
+
throw new Error("[PowerLimitsSetupModal] token is required");
|
|
17567
|
+
}
|
|
17568
|
+
if (!params.customerId) {
|
|
17569
|
+
throw new Error("[PowerLimitsSetupModal] customerId is required");
|
|
17570
|
+
}
|
|
17571
|
+
const persister = new PowerLimitsPersister(params.token, params.tbBaseUrl);
|
|
17572
|
+
let currentDeviceType = params.deviceType || "ELEVADOR";
|
|
17573
|
+
let currentTelemetryType = params.telemetryType || "consumption";
|
|
17574
|
+
let existingLimits = params.existingMapPower || null;
|
|
17575
|
+
const view = new PowerLimitsModalView({
|
|
17576
|
+
deviceType: currentDeviceType,
|
|
17577
|
+
telemetryType: currentTelemetryType,
|
|
17578
|
+
styles: params.styles,
|
|
17579
|
+
locale: params.locale,
|
|
17580
|
+
onDeviceTypeChange: async (deviceType) => {
|
|
17581
|
+
currentDeviceType = deviceType;
|
|
17582
|
+
await loadFormData();
|
|
17583
|
+
},
|
|
17584
|
+
onTelemetryTypeChange: async (telemetryType) => {
|
|
17585
|
+
currentTelemetryType = telemetryType;
|
|
17586
|
+
await loadFormData();
|
|
17587
|
+
},
|
|
17588
|
+
onSave: async () => {
|
|
17589
|
+
const formData = view.getFormData();
|
|
17590
|
+
const updatedLimits = persister.mergeFormDataIntoLimits(existingLimits, formData);
|
|
17591
|
+
const result = await persister.saveCustomerPowerLimits(params.customerId, updatedLimits);
|
|
17592
|
+
if (!result.ok) {
|
|
17593
|
+
throw new Error(result.error?.message || "Failed to save configuration");
|
|
17594
|
+
}
|
|
17595
|
+
existingLimits = updatedLimits;
|
|
17596
|
+
if (params.onSave) {
|
|
17597
|
+
params.onSave(updatedLimits);
|
|
17598
|
+
}
|
|
17599
|
+
},
|
|
17600
|
+
onClose: () => {
|
|
17601
|
+
if (params.onClose) {
|
|
17602
|
+
params.onClose();
|
|
17603
|
+
}
|
|
17604
|
+
}
|
|
17605
|
+
});
|
|
17606
|
+
async function loadFormData() {
|
|
17607
|
+
view.showLoading();
|
|
17608
|
+
try {
|
|
17609
|
+
if (!existingLimits) {
|
|
17610
|
+
existingLimits = await persister.loadCustomerPowerLimits(params.customerId);
|
|
17611
|
+
}
|
|
17612
|
+
const formData = persister.extractFormData(existingLimits, currentDeviceType, currentTelemetryType);
|
|
17613
|
+
view.setFormData(formData);
|
|
17614
|
+
} catch (error) {
|
|
17615
|
+
console.error("[PowerLimitsSetupModal] Error loading form data:", error);
|
|
17616
|
+
view.showError(error.message || "Failed to load configuration");
|
|
17617
|
+
} finally {
|
|
17618
|
+
view.hideLoading();
|
|
17619
|
+
}
|
|
17620
|
+
}
|
|
17621
|
+
let container;
|
|
17622
|
+
if (params.container) {
|
|
17623
|
+
if (typeof params.container === "string") {
|
|
17624
|
+
container = document.querySelector(params.container);
|
|
17625
|
+
} else {
|
|
17626
|
+
container = params.container;
|
|
17627
|
+
}
|
|
17628
|
+
}
|
|
17629
|
+
view.render(container);
|
|
17630
|
+
await loadFormData();
|
|
17631
|
+
return {
|
|
17632
|
+
destroy: () => view.destroy(),
|
|
17633
|
+
getFormData: () => view.getFormData(),
|
|
17634
|
+
setFormData: (data) => view.setFormData(data)
|
|
17635
|
+
};
|
|
17636
|
+
}
|
|
17637
|
+
|
|
16642
17638
|
// src/components/premium-modals/settings/SettingsModalView.ts
|
|
16643
17639
|
var SettingsModalView = class {
|
|
16644
17640
|
container;
|
|
@@ -26905,6 +27901,9 @@ export {
|
|
|
26905
27901
|
MyIOSelectionStore,
|
|
26906
27902
|
MyIOSelectionStoreClass,
|
|
26907
27903
|
MyIOToast,
|
|
27904
|
+
DEVICE_TYPES as POWER_LIMITS_DEVICE_TYPES,
|
|
27905
|
+
STATUS_CONFIG as POWER_LIMITS_STATUS_CONFIG,
|
|
27906
|
+
TELEMETRY_TYPES2 as POWER_LIMITS_TELEMETRY_TYPES,
|
|
26908
27907
|
addDetectionContext,
|
|
26909
27908
|
addNamespace,
|
|
26910
27909
|
aggregateByDay,
|
|
@@ -27002,6 +28001,7 @@ export {
|
|
|
27002
28001
|
openDashboardPopupWaterTank,
|
|
27003
28002
|
openDemandModal,
|
|
27004
28003
|
openGoalsPanel,
|
|
28004
|
+
openPowerLimitsSetupModal,
|
|
27005
28005
|
openRealTimeTelemetryModal,
|
|
27006
28006
|
openTemperatureComparisonModal,
|
|
27007
28007
|
openTemperatureModal,
|