myio-js-library 0.1.213 → 0.1.214
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 +448 -62
- package/dist/index.js +448 -62
- package/dist/myio-js-library.umd.js +448 -62
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21471,26 +21471,26 @@ var WaterTankModalView = class {
|
|
|
21471
21471
|
*/
|
|
21472
21472
|
getI18n() {
|
|
21473
21473
|
const defaults = {
|
|
21474
|
-
title: "
|
|
21475
|
-
loading: "
|
|
21476
|
-
error: "
|
|
21477
|
-
noData: "
|
|
21478
|
-
exportCsv: "
|
|
21479
|
-
close: "
|
|
21480
|
-
currentLevel: "
|
|
21481
|
-
averageLevel: "
|
|
21482
|
-
minLevel: "
|
|
21483
|
-
maxLevel: "
|
|
21484
|
-
dateRange: "
|
|
21485
|
-
deviceInfo: "
|
|
21486
|
-
levelChart: "
|
|
21474
|
+
title: "Caixa d'\xC1gua",
|
|
21475
|
+
loading: "Carregando...",
|
|
21476
|
+
error: "Erro ao carregar dados",
|
|
21477
|
+
noData: "Nenhum dado dispon\xEDvel",
|
|
21478
|
+
exportCsv: "Exportar CSV",
|
|
21479
|
+
close: "Fechar",
|
|
21480
|
+
currentLevel: "N\xEDvel Atual",
|
|
21481
|
+
averageLevel: "N\xEDvel M\xE9dio",
|
|
21482
|
+
minLevel: "N\xEDvel M\xEDnimo",
|
|
21483
|
+
maxLevel: "N\xEDvel M\xE1ximo",
|
|
21484
|
+
dateRange: "Per\xEDodo",
|
|
21485
|
+
deviceInfo: "Informa\xE7\xF5es do Dispositivo",
|
|
21486
|
+
levelChart: "Hist\xF3rico de N\xEDvel (m.c.a)",
|
|
21487
21487
|
percentUnit: "%",
|
|
21488
21488
|
status: {
|
|
21489
|
-
critical: "
|
|
21490
|
-
low: "
|
|
21491
|
-
medium: "
|
|
21492
|
-
good: "
|
|
21493
|
-
full: "
|
|
21489
|
+
critical: "Cr\xEDtico",
|
|
21490
|
+
low: "Baixo",
|
|
21491
|
+
medium: "M\xE9dio",
|
|
21492
|
+
good: "Bom",
|
|
21493
|
+
full: "Cheio"
|
|
21494
21494
|
}
|
|
21495
21495
|
};
|
|
21496
21496
|
return {
|
|
@@ -21591,62 +21591,327 @@ var WaterTankModalView = class {
|
|
|
21591
21591
|
this.attachEventListeners();
|
|
21592
21592
|
}
|
|
21593
21593
|
/**
|
|
21594
|
-
* Render modal header
|
|
21594
|
+
* Render modal header - MyIO Premium Style
|
|
21595
21595
|
*/
|
|
21596
21596
|
renderHeader() {
|
|
21597
21597
|
const { context, params } = this.config;
|
|
21598
21598
|
const title = params.ui?.title || `${this.i18n.title} - ${context.device.label}`;
|
|
21599
21599
|
return `
|
|
21600
21600
|
<div class="myio-water-tank-modal-header" style="
|
|
21601
|
-
padding:
|
|
21602
|
-
border-bottom: 1px solid #e0e0e0;
|
|
21601
|
+
padding: 4px 8px;
|
|
21603
21602
|
display: flex;
|
|
21604
21603
|
align-items: center;
|
|
21605
21604
|
justify-content: space-between;
|
|
21605
|
+
background: #3e1a7d;
|
|
21606
|
+
color: white;
|
|
21607
|
+
border-radius: 12px 12px 0 0;
|
|
21608
|
+
min-height: 20px;
|
|
21606
21609
|
">
|
|
21607
21610
|
<h2 style="
|
|
21608
|
-
margin:
|
|
21609
|
-
font-size:
|
|
21611
|
+
margin: 6px;
|
|
21612
|
+
font-size: 18px;
|
|
21610
21613
|
font-weight: 600;
|
|
21611
|
-
color:
|
|
21612
|
-
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
transition: background 0.2s ease;
|
|
21627
|
-
" title="${this.i18n.close}">
|
|
21628
|
-
\xD7
|
|
21629
|
-
</button>
|
|
21614
|
+
color: white;
|
|
21615
|
+
line-height: 2;
|
|
21616
|
+
">\u{1F4A7} ${title}</h2>
|
|
21617
|
+
<div style="display: flex; gap: 4px; align-items: center;">
|
|
21618
|
+
<button class="myio-water-tank-modal-close" title="${this.i18n.close}" style="
|
|
21619
|
+
background: none;
|
|
21620
|
+
border: none;
|
|
21621
|
+
font-size: 20px;
|
|
21622
|
+
cursor: pointer;
|
|
21623
|
+
padding: 4px 8px;
|
|
21624
|
+
border-radius: 6px;
|
|
21625
|
+
color: rgba(255,255,255,0.8);
|
|
21626
|
+
transition: background-color 0.2s;
|
|
21627
|
+
">\xD7</button>
|
|
21628
|
+
</div>
|
|
21630
21629
|
</div>
|
|
21631
21630
|
`;
|
|
21632
21631
|
}
|
|
21633
21632
|
/**
|
|
21634
|
-
* Render modal body
|
|
21633
|
+
* RFC-0107: Render modal body with new layout
|
|
21634
|
+
* Left side: Tank visualization with percentage
|
|
21635
|
+
* Right side: Chart with controls (larger area)
|
|
21635
21636
|
*/
|
|
21636
21637
|
renderBody() {
|
|
21637
21638
|
return `
|
|
21638
21639
|
<div class="myio-water-tank-modal-body" style="
|
|
21639
|
-
padding:
|
|
21640
|
+
padding: 20px;
|
|
21640
21641
|
overflow-y: auto;
|
|
21641
21642
|
flex: 1;
|
|
21643
|
+
display: flex;
|
|
21644
|
+
flex-direction: column;
|
|
21645
|
+
gap: 16px;
|
|
21642
21646
|
">
|
|
21643
|
-
${this.
|
|
21644
|
-
|
|
21645
|
-
|
|
21647
|
+
${this.renderControlsBar()}
|
|
21648
|
+
<div style="
|
|
21649
|
+
display: flex;
|
|
21650
|
+
gap: 20px;
|
|
21651
|
+
flex: 1;
|
|
21652
|
+
min-height: 400px;
|
|
21653
|
+
">
|
|
21654
|
+
${this.renderTankPanel()}
|
|
21655
|
+
${this.renderChartPanel()}
|
|
21656
|
+
</div>
|
|
21646
21657
|
</div>
|
|
21647
21658
|
${this.renderFooter()}
|
|
21648
21659
|
`;
|
|
21649
21660
|
}
|
|
21661
|
+
/**
|
|
21662
|
+
* RFC-0107: Render controls bar with date range, aggregation, and limit
|
|
21663
|
+
*/
|
|
21664
|
+
renderControlsBar() {
|
|
21665
|
+
const { params } = this.config;
|
|
21666
|
+
const startDate = this.formatDateForInput(params.startTs);
|
|
21667
|
+
const endDate = this.formatDateForInput(params.endTs);
|
|
21668
|
+
const currentAggregation = params.aggregation || "NONE";
|
|
21669
|
+
const currentLimit = params.limit || 1e3;
|
|
21670
|
+
return `
|
|
21671
|
+
<div style="
|
|
21672
|
+
background: #f8f9fa;
|
|
21673
|
+
border: 1px solid #e0e0e0;
|
|
21674
|
+
border-radius: 8px;
|
|
21675
|
+
padding: 12px 16px;
|
|
21676
|
+
display: flex;
|
|
21677
|
+
align-items: center;
|
|
21678
|
+
gap: 16px;
|
|
21679
|
+
flex-wrap: wrap;
|
|
21680
|
+
">
|
|
21681
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21682
|
+
<label style="font-size: 13px; font-weight: 500; color: #2c3e50;">De:</label>
|
|
21683
|
+
<input type="date" id="myio-water-tank-start-date" value="${startDate}" style="
|
|
21684
|
+
padding: 6px 10px;
|
|
21685
|
+
border: 1px solid #ddd;
|
|
21686
|
+
border-radius: 6px;
|
|
21687
|
+
font-size: 13px;
|
|
21688
|
+
color: #2c3e50;
|
|
21689
|
+
cursor: pointer;
|
|
21690
|
+
"/>
|
|
21691
|
+
</div>
|
|
21692
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21693
|
+
<label style="font-size: 13px; font-weight: 500; color: #2c3e50;">At\xE9:</label>
|
|
21694
|
+
<input type="date" id="myio-water-tank-end-date" value="${endDate}" style="
|
|
21695
|
+
padding: 6px 10px;
|
|
21696
|
+
border: 1px solid #ddd;
|
|
21697
|
+
border-radius: 6px;
|
|
21698
|
+
font-size: 13px;
|
|
21699
|
+
color: #2c3e50;
|
|
21700
|
+
cursor: pointer;
|
|
21701
|
+
"/>
|
|
21702
|
+
</div>
|
|
21703
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21704
|
+
<label style="font-size: 13px; font-weight: 500; color: #2c3e50;">Agrega\xE7\xE3o:</label>
|
|
21705
|
+
<select id="myio-water-tank-aggregation" style="
|
|
21706
|
+
padding: 6px 10px;
|
|
21707
|
+
border: 1px solid #ddd;
|
|
21708
|
+
border-radius: 6px;
|
|
21709
|
+
font-size: 13px;
|
|
21710
|
+
color: #2c3e50;
|
|
21711
|
+
background: white;
|
|
21712
|
+
cursor: pointer;
|
|
21713
|
+
">
|
|
21714
|
+
<option value="NONE" ${currentAggregation === "NONE" ? "selected" : ""}>Nenhuma</option>
|
|
21715
|
+
<option value="AVG" ${currentAggregation === "AVG" ? "selected" : ""}>M\xE9dia</option>
|
|
21716
|
+
<option value="MIN" ${currentAggregation === "MIN" ? "selected" : ""}>M\xEDnimo</option>
|
|
21717
|
+
<option value="MAX" ${currentAggregation === "MAX" ? "selected" : ""}>M\xE1ximo</option>
|
|
21718
|
+
<option value="SUM" ${currentAggregation === "SUM" ? "selected" : ""}>Soma</option>
|
|
21719
|
+
<option value="COUNT" ${currentAggregation === "COUNT" ? "selected" : ""}>Contagem</option>
|
|
21720
|
+
</select>
|
|
21721
|
+
</div>
|
|
21722
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21723
|
+
<label style="font-size: 13px; font-weight: 500; color: #2c3e50;">Limite:</label>
|
|
21724
|
+
<select id="myio-water-tank-limit" style="
|
|
21725
|
+
padding: 6px 10px;
|
|
21726
|
+
border: 1px solid #ddd;
|
|
21727
|
+
border-radius: 6px;
|
|
21728
|
+
font-size: 13px;
|
|
21729
|
+
color: #2c3e50;
|
|
21730
|
+
background: white;
|
|
21731
|
+
cursor: pointer;
|
|
21732
|
+
">
|
|
21733
|
+
<option value="100" ${currentLimit === 100 ? "selected" : ""}>100</option>
|
|
21734
|
+
<option value="500" ${currentLimit === 500 ? "selected" : ""}>500</option>
|
|
21735
|
+
<option value="1000" ${currentLimit === 1e3 ? "selected" : ""}>1000</option>
|
|
21736
|
+
<option value="2000" ${currentLimit === 2e3 ? "selected" : ""}>2000</option>
|
|
21737
|
+
<option value="5000" ${currentLimit === 5e3 ? "selected" : ""}>5000</option>
|
|
21738
|
+
</select>
|
|
21739
|
+
</div>
|
|
21740
|
+
<button id="myio-water-tank-apply-dates" style="
|
|
21741
|
+
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
|
|
21742
|
+
color: white;
|
|
21743
|
+
border: none;
|
|
21744
|
+
padding: 6px 16px;
|
|
21745
|
+
border-radius: 6px;
|
|
21746
|
+
font-size: 13px;
|
|
21747
|
+
font-weight: 500;
|
|
21748
|
+
cursor: pointer;
|
|
21749
|
+
transition: all 0.2s ease;
|
|
21750
|
+
">
|
|
21751
|
+
Aplicar
|
|
21752
|
+
</button>
|
|
21753
|
+
</div>
|
|
21754
|
+
`;
|
|
21755
|
+
}
|
|
21756
|
+
/**
|
|
21757
|
+
* RFC-0107: Render tank panel (left side)
|
|
21758
|
+
*/
|
|
21759
|
+
renderTankPanel() {
|
|
21760
|
+
const { data, context } = this.config;
|
|
21761
|
+
let percentage = 0;
|
|
21762
|
+
const percentagePoints = data.telemetry.filter((p) => p.key === "water_percentage");
|
|
21763
|
+
if (percentagePoints.length > 0) {
|
|
21764
|
+
const latestPercentage = percentagePoints[percentagePoints.length - 1].value;
|
|
21765
|
+
percentage = latestPercentage <= 1.5 ? latestPercentage * 100 : latestPercentage;
|
|
21766
|
+
} else if (context.device.currentLevel !== void 0) {
|
|
21767
|
+
const level = context.device.currentLevel;
|
|
21768
|
+
percentage = level <= 1.5 ? level * 100 : level;
|
|
21769
|
+
}
|
|
21770
|
+
const levelStatus = this.getLevelStatus(Math.min(percentage, 100));
|
|
21771
|
+
const tankImageUrl = this.getTankImageUrl(Math.min(percentage, 100));
|
|
21772
|
+
const displayPercentage = percentage.toFixed(1);
|
|
21773
|
+
return `
|
|
21774
|
+
<div style="
|
|
21775
|
+
width: 200px;
|
|
21776
|
+
min-width: 200px;
|
|
21777
|
+
background: linear-gradient(135deg, ${levelStatus.color}10 0%, ${levelStatus.color}05 100%);
|
|
21778
|
+
border: 1px solid ${levelStatus.color}30;
|
|
21779
|
+
border-radius: 12px;
|
|
21780
|
+
padding: 24px 16px;
|
|
21781
|
+
display: flex;
|
|
21782
|
+
flex-direction: column;
|
|
21783
|
+
align-items: center;
|
|
21784
|
+
justify-content: center;
|
|
21785
|
+
gap: 16px;
|
|
21786
|
+
">
|
|
21787
|
+
<img src="${tankImageUrl}" alt="Water Tank" style="
|
|
21788
|
+
width: 100px;
|
|
21789
|
+
height: auto;
|
|
21790
|
+
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1));
|
|
21791
|
+
"/>
|
|
21792
|
+
<div style="
|
|
21793
|
+
font-size: 42px;
|
|
21794
|
+
font-weight: 700;
|
|
21795
|
+
color: ${levelStatus.color};
|
|
21796
|
+
line-height: 1;
|
|
21797
|
+
">${displayPercentage}%</div>
|
|
21798
|
+
<div style="
|
|
21799
|
+
background: ${levelStatus.color};
|
|
21800
|
+
color: white;
|
|
21801
|
+
padding: 4px 12px;
|
|
21802
|
+
border-radius: 20px;
|
|
21803
|
+
font-size: 11px;
|
|
21804
|
+
font-weight: 600;
|
|
21805
|
+
text-transform: uppercase;
|
|
21806
|
+
">${levelStatus.label}</div>
|
|
21807
|
+
<div style="
|
|
21808
|
+
font-size: 12px;
|
|
21809
|
+
color: #7f8c8d;
|
|
21810
|
+
text-align: center;
|
|
21811
|
+
">${this.i18n.currentLevel}</div>
|
|
21812
|
+
</div>
|
|
21813
|
+
`;
|
|
21814
|
+
}
|
|
21815
|
+
/**
|
|
21816
|
+
* RFC-0107: Render chart panel (right side) with maximize button
|
|
21817
|
+
*/
|
|
21818
|
+
renderChartPanel() {
|
|
21819
|
+
const chartPoints = this.getChartDataPoints();
|
|
21820
|
+
const chartTitle = this.chartDisplayMode === "water_percentage" ? "Hist\xF3rico de N\xEDvel (%)" : this.i18n.levelChart;
|
|
21821
|
+
if (chartPoints.length === 0) {
|
|
21822
|
+
const displayLabel = this.chartDisplayMode === "water_percentage" ? "%" : "m.c.a";
|
|
21823
|
+
return `
|
|
21824
|
+
<div style="
|
|
21825
|
+
flex: 1;
|
|
21826
|
+
background: #f8f9fa;
|
|
21827
|
+
border: 1px solid #e0e0e0;
|
|
21828
|
+
border-radius: 12px;
|
|
21829
|
+
display: flex;
|
|
21830
|
+
flex-direction: column;
|
|
21831
|
+
align-items: center;
|
|
21832
|
+
justify-content: center;
|
|
21833
|
+
padding: 24px;
|
|
21834
|
+
">
|
|
21835
|
+
<div style="font-size: 48px; margin-bottom: 16px; opacity: 0.3;">\u{1F4CA}</div>
|
|
21836
|
+
<div style="color: #7f8c8d; font-size: 16px;">${this.i18n.noData}</div>
|
|
21837
|
+
<div style="color: #bdc3c7; font-size: 13px; margin-top: 8px;">
|
|
21838
|
+
Sem dados de ${this.chartDisplayMode === "water_percentage" ? "percentual" : "n\xEDvel"} (${displayLabel}) dispon\xEDveis
|
|
21839
|
+
</div>
|
|
21840
|
+
</div>
|
|
21841
|
+
`;
|
|
21842
|
+
}
|
|
21843
|
+
const firstTs = chartPoints[0]?.ts;
|
|
21844
|
+
const lastTs = chartPoints[chartPoints.length - 1]?.ts;
|
|
21845
|
+
return `
|
|
21846
|
+
<div id="myio-water-tank-chart-panel" style="
|
|
21847
|
+
flex: 1;
|
|
21848
|
+
background: white;
|
|
21849
|
+
border: 1px solid #e0e0e0;
|
|
21850
|
+
border-radius: 12px;
|
|
21851
|
+
padding: 16px;
|
|
21852
|
+
display: flex;
|
|
21853
|
+
flex-direction: column;
|
|
21854
|
+
position: relative;
|
|
21855
|
+
">
|
|
21856
|
+
<div style="
|
|
21857
|
+
display: flex;
|
|
21858
|
+
align-items: center;
|
|
21859
|
+
justify-content: space-between;
|
|
21860
|
+
margin-bottom: 12px;
|
|
21861
|
+
">
|
|
21862
|
+
<h3 style="
|
|
21863
|
+
margin: 0;
|
|
21864
|
+
font-size: 15px;
|
|
21865
|
+
font-weight: 600;
|
|
21866
|
+
color: #2c3e50;
|
|
21867
|
+
">${chartTitle}</h3>
|
|
21868
|
+
<div style="
|
|
21869
|
+
display: flex;
|
|
21870
|
+
align-items: center;
|
|
21871
|
+
gap: 8px;
|
|
21872
|
+
">
|
|
21873
|
+
<select id="myio-water-tank-display-mode" style="
|
|
21874
|
+
padding: 4px 8px;
|
|
21875
|
+
border: 1px solid #ddd;
|
|
21876
|
+
border-radius: 4px;
|
|
21877
|
+
font-size: 12px;
|
|
21878
|
+
color: #2c3e50;
|
|
21879
|
+
background: white;
|
|
21880
|
+
cursor: pointer;
|
|
21881
|
+
">
|
|
21882
|
+
<option value="water_level" ${this.chartDisplayMode === "water_level" ? "selected" : ""}>N\xEDvel (m.c.a)</option>
|
|
21883
|
+
<option value="water_percentage" ${this.chartDisplayMode === "water_percentage" ? "selected" : ""}>Percentual (%)</option>
|
|
21884
|
+
</select>
|
|
21885
|
+
<button id="myio-water-tank-maximize" title="Maximizar gr\xE1fico" style="
|
|
21886
|
+
background: #f0f0f0;
|
|
21887
|
+
border: 1px solid #ddd;
|
|
21888
|
+
border-radius: 4px;
|
|
21889
|
+
padding: 4px 8px;
|
|
21890
|
+
cursor: pointer;
|
|
21891
|
+
font-size: 14px;
|
|
21892
|
+
display: flex;
|
|
21893
|
+
align-items: center;
|
|
21894
|
+
justify-content: center;
|
|
21895
|
+
">\u26F6</button>
|
|
21896
|
+
</div>
|
|
21897
|
+
</div>
|
|
21898
|
+
<div style="flex: 1; min-height: 300px;">
|
|
21899
|
+
<canvas id="myio-water-tank-chart" style="width: 100%; height: 100%;"></canvas>
|
|
21900
|
+
</div>
|
|
21901
|
+
${firstTs && lastTs ? `
|
|
21902
|
+
<div style="
|
|
21903
|
+
margin-top: 8px;
|
|
21904
|
+
font-size: 11px;
|
|
21905
|
+
color: #7f8c8d;
|
|
21906
|
+
text-align: center;
|
|
21907
|
+
">
|
|
21908
|
+
${this.formatDate(firstTs, false)} \u2014 ${this.formatDate(lastTs, false)}
|
|
21909
|
+
(${chartPoints.length} leituras)
|
|
21910
|
+
</div>
|
|
21911
|
+
` : ""}
|
|
21912
|
+
</div>
|
|
21913
|
+
`;
|
|
21914
|
+
}
|
|
21650
21915
|
/**
|
|
21651
21916
|
* Render date range picker
|
|
21652
21917
|
*/
|
|
@@ -21667,7 +21932,7 @@ var WaterTankModalView = class {
|
|
|
21667
21932
|
flex-wrap: wrap;
|
|
21668
21933
|
">
|
|
21669
21934
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21670
|
-
<label style="font-size: 14px; font-weight: 500; color: #2c3e50;">
|
|
21935
|
+
<label style="font-size: 14px; font-weight: 500; color: #2c3e50;">De:</label>
|
|
21671
21936
|
<input type="date" id="myio-water-tank-start-date" value="${startDate}" style="
|
|
21672
21937
|
padding: 8px 12px;
|
|
21673
21938
|
border: 1px solid #ddd;
|
|
@@ -21678,7 +21943,7 @@ var WaterTankModalView = class {
|
|
|
21678
21943
|
"/>
|
|
21679
21944
|
</div>
|
|
21680
21945
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
21681
|
-
<label style="font-size: 14px; font-weight: 500; color: #2c3e50;">
|
|
21946
|
+
<label style="font-size: 14px; font-weight: 500; color: #2c3e50;">At\xE9:</label>
|
|
21682
21947
|
<input type="date" id="myio-water-tank-end-date" value="${endDate}" style="
|
|
21683
21948
|
padding: 8px 12px;
|
|
21684
21949
|
border: 1px solid #ddd;
|
|
@@ -21699,7 +21964,7 @@ var WaterTankModalView = class {
|
|
|
21699
21964
|
cursor: pointer;
|
|
21700
21965
|
transition: all 0.2s ease;
|
|
21701
21966
|
">
|
|
21702
|
-
|
|
21967
|
+
Aplicar
|
|
21703
21968
|
</button>
|
|
21704
21969
|
</div>
|
|
21705
21970
|
`;
|
|
@@ -21921,7 +22186,7 @@ var WaterTankModalView = class {
|
|
|
21921
22186
|
}
|
|
21922
22187
|
const applyDatesBtn = this.modal.querySelector("#myio-water-tank-apply-dates");
|
|
21923
22188
|
if (applyDatesBtn) {
|
|
21924
|
-
applyDatesBtn.addEventListener("click", () => this.
|
|
22189
|
+
applyDatesBtn.addEventListener("click", () => this.handleApplyParams());
|
|
21925
22190
|
}
|
|
21926
22191
|
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
21927
22192
|
if (displayModeSelect) {
|
|
@@ -21930,6 +22195,10 @@ var WaterTankModalView = class {
|
|
|
21930
22195
|
this.refreshChart();
|
|
21931
22196
|
});
|
|
21932
22197
|
}
|
|
22198
|
+
const maximizeBtn = this.modal.querySelector("#myio-water-tank-maximize");
|
|
22199
|
+
if (maximizeBtn) {
|
|
22200
|
+
maximizeBtn.addEventListener("click", () => this.handleMaximize());
|
|
22201
|
+
}
|
|
21933
22202
|
this.overlay.addEventListener("click", (e) => {
|
|
21934
22203
|
if (e.target === this.overlay) {
|
|
21935
22204
|
this.config.onClose();
|
|
@@ -21944,12 +22213,20 @@ var WaterTankModalView = class {
|
|
|
21944
22213
|
});
|
|
21945
22214
|
}
|
|
21946
22215
|
/**
|
|
21947
|
-
* Handle date range change
|
|
22216
|
+
* Handle date range change (legacy - kept for compatibility)
|
|
21948
22217
|
*/
|
|
21949
22218
|
handleDateRangeChange() {
|
|
22219
|
+
this.handleApplyParams();
|
|
22220
|
+
}
|
|
22221
|
+
/**
|
|
22222
|
+
* RFC-0107: Handle apply params (date range, aggregation, limit)
|
|
22223
|
+
*/
|
|
22224
|
+
handleApplyParams() {
|
|
21950
22225
|
if (!this.modal) return;
|
|
21951
22226
|
const startInput = this.modal.querySelector("#myio-water-tank-start-date");
|
|
21952
22227
|
const endInput = this.modal.querySelector("#myio-water-tank-end-date");
|
|
22228
|
+
const aggregationSelect = this.modal.querySelector("#myio-water-tank-aggregation");
|
|
22229
|
+
const limitSelect = this.modal.querySelector("#myio-water-tank-limit");
|
|
21953
22230
|
if (startInput && endInput) {
|
|
21954
22231
|
const startTs = new Date(startInput.value).setHours(0, 0, 0, 0);
|
|
21955
22232
|
const endTs = new Date(endInput.value).setHours(23, 59, 59, 999);
|
|
@@ -21957,17 +22234,77 @@ var WaterTankModalView = class {
|
|
|
21957
22234
|
alert("Start date must be before end date");
|
|
21958
22235
|
return;
|
|
21959
22236
|
}
|
|
21960
|
-
|
|
22237
|
+
const aggregation = aggregationSelect?.value || "NONE";
|
|
22238
|
+
const limit = parseInt(limitSelect?.value || "1000", 10);
|
|
22239
|
+
console.log("[WaterTankModalView] Params changed:", {
|
|
21961
22240
|
startTs,
|
|
21962
22241
|
endTs,
|
|
22242
|
+
aggregation,
|
|
22243
|
+
limit,
|
|
21963
22244
|
startDate: new Date(startTs).toISOString(),
|
|
21964
22245
|
endDate: new Date(endTs).toISOString()
|
|
21965
22246
|
});
|
|
21966
|
-
|
|
22247
|
+
this.config.params.startTs = startTs;
|
|
22248
|
+
this.config.params.endTs = endTs;
|
|
22249
|
+
this.config.params.aggregation = aggregation;
|
|
22250
|
+
this.config.params.limit = limit;
|
|
22251
|
+
if (this.config.onParamsChange) {
|
|
22252
|
+
this.config.onParamsChange({ startTs, endTs, aggregation, limit });
|
|
22253
|
+
} else if (this.config.onDateRangeChange) {
|
|
21967
22254
|
this.config.onDateRangeChange(startTs, endTs);
|
|
21968
22255
|
}
|
|
21969
22256
|
}
|
|
21970
22257
|
}
|
|
22258
|
+
/**
|
|
22259
|
+
* RFC-0107: Handle maximize/restore chart
|
|
22260
|
+
*/
|
|
22261
|
+
isMaximized = false;
|
|
22262
|
+
originalModalStyle = "";
|
|
22263
|
+
handleMaximize() {
|
|
22264
|
+
if (!this.modal) return;
|
|
22265
|
+
const chartPanel = this.modal.querySelector("#myio-water-tank-chart-panel");
|
|
22266
|
+
const tankPanel = chartPanel?.previousElementSibling;
|
|
22267
|
+
const maximizeBtn = this.modal.querySelector("#myio-water-tank-maximize");
|
|
22268
|
+
if (!chartPanel) return;
|
|
22269
|
+
if (this.isMaximized) {
|
|
22270
|
+
this.modal.style.cssText = this.originalModalStyle;
|
|
22271
|
+
if (tankPanel) tankPanel.style.display = "";
|
|
22272
|
+
chartPanel.style.cssText = `
|
|
22273
|
+
flex: 1;
|
|
22274
|
+
background: white;
|
|
22275
|
+
border: 1px solid #e0e0e0;
|
|
22276
|
+
border-radius: 12px;
|
|
22277
|
+
padding: 16px;
|
|
22278
|
+
display: flex;
|
|
22279
|
+
flex-direction: column;
|
|
22280
|
+
position: relative;
|
|
22281
|
+
`;
|
|
22282
|
+
if (maximizeBtn) maximizeBtn.textContent = "\u26F6";
|
|
22283
|
+
this.isMaximized = false;
|
|
22284
|
+
} else {
|
|
22285
|
+
this.originalModalStyle = this.modal.style.cssText;
|
|
22286
|
+
this.modal.style.width = "95vw";
|
|
22287
|
+
this.modal.style.height = "90vh";
|
|
22288
|
+
this.modal.style.maxWidth = "95vw";
|
|
22289
|
+
if (tankPanel) tankPanel.style.display = "none";
|
|
22290
|
+
chartPanel.style.cssText = `
|
|
22291
|
+
flex: 1;
|
|
22292
|
+
background: white;
|
|
22293
|
+
border: 1px solid #e0e0e0;
|
|
22294
|
+
border-radius: 12px;
|
|
22295
|
+
padding: 16px;
|
|
22296
|
+
display: flex;
|
|
22297
|
+
flex-direction: column;
|
|
22298
|
+
position: relative;
|
|
22299
|
+
min-height: 100%;
|
|
22300
|
+
`;
|
|
22301
|
+
if (maximizeBtn) maximizeBtn.textContent = "\u26F6";
|
|
22302
|
+
this.isMaximized = true;
|
|
22303
|
+
}
|
|
22304
|
+
requestAnimationFrame(() => {
|
|
22305
|
+
this.renderCanvasChart();
|
|
22306
|
+
});
|
|
22307
|
+
}
|
|
21971
22308
|
handleEscapeKey(e) {
|
|
21972
22309
|
if (e.key === "Escape") {
|
|
21973
22310
|
this.config.onClose();
|
|
@@ -22106,7 +22443,7 @@ var WaterTankModalView = class {
|
|
|
22106
22443
|
}
|
|
22107
22444
|
}
|
|
22108
22445
|
/**
|
|
22109
|
-
* Update data and re-render chart
|
|
22446
|
+
* Update data and re-render chart with new layout
|
|
22110
22447
|
*/
|
|
22111
22448
|
updateData(data) {
|
|
22112
22449
|
this.config.data = data;
|
|
@@ -22114,13 +22451,20 @@ var WaterTankModalView = class {
|
|
|
22114
22451
|
const bodyEl = this.modal.querySelector(".myio-water-tank-modal-body");
|
|
22115
22452
|
if (bodyEl) {
|
|
22116
22453
|
bodyEl.innerHTML = `
|
|
22117
|
-
${this.
|
|
22118
|
-
|
|
22119
|
-
|
|
22454
|
+
${this.renderControlsBar()}
|
|
22455
|
+
<div style="
|
|
22456
|
+
display: flex;
|
|
22457
|
+
gap: 20px;
|
|
22458
|
+
flex: 1;
|
|
22459
|
+
min-height: 400px;
|
|
22460
|
+
">
|
|
22461
|
+
${this.renderTankPanel()}
|
|
22462
|
+
${this.renderChartPanel()}
|
|
22463
|
+
</div>
|
|
22120
22464
|
`;
|
|
22121
22465
|
const applyDatesBtn = this.modal.querySelector("#myio-water-tank-apply-dates");
|
|
22122
22466
|
if (applyDatesBtn) {
|
|
22123
|
-
applyDatesBtn.addEventListener("click", () => this.
|
|
22467
|
+
applyDatesBtn.addEventListener("click", () => this.handleApplyParams());
|
|
22124
22468
|
}
|
|
22125
22469
|
const displayModeSelect = this.modal.querySelector("#myio-water-tank-display-mode");
|
|
22126
22470
|
if (displayModeSelect) {
|
|
@@ -22129,6 +22473,10 @@ var WaterTankModalView = class {
|
|
|
22129
22473
|
this.refreshChart();
|
|
22130
22474
|
});
|
|
22131
22475
|
}
|
|
22476
|
+
const maximizeBtn = this.modal.querySelector("#myio-water-tank-maximize");
|
|
22477
|
+
if (maximizeBtn) {
|
|
22478
|
+
maximizeBtn.addEventListener("click", () => this.handleMaximize());
|
|
22479
|
+
}
|
|
22132
22480
|
requestAnimationFrame(() => {
|
|
22133
22481
|
this.renderCanvasChart();
|
|
22134
22482
|
});
|
|
@@ -22408,7 +22756,8 @@ var WaterTankModal = class {
|
|
|
22408
22756
|
onError: (error) => this.handleError(error),
|
|
22409
22757
|
onClose: () => this.close(),
|
|
22410
22758
|
// Call close() to destroy view and trigger user callback
|
|
22411
|
-
onDateRangeChange: (startTs, endTs) => this.handleDateRangeChange(startTs, endTs)
|
|
22759
|
+
onDateRangeChange: (startTs, endTs) => this.handleDateRangeChange(startTs, endTs),
|
|
22760
|
+
onParamsChange: (params) => this.handleParamsChange(params)
|
|
22412
22761
|
});
|
|
22413
22762
|
this.view.render();
|
|
22414
22763
|
this.view.show();
|
|
@@ -22473,6 +22822,43 @@ var WaterTankModal = class {
|
|
|
22473
22822
|
this.handleError(error);
|
|
22474
22823
|
}
|
|
22475
22824
|
}
|
|
22825
|
+
/**
|
|
22826
|
+
* RFC-0107: Handle params change (date range, aggregation, limit)
|
|
22827
|
+
*/
|
|
22828
|
+
async handleParamsChange(params) {
|
|
22829
|
+
console.log("[WaterTankModal] Params changed:", {
|
|
22830
|
+
startTs: params.startTs,
|
|
22831
|
+
endTs: params.endTs,
|
|
22832
|
+
aggregation: params.aggregation,
|
|
22833
|
+
limit: params.limit,
|
|
22834
|
+
startDate: new Date(params.startTs).toISOString(),
|
|
22835
|
+
endDate: new Date(params.endTs).toISOString()
|
|
22836
|
+
});
|
|
22837
|
+
this.options.startTs = params.startTs;
|
|
22838
|
+
this.options.endTs = params.endTs;
|
|
22839
|
+
this.options.aggregation = params.aggregation;
|
|
22840
|
+
this.options.limit = params.limit;
|
|
22841
|
+
this.context.timeRange.startTs = params.startTs;
|
|
22842
|
+
this.context.timeRange.endTs = params.endTs;
|
|
22843
|
+
try {
|
|
22844
|
+
console.log("[WaterTankModal] Fetching data with new params...");
|
|
22845
|
+
this.data = await this.fetchTelemetryData();
|
|
22846
|
+
if (this.view) {
|
|
22847
|
+
this.view.updateData(this.data);
|
|
22848
|
+
}
|
|
22849
|
+
if (this.options.onDataLoaded) {
|
|
22850
|
+
try {
|
|
22851
|
+
this.options.onDataLoaded(this.data);
|
|
22852
|
+
} catch (callbackError) {
|
|
22853
|
+
console.warn("[WaterTankModal] onDataLoaded callback error:", callbackError);
|
|
22854
|
+
}
|
|
22855
|
+
}
|
|
22856
|
+
console.log("[WaterTankModal] Data refreshed with new params successfully");
|
|
22857
|
+
} catch (error) {
|
|
22858
|
+
console.error("[WaterTankModal] Failed to fetch data with new params:", error);
|
|
22859
|
+
this.handleError(error);
|
|
22860
|
+
}
|
|
22861
|
+
}
|
|
22476
22862
|
/**
|
|
22477
22863
|
* Handle export functionality
|
|
22478
22864
|
*/
|
|
@@ -22594,8 +22980,8 @@ function validateOptions2(options) {
|
|
|
22594
22980
|
}
|
|
22595
22981
|
if (options.currentLevel !== void 0) {
|
|
22596
22982
|
const level = Number(options.currentLevel);
|
|
22597
|
-
if (isNaN(level) || level < 0
|
|
22598
|
-
errors.push("currentLevel must be a number
|
|
22983
|
+
if (isNaN(level) || level < 0) {
|
|
22984
|
+
errors.push("currentLevel must be a non-negative number");
|
|
22599
22985
|
}
|
|
22600
22986
|
}
|
|
22601
22987
|
if (options.limit !== void 0) {
|