myio-js-library 0.1.137 → 0.1.139

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.
@@ -7193,6 +7193,8 @@ ${rangeText}`;
7193
7193
  padding: 20px;
7194
7194
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
7195
7195
  margin-bottom: 20px;
7196
+ max-height: 520px;
7197
+ overflow: hidden;
7196
7198
  }
7197
7199
 
7198
7200
  .myio-telemetry-chart-title {
@@ -7203,7 +7205,9 @@ ${rangeText}`;
7203
7205
  }
7204
7206
 
7205
7207
  .myio-telemetry-chart {
7206
- height: 250px;
7208
+ height: 300px;
7209
+ max-height: 450px;
7210
+ width: 100%;
7207
7211
  }
7208
7212
 
7209
7213
  .myio-telemetry-selector {
@@ -7373,21 +7377,21 @@ ${rangeText}`;
7373
7377
  </div>
7374
7378
  `;
7375
7379
  document.body.appendChild(overlay);
7376
- const closeBtn = document.getElementById("close-btn");
7377
- const pauseBtn = document.getElementById("pause-btn");
7378
- const pauseBtnIcon = document.getElementById("pause-btn-icon");
7379
- const pauseBtnText = document.getElementById("pause-btn-text");
7380
- const exportBtn = document.getElementById("export-btn");
7381
- const loadingState = document.getElementById("loading-state");
7382
- const telemetryContent = document.getElementById("telemetry-content");
7383
- const errorState = document.getElementById("error-state");
7384
- const telemetryCards = document.getElementById("telemetry-cards");
7385
- const chartContainer = document.getElementById("chart-container");
7386
- const chartCanvas = document.getElementById("telemetry-chart");
7387
- const chartKeySelector = document.getElementById("chart-key-selector");
7388
- const statusIndicator = document.getElementById("status-indicator");
7389
- const statusText = document.getElementById("status-text");
7390
- const lastUpdateText = document.getElementById("last-update-text");
7380
+ const closeBtn = overlay.querySelector("#close-btn");
7381
+ const pauseBtn = overlay.querySelector("#pause-btn");
7382
+ const pauseBtnIcon = overlay.querySelector("#pause-btn-icon");
7383
+ const pauseBtnText = overlay.querySelector("#pause-btn-text");
7384
+ const exportBtn = overlay.querySelector("#export-btn");
7385
+ const loadingState = overlay.querySelector("#loading-state");
7386
+ const telemetryContent = overlay.querySelector("#telemetry-content");
7387
+ const errorState = overlay.querySelector("#error-state");
7388
+ const telemetryCards = overlay.querySelector("#telemetry-cards");
7389
+ const chartContainer = overlay.querySelector("#chart-container");
7390
+ const chartCanvas = overlay.querySelector("#telemetry-chart");
7391
+ const chartKeySelector = overlay.querySelector("#chart-key-selector");
7392
+ const statusIndicator = overlay.querySelector("#status-indicator");
7393
+ const statusText = overlay.querySelector("#status-text");
7394
+ const lastUpdateText = overlay.querySelector("#last-update-text");
7391
7395
  function closeModal() {
7392
7396
  if (refreshIntervalId) {
7393
7397
  clearInterval(refreshIntervalId);
@@ -8822,18 +8826,20 @@ ${rangeText}`;
8822
8826
  "/assets/vendor/moment.min.js",
8823
8827
  "/assets/vendor/daterangepicker.min.js"
8824
8828
  ];
8825
- var PT_BR_LOCALE = {
8826
- format: "DD/MM/YY HH:mm",
8827
- separator: " at\xE9 ",
8828
- applyLabel: "Aplicar",
8829
- cancelLabel: "Cancelar",
8830
- fromLabel: "De",
8831
- toLabel: "At\xE9",
8832
- customRangeLabel: "Personalizado",
8833
- daysOfWeek: ["Do", "Se", "Te", "Qa", "Qi", "Se", "Sa"],
8834
- monthNames: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
8835
- firstDay: 1
8836
- };
8829
+ function getLocaleConfig(includeTime = false) {
8830
+ return {
8831
+ format: includeTime ? "DD/MM/YY HH:mm" : "DD/MM/YYYY",
8832
+ separator: " at\xE9 ",
8833
+ applyLabel: "Aplicar",
8834
+ cancelLabel: "Cancelar",
8835
+ fromLabel: "De",
8836
+ toLabel: "At\xE9",
8837
+ customRangeLabel: "Personalizado",
8838
+ daysOfWeek: ["Do", "Se", "Te", "Qa", "Qi", "Se", "Sa"],
8839
+ monthNames: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
8840
+ firstDay: 1
8841
+ };
8842
+ }
8837
8843
  var CDNLoader = class {
8838
8844
  static jQueryInstance = null;
8839
8845
  static loadingPromise = null;
@@ -8954,14 +8960,46 @@ ${rangeText}`;
8954
8960
  helpText.style.display = "flex";
8955
8961
  helpText.style.alignItems = "center";
8956
8962
  input.parentNode?.appendChild(helpText);
8963
+ const includeTime = opts.includeTime === true;
8964
+ const timePrecision = opts.timePrecision || "minute";
8965
+ const localeConfig = getLocaleConfig(includeTime);
8957
8966
  const moment = window.moment;
8958
- const startDate = opts.presetStart ? moment(opts.presetStart).startOf("day") : moment().startOf("month");
8959
- const endDate = opts.presetEnd ? moment(opts.presetEnd).endOf("day") : moment().endOf("day");
8967
+ let startDate, endDate;
8968
+ if (includeTime) {
8969
+ startDate = opts.presetStart ? moment(opts.presetStart) : moment().startOf("day");
8970
+ endDate = opts.presetEnd ? moment(opts.presetEnd) : moment();
8971
+ } else {
8972
+ startDate = opts.presetStart ? moment(opts.presetStart).startOf("day") : moment().startOf("month");
8973
+ endDate = opts.presetEnd ? moment(opts.presetEnd).endOf("day") : moment().endOf("day");
8974
+ }
8975
+ let ranges;
8976
+ if (includeTime) {
8977
+ const now = moment();
8978
+ ranges = {
8979
+ "\xDAltima hora": [moment().subtract(1, "hours"), now.clone()],
8980
+ "\xDAltimas 6 horas": [moment().subtract(6, "hours"), now.clone()],
8981
+ "\xDAltimas 12 horas": [moment().subtract(12, "hours"), now.clone()],
8982
+ "\xDAltimas 24 horas": [moment().subtract(24, "hours"), now.clone()],
8983
+ "Hoje": [moment().startOf("day"), now.clone()],
8984
+ "Ontem": [moment().subtract(1, "day").startOf("day"), moment().subtract(1, "day").endOf("day")],
8985
+ "\xDAltimos 7 dias": [moment().subtract(6, "days").startOf("day"), now.clone()],
8986
+ "Este m\xEAs": [moment().startOf("month"), now.clone()]
8987
+ };
8988
+ } else {
8989
+ ranges = {
8990
+ "Hoje": [moment().startOf("day"), moment().endOf("day")],
8991
+ "\xDAltimos 7 dias": [moment().subtract(6, "days").startOf("day"), moment().endOf("day")],
8992
+ "\xDAltimos 30 dias": [moment().subtract(29, "days").startOf("day"), moment().endOf("day")],
8993
+ "M\xEAs Anterior": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
8994
+ };
8995
+ }
8960
8996
  $input.daterangepicker({
8961
8997
  parentEl: opts.parentEl || document.body,
8962
- timePicker: true,
8998
+ timePicker: includeTime,
8999
+ // RFC-0086: Conditional time picker
8963
9000
  timePicker24Hour: true,
8964
- timePickerIncrement: 1,
9001
+ timePickerIncrement: timePrecision === "hour" ? 60 : 1,
9002
+ // RFC-0086: Hour vs minute precision
8965
9003
  autoApply: true,
8966
9004
  autoUpdateInput: true,
8967
9005
  linkedCalendars: true,
@@ -8972,15 +9010,12 @@ ${rangeText}`;
8972
9010
  endDate,
8973
9011
  opens: "right",
8974
9012
  drops: "down",
8975
- locale: PT_BR_LOCALE,
9013
+ locale: localeConfig,
9014
+ // RFC-0086: Dynamic locale format
8976
9015
  applyButtonClasses: "btn btn-primary",
8977
9016
  cancelClass: "btn btn-muted",
8978
- ranges: {
8979
- "Hoje": [moment().startOf("day"), moment().endOf("day")],
8980
- "\xDAltimos 7 dias": [moment().subtract(6, "days").startOf("day"), moment().endOf("day")],
8981
- "\xDAltimos 30 dias": [moment().subtract(29, "days").startOf("day"), moment().endOf("day")],
8982
- "M\xEAs Anterior": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
8983
- }
9017
+ ranges
9018
+ // RFC-0086: Dynamic ranges
8984
9019
  });
8985
9020
  updateInputDisplay();
8986
9021
  $input.on("apply.daterangepicker.myio", () => {
@@ -8999,7 +9034,7 @@ ${rangeText}`;
8999
9034
  function updateInputDisplay() {
9000
9035
  const picker = $input.data("daterangepicker");
9001
9036
  if (picker) {
9002
- const formatted = `${picker.startDate.format(PT_BR_LOCALE.format)}${PT_BR_LOCALE.separator}${picker.endDate.format(PT_BR_LOCALE.format)}`;
9037
+ const formatted = `${picker.startDate.format(localeConfig.format)}${localeConfig.separator}${picker.endDate.format(localeConfig.format)}`;
9003
9038
  $input.val(formatted);
9004
9039
  }
9005
9040
  }
@@ -9007,8 +9042,8 @@ ${rangeText}`;
9007
9042
  const picker = $input.data("daterangepicker");
9008
9043
  const startISO = picker.startDate.format("YYYY-MM-DD[T]HH:mm:ssZ");
9009
9044
  const endISO = picker.endDate.format("YYYY-MM-DD[T]HH:mm:ssZ");
9010
- const startLabel = picker.startDate.format(PT_BR_LOCALE.format);
9011
- const endLabel = picker.endDate.format(PT_BR_LOCALE.format);
9045
+ const startLabel = picker.startDate.format(localeConfig.format);
9046
+ const endLabel = picker.endDate.format(localeConfig.format);
9012
9047
  return { startISO, endISO, startLabel, endLabel };
9013
9048
  }
9014
9049
  function setDates(startISO, endISO) {
@@ -9804,7 +9839,7 @@ ${rangeText}`;
9804
9839
  isEmpty = false;
9805
9840
  const sortedData = rawSeries.sort((a, b) => a.ts - b.ts);
9806
9841
  const points = [];
9807
- const isAggregated = aggregation && aggregation !== "NONE";
9842
+ const isAggregated = aggregation !== "NONE";
9808
9843
  if (isAggregated) {
9809
9844
  for (let i = 0; i < sortedData.length; i++) {
9810
9845
  const current = sortedData[i];
@@ -9979,10 +10014,7 @@ ${rangeText}`;
9979
10014
  <button class="myio-demand-modal-btn-update" type="button">
9980
10015
  ${strings.updatePeriod}
9981
10016
  </button>
9982
- <button id="realtime-toggle-btn" class="myio-demand-modal-btn-realtime" type="button" title="Ativar modo tempo real (atualiza\xE7\xE3o a cada 8 segundos)">
9983
- <span class="realtime-indicator"></span>
9984
- <span class="realtime-text">REAL TIME</span>
9985
- </button>
10017
+ <!-- RFC-0084: REAL TIME button removed - use RealTimeTelemetryModal instead -->
9986
10018
  <div class="myio-demand-modal-period-error" style="display: none;"></div>
9987
10019
  </div>
9988
10020
 
@@ -10030,7 +10062,6 @@ ${rangeText}`;
10030
10062
  const dateStartInput = overlay.querySelector(".myio-demand-modal-date-start");
10031
10063
  const dateEndInput = overlay.querySelector(".myio-demand-modal-date-end");
10032
10064
  const updateBtn = overlay.querySelector(".myio-demand-modal-btn-update");
10033
- const realTimeToggleBtn = overlay.querySelector("#realtime-toggle-btn");
10034
10065
  const periodErrorEl = overlay.querySelector(".myio-demand-modal-period-error");
10035
10066
  const telemetryTypeSelect = overlay.querySelector("#telemetry-type-select");
10036
10067
  const intervalSelect = overlay.querySelector("#demand-interval-select");
@@ -10041,16 +10072,10 @@ ${rangeText}`;
10041
10072
  let currentStartDate = params.startDate;
10042
10073
  let currentEndDate = params.endDate;
10043
10074
  let activeTelemetryType = currentTelemetryType;
10044
- let isRealTimeMode = false;
10045
- let realTimeIntervalId = null;
10046
- let lastFetchedTimestamp = null;
10047
10075
  const originalOverflow = document.body.style.overflow;
10048
10076
  document.body.style.overflow = "hidden";
10049
10077
  const releaseFocusTrap = createFocusTrap(overlay);
10050
10078
  function closeModal() {
10051
- if (isRealTimeMode && realTimeIntervalId) {
10052
- window.clearInterval(realTimeIntervalId);
10053
- }
10054
10079
  if (chart) {
10055
10080
  chart.destroy();
10056
10081
  }
@@ -10183,124 +10208,6 @@ ${rangeText}`;
10183
10208
  btn.innerHTML = originalHtml;
10184
10209
  }
10185
10210
  }
10186
- function getTodayStart() {
10187
- const today = /* @__PURE__ */ new Date();
10188
- today.setHours(0, 0, 0, 0);
10189
- return today.toISOString();
10190
- }
10191
- async function enableRealTimeMode() {
10192
- try {
10193
- currentStartDate = getTodayStart();
10194
- currentEndDate = (/* @__PURE__ */ new Date()).toISOString();
10195
- initializeDateInputs();
10196
- dateStartInput.disabled = true;
10197
- dateEndInput.disabled = true;
10198
- dateStartInput.style.opacity = "0.5";
10199
- dateEndInput.style.opacity = "0.5";
10200
- if (intervalSelect) {
10201
- intervalSelect.disabled = true;
10202
- intervalSelect.style.opacity = "0.5";
10203
- }
10204
- if (aggSelect) {
10205
- aggSelect.disabled = true;
10206
- aggSelect.style.opacity = "0.5";
10207
- }
10208
- if (intervalSelect) intervalSelect.value = "8000";
10209
- if (aggSelect) aggSelect.value = "AVG";
10210
- await loadData();
10211
- lastFetchedTimestamp = Date.now();
10212
- const intervalMs = params.realTimeInterval || 8e3;
10213
- realTimeIntervalId = window.setInterval(async () => {
10214
- try {
10215
- await fetchIncrementalData();
10216
- } catch (error) {
10217
- console.error("[DemandModal] Real-time update failed:", error);
10218
- }
10219
- }, intervalMs);
10220
- realTimeToggleBtn.classList.add("active");
10221
- isRealTimeMode = true;
10222
- console.log(`[DemandModal] Real-time mode started (${intervalMs}ms interval)`);
10223
- } catch (error) {
10224
- console.error("[DemandModal] Failed to enable real-time mode:", error);
10225
- await disableRealTimeMode();
10226
- alert("Erro ao ativar modo tempo real. Tente novamente.");
10227
- }
10228
- }
10229
- async function fetchIncrementalData() {
10230
- if (!lastFetchedTimestamp) {
10231
- throw new Error("No last fetched timestamp available");
10232
- }
10233
- const startTs = lastFetchedTimestamp;
10234
- const endTs = Date.now();
10235
- const startDate = new Date(startTs).toISOString();
10236
- const endDate = new Date(endTs).toISOString();
10237
- const keysStr = Array.isArray(activeTelemetryType.keys) ? activeTelemetryType.keys.join(",") : activeTelemetryType.keys;
10238
- const telemetryQuery = {
10239
- keys: keysStr,
10240
- interval: 8e3,
10241
- // 8 seconds (fixed for real-time mode)
10242
- agg: "AVG",
10243
- // Average (fixed for real-time mode)
10244
- intervalType: "MILLISECONDS",
10245
- orderBy: "ASC"
10246
- };
10247
- const newRawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate, endDate, telemetryQuery }) : await fetchTelemetryData(params.token, params.deviceId, startDate, endDate, telemetryQuery);
10248
- const newChartData = processMultiSeriesChartData(
10249
- newRawData,
10250
- keysStr,
10251
- params.correctionFactor || 1,
10252
- locale,
10253
- "AVG",
10254
- params.timezoneOffset
10255
- );
10256
- if (!newChartData.isEmpty && chart && chartData) {
10257
- newChartData.series.forEach((newSeries, seriesIndex) => {
10258
- if (newSeries.points.length > 0 && chart.data.datasets[seriesIndex]) {
10259
- newSeries.points.forEach((point) => {
10260
- chart.data.datasets[seriesIndex].data.push({
10261
- x: point.x,
10262
- y: point.y
10263
- });
10264
- chart.data.labels.push(point.x);
10265
- });
10266
- }
10267
- });
10268
- chart.update("none");
10269
- if (params.realTimeAutoScroll !== false) {
10270
- const latestTimestamp = newChartData.series[0]?.points[newChartData.series[0].points.length - 1]?.x;
10271
- if (latestTimestamp && chart.options.scales?.x) {
10272
- const visibleRange = 3e5;
10273
- chart.options.scales.x.min = latestTimestamp - visibleRange;
10274
- chart.options.scales.x.max = latestTimestamp;
10275
- chart.update("none");
10276
- }
10277
- }
10278
- }
10279
- lastFetchedTimestamp = endTs;
10280
- console.log(`[DemandModal] Incremental fetch completed (${newChartData.series.reduce((sum, s) => sum + s.points.length, 0)} new points)`);
10281
- }
10282
- async function disableRealTimeMode() {
10283
- if (realTimeIntervalId) {
10284
- window.clearInterval(realTimeIntervalId);
10285
- realTimeIntervalId = null;
10286
- }
10287
- dateStartInput.disabled = false;
10288
- dateEndInput.disabled = false;
10289
- dateStartInput.style.opacity = "1";
10290
- dateEndInput.style.opacity = "1";
10291
- if (intervalSelect) {
10292
- intervalSelect.disabled = false;
10293
- intervalSelect.style.opacity = "1";
10294
- }
10295
- if (aggSelect) {
10296
- aggSelect.disabled = false;
10297
- aggSelect.style.opacity = "1";
10298
- }
10299
- isRealTimeMode = false;
10300
- lastFetchedTimestamp = null;
10301
- realTimeToggleBtn.classList.remove("active");
10302
- console.log("[DemandModal] Real-time mode stopped");
10303
- }
10304
10211
  function initializeDateInputs() {
10305
10212
  const startDate = new Date(currentStartDate);
10306
10213
  const endDate = new Date(currentEndDate);
@@ -10381,13 +10288,6 @@ ${rangeText}`;
10381
10288
  pdfBtn.addEventListener("click", exportPdf);
10382
10289
  csvBtn.addEventListener("click", exportCsv);
10383
10290
  updateBtn.addEventListener("click", updatePeriod);
10384
- realTimeToggleBtn.addEventListener("click", async () => {
10385
- if (isRealTimeMode) {
10386
- await disableRealTimeMode();
10387
- } else {
10388
- await enableRealTimeMode();
10389
- }
10390
- });
10391
10291
  if (telemetryTypeSelect && allowTelemetrySwitch) {
10392
10292
  const debouncedSwitch = debounce(switchTelemetryType, 300);
10393
10293
  telemetryTypeSelect.addEventListener("change", (e) => {