myio-js-library 0.1.69 → 0.1.70
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 +285 -94
- package/dist/index.js +285 -94
- package/dist/myio-js-library.umd.js +285 -94
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8860,11 +8860,11 @@ var AllReportModal = class {
|
|
|
8860
8860
|
parentEl: this.modal.element,
|
|
8861
8861
|
onApply: ({ startISO, endISO }) => {
|
|
8862
8862
|
this.hideError();
|
|
8863
|
-
|
|
8863
|
+
this.debugLog("Date range selected:", { startISO, endISO });
|
|
8864
8864
|
}
|
|
8865
8865
|
});
|
|
8866
8866
|
} catch (error) {
|
|
8867
|
-
|
|
8867
|
+
this.debugLog("DateRangePicker initialization failed, using fallback:", error);
|
|
8868
8868
|
}
|
|
8869
8869
|
}
|
|
8870
8870
|
async loadData() {
|
|
@@ -8922,7 +8922,7 @@ var AllReportModal = class {
|
|
|
8922
8922
|
} catch (error) {
|
|
8923
8923
|
this.debugLog("\u274C Error in loadData", error);
|
|
8924
8924
|
this.showError("Erro ao carregar dados: " + error.message);
|
|
8925
|
-
|
|
8925
|
+
this.debugLog("Error loading data:", error);
|
|
8926
8926
|
this.emit("error", { message: error.message, context: "loadData" });
|
|
8927
8927
|
} finally {
|
|
8928
8928
|
this.isLoading = false;
|
|
@@ -9245,7 +9245,7 @@ var AllReportModal = class {
|
|
|
9245
9245
|
const endTime = encodeURIComponent(endISO);
|
|
9246
9246
|
const endpoint = this.domainConfig.endpoint;
|
|
9247
9247
|
const url = `${baseUrl}/api/v1/telemetry/customers/${this.params.customerId}/${endpoint}/devices/totals?startTime=${startTime}&endTime=${endTime}`;
|
|
9248
|
-
|
|
9248
|
+
this.debugLog("[AllReportModal] Fetching customer totals:", { url, customerId: this.params.customerId, domain: this.params.domain || "energy" });
|
|
9249
9249
|
const response = await fetch(url, {
|
|
9250
9250
|
method: "GET",
|
|
9251
9251
|
headers: {
|
|
@@ -9258,14 +9258,14 @@ var AllReportModal = class {
|
|
|
9258
9258
|
throw new Error(`Erro na API: ${response.status} ${response.statusText}`);
|
|
9259
9259
|
}
|
|
9260
9260
|
const data = await response.json();
|
|
9261
|
-
|
|
9261
|
+
this.debugLog("[AllReportModal] Customer totals response:", data);
|
|
9262
9262
|
return data;
|
|
9263
9263
|
}
|
|
9264
9264
|
mapCustomerTotalsResponse(apiResponse) {
|
|
9265
9265
|
this.debugLog("\u{1F50D} Starting mapCustomerTotalsResponse", { apiResponse });
|
|
9266
9266
|
const apiArray = Array.isArray(apiResponse?.data) ? apiResponse.data : Array.isArray(apiResponse) ? apiResponse : [];
|
|
9267
|
-
|
|
9268
|
-
|
|
9267
|
+
this.debugLog("[AllReportModal] NEW MAPPING - API array length:", apiArray.length);
|
|
9268
|
+
this.debugLog("[AllReportModal] NEW MAPPING - ItemsList length:", this.params.itemsList.length);
|
|
9269
9269
|
this.debugLog("\u{1F4CB} API data array extracted", {
|
|
9270
9270
|
isDataProperty: !!apiResponse?.data,
|
|
9271
9271
|
isDirectArray: Array.isArray(apiResponse),
|
|
@@ -9274,7 +9274,7 @@ var AllReportModal = class {
|
|
|
9274
9274
|
});
|
|
9275
9275
|
if (!apiArray.length) {
|
|
9276
9276
|
this.debugLog("\u26A0\uFE0F Empty API array, returning empty result");
|
|
9277
|
-
|
|
9277
|
+
this.debugLog("[AllReportModal] Empty/invalid API response:", apiResponse);
|
|
9278
9278
|
return [];
|
|
9279
9279
|
}
|
|
9280
9280
|
const sumByApiId = /* @__PURE__ */ new Map();
|
|
@@ -9285,7 +9285,7 @@ var AllReportModal = class {
|
|
|
9285
9285
|
const consumption = this.pickConsumption(item);
|
|
9286
9286
|
totalApiConsumption += consumption;
|
|
9287
9287
|
if (index < 3) {
|
|
9288
|
-
|
|
9288
|
+
this.debugLog(`[AllReportModal] NEW MAPPING - API item ${index}:`, {
|
|
9289
9289
|
id: item?.id,
|
|
9290
9290
|
name: item?.name,
|
|
9291
9291
|
assetName: item?.assetName,
|
|
@@ -9308,8 +9308,8 @@ var AllReportModal = class {
|
|
|
9308
9308
|
this.debugLog(`\u274C API item without ID:`, item);
|
|
9309
9309
|
}
|
|
9310
9310
|
}
|
|
9311
|
-
|
|
9312
|
-
|
|
9311
|
+
this.debugLog("[AllReportModal] NEW MAPPING - Total API consumption:", totalApiConsumption);
|
|
9312
|
+
this.debugLog("[AllReportModal] NEW MAPPING - Unique API IDs:", sumByApiId.size);
|
|
9313
9313
|
this.debugLog("\u{1F4CA} ID index built", {
|
|
9314
9314
|
sumByApiIdSize: sumByApiId.size,
|
|
9315
9315
|
sumByApiIdEntries: Array.from(sumByApiId.entries()),
|
|
@@ -9323,7 +9323,7 @@ var AllReportModal = class {
|
|
|
9323
9323
|
let consumption = sumByApiId.get(listItem.id) ?? 0;
|
|
9324
9324
|
this.debugLog(`\u{1F3AF} Primary ID match for ${listItem.id}: ${consumption}`);
|
|
9325
9325
|
if (index < 3) {
|
|
9326
|
-
|
|
9326
|
+
this.debugLog(`[AllReportModal] NEW MAPPING - ItemsList item ${index}:`, {
|
|
9327
9327
|
id: listItem.id,
|
|
9328
9328
|
identifier: listItem.identifier,
|
|
9329
9329
|
label: listItem.label,
|
|
@@ -9344,7 +9344,7 @@ var AllReportModal = class {
|
|
|
9344
9344
|
const itemConsumption = this.pickConsumption(apiItem);
|
|
9345
9345
|
consumption += itemConsumption;
|
|
9346
9346
|
if (index < 3) {
|
|
9347
|
-
|
|
9347
|
+
this.debugLog(`[AllReportModal] NEW MAPPING - Substring match for ${listItem.identifier}:`, {
|
|
9348
9348
|
apiItemName: name,
|
|
9349
9349
|
apiItemAssetName: assetName,
|
|
9350
9350
|
itemConsumption,
|
|
@@ -9389,9 +9389,9 @@ var AllReportModal = class {
|
|
|
9389
9389
|
totalApiConsumption,
|
|
9390
9390
|
totalMappedConsumption
|
|
9391
9391
|
};
|
|
9392
|
-
|
|
9392
|
+
this.debugLog("[AllReportModal] NEW MAPPING - Final stats:", stats);
|
|
9393
9393
|
this.debugLog("\u{1F4CA} Final mapping stats:", stats);
|
|
9394
|
-
|
|
9394
|
+
this.debugLog("[AllReportModal] Mapping stats:", stats);
|
|
9395
9395
|
return rows;
|
|
9396
9396
|
}
|
|
9397
9397
|
parseConsumptionValue(item) {
|
|
@@ -9412,7 +9412,7 @@ var AllReportModal = class {
|
|
|
9412
9412
|
}
|
|
9413
9413
|
}
|
|
9414
9414
|
}
|
|
9415
|
-
|
|
9415
|
+
this.debugLog("[AllReportModal] No valid consumption value found in item:", item);
|
|
9416
9416
|
return 0;
|
|
9417
9417
|
}
|
|
9418
9418
|
downloadCSV(content, filename) {
|
|
@@ -10891,16 +10891,22 @@ var STRINGS = {
|
|
|
10891
10891
|
atTime: "\xE1s",
|
|
10892
10892
|
timeUnit: "hs",
|
|
10893
10893
|
exportPdf: "Exportar PDF",
|
|
10894
|
+
exportCsv: "Exportar CSV",
|
|
10894
10895
|
fullscreen: "Tela cheia",
|
|
10895
10896
|
close: "Fechar",
|
|
10896
10897
|
resetZoom: "Reset Zoom",
|
|
10897
10898
|
loading: "Carregando dados...",
|
|
10898
10899
|
noData: "Sem pontos de demanda no per\xEDodo selecionado",
|
|
10899
10900
|
error: "Erro ao carregar dados",
|
|
10900
|
-
zoomHelp: "Scroll: zoom |
|
|
10901
|
+
zoomHelp: "Scroll: zoom | Arraste: mover | Ctrl+Arraste: selecionar",
|
|
10901
10902
|
demand: "Demanda (kW)",
|
|
10902
10903
|
reportTitle: "Relat\xF3rio de Demanda",
|
|
10903
|
-
reportFooter: "MyIO Energy Management System"
|
|
10904
|
+
reportFooter: "MyIO Energy Management System",
|
|
10905
|
+
startDate: "Data Inicial",
|
|
10906
|
+
endDate: "Data Final",
|
|
10907
|
+
updatePeriod: "Atualizar",
|
|
10908
|
+
invalidDateRange: "Data final deve ser maior que data inicial",
|
|
10909
|
+
maxRangeExceeded: "Per\xEDodo m\xE1ximo de 30 dias"
|
|
10904
10910
|
},
|
|
10905
10911
|
"en-US": {
|
|
10906
10912
|
title: "Demand",
|
|
@@ -10910,16 +10916,22 @@ var STRINGS = {
|
|
|
10910
10916
|
atTime: "at",
|
|
10911
10917
|
timeUnit: "",
|
|
10912
10918
|
exportPdf: "Export PDF",
|
|
10919
|
+
exportCsv: "Export CSV",
|
|
10913
10920
|
fullscreen: "Fullscreen",
|
|
10914
10921
|
close: "Close",
|
|
10915
10922
|
resetZoom: "Reset Zoom",
|
|
10916
10923
|
loading: "Loading data...",
|
|
10917
10924
|
noData: "No demand points in the selected period",
|
|
10918
10925
|
error: "Error loading data",
|
|
10919
|
-
zoomHelp: "Scroll: zoom | Drag:
|
|
10926
|
+
zoomHelp: "Scroll: zoom | Drag: pan | Ctrl+Drag: select",
|
|
10920
10927
|
demand: "Demand (kW)",
|
|
10921
10928
|
reportTitle: "Demand Report",
|
|
10922
|
-
reportFooter: "MyIO Energy Management System"
|
|
10929
|
+
reportFooter: "MyIO Energy Management System",
|
|
10930
|
+
startDate: "Start Date",
|
|
10931
|
+
endDate: "End Date",
|
|
10932
|
+
updatePeriod: "Update",
|
|
10933
|
+
invalidDateRange: "End date must be greater than start date",
|
|
10934
|
+
maxRangeExceeded: "Maximum range of 30 days"
|
|
10923
10935
|
}
|
|
10924
10936
|
};
|
|
10925
10937
|
async function loadScript(url, checkGlobal) {
|
|
@@ -11156,6 +11168,69 @@ function injectCSS(styles) {
|
|
|
11156
11168
|
border-bottom: 1px solid #e0e0e0;
|
|
11157
11169
|
}
|
|
11158
11170
|
|
|
11171
|
+
.myio-demand-modal-period-selector {
|
|
11172
|
+
display: flex;
|
|
11173
|
+
align-items: center;
|
|
11174
|
+
gap: ${styles.spacingMd};
|
|
11175
|
+
padding: ${styles.spacingMd} ${styles.spacingLg};
|
|
11176
|
+
background: #f9f9f9;
|
|
11177
|
+
border-bottom: 1px solid #e0e0e0;
|
|
11178
|
+
flex-wrap: wrap;
|
|
11179
|
+
}
|
|
11180
|
+
|
|
11181
|
+
.myio-demand-modal-period-selector label {
|
|
11182
|
+
display: flex;
|
|
11183
|
+
flex-direction: column;
|
|
11184
|
+
gap: ${styles.spacingXs};
|
|
11185
|
+
font-size: ${styles.fontSizeSm};
|
|
11186
|
+
color: ${styles.textPrimary};
|
|
11187
|
+
font-weight: ${styles.fontWeightBold};
|
|
11188
|
+
}
|
|
11189
|
+
|
|
11190
|
+
.myio-demand-modal-date-input {
|
|
11191
|
+
padding: ${styles.spacingSm};
|
|
11192
|
+
border: 1px solid #ccc;
|
|
11193
|
+
border-radius: ${styles.buttonRadius};
|
|
11194
|
+
font-size: ${styles.fontSizeSm};
|
|
11195
|
+
font-family: inherit;
|
|
11196
|
+
min-width: 150px;
|
|
11197
|
+
}
|
|
11198
|
+
|
|
11199
|
+
.myio-demand-modal-date-input:focus {
|
|
11200
|
+
outline: 2px solid ${styles.primaryColor};
|
|
11201
|
+
outline-offset: 1px;
|
|
11202
|
+
}
|
|
11203
|
+
|
|
11204
|
+
.myio-demand-modal-btn-update {
|
|
11205
|
+
background: ${styles.primaryColor};
|
|
11206
|
+
border: none;
|
|
11207
|
+
color: white;
|
|
11208
|
+
padding: ${styles.spacingSm} ${styles.spacingMd};
|
|
11209
|
+
border-radius: ${styles.buttonRadius};
|
|
11210
|
+
cursor: pointer;
|
|
11211
|
+
font-size: ${styles.fontSizeSm};
|
|
11212
|
+
font-family: inherit;
|
|
11213
|
+
font-weight: ${styles.fontWeightBold};
|
|
11214
|
+
align-self: flex-end;
|
|
11215
|
+
margin-bottom: 2px;
|
|
11216
|
+
}
|
|
11217
|
+
|
|
11218
|
+
.myio-demand-modal-btn-update:hover {
|
|
11219
|
+
background: #6A1B9A;
|
|
11220
|
+
}
|
|
11221
|
+
|
|
11222
|
+
.myio-demand-modal-btn-update:disabled {
|
|
11223
|
+
background: #ccc;
|
|
11224
|
+
cursor: not-allowed;
|
|
11225
|
+
}
|
|
11226
|
+
|
|
11227
|
+
.myio-demand-modal-period-error {
|
|
11228
|
+
flex-basis: 100%;
|
|
11229
|
+
color: ${styles.dangerColor};
|
|
11230
|
+
font-size: ${styles.fontSizeXs};
|
|
11231
|
+
margin-top: -${styles.spacingSm};
|
|
11232
|
+
}
|
|
11233
|
+
|
|
11159
11234
|
.myio-demand-modal-peak {
|
|
11160
11235
|
margin: ${styles.spacingMd} ${styles.spacingLg} 0;
|
|
11161
11236
|
padding: ${styles.spacingSm} ${styles.spacingMd};
|
|
@@ -11306,12 +11381,14 @@ async function fetchTelemetryData(token, deviceId, startDate, endDate, queryPara
|
|
|
11306
11381
|
const startTs = new Date(startDate).getTime();
|
|
11307
11382
|
const endTs = new Date(endDate).getTime();
|
|
11308
11383
|
const keys = queryParams?.keys || "consumption";
|
|
11309
|
-
const limit = queryParams?.limit || 5e4;
|
|
11310
11384
|
const intervalType = queryParams?.intervalType || "MILLISECONDS";
|
|
11311
|
-
const interval = queryParams?.interval ||
|
|
11312
|
-
const agg = queryParams?.agg || "
|
|
11385
|
+
const interval = queryParams?.interval || 864e5;
|
|
11386
|
+
const agg = queryParams?.agg || "MAX";
|
|
11313
11387
|
const orderBy = queryParams?.orderBy || "ASC";
|
|
11314
|
-
|
|
11388
|
+
let url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=${keys}&startTs=${startTs}&endTs=${endTs}&intervalType=${intervalType}&interval=${interval}&agg=${agg}&orderBy=${orderBy}`;
|
|
11389
|
+
if (agg === "NONE" && queryParams?.limit) {
|
|
11390
|
+
url += `&limit=${queryParams.limit}`;
|
|
11391
|
+
}
|
|
11315
11392
|
const response = await fetch(url, {
|
|
11316
11393
|
headers: {
|
|
11317
11394
|
"X-Authorization": `Bearer ${token}`,
|
|
@@ -11445,9 +11522,12 @@ async function openDemandModal(params) {
|
|
|
11445
11522
|
<h2 id="modal-title" class="myio-demand-modal-title">${strings.title} \u2013 ${label}</h2>
|
|
11446
11523
|
</div>
|
|
11447
11524
|
<div class="myio-demand-modal-actions">
|
|
11448
|
-
<button class="myio-demand-modal-btn myio-demand-modal-btn-pdf" type="button">
|
|
11525
|
+
<button class="myio-demand-modal-btn myio-demand-modal-btn-pdf" type="button" style="display: none;">
|
|
11449
11526
|
${strings.exportPdf}
|
|
11450
11527
|
</button>
|
|
11528
|
+
<button class="myio-demand-modal-btn myio-demand-modal-btn-csv" type="button">
|
|
11529
|
+
${strings.exportCsv}
|
|
11530
|
+
</button>
|
|
11451
11531
|
<button class="myio-demand-modal-btn myio-demand-modal-btn-fullscreen" type="button" aria-label="${strings.fullscreen}">
|
|
11452
11532
|
\u26F6
|
|
11453
11533
|
</button>
|
|
@@ -11460,7 +11540,22 @@ async function openDemandModal(params) {
|
|
|
11460
11540
|
<div class="myio-demand-modal-period">
|
|
11461
11541
|
${strings.period}: ${startDateFormatted} \u2192 ${endDateFormatted}
|
|
11462
11542
|
</div>
|
|
11463
|
-
|
|
11543
|
+
|
|
11544
|
+
<div class="myio-demand-modal-period-selector">
|
|
11545
|
+
<label>
|
|
11546
|
+
${strings.startDate}:
|
|
11547
|
+
<input type="date" class="myio-demand-modal-date-input myio-demand-modal-date-start" />
|
|
11548
|
+
</label>
|
|
11549
|
+
<label>
|
|
11550
|
+
${strings.endDate}:
|
|
11551
|
+
<input type="date" class="myio-demand-modal-date-input myio-demand-modal-date-end" />
|
|
11552
|
+
</label>
|
|
11553
|
+
<button class="myio-demand-modal-btn-update" type="button">
|
|
11554
|
+
${strings.updatePeriod}
|
|
11555
|
+
</button>
|
|
11556
|
+
<div class="myio-demand-modal-period-error" style="display: none;"></div>
|
|
11557
|
+
</div>
|
|
11558
|
+
|
|
11464
11559
|
<div class="myio-demand-modal-peak" style="display: none;"></div>
|
|
11465
11560
|
|
|
11466
11561
|
<div class="myio-demand-modal-content">
|
|
@@ -11494,6 +11589,7 @@ async function openDemandModal(params) {
|
|
|
11494
11589
|
const closeBtn = overlay.querySelector(".myio-demand-modal-btn-close");
|
|
11495
11590
|
const fullscreenBtn = overlay.querySelector(".myio-demand-modal-btn-fullscreen");
|
|
11496
11591
|
const pdfBtn = overlay.querySelector(".myio-demand-modal-btn-pdf");
|
|
11592
|
+
const csvBtn = overlay.querySelector(".myio-demand-modal-btn-csv");
|
|
11497
11593
|
const resetBtn = overlay.querySelector(".myio-demand-modal-btn-reset");
|
|
11498
11594
|
const chartCanvas = overlay.querySelector(".myio-demand-modal-chart");
|
|
11499
11595
|
const loadingEl = overlay.querySelector(".myio-demand-modal-loading");
|
|
@@ -11501,9 +11597,16 @@ async function openDemandModal(params) {
|
|
|
11501
11597
|
const errorText = overlay.querySelector(".myio-demand-modal-error-text");
|
|
11502
11598
|
const peakEl = overlay.querySelector(".myio-demand-modal-peak");
|
|
11503
11599
|
const contentEl = overlay.querySelector(".myio-demand-modal-content");
|
|
11600
|
+
const periodDisplayEl = overlay.querySelector(".myio-demand-modal-period");
|
|
11601
|
+
const dateStartInput = overlay.querySelector(".myio-demand-modal-date-start");
|
|
11602
|
+
const dateEndInput = overlay.querySelector(".myio-demand-modal-date-end");
|
|
11603
|
+
const updateBtn = overlay.querySelector(".myio-demand-modal-btn-update");
|
|
11604
|
+
const periodErrorEl = overlay.querySelector(".myio-demand-modal-period-error");
|
|
11504
11605
|
let chart = null;
|
|
11505
11606
|
let chartData = null;
|
|
11506
11607
|
let isFullscreen = false;
|
|
11608
|
+
let currentStartDate = params.startDate;
|
|
11609
|
+
let currentEndDate = params.endDate;
|
|
11507
11610
|
const originalOverflow = document.body.style.overflow;
|
|
11508
11611
|
document.body.style.overflow = "hidden";
|
|
11509
11612
|
const releaseFocusTrap = createFocusTrap(overlay);
|
|
@@ -11528,6 +11631,45 @@ async function openDemandModal(params) {
|
|
|
11528
11631
|
chart.resetZoom();
|
|
11529
11632
|
}
|
|
11530
11633
|
}
|
|
11634
|
+
function exportCsv() {
|
|
11635
|
+
if (!chartData) {
|
|
11636
|
+
alert("Nenhum dado dispon\xEDvel para exportar");
|
|
11637
|
+
return;
|
|
11638
|
+
}
|
|
11639
|
+
const btn = csvBtn;
|
|
11640
|
+
const originalHtml = btn.innerHTML;
|
|
11641
|
+
btn.disabled = true;
|
|
11642
|
+
btn.innerHTML = "<span>\u23F3</span> Gerando CSV...";
|
|
11643
|
+
try {
|
|
11644
|
+
const BOM = "\uFEFF";
|
|
11645
|
+
let csv = BOM + "Data/Hora,S\xE9rie,Valor (kW)\n";
|
|
11646
|
+
chartData.series.forEach((series) => {
|
|
11647
|
+
series.points.forEach((point) => {
|
|
11648
|
+
const dateStr2 = formatDateTime(new Date(point.x), locale);
|
|
11649
|
+
const value = point.y.toFixed(2);
|
|
11650
|
+
csv += `${dateStr2},${series.label},${value}
|
|
11651
|
+
`;
|
|
11652
|
+
});
|
|
11653
|
+
});
|
|
11654
|
+
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
|
|
11655
|
+
const url = URL.createObjectURL(blob);
|
|
11656
|
+
const link = document.createElement("a");
|
|
11657
|
+
link.href = url;
|
|
11658
|
+
const labelSafe = label.replace(/\s+/g, "_");
|
|
11659
|
+
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
11660
|
+
link.download = `demanda_${labelSafe}_${dateStr}.csv`;
|
|
11661
|
+
document.body.appendChild(link);
|
|
11662
|
+
link.click();
|
|
11663
|
+
document.body.removeChild(link);
|
|
11664
|
+
URL.revokeObjectURL(url);
|
|
11665
|
+
} catch (error) {
|
|
11666
|
+
console.error("[CSV Export] Error:", error);
|
|
11667
|
+
alert("Erro ao gerar CSV. Por favor, tente novamente.");
|
|
11668
|
+
} finally {
|
|
11669
|
+
btn.disabled = false;
|
|
11670
|
+
btn.innerHTML = originalHtml;
|
|
11671
|
+
}
|
|
11672
|
+
}
|
|
11531
11673
|
async function exportPdf() {
|
|
11532
11674
|
if (!chartData || !chart) {
|
|
11533
11675
|
alert("Nenhum dado dispon\xEDvel para exportar");
|
|
@@ -11601,10 +11743,45 @@ async function openDemandModal(params) {
|
|
|
11601
11743
|
btn.innerHTML = originalHtml;
|
|
11602
11744
|
}
|
|
11603
11745
|
}
|
|
11746
|
+
function initializeDateInputs() {
|
|
11747
|
+
const startDate = new Date(currentStartDate);
|
|
11748
|
+
const endDate = new Date(currentEndDate);
|
|
11749
|
+
dateStartInput.value = startDate.toISOString().split("T")[0];
|
|
11750
|
+
dateEndInput.value = endDate.toISOString().split("T")[0];
|
|
11751
|
+
}
|
|
11752
|
+
async function updatePeriod() {
|
|
11753
|
+
periodErrorEl.style.display = "none";
|
|
11754
|
+
const newStartDate = dateStartInput.value;
|
|
11755
|
+
const newEndDate = dateEndInput.value;
|
|
11756
|
+
if (!newStartDate || !newEndDate) {
|
|
11757
|
+
periodErrorEl.textContent = strings.error;
|
|
11758
|
+
periodErrorEl.style.display = "block";
|
|
11759
|
+
return;
|
|
11760
|
+
}
|
|
11761
|
+
const startDateObj = new Date(newStartDate);
|
|
11762
|
+
const endDateObj = new Date(newEndDate);
|
|
11763
|
+
if (endDateObj < startDateObj) {
|
|
11764
|
+
periodErrorEl.textContent = strings.invalidDateRange;
|
|
11765
|
+
periodErrorEl.style.display = "block";
|
|
11766
|
+
return;
|
|
11767
|
+
}
|
|
11768
|
+
const diffTime = Math.abs(endDateObj.getTime() - startDateObj.getTime());
|
|
11769
|
+
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
11770
|
+
if (diffDays > 30) {
|
|
11771
|
+
periodErrorEl.textContent = strings.maxRangeExceeded;
|
|
11772
|
+
periodErrorEl.style.display = "block";
|
|
11773
|
+
return;
|
|
11774
|
+
}
|
|
11775
|
+
currentStartDate = startDateObj.toISOString();
|
|
11776
|
+
currentEndDate = endDateObj.toISOString();
|
|
11777
|
+
await loadData();
|
|
11778
|
+
}
|
|
11604
11779
|
closeBtn.addEventListener("click", closeModal);
|
|
11605
11780
|
fullscreenBtn.addEventListener("click", toggleFullscreen);
|
|
11606
11781
|
resetBtn.addEventListener("click", resetZoom);
|
|
11607
11782
|
pdfBtn.addEventListener("click", exportPdf);
|
|
11783
|
+
csvBtn.addEventListener("click", exportCsv);
|
|
11784
|
+
updateBtn.addEventListener("click", updatePeriod);
|
|
11608
11785
|
overlay.addEventListener("click", (e) => {
|
|
11609
11786
|
if (e.target === overlay) {
|
|
11610
11787
|
closeModal();
|
|
@@ -11620,8 +11797,9 @@ async function openDemandModal(params) {
|
|
|
11620
11797
|
loadingEl.style.display = "flex";
|
|
11621
11798
|
contentEl.style.display = "none";
|
|
11622
11799
|
errorEl.style.display = "none";
|
|
11623
|
-
|
|
11624
|
-
const
|
|
11800
|
+
peakEl.style.display = "none";
|
|
11801
|
+
const startDateObj = new Date(currentStartDate);
|
|
11802
|
+
const endDateObj = new Date(currentEndDate);
|
|
11625
11803
|
const diffTime = Math.abs(endDateObj.getTime() - startDateObj.getTime());
|
|
11626
11804
|
const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
|
|
11627
11805
|
if (diffDays > 30) {
|
|
@@ -11630,7 +11808,10 @@ async function openDemandModal(params) {
|
|
|
11630
11808
|
errorText.textContent = "O Limite de busca \xE9 de 30 dias de intervalo.";
|
|
11631
11809
|
return;
|
|
11632
11810
|
}
|
|
11633
|
-
const
|
|
11811
|
+
const startDateFormatted2 = formatDate2(startDateObj, locale);
|
|
11812
|
+
const endDateFormatted2 = formatDate2(endDateObj, locale);
|
|
11813
|
+
periodDisplayEl.textContent = `${strings.period}: ${startDateFormatted2} \u2192 ${endDateFormatted2}`;
|
|
11814
|
+
const rawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate: currentStartDate, endDate: currentEndDate, telemetryQuery: params.telemetryQuery }) : await fetchTelemetryData(params.token, params.deviceId, currentStartDate, currentEndDate, params.telemetryQuery);
|
|
11634
11815
|
chartData = processMultiSeriesChartData(
|
|
11635
11816
|
rawData,
|
|
11636
11817
|
params.telemetryQuery?.keys || "consumption",
|
|
@@ -11659,79 +11840,88 @@ async function openDemandModal(params) {
|
|
|
11659
11840
|
}
|
|
11660
11841
|
const Chart = window.Chart;
|
|
11661
11842
|
Chart.register(window.ChartZoom);
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11674
|
-
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
|
|
11679
|
-
|
|
11680
|
-
|
|
11681
|
-
|
|
11682
|
-
|
|
11683
|
-
|
|
11684
|
-
position: "top"
|
|
11685
|
-
},
|
|
11686
|
-
zoom: {
|
|
11687
|
-
zoom: {
|
|
11688
|
-
wheel: { enabled: true },
|
|
11689
|
-
pinch: { enabled: true },
|
|
11690
|
-
drag: { enabled: true, modifierKey: "ctrl" },
|
|
11691
|
-
mode: "x"
|
|
11692
|
-
},
|
|
11693
|
-
pan: {
|
|
11694
|
-
enabled: true,
|
|
11695
|
-
mode: "x",
|
|
11696
|
-
modifierKey: "ctrl"
|
|
11697
|
-
}
|
|
11698
|
-
}
|
|
11843
|
+
if (chart) {
|
|
11844
|
+
chart.data.datasets = chartData.series.map((series) => ({
|
|
11845
|
+
label: series.label,
|
|
11846
|
+
data: series.points,
|
|
11847
|
+
borderColor: series.color,
|
|
11848
|
+
backgroundColor: series.color + "CC",
|
|
11849
|
+
borderWidth: 1
|
|
11850
|
+
}));
|
|
11851
|
+
chart.options.plugins.legend.display = chartData.series.length > 1;
|
|
11852
|
+
chart.update();
|
|
11853
|
+
} else {
|
|
11854
|
+
chart = new Chart(chartCanvas, {
|
|
11855
|
+
type: "bar",
|
|
11856
|
+
data: {
|
|
11857
|
+
datasets: chartData.series.map((series) => ({
|
|
11858
|
+
label: series.label,
|
|
11859
|
+
data: series.points,
|
|
11860
|
+
borderColor: series.color,
|
|
11861
|
+
backgroundColor: series.color + "CC",
|
|
11862
|
+
// More opaque for bars
|
|
11863
|
+
borderWidth: 1
|
|
11864
|
+
}))
|
|
11699
11865
|
},
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
display:
|
|
11706
|
-
|
|
11866
|
+
options: {
|
|
11867
|
+
responsive: true,
|
|
11868
|
+
maintainAspectRatio: false,
|
|
11869
|
+
plugins: {
|
|
11870
|
+
legend: {
|
|
11871
|
+
display: chartData.series.length > 1,
|
|
11872
|
+
// Show legend only if multiple series
|
|
11873
|
+
position: "top"
|
|
11707
11874
|
},
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11875
|
+
zoom: {
|
|
11876
|
+
zoom: {
|
|
11877
|
+
wheel: { enabled: true },
|
|
11878
|
+
pinch: { enabled: true },
|
|
11879
|
+
drag: { enabled: true, modifierKey: "ctrl" },
|
|
11880
|
+
mode: "x"
|
|
11881
|
+
},
|
|
11882
|
+
pan: {
|
|
11883
|
+
enabled: true,
|
|
11884
|
+
mode: "x"
|
|
11885
|
+
// No modifierKey - pan is free after zoom
|
|
11717
11886
|
}
|
|
11718
11887
|
}
|
|
11719
11888
|
},
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11889
|
+
scales: {
|
|
11890
|
+
x: {
|
|
11891
|
+
type: "linear",
|
|
11892
|
+
position: "bottom",
|
|
11893
|
+
title: {
|
|
11894
|
+
display: true,
|
|
11895
|
+
text: "Tempo"
|
|
11896
|
+
},
|
|
11897
|
+
ticks: {
|
|
11898
|
+
callback: function(value) {
|
|
11899
|
+
const date = new Date(value);
|
|
11900
|
+
return date.toLocaleDateString(locale, {
|
|
11901
|
+
month: "2-digit",
|
|
11902
|
+
day: "2-digit",
|
|
11903
|
+
hour: "2-digit",
|
|
11904
|
+
minute: "2-digit"
|
|
11905
|
+
});
|
|
11906
|
+
}
|
|
11907
|
+
}
|
|
11725
11908
|
},
|
|
11726
|
-
|
|
11909
|
+
y: {
|
|
11910
|
+
title: {
|
|
11911
|
+
display: true,
|
|
11912
|
+
text: params.yAxisLabel || strings.demand
|
|
11913
|
+
// Use configurable Y-axis label
|
|
11914
|
+
},
|
|
11915
|
+
beginAtZero: true
|
|
11916
|
+
}
|
|
11917
|
+
},
|
|
11918
|
+
interaction: {
|
|
11919
|
+
intersect: false,
|
|
11920
|
+
mode: "index"
|
|
11727
11921
|
}
|
|
11728
|
-
},
|
|
11729
|
-
interaction: {
|
|
11730
|
-
intersect: false,
|
|
11731
|
-
mode: "index"
|
|
11732
11922
|
}
|
|
11733
|
-
}
|
|
11734
|
-
}
|
|
11923
|
+
});
|
|
11924
|
+
}
|
|
11735
11925
|
loadingEl.style.display = "none";
|
|
11736
11926
|
contentEl.style.display = "flex";
|
|
11737
11927
|
} catch (error) {
|
|
@@ -11741,6 +11931,7 @@ async function openDemandModal(params) {
|
|
|
11741
11931
|
errorText.textContent = `${strings.error}: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
11742
11932
|
}
|
|
11743
11933
|
}
|
|
11934
|
+
initializeDateInputs();
|
|
11744
11935
|
loadData();
|
|
11745
11936
|
return {
|
|
11746
11937
|
destroy: closeModal
|