myio-js-library 0.1.181 → 0.1.182
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 +922 -316
- package/dist/index.d.cts +151 -1
- package/dist/index.js +920 -316
- package/dist/myio-js-library.umd.js +960 -351
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -5910,185 +5910,253 @@
|
|
|
5910
5910
|
};
|
|
5911
5911
|
}
|
|
5912
5912
|
|
|
5913
|
-
// src/
|
|
5914
|
-
var
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
5913
|
+
// src/utils/TempRangeTooltip.ts
|
|
5914
|
+
var TOOLTIP_STYLES = `
|
|
5915
|
+
.temp-range-tooltip {
|
|
5916
|
+
position: fixed;
|
|
5917
|
+
z-index: 99999;
|
|
5918
|
+
pointer-events: none;
|
|
5919
|
+
opacity: 0;
|
|
5920
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
5921
|
+
transform: translateY(5px);
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5924
|
+
.temp-range-tooltip.visible {
|
|
5925
|
+
opacity: 1;
|
|
5926
|
+
pointer-events: auto;
|
|
5927
|
+
transform: translateY(0);
|
|
5928
|
+
}
|
|
5929
|
+
|
|
5930
|
+
.temp-range-tooltip__content {
|
|
5931
|
+
background: #ffffff;
|
|
5932
|
+
border: 1px solid #e2e8f0;
|
|
5933
|
+
border-radius: 12px;
|
|
5934
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
5935
|
+
min-width: 280px;
|
|
5936
|
+
max-width: 320px;
|
|
5937
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
5938
|
+
font-size: 12px;
|
|
5939
|
+
color: #1e293b;
|
|
5940
|
+
overflow: hidden;
|
|
5941
|
+
}
|
|
5942
|
+
|
|
5943
|
+
.temp-range-tooltip__header {
|
|
5944
|
+
display: flex;
|
|
5945
|
+
align-items: center;
|
|
5946
|
+
gap: 8px;
|
|
5947
|
+
padding: 12px 16px;
|
|
5948
|
+
background: linear-gradient(90deg, #fff7ed 0%, #fed7aa 100%);
|
|
5949
|
+
border-bottom: 1px solid #fdba74;
|
|
5950
|
+
}
|
|
5951
|
+
|
|
5952
|
+
.temp-range-tooltip__icon {
|
|
5953
|
+
font-size: 18px;
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5956
|
+
.temp-range-tooltip__title {
|
|
5957
|
+
font-weight: 700;
|
|
5958
|
+
font-size: 13px;
|
|
5959
|
+
color: #c2410c;
|
|
5960
|
+
}
|
|
5961
|
+
|
|
5962
|
+
.temp-range-tooltip__body {
|
|
5963
|
+
padding: 16px;
|
|
5964
|
+
}
|
|
5965
|
+
|
|
5966
|
+
.temp-range-tooltip__value-row {
|
|
5967
|
+
display: flex;
|
|
5968
|
+
justify-content: space-between;
|
|
5969
|
+
align-items: center;
|
|
5970
|
+
margin-bottom: 16px;
|
|
5971
|
+
}
|
|
5972
|
+
|
|
5973
|
+
.temp-range-tooltip__current {
|
|
5974
|
+
font-size: 28px;
|
|
5975
|
+
font-weight: 700;
|
|
5976
|
+
color: #1e293b;
|
|
5977
|
+
}
|
|
5978
|
+
|
|
5979
|
+
.temp-range-tooltip__current sup {
|
|
5980
|
+
font-size: 14px;
|
|
5981
|
+
color: #64748b;
|
|
5982
|
+
}
|
|
5983
|
+
|
|
5984
|
+
.temp-range-tooltip__deviation {
|
|
5985
|
+
text-align: right;
|
|
5986
|
+
}
|
|
5987
|
+
|
|
5988
|
+
.temp-range-tooltip__deviation-value {
|
|
5989
|
+
font-size: 16px;
|
|
5990
|
+
font-weight: 700;
|
|
5991
|
+
}
|
|
5992
|
+
|
|
5993
|
+
.temp-range-tooltip__deviation-value.cold {
|
|
5994
|
+
color: #2563eb;
|
|
5995
|
+
}
|
|
5996
|
+
|
|
5997
|
+
.temp-range-tooltip__deviation-value.ok {
|
|
5998
|
+
color: #16a34a;
|
|
5999
|
+
}
|
|
6000
|
+
|
|
6001
|
+
.temp-range-tooltip__deviation-value.hot {
|
|
6002
|
+
color: #dc2626;
|
|
6003
|
+
}
|
|
6004
|
+
|
|
6005
|
+
.temp-range-tooltip__deviation-label {
|
|
6006
|
+
font-size: 10px;
|
|
6007
|
+
color: #64748b;
|
|
6008
|
+
text-transform: uppercase;
|
|
6009
|
+
letter-spacing: 0.5px;
|
|
6010
|
+
}
|
|
6011
|
+
|
|
6012
|
+
.temp-range-tooltip__ruler {
|
|
6013
|
+
position: relative;
|
|
6014
|
+
height: 32px;
|
|
6015
|
+
margin: 12px 0;
|
|
6016
|
+
border-radius: 8px;
|
|
6017
|
+
overflow: visible;
|
|
6018
|
+
}
|
|
6019
|
+
|
|
6020
|
+
.temp-range-tooltip__ruler-track {
|
|
6021
|
+
position: absolute;
|
|
6022
|
+
top: 12px;
|
|
6023
|
+
left: 0;
|
|
6024
|
+
right: 0;
|
|
6025
|
+
height: 8px;
|
|
6026
|
+
background: linear-gradient(90deg, #dbeafe 0%, #dcfce7 50%, #fee2e2 100%);
|
|
6027
|
+
border-radius: 4px;
|
|
6028
|
+
border: 1px solid #e2e8f0;
|
|
6029
|
+
}
|
|
6030
|
+
|
|
6031
|
+
.temp-range-tooltip__ruler-range {
|
|
6032
|
+
position: absolute;
|
|
6033
|
+
top: 12px;
|
|
6034
|
+
height: 8px;
|
|
6035
|
+
background: #22c55e;
|
|
6036
|
+
border-radius: 4px;
|
|
6037
|
+
opacity: 0.6;
|
|
6038
|
+
}
|
|
6039
|
+
|
|
6040
|
+
.temp-range-tooltip__ruler-marker {
|
|
6041
|
+
position: absolute;
|
|
6042
|
+
top: 4px;
|
|
6043
|
+
width: 4px;
|
|
6044
|
+
height: 24px;
|
|
6045
|
+
background: #1e293b;
|
|
6046
|
+
border-radius: 2px;
|
|
6047
|
+
transform: translateX(-50%);
|
|
6048
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6049
|
+
}
|
|
6050
|
+
|
|
6051
|
+
.temp-range-tooltip__ruler-marker::after {
|
|
6052
|
+
content: '';
|
|
6053
|
+
position: absolute;
|
|
6054
|
+
top: -4px;
|
|
6055
|
+
left: 50%;
|
|
6056
|
+
transform: translateX(-50%);
|
|
6057
|
+
width: 12px;
|
|
6058
|
+
height: 12px;
|
|
6059
|
+
background: #1e293b;
|
|
6060
|
+
border-radius: 50%;
|
|
6061
|
+
border: 2px solid #fff;
|
|
6062
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6063
|
+
}
|
|
6064
|
+
|
|
6065
|
+
.temp-range-tooltip__ruler-labels {
|
|
6066
|
+
display: flex;
|
|
6067
|
+
justify-content: space-between;
|
|
6068
|
+
margin-top: 8px;
|
|
6069
|
+
font-size: 10px;
|
|
6070
|
+
color: #64748b;
|
|
6071
|
+
}
|
|
6072
|
+
|
|
6073
|
+
.temp-range-tooltip__ruler-min,
|
|
6074
|
+
.temp-range-tooltip__ruler-max {
|
|
6075
|
+
font-weight: 600;
|
|
6076
|
+
}
|
|
6077
|
+
|
|
6078
|
+
.temp-range-tooltip__range-info {
|
|
6079
|
+
display: flex;
|
|
6080
|
+
justify-content: space-between;
|
|
6081
|
+
padding: 10px 12px;
|
|
6082
|
+
background: #f8fafc;
|
|
6083
|
+
border-radius: 8px;
|
|
6084
|
+
margin-top: 12px;
|
|
6085
|
+
}
|
|
6086
|
+
|
|
6087
|
+
.temp-range-tooltip__range-item {
|
|
6088
|
+
text-align: center;
|
|
6089
|
+
}
|
|
6090
|
+
|
|
6091
|
+
.temp-range-tooltip__range-label {
|
|
6092
|
+
font-size: 10px;
|
|
6093
|
+
color: #64748b;
|
|
6094
|
+
text-transform: uppercase;
|
|
6095
|
+
letter-spacing: 0.3px;
|
|
6096
|
+
margin-bottom: 2px;
|
|
6097
|
+
}
|
|
6098
|
+
|
|
6099
|
+
.temp-range-tooltip__range-value {
|
|
6100
|
+
font-size: 14px;
|
|
6101
|
+
font-weight: 600;
|
|
6102
|
+
color: #334155;
|
|
6103
|
+
}
|
|
6104
|
+
|
|
6105
|
+
.temp-range-tooltip__status {
|
|
6106
|
+
display: flex;
|
|
6107
|
+
align-items: center;
|
|
6108
|
+
justify-content: center;
|
|
6109
|
+
gap: 6px;
|
|
6110
|
+
margin-top: 12px;
|
|
6111
|
+
padding: 8px 12px;
|
|
6112
|
+
border-radius: 6px;
|
|
6113
|
+
font-size: 11px;
|
|
6114
|
+
font-weight: 600;
|
|
6115
|
+
}
|
|
6116
|
+
|
|
6117
|
+
.temp-range-tooltip__status.cold {
|
|
6118
|
+
background: #dbeafe;
|
|
6119
|
+
color: #1d4ed8;
|
|
6120
|
+
border: 1px solid #93c5fd;
|
|
6121
|
+
}
|
|
6122
|
+
|
|
6123
|
+
.temp-range-tooltip__status.ok {
|
|
6124
|
+
background: #dcfce7;
|
|
6125
|
+
color: #15803d;
|
|
6126
|
+
border: 1px solid #86efac;
|
|
6127
|
+
}
|
|
6128
|
+
|
|
6129
|
+
.temp-range-tooltip__status.hot {
|
|
6130
|
+
background: #fee2e2;
|
|
6131
|
+
color: #b91c1c;
|
|
6132
|
+
border: 1px solid #fca5a5;
|
|
6133
|
+
}
|
|
6134
|
+
|
|
6135
|
+
.temp-range-tooltip__status.unknown {
|
|
6136
|
+
background: #f3f4f6;
|
|
6137
|
+
color: #6b7280;
|
|
6138
|
+
border: 1px solid #d1d5db;
|
|
6139
|
+
}
|
|
6140
|
+
`;
|
|
6141
|
+
function injectStyles() {
|
|
6142
|
+
if (typeof document === "undefined") return;
|
|
6143
|
+
const styleId = "myio-temp-range-tooltip-styles";
|
|
6144
|
+
if (document.getElementById(styleId)) return;
|
|
6145
|
+
const style = document.createElement("style");
|
|
6146
|
+
style.id = styleId;
|
|
6147
|
+
style.textContent = TOOLTIP_STYLES;
|
|
6148
|
+
document.head.appendChild(style);
|
|
6012
6149
|
}
|
|
6013
|
-
function
|
|
6014
|
-
|
|
6015
|
-
// --- Novos Status de Temperatura ---
|
|
6016
|
-
case "normal":
|
|
6017
|
-
return { chipClass: "chip--ok", label: "Normal" };
|
|
6018
|
-
case "cold":
|
|
6019
|
-
return { chipClass: "chip--standby", label: "Frio" };
|
|
6020
|
-
case "hot":
|
|
6021
|
-
return { chipClass: "chip--alert", label: "Quente" };
|
|
6022
|
-
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
6023
|
-
case DeviceStatusType.POWER_ON:
|
|
6024
|
-
if (domain === "water") {
|
|
6025
|
-
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
6026
|
-
}
|
|
6027
|
-
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
6028
|
-
case DeviceStatusType.STANDBY:
|
|
6029
|
-
return { chipClass: "chip--standby", label: i18n.standby };
|
|
6030
|
-
case DeviceStatusType.WARNING:
|
|
6031
|
-
return { chipClass: "chip--warning", label: i18n.alert };
|
|
6032
|
-
case DeviceStatusType.MAINTENANCE:
|
|
6033
|
-
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
6034
|
-
case DeviceStatusType.FAILURE:
|
|
6035
|
-
return { chipClass: "chip--failure", label: i18n.failure };
|
|
6036
|
-
case DeviceStatusType.POWER_OFF:
|
|
6037
|
-
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
6038
|
-
case DeviceStatusType.OFFLINE:
|
|
6039
|
-
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6040
|
-
case DeviceStatusType.NO_INFO:
|
|
6041
|
-
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
6042
|
-
case DeviceStatusType.NOT_INSTALLED:
|
|
6043
|
-
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
6044
|
-
default:
|
|
6045
|
-
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6046
|
-
}
|
|
6150
|
+
function extractTemperature(entityData) {
|
|
6151
|
+
return Number(entityData.val ?? entityData.currentTemperature ?? entityData.temperature) || 0;
|
|
6047
6152
|
}
|
|
6048
|
-
function
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
// Blue border
|
|
6053
|
-
case DeviceStatusType.STANDBY:
|
|
6054
|
-
return "is-standby";
|
|
6055
|
-
// Green border
|
|
6056
|
-
case DeviceStatusType.WARNING:
|
|
6057
|
-
return "is-warning";
|
|
6058
|
-
// Yellow border
|
|
6059
|
-
case DeviceStatusType.MAINTENANCE:
|
|
6060
|
-
return "is-maintenance";
|
|
6061
|
-
// Yellow border
|
|
6062
|
-
case DeviceStatusType.FAILURE:
|
|
6063
|
-
return "is-failure";
|
|
6064
|
-
// Dark Red border
|
|
6065
|
-
case DeviceStatusType.POWER_OFF:
|
|
6066
|
-
return "is-power-off";
|
|
6067
|
-
// Light Red border
|
|
6068
|
-
case DeviceStatusType.OFFLINE:
|
|
6069
|
-
return "is-offline";
|
|
6070
|
-
// Dark Gray border
|
|
6071
|
-
case DeviceStatusType.NO_INFO:
|
|
6072
|
-
return "is-no-info";
|
|
6073
|
-
// Dark Orange border
|
|
6074
|
-
case DeviceStatusType.NOT_INSTALLED:
|
|
6075
|
-
return "is-not-installed";
|
|
6076
|
-
// Purple border
|
|
6077
|
-
default:
|
|
6078
|
-
return "";
|
|
6079
|
-
}
|
|
6153
|
+
function extractRange(entityData) {
|
|
6154
|
+
const tempMin = entityData.temperatureMin ?? entityData.minTemperature ?? null;
|
|
6155
|
+
const tempMax = entityData.temperatureMax ?? entityData.maxTemperature ?? null;
|
|
6156
|
+
return { tempMin, tempMax };
|
|
6080
6157
|
}
|
|
6081
|
-
function
|
|
6082
|
-
|
|
6083
|
-
const currentTemp = Number(entityObject.val ?? entityObject.currentTemperature ?? entityObject.temperature) || 0;
|
|
6084
|
-
const tempMin = entityObject.temperatureMin ?? entityObject.minTemperature;
|
|
6085
|
-
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
6086
|
-
if (tempMin === void 0 || tempMax === void 0 || tempMin === null || tempMax === null) {
|
|
6087
|
-
return "";
|
|
6088
|
-
}
|
|
6089
|
-
if (currentTemp > tempMax) return "is-temp-hot";
|
|
6090
|
-
if (currentTemp < tempMin) return "is-temp-cold";
|
|
6091
|
-
return "is-temp-ok";
|
|
6158
|
+
function extractLabel(entityData) {
|
|
6159
|
+
return entityData.labelOrName || entityData.name || entityData.label || "Sensor";
|
|
6092
6160
|
}
|
|
6093
6161
|
var TempRangeTooltip = {
|
|
6094
6162
|
containerId: "myio-temp-range-tooltip",
|
|
@@ -6096,6 +6164,7 @@
|
|
|
6096
6164
|
* Create or get the tooltip container
|
|
6097
6165
|
*/
|
|
6098
6166
|
getContainer() {
|
|
6167
|
+
injectStyles();
|
|
6099
6168
|
let container = document.getElementById(this.containerId);
|
|
6100
6169
|
if (!container) {
|
|
6101
6170
|
container = document.createElement("div");
|
|
@@ -6143,20 +6212,20 @@
|
|
|
6143
6212
|
},
|
|
6144
6213
|
/**
|
|
6145
6214
|
* Show tooltip for a temperature card
|
|
6146
|
-
* @param
|
|
6147
|
-
* @param
|
|
6148
|
-
* @param
|
|
6215
|
+
* @param triggerElement - The card element
|
|
6216
|
+
* @param entityData - Entity data with temperature info
|
|
6217
|
+
* @param event - Mouse event for cursor position
|
|
6149
6218
|
*/
|
|
6150
|
-
show(triggerElement,
|
|
6219
|
+
show(triggerElement, entityData, event) {
|
|
6151
6220
|
const container = this.getContainer();
|
|
6152
|
-
const currentTemp =
|
|
6153
|
-
const tempMin
|
|
6154
|
-
const
|
|
6221
|
+
const currentTemp = extractTemperature(entityData);
|
|
6222
|
+
const { tempMin, tempMax } = extractRange(entityData);
|
|
6223
|
+
const label = extractLabel(entityData);
|
|
6155
6224
|
const hasRange = tempMin != null && tempMax != null;
|
|
6156
|
-
const { status,
|
|
6225
|
+
const { status, deviationPercent } = this.calculateStatus(currentTemp, tempMin, tempMax);
|
|
6157
6226
|
const markerPos = this.calculateMarkerPosition(currentTemp, tempMin, tempMax);
|
|
6158
6227
|
let rangeLeft = 0, rangeWidth = 100;
|
|
6159
|
-
if (hasRange) {
|
|
6228
|
+
if (hasRange && tempMin != null && tempMax != null) {
|
|
6160
6229
|
const rangeSize = tempMax - tempMin;
|
|
6161
6230
|
const extension = rangeSize * 0.3;
|
|
6162
6231
|
const visibleMin = tempMin - extension;
|
|
@@ -6165,23 +6234,23 @@
|
|
|
6165
6234
|
rangeLeft = (tempMin - visibleMin) / visibleRange * 100;
|
|
6166
6235
|
rangeWidth = rangeSize / visibleRange * 100;
|
|
6167
6236
|
}
|
|
6168
|
-
let deviationClass = status;
|
|
6169
|
-
if (status === "cold") {
|
|
6170
|
-
`${Math.abs(deviation).toFixed(1)}\xB0C abaixo`;
|
|
6171
|
-
} else if (status === "hot") {
|
|
6172
|
-
`+${deviation.toFixed(1)}\xB0C acima`;
|
|
6173
|
-
} else ;
|
|
6174
6237
|
const statusLabels = {
|
|
6175
6238
|
cold: "\u2744\uFE0F Abaixo da Faixa Ideal",
|
|
6176
6239
|
ok: "\u2714\uFE0F Dentro da Faixa Ideal",
|
|
6177
6240
|
hot: "\u{1F525} Acima da Faixa Ideal",
|
|
6178
6241
|
unknown: "\u2753 Faixa N\xE3o Configurada"
|
|
6179
6242
|
};
|
|
6243
|
+
const statusColors = {
|
|
6244
|
+
cold: "#2563eb",
|
|
6245
|
+
ok: "#16a34a",
|
|
6246
|
+
hot: "#dc2626",
|
|
6247
|
+
unknown: "#64748b"
|
|
6248
|
+
};
|
|
6180
6249
|
container.innerHTML = `
|
|
6181
6250
|
<div class="temp-range-tooltip__content">
|
|
6182
6251
|
<div class="temp-range-tooltip__header">
|
|
6183
6252
|
<span class="temp-range-tooltip__icon">\u{1F321}\uFE0F</span>
|
|
6184
|
-
<span class="temp-range-tooltip__title">${
|
|
6253
|
+
<span class="temp-range-tooltip__title">${label}</span>
|
|
6185
6254
|
</div>
|
|
6186
6255
|
<div class="temp-range-tooltip__body">
|
|
6187
6256
|
<div class="temp-range-tooltip__value-row">
|
|
@@ -6189,79 +6258,392 @@
|
|
|
6189
6258
|
${currentTemp.toFixed(1)}<sup>\xB0C</sup>
|
|
6190
6259
|
</div>
|
|
6191
6260
|
<div class="temp-range-tooltip__deviation">
|
|
6192
|
-
<div class="temp-range-tooltip__deviation-value ${
|
|
6261
|
+
<div class="temp-range-tooltip__deviation-value ${status}">
|
|
6193
6262
|
${status === "ok" ? "\u2713" : status === "cold" ? "\u2193" : status === "hot" ? "\u2191" : "?"} ${Math.abs(deviationPercent || 0).toFixed(0)}%
|
|
6194
6263
|
</div>
|
|
6195
6264
|
<div class="temp-range-tooltip__deviation-label">Desvio</div>
|
|
6196
6265
|
</div>
|
|
6197
6266
|
</div>
|
|
6198
6267
|
|
|
6199
|
-
${hasRange ? `
|
|
6200
|
-
<div class="temp-range-tooltip__ruler">
|
|
6201
|
-
<div class="temp-range-tooltip__ruler-track"></div>
|
|
6202
|
-
<div class="temp-range-tooltip__ruler-range" style="left: ${rangeLeft}%; width: ${rangeWidth}%;"></div>
|
|
6203
|
-
<div class="temp-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6204
|
-
</div>
|
|
6205
|
-
<div class="temp-range-tooltip__ruler-labels">
|
|
6206
|
-
<span class="temp-range-tooltip__ruler-min">${tempMin}\xB0C</span>
|
|
6207
|
-
<span style="color: #22c55e; font-weight: 600;">Faixa Ideal</span>
|
|
6208
|
-
<span class="temp-range-tooltip__ruler-max">${tempMax}\xB0C</span>
|
|
6209
|
-
</div>
|
|
6210
|
-
` : ""}
|
|
6268
|
+
${hasRange ? `
|
|
6269
|
+
<div class="temp-range-tooltip__ruler">
|
|
6270
|
+
<div class="temp-range-tooltip__ruler-track"></div>
|
|
6271
|
+
<div class="temp-range-tooltip__ruler-range" style="left: ${rangeLeft}%; width: ${rangeWidth}%;"></div>
|
|
6272
|
+
<div class="temp-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6273
|
+
</div>
|
|
6274
|
+
<div class="temp-range-tooltip__ruler-labels">
|
|
6275
|
+
<span class="temp-range-tooltip__ruler-min">${tempMin}\xB0C</span>
|
|
6276
|
+
<span style="color: #22c55e; font-weight: 600;">Faixa Ideal</span>
|
|
6277
|
+
<span class="temp-range-tooltip__ruler-max">${tempMax}\xB0C</span>
|
|
6278
|
+
</div>
|
|
6279
|
+
` : ""}
|
|
6280
|
+
|
|
6281
|
+
<div class="temp-range-tooltip__range-info">
|
|
6282
|
+
<div class="temp-range-tooltip__range-item">
|
|
6283
|
+
<div class="temp-range-tooltip__range-label">M\xEDnimo</div>
|
|
6284
|
+
<div class="temp-range-tooltip__range-value">${hasRange ? tempMin + "\xB0C" : "--"}</div>
|
|
6285
|
+
</div>
|
|
6286
|
+
<div class="temp-range-tooltip__range-item">
|
|
6287
|
+
<div class="temp-range-tooltip__range-label">Atual</div>
|
|
6288
|
+
<div class="temp-range-tooltip__range-value" style="color: ${statusColors[status]}">${currentTemp.toFixed(1)}\xB0C</div>
|
|
6289
|
+
</div>
|
|
6290
|
+
<div class="temp-range-tooltip__range-item">
|
|
6291
|
+
<div class="temp-range-tooltip__range-label">M\xE1ximo</div>
|
|
6292
|
+
<div class="temp-range-tooltip__range-value">${hasRange ? tempMax + "\xB0C" : "--"}</div>
|
|
6293
|
+
</div>
|
|
6294
|
+
</div>
|
|
6295
|
+
|
|
6296
|
+
<div class="temp-range-tooltip__status ${status}">
|
|
6297
|
+
${statusLabels[status]}
|
|
6298
|
+
</div>
|
|
6299
|
+
</div>
|
|
6300
|
+
</div>
|
|
6301
|
+
`;
|
|
6302
|
+
let left, top;
|
|
6303
|
+
if (event && event.clientX && event.clientY) {
|
|
6304
|
+
left = event.clientX + 15;
|
|
6305
|
+
top = event.clientY + 15;
|
|
6306
|
+
} else {
|
|
6307
|
+
const rect = triggerElement.getBoundingClientRect();
|
|
6308
|
+
left = rect.left + rect.width / 2 - 150;
|
|
6309
|
+
top = rect.bottom + 8;
|
|
6310
|
+
}
|
|
6311
|
+
const tooltipWidth = 300;
|
|
6312
|
+
const tooltipHeight = 350;
|
|
6313
|
+
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6314
|
+
left = (event?.clientX || left) - tooltipWidth - 15;
|
|
6315
|
+
}
|
|
6316
|
+
if (left < 10) left = 10;
|
|
6317
|
+
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6318
|
+
top = (event?.clientY || top) - tooltipHeight - 15;
|
|
6319
|
+
}
|
|
6320
|
+
if (top < 10) top = 10;
|
|
6321
|
+
container.style.left = left + "px";
|
|
6322
|
+
container.style.top = top + "px";
|
|
6323
|
+
container.classList.add("visible");
|
|
6324
|
+
},
|
|
6325
|
+
/**
|
|
6326
|
+
* Hide tooltip
|
|
6327
|
+
*/
|
|
6328
|
+
hide() {
|
|
6329
|
+
const container = document.getElementById(this.containerId);
|
|
6330
|
+
if (container) {
|
|
6331
|
+
container.classList.remove("visible");
|
|
6332
|
+
}
|
|
6333
|
+
},
|
|
6334
|
+
/**
|
|
6335
|
+
* Attach tooltip to an element
|
|
6336
|
+
* Returns cleanup function
|
|
6337
|
+
*/
|
|
6338
|
+
attach(element, entityData) {
|
|
6339
|
+
const showHandler = (e) => this.show(element, entityData, e);
|
|
6340
|
+
const hideHandler = () => this.hide();
|
|
6341
|
+
element.style.cursor = "help";
|
|
6342
|
+
element.addEventListener("mouseenter", showHandler);
|
|
6343
|
+
element.addEventListener("mouseleave", hideHandler);
|
|
6344
|
+
return () => {
|
|
6345
|
+
element.removeEventListener("mouseenter", showHandler);
|
|
6346
|
+
element.removeEventListener("mouseleave", hideHandler);
|
|
6347
|
+
element.style.cursor = "";
|
|
6348
|
+
this.hide();
|
|
6349
|
+
};
|
|
6350
|
+
}
|
|
6351
|
+
};
|
|
6352
|
+
|
|
6353
|
+
// src/utils/EnergyRangeTooltip.ts
|
|
6354
|
+
var ENERGY_RANGE_TOOLTIP_CSS = `
|
|
6355
|
+
/* ============================================
|
|
6356
|
+
Energy Range Tooltip (for domain=energy)
|
|
6357
|
+
Shows power ruler with current position and status ranges
|
|
6358
|
+
============================================ */
|
|
6359
|
+
.energy-range-tooltip {
|
|
6360
|
+
position: fixed;
|
|
6361
|
+
z-index: 99999;
|
|
6362
|
+
pointer-events: none;
|
|
6363
|
+
opacity: 0;
|
|
6364
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
6365
|
+
transform: translateY(5px);
|
|
6366
|
+
}
|
|
6367
|
+
|
|
6368
|
+
.energy-range-tooltip.visible {
|
|
6369
|
+
opacity: 1;
|
|
6370
|
+
pointer-events: auto;
|
|
6371
|
+
transform: translateY(0);
|
|
6372
|
+
}
|
|
6373
|
+
|
|
6374
|
+
.energy-range-tooltip__content {
|
|
6375
|
+
background: #ffffff;
|
|
6376
|
+
border: 1px solid #e2e8f0;
|
|
6377
|
+
border-radius: 12px;
|
|
6378
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
6379
|
+
min-width: 300px;
|
|
6380
|
+
max-width: 360px;
|
|
6381
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
6382
|
+
font-size: 12px;
|
|
6383
|
+
color: #1e293b;
|
|
6384
|
+
overflow: hidden;
|
|
6385
|
+
}
|
|
6386
|
+
|
|
6387
|
+
.energy-range-tooltip__header {
|
|
6388
|
+
display: flex;
|
|
6389
|
+
align-items: center;
|
|
6390
|
+
gap: 8px;
|
|
6391
|
+
padding: 12px 16px;
|
|
6392
|
+
background: linear-gradient(90deg, #ecfdf5 0%, #d1fae5 100%);
|
|
6393
|
+
border-bottom: 1px solid #6ee7b7;
|
|
6394
|
+
}
|
|
6395
|
+
|
|
6396
|
+
.energy-range-tooltip__icon {
|
|
6397
|
+
font-size: 18px;
|
|
6398
|
+
}
|
|
6399
|
+
|
|
6400
|
+
.energy-range-tooltip__title {
|
|
6401
|
+
font-weight: 700;
|
|
6402
|
+
font-size: 13px;
|
|
6403
|
+
color: #047857;
|
|
6404
|
+
}
|
|
6405
|
+
|
|
6406
|
+
.energy-range-tooltip__body {
|
|
6407
|
+
padding: 16px;
|
|
6408
|
+
}
|
|
6409
|
+
|
|
6410
|
+
/* Power value display */
|
|
6411
|
+
.energy-range-tooltip__value-row {
|
|
6412
|
+
display: flex;
|
|
6413
|
+
justify-content: space-between;
|
|
6414
|
+
align-items: center;
|
|
6415
|
+
margin-bottom: 16px;
|
|
6416
|
+
}
|
|
6417
|
+
|
|
6418
|
+
.energy-range-tooltip__current {
|
|
6419
|
+
font-size: 28px;
|
|
6420
|
+
font-weight: 700;
|
|
6421
|
+
color: #1e293b;
|
|
6422
|
+
}
|
|
6211
6423
|
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
</div>
|
|
6217
|
-
<div class="temp-range-tooltip__range-item">
|
|
6218
|
-
<div class="temp-range-tooltip__range-label">Atual</div>
|
|
6219
|
-
<div class="temp-range-tooltip__range-value" style="color: ${status === "ok" ? "#16a34a" : status === "cold" ? "#2563eb" : "#dc2626"}">${currentTemp.toFixed(1)}\xB0C</div>
|
|
6220
|
-
</div>
|
|
6221
|
-
<div class="temp-range-tooltip__range-item">
|
|
6222
|
-
<div class="temp-range-tooltip__range-label">M\xE1ximo</div>
|
|
6223
|
-
<div class="temp-range-tooltip__range-value">${hasRange ? tempMax + "\xB0C" : "--"}</div>
|
|
6224
|
-
</div>
|
|
6225
|
-
</div>
|
|
6424
|
+
.energy-range-tooltip__current sup {
|
|
6425
|
+
font-size: 14px;
|
|
6426
|
+
color: #64748b;
|
|
6427
|
+
}
|
|
6226
6428
|
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6429
|
+
.energy-range-tooltip__status-badge {
|
|
6430
|
+
text-align: right;
|
|
6431
|
+
}
|
|
6432
|
+
|
|
6433
|
+
.energy-range-tooltip__status-value {
|
|
6434
|
+
font-size: 14px;
|
|
6435
|
+
font-weight: 700;
|
|
6436
|
+
padding: 4px 10px;
|
|
6437
|
+
border-radius: 6px;
|
|
6438
|
+
}
|
|
6439
|
+
|
|
6440
|
+
.energy-range-tooltip__status-value.standby {
|
|
6441
|
+
background: #dbeafe;
|
|
6442
|
+
color: #1d4ed8;
|
|
6443
|
+
}
|
|
6444
|
+
|
|
6445
|
+
.energy-range-tooltip__status-value.normal {
|
|
6446
|
+
background: #dcfce7;
|
|
6447
|
+
color: #15803d;
|
|
6448
|
+
}
|
|
6449
|
+
|
|
6450
|
+
.energy-range-tooltip__status-value.alert {
|
|
6451
|
+
background: #fef3c7;
|
|
6452
|
+
color: #b45309;
|
|
6453
|
+
}
|
|
6454
|
+
|
|
6455
|
+
.energy-range-tooltip__status-value.failure {
|
|
6456
|
+
background: #fee2e2;
|
|
6457
|
+
color: #b91c1c;
|
|
6458
|
+
}
|
|
6459
|
+
|
|
6460
|
+
.energy-range-tooltip__status-value.offline {
|
|
6461
|
+
background: #f3f4f6;
|
|
6462
|
+
color: #6b7280;
|
|
6463
|
+
}
|
|
6464
|
+
|
|
6465
|
+
/* Power ruler/gauge */
|
|
6466
|
+
.energy-range-tooltip__ruler {
|
|
6467
|
+
position: relative;
|
|
6468
|
+
height: 40px;
|
|
6469
|
+
margin: 12px 0;
|
|
6470
|
+
border-radius: 8px;
|
|
6471
|
+
overflow: visible;
|
|
6472
|
+
}
|
|
6473
|
+
|
|
6474
|
+
.energy-range-tooltip__ruler-track {
|
|
6475
|
+
position: absolute;
|
|
6476
|
+
top: 16px;
|
|
6477
|
+
left: 0;
|
|
6478
|
+
right: 0;
|
|
6479
|
+
height: 8px;
|
|
6480
|
+
display: flex;
|
|
6481
|
+
border-radius: 4px;
|
|
6482
|
+
overflow: hidden;
|
|
6483
|
+
border: 1px solid #e2e8f0;
|
|
6484
|
+
}
|
|
6485
|
+
|
|
6486
|
+
.energy-range-tooltip__ruler-segment {
|
|
6487
|
+
height: 100%;
|
|
6488
|
+
}
|
|
6489
|
+
|
|
6490
|
+
.energy-range-tooltip__ruler-segment.standby {
|
|
6491
|
+
background: #dbeafe;
|
|
6492
|
+
}
|
|
6493
|
+
|
|
6494
|
+
.energy-range-tooltip__ruler-segment.normal {
|
|
6495
|
+
background: #dcfce7;
|
|
6496
|
+
}
|
|
6497
|
+
|
|
6498
|
+
.energy-range-tooltip__ruler-segment.alert {
|
|
6499
|
+
background: #fef3c7;
|
|
6500
|
+
}
|
|
6501
|
+
|
|
6502
|
+
.energy-range-tooltip__ruler-segment.failure {
|
|
6503
|
+
background: #fee2e2;
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6506
|
+
.energy-range-tooltip__ruler-marker {
|
|
6507
|
+
position: absolute;
|
|
6508
|
+
top: 8px;
|
|
6509
|
+
width: 4px;
|
|
6510
|
+
height: 24px;
|
|
6511
|
+
background: #1e293b;
|
|
6512
|
+
border-radius: 2px;
|
|
6513
|
+
transform: translateX(-50%);
|
|
6514
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6515
|
+
}
|
|
6516
|
+
|
|
6517
|
+
.energy-range-tooltip__ruler-marker::after {
|
|
6518
|
+
content: '';
|
|
6519
|
+
position: absolute;
|
|
6520
|
+
top: -4px;
|
|
6521
|
+
left: 50%;
|
|
6522
|
+
transform: translateX(-50%);
|
|
6523
|
+
width: 12px;
|
|
6524
|
+
height: 12px;
|
|
6525
|
+
background: #1e293b;
|
|
6526
|
+
border-radius: 50%;
|
|
6527
|
+
border: 2px solid #fff;
|
|
6528
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6529
|
+
}
|
|
6530
|
+
|
|
6531
|
+
/* Range info grid */
|
|
6532
|
+
.energy-range-tooltip__ranges {
|
|
6533
|
+
display: grid;
|
|
6534
|
+
grid-template-columns: repeat(4, 1fr);
|
|
6535
|
+
gap: 8px;
|
|
6536
|
+
margin-top: 16px;
|
|
6537
|
+
}
|
|
6538
|
+
|
|
6539
|
+
.energy-range-tooltip__range-item {
|
|
6540
|
+
text-align: center;
|
|
6541
|
+
padding: 8px 4px;
|
|
6542
|
+
border-radius: 6px;
|
|
6543
|
+
background: #f8fafc;
|
|
6544
|
+
}
|
|
6545
|
+
|
|
6546
|
+
.energy-range-tooltip__range-item.standby {
|
|
6547
|
+
border-left: 3px solid #3b82f6;
|
|
6548
|
+
}
|
|
6549
|
+
|
|
6550
|
+
.energy-range-tooltip__range-item.normal {
|
|
6551
|
+
border-left: 3px solid #22c55e;
|
|
6552
|
+
}
|
|
6553
|
+
|
|
6554
|
+
.energy-range-tooltip__range-item.alert {
|
|
6555
|
+
border-left: 3px solid #f59e0b;
|
|
6556
|
+
}
|
|
6557
|
+
|
|
6558
|
+
.energy-range-tooltip__range-item.failure {
|
|
6559
|
+
border-left: 3px solid #ef4444;
|
|
6560
|
+
}
|
|
6561
|
+
|
|
6562
|
+
.energy-range-tooltip__range-label {
|
|
6563
|
+
font-size: 9px;
|
|
6564
|
+
color: #64748b;
|
|
6565
|
+
text-transform: uppercase;
|
|
6566
|
+
letter-spacing: 0.3px;
|
|
6567
|
+
margin-bottom: 2px;
|
|
6568
|
+
}
|
|
6569
|
+
|
|
6570
|
+
.energy-range-tooltip__range-value {
|
|
6571
|
+
font-size: 11px;
|
|
6572
|
+
font-weight: 600;
|
|
6573
|
+
color: #334155;
|
|
6574
|
+
}
|
|
6575
|
+
|
|
6576
|
+
/* Status info */
|
|
6577
|
+
.energy-range-tooltip__status-info {
|
|
6578
|
+
display: flex;
|
|
6579
|
+
align-items: center;
|
|
6580
|
+
justify-content: center;
|
|
6581
|
+
gap: 6px;
|
|
6582
|
+
margin-top: 12px;
|
|
6583
|
+
padding: 8px 12px;
|
|
6584
|
+
border-radius: 6px;
|
|
6585
|
+
font-size: 11px;
|
|
6586
|
+
font-weight: 600;
|
|
6587
|
+
}
|
|
6588
|
+
|
|
6589
|
+
.energy-range-tooltip__status-info.standby {
|
|
6590
|
+
background: #dbeafe;
|
|
6591
|
+
color: #1d4ed8;
|
|
6592
|
+
border: 1px solid #93c5fd;
|
|
6593
|
+
}
|
|
6594
|
+
|
|
6595
|
+
.energy-range-tooltip__status-info.normal {
|
|
6596
|
+
background: #dcfce7;
|
|
6597
|
+
color: #15803d;
|
|
6598
|
+
border: 1px solid #86efac;
|
|
6599
|
+
}
|
|
6600
|
+
|
|
6601
|
+
.energy-range-tooltip__status-info.alert {
|
|
6602
|
+
background: #fef3c7;
|
|
6603
|
+
color: #b45309;
|
|
6604
|
+
border: 1px solid #fcd34d;
|
|
6605
|
+
}
|
|
6606
|
+
|
|
6607
|
+
.energy-range-tooltip__status-info.failure {
|
|
6608
|
+
background: #fee2e2;
|
|
6609
|
+
color: #b91c1c;
|
|
6610
|
+
border: 1px solid #fca5a5;
|
|
6611
|
+
}
|
|
6612
|
+
|
|
6613
|
+
.energy-range-tooltip__status-info.offline {
|
|
6614
|
+
background: #f3f4f6;
|
|
6615
|
+
color: #6b7280;
|
|
6616
|
+
border: 1px solid #d1d5db;
|
|
6617
|
+
}
|
|
6618
|
+
`;
|
|
6619
|
+
var cssInjected = false;
|
|
6620
|
+
function injectCSS() {
|
|
6621
|
+
if (cssInjected) return;
|
|
6622
|
+
if (typeof document === "undefined") return;
|
|
6623
|
+
const styleId = "myio-energy-range-tooltip-styles";
|
|
6624
|
+
if (document.getElementById(styleId)) {
|
|
6625
|
+
cssInjected = true;
|
|
6626
|
+
return;
|
|
6264
6627
|
}
|
|
6628
|
+
const style = document.createElement("style");
|
|
6629
|
+
style.id = styleId;
|
|
6630
|
+
style.textContent = ENERGY_RANGE_TOOLTIP_CSS;
|
|
6631
|
+
document.head.appendChild(style);
|
|
6632
|
+
cssInjected = true;
|
|
6633
|
+
}
|
|
6634
|
+
var STATUS_LABELS = {
|
|
6635
|
+
standby: "Standby",
|
|
6636
|
+
normal: "Operacao Normal",
|
|
6637
|
+
alert: "Alerta",
|
|
6638
|
+
failure: "Falha",
|
|
6639
|
+
offline: "Fora da faixa"
|
|
6640
|
+
};
|
|
6641
|
+
var STATUS_INFO_LABELS = {
|
|
6642
|
+
standby: "\u{1F535} Standby",
|
|
6643
|
+
normal: "\u2705 Operacao Normal",
|
|
6644
|
+
alert: "\u26A0\uFE0F Alerta",
|
|
6645
|
+
failure: "\u{1F534} Falha",
|
|
6646
|
+
offline: "\u26AB Offline / Sem dados"
|
|
6265
6647
|
};
|
|
6266
6648
|
var EnergyRangeTooltip = {
|
|
6267
6649
|
containerId: "myio-energy-range-tooltip",
|
|
@@ -6269,6 +6651,7 @@
|
|
|
6269
6651
|
* Create or get the tooltip container
|
|
6270
6652
|
*/
|
|
6271
6653
|
getContainer() {
|
|
6654
|
+
injectCSS();
|
|
6272
6655
|
let container = document.getElementById(this.containerId);
|
|
6273
6656
|
if (!container) {
|
|
6274
6657
|
container = document.createElement("div");
|
|
@@ -6288,18 +6671,18 @@
|
|
|
6288
6671
|
const power = Number(powerValue) || 0;
|
|
6289
6672
|
const { standbyRange, normalRange, alertRange, failureRange } = ranges;
|
|
6290
6673
|
if (standbyRange && power >= standbyRange.down && power <= standbyRange.up) {
|
|
6291
|
-
return { status: "standby", label:
|
|
6674
|
+
return { status: "standby", label: STATUS_LABELS.standby };
|
|
6292
6675
|
}
|
|
6293
6676
|
if (normalRange && power >= normalRange.down && power <= normalRange.up) {
|
|
6294
|
-
return { status: "normal", label:
|
|
6677
|
+
return { status: "normal", label: STATUS_LABELS.normal };
|
|
6295
6678
|
}
|
|
6296
6679
|
if (alertRange && power >= alertRange.down && power <= alertRange.up) {
|
|
6297
|
-
return { status: "alert", label:
|
|
6680
|
+
return { status: "alert", label: STATUS_LABELS.alert };
|
|
6298
6681
|
}
|
|
6299
6682
|
if (failureRange && power >= failureRange.down && power <= failureRange.up) {
|
|
6300
|
-
return { status: "failure", label:
|
|
6683
|
+
return { status: "failure", label: STATUS_LABELS.failure };
|
|
6301
6684
|
}
|
|
6302
|
-
return { status: "offline", label:
|
|
6685
|
+
return { status: "offline", label: STATUS_LABELS.offline };
|
|
6303
6686
|
},
|
|
6304
6687
|
/**
|
|
6305
6688
|
* Calculate marker position on ruler (0-100%)
|
|
@@ -6330,7 +6713,7 @@
|
|
|
6330
6713
|
* Format power value for display
|
|
6331
6714
|
*/
|
|
6332
6715
|
formatPower(value) {
|
|
6333
|
-
if (value == null || isNaN(value)) return "-";
|
|
6716
|
+
if (value == null || isNaN(Number(value))) return "-";
|
|
6334
6717
|
const num = Number(value);
|
|
6335
6718
|
if (num >= 1e3) {
|
|
6336
6719
|
return `${(num / 1e3).toFixed(2)} kW`;
|
|
@@ -6348,13 +6731,40 @@
|
|
|
6348
6731
|
const { status, label } = this.calculateStatus(powerValue, ranges);
|
|
6349
6732
|
const markerPos = this.calculateMarkerPosition(powerValue, ranges);
|
|
6350
6733
|
const segmentWidths = this.calculateSegmentWidths(ranges);
|
|
6351
|
-
const
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6734
|
+
const rangesHtml = hasRanges && ranges ? `
|
|
6735
|
+
<div class="energy-range-tooltip__ruler">
|
|
6736
|
+
<div class="energy-range-tooltip__ruler-track">
|
|
6737
|
+
<div class="energy-range-tooltip__ruler-segment standby" style="width: ${segmentWidths.standby}%"></div>
|
|
6738
|
+
<div class="energy-range-tooltip__ruler-segment normal" style="width: ${segmentWidths.normal}%"></div>
|
|
6739
|
+
<div class="energy-range-tooltip__ruler-segment alert" style="width: ${segmentWidths.alert}%"></div>
|
|
6740
|
+
<div class="energy-range-tooltip__ruler-segment failure" style="width: ${segmentWidths.failure}%"></div>
|
|
6741
|
+
</div>
|
|
6742
|
+
<div class="energy-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6743
|
+
</div>
|
|
6744
|
+
|
|
6745
|
+
<div class="energy-range-tooltip__ranges">
|
|
6746
|
+
<div class="energy-range-tooltip__range-item standby">
|
|
6747
|
+
<div class="energy-range-tooltip__range-label">Standby</div>
|
|
6748
|
+
<div class="energy-range-tooltip__range-value">${ranges.standbyRange?.down || 0}-${ranges.standbyRange?.up || 0}W</div>
|
|
6749
|
+
</div>
|
|
6750
|
+
<div class="energy-range-tooltip__range-item normal">
|
|
6751
|
+
<div class="energy-range-tooltip__range-label">Normal</div>
|
|
6752
|
+
<div class="energy-range-tooltip__range-value">${ranges.normalRange?.down || 0}-${ranges.normalRange?.up || 0}W</div>
|
|
6753
|
+
</div>
|
|
6754
|
+
<div class="energy-range-tooltip__range-item alert">
|
|
6755
|
+
<div class="energy-range-tooltip__range-label">Alerta</div>
|
|
6756
|
+
<div class="energy-range-tooltip__range-value">${ranges.alertRange?.down || 0}-${ranges.alertRange?.up || 0}W</div>
|
|
6757
|
+
</div>
|
|
6758
|
+
<div class="energy-range-tooltip__range-item failure">
|
|
6759
|
+
<div class="energy-range-tooltip__range-label">Falha</div>
|
|
6760
|
+
<div class="energy-range-tooltip__range-value">>${ranges.failureRange?.down || 0}W</div>
|
|
6761
|
+
</div>
|
|
6762
|
+
</div>
|
|
6763
|
+
` : `
|
|
6764
|
+
<div style="text-align: center; padding: 16px; color: #64748b; font-size: 12px;">
|
|
6765
|
+
Ranges de potencia nao configurados
|
|
6766
|
+
</div>
|
|
6767
|
+
`;
|
|
6358
6768
|
container.innerHTML = `
|
|
6359
6769
|
<div class="energy-range-tooltip__content">
|
|
6360
6770
|
<div class="energy-range-tooltip__header">
|
|
@@ -6371,51 +6781,18 @@
|
|
|
6371
6781
|
</div>
|
|
6372
6782
|
</div>
|
|
6373
6783
|
|
|
6374
|
-
${
|
|
6375
|
-
<div class="energy-range-tooltip__ruler">
|
|
6376
|
-
<div class="energy-range-tooltip__ruler-track">
|
|
6377
|
-
<div class="energy-range-tooltip__ruler-segment standby" style="width: ${segmentWidths.standby}%"></div>
|
|
6378
|
-
<div class="energy-range-tooltip__ruler-segment normal" style="width: ${segmentWidths.normal}%"></div>
|
|
6379
|
-
<div class="energy-range-tooltip__ruler-segment alert" style="width: ${segmentWidths.alert}%"></div>
|
|
6380
|
-
<div class="energy-range-tooltip__ruler-segment failure" style="width: ${segmentWidths.failure}%"></div>
|
|
6381
|
-
</div>
|
|
6382
|
-
<div class="energy-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6383
|
-
</div>
|
|
6384
|
-
|
|
6385
|
-
<div class="energy-range-tooltip__ranges">
|
|
6386
|
-
<div class="energy-range-tooltip__range-item standby">
|
|
6387
|
-
<div class="energy-range-tooltip__range-label">Standby</div>
|
|
6388
|
-
<div class="energy-range-tooltip__range-value">${ranges.standbyRange?.down || 0}-${ranges.standbyRange?.up || 0}W</div>
|
|
6389
|
-
</div>
|
|
6390
|
-
<div class="energy-range-tooltip__range-item normal">
|
|
6391
|
-
<div class="energy-range-tooltip__range-label">Normal</div>
|
|
6392
|
-
<div class="energy-range-tooltip__range-value">${ranges.normalRange?.down || 0}-${ranges.normalRange?.up || 0}W</div>
|
|
6393
|
-
</div>
|
|
6394
|
-
<div class="energy-range-tooltip__range-item alert">
|
|
6395
|
-
<div class="energy-range-tooltip__range-label">Alerta</div>
|
|
6396
|
-
<div class="energy-range-tooltip__range-value">${ranges.alertRange?.down || 0}-${ranges.alertRange?.up || 0}W</div>
|
|
6397
|
-
</div>
|
|
6398
|
-
<div class="energy-range-tooltip__range-item failure">
|
|
6399
|
-
<div class="energy-range-tooltip__range-label">Falha</div>
|
|
6400
|
-
<div class="energy-range-tooltip__range-value">>${ranges.failureRange?.down || 0}W</div>
|
|
6401
|
-
</div>
|
|
6402
|
-
</div>
|
|
6403
|
-
` : `
|
|
6404
|
-
<div style="text-align: center; padding: 16px; color: #64748b; font-size: 12px;">
|
|
6405
|
-
Ranges de pot\xEAncia n\xE3o configurados
|
|
6406
|
-
</div>
|
|
6407
|
-
`}
|
|
6784
|
+
${rangesHtml}
|
|
6408
6785
|
|
|
6409
6786
|
<div class="energy-range-tooltip__status-info ${status}">
|
|
6410
|
-
${
|
|
6787
|
+
${STATUS_INFO_LABELS[status] || STATUS_INFO_LABELS.offline}
|
|
6411
6788
|
</div>
|
|
6412
6789
|
</div>
|
|
6413
6790
|
</div>
|
|
6414
6791
|
`;
|
|
6415
6792
|
let left, top;
|
|
6416
6793
|
if (event && event.clientX && event.clientY) {
|
|
6417
|
-
left = event.clientX +
|
|
6418
|
-
top = event.clientY +
|
|
6794
|
+
left = event.clientX + 8;
|
|
6795
|
+
top = event.clientY + 8;
|
|
6419
6796
|
} else {
|
|
6420
6797
|
const rect = triggerElement.getBoundingClientRect();
|
|
6421
6798
|
left = rect.left + rect.width / 2 - 150;
|
|
@@ -6424,11 +6801,11 @@
|
|
|
6424
6801
|
const tooltipWidth = 320;
|
|
6425
6802
|
const tooltipHeight = 380;
|
|
6426
6803
|
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6427
|
-
left = (event?.clientX || left) - tooltipWidth -
|
|
6804
|
+
left = (event?.clientX || left) - tooltipWidth - 8;
|
|
6428
6805
|
}
|
|
6429
6806
|
if (left < 10) left = 10;
|
|
6430
6807
|
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6431
|
-
top = (event?.clientY || top) - tooltipHeight -
|
|
6808
|
+
top = (event?.clientY || top) - tooltipHeight - 8;
|
|
6432
6809
|
}
|
|
6433
6810
|
if (top < 10) top = 10;
|
|
6434
6811
|
container.style.left = left + "px";
|
|
@@ -6443,8 +6820,229 @@
|
|
|
6443
6820
|
if (container) {
|
|
6444
6821
|
container.classList.remove("visible");
|
|
6445
6822
|
}
|
|
6823
|
+
},
|
|
6824
|
+
/**
|
|
6825
|
+
* Attach tooltip to an element with automatic show/hide on hover
|
|
6826
|
+
* Returns cleanup function to remove event listeners
|
|
6827
|
+
*/
|
|
6828
|
+
attach(element, entityData) {
|
|
6829
|
+
const handleMouseEnter = (e) => {
|
|
6830
|
+
this.show(element, entityData, e);
|
|
6831
|
+
};
|
|
6832
|
+
const handleMouseLeave = () => {
|
|
6833
|
+
this.hide();
|
|
6834
|
+
};
|
|
6835
|
+
const handleMouseMove = (e) => {
|
|
6836
|
+
const container = document.getElementById(this.containerId);
|
|
6837
|
+
if (container && container.classList.contains("visible")) {
|
|
6838
|
+
let left = e.clientX + 8;
|
|
6839
|
+
let top = e.clientY + 8;
|
|
6840
|
+
const tooltipWidth = 320;
|
|
6841
|
+
const tooltipHeight = 380;
|
|
6842
|
+
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6843
|
+
left = e.clientX - tooltipWidth - 8;
|
|
6844
|
+
}
|
|
6845
|
+
if (left < 10) left = 10;
|
|
6846
|
+
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6847
|
+
top = e.clientY - tooltipHeight - 8;
|
|
6848
|
+
}
|
|
6849
|
+
if (top < 10) top = 10;
|
|
6850
|
+
container.style.left = left + "px";
|
|
6851
|
+
container.style.top = top + "px";
|
|
6852
|
+
}
|
|
6853
|
+
};
|
|
6854
|
+
element.addEventListener("mouseenter", handleMouseEnter);
|
|
6855
|
+
element.addEventListener("mouseleave", handleMouseLeave);
|
|
6856
|
+
element.addEventListener("mousemove", handleMouseMove);
|
|
6857
|
+
return () => {
|
|
6858
|
+
element.removeEventListener("mouseenter", handleMouseEnter);
|
|
6859
|
+
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
6860
|
+
element.removeEventListener("mousemove", handleMouseMove);
|
|
6861
|
+
this.hide();
|
|
6862
|
+
};
|
|
6446
6863
|
}
|
|
6447
6864
|
};
|
|
6865
|
+
|
|
6866
|
+
// src/thingsboard/main-dashboard-shopping/v-4.0.0/card/head-office/card-head-office.js
|
|
6867
|
+
var LABEL_CHAR_LIMIT = 18;
|
|
6868
|
+
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
6869
|
+
var CSS_TAG = "head-office-card-v1";
|
|
6870
|
+
function ensureCss() {
|
|
6871
|
+
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
6872
|
+
const style = document.createElement("style");
|
|
6873
|
+
style.setAttribute("data-myio-css", CSS_TAG);
|
|
6874
|
+
style.textContent = CSS_STRING;
|
|
6875
|
+
document.head.appendChild(style);
|
|
6876
|
+
}
|
|
6877
|
+
}
|
|
6878
|
+
function normalizeParams(params) {
|
|
6879
|
+
if (!params || !params.entityObject) {
|
|
6880
|
+
throw new Error("renderCardCompenteHeadOffice: entityObject is required");
|
|
6881
|
+
}
|
|
6882
|
+
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
6883
|
+
const entityObject = params.entityObject;
|
|
6884
|
+
if (!entityObject.entityId) {
|
|
6885
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing, generating temporary ID");
|
|
6886
|
+
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
6887
|
+
}
|
|
6888
|
+
if (!params.delayTimeConnectionInMins) {
|
|
6889
|
+
LogHelper2.warn(
|
|
6890
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
6891
|
+
);
|
|
6892
|
+
}
|
|
6893
|
+
return {
|
|
6894
|
+
entityObject,
|
|
6895
|
+
i18n: { ...DEFAULT_I18N, ...params.i18n || {} },
|
|
6896
|
+
enableSelection: Boolean(params.enableSelection),
|
|
6897
|
+
enableDragDrop: Boolean(params.enableDragDrop),
|
|
6898
|
+
useNewComponents: Boolean(params.useNewComponents),
|
|
6899
|
+
// RFC-0091: Configurable delay time for connection status check (default 15 minutes)
|
|
6900
|
+
delayTimeConnectionInMins: params.delayTimeConnectionInMins ?? DEFAUL_DELAY_TIME_CONNECTION_IN_MINS,
|
|
6901
|
+
// Debug options
|
|
6902
|
+
debugActive: params.debugActive ?? false,
|
|
6903
|
+
activeTooltipDebug: params.activeTooltipDebug ?? false,
|
|
6904
|
+
// LogHelper instance for this card
|
|
6905
|
+
LogHelper: LogHelper2,
|
|
6906
|
+
callbacks: {
|
|
6907
|
+
handleActionDashboard: params.handleActionDashboard,
|
|
6908
|
+
handleActionReport: params.handleActionReport,
|
|
6909
|
+
handleActionSettings: params.handleActionSettings,
|
|
6910
|
+
handleSelect: params.handleSelect,
|
|
6911
|
+
handInfo: params.handInfo,
|
|
6912
|
+
handleClickCard: params.handleClickCard
|
|
6913
|
+
}
|
|
6914
|
+
};
|
|
6915
|
+
}
|
|
6916
|
+
function getIconSvg(deviceType, domain) {
|
|
6917
|
+
if (domain === "water") {
|
|
6918
|
+
return Icons.waterDrop;
|
|
6919
|
+
}
|
|
6920
|
+
if (domain === "temperature") {
|
|
6921
|
+
return Icons.thermometer;
|
|
6922
|
+
}
|
|
6923
|
+
return ICON_MAP[deviceType] || ICON_MAP.DEFAULT;
|
|
6924
|
+
}
|
|
6925
|
+
function formatPower(valueInWatts) {
|
|
6926
|
+
if (valueInWatts === null || valueInWatts === void 0 || isNaN(valueInWatts)) {
|
|
6927
|
+
return { num: "-", unit: "" };
|
|
6928
|
+
}
|
|
6929
|
+
const val = Number(valueInWatts);
|
|
6930
|
+
if (val >= 1e3) {
|
|
6931
|
+
const kw = Math.ceil(val / 1e3 * 100) / 100;
|
|
6932
|
+
return { num: kw.toFixed(2), unit: "kW" };
|
|
6933
|
+
} else {
|
|
6934
|
+
const w = Math.ceil(val);
|
|
6935
|
+
return { num: w.toString(), unit: "W" };
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
function formatValueByDomain(value, domain) {
|
|
6939
|
+
if (domain === "water") {
|
|
6940
|
+
return formatWaterVolumeM3(value);
|
|
6941
|
+
}
|
|
6942
|
+
if (domain === "temperature") {
|
|
6943
|
+
return formatTemperature(value, 0);
|
|
6944
|
+
}
|
|
6945
|
+
return formatEnergy(value);
|
|
6946
|
+
}
|
|
6947
|
+
function formatRelativeTime2(timestamp) {
|
|
6948
|
+
if (!timestamp || isNaN(timestamp)) return "\u2014";
|
|
6949
|
+
const date = new Date(timestamp);
|
|
6950
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
6951
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
6952
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
6953
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
6954
|
+
const year = date.getFullYear();
|
|
6955
|
+
return `${hours}:${minutes} ${day}/${month}/${year}`;
|
|
6956
|
+
}
|
|
6957
|
+
function calculateConsumptionPercentage(target, consumption) {
|
|
6958
|
+
const numericTarget = Number(target);
|
|
6959
|
+
const numericConsumption = Number(consumption);
|
|
6960
|
+
if (isNaN(numericTarget) || isNaN(numericConsumption) || numericTarget <= 0) {
|
|
6961
|
+
return 0;
|
|
6962
|
+
}
|
|
6963
|
+
const percentage = numericConsumption / numericTarget * 100;
|
|
6964
|
+
return percentage;
|
|
6965
|
+
}
|
|
6966
|
+
function getStatusInfo(deviceStatus, i18n, domain) {
|
|
6967
|
+
switch (deviceStatus) {
|
|
6968
|
+
// --- Novos Status de Temperatura ---
|
|
6969
|
+
case "normal":
|
|
6970
|
+
return { chipClass: "chip--ok", label: "Normal" };
|
|
6971
|
+
case "cold":
|
|
6972
|
+
return { chipClass: "chip--standby", label: "Frio" };
|
|
6973
|
+
case "hot":
|
|
6974
|
+
return { chipClass: "chip--alert", label: "Quente" };
|
|
6975
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
6976
|
+
case DeviceStatusType.POWER_ON:
|
|
6977
|
+
if (domain === "water") {
|
|
6978
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
6979
|
+
}
|
|
6980
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
6981
|
+
case DeviceStatusType.STANDBY:
|
|
6982
|
+
return { chipClass: "chip--standby", label: i18n.standby };
|
|
6983
|
+
case DeviceStatusType.WARNING:
|
|
6984
|
+
return { chipClass: "chip--warning", label: i18n.alert };
|
|
6985
|
+
case DeviceStatusType.MAINTENANCE:
|
|
6986
|
+
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
6987
|
+
case DeviceStatusType.FAILURE:
|
|
6988
|
+
return { chipClass: "chip--failure", label: i18n.failure };
|
|
6989
|
+
case DeviceStatusType.POWER_OFF:
|
|
6990
|
+
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
6991
|
+
case DeviceStatusType.OFFLINE:
|
|
6992
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6993
|
+
case DeviceStatusType.NO_INFO:
|
|
6994
|
+
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
6995
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
6996
|
+
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
6997
|
+
default:
|
|
6998
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6999
|
+
}
|
|
7000
|
+
}
|
|
7001
|
+
function getCardStateClass(deviceStatus) {
|
|
7002
|
+
switch (deviceStatus) {
|
|
7003
|
+
case DeviceStatusType.POWER_ON:
|
|
7004
|
+
return "is-power-on";
|
|
7005
|
+
// Blue border
|
|
7006
|
+
case DeviceStatusType.STANDBY:
|
|
7007
|
+
return "is-standby";
|
|
7008
|
+
// Green border
|
|
7009
|
+
case DeviceStatusType.WARNING:
|
|
7010
|
+
return "is-warning";
|
|
7011
|
+
// Yellow border
|
|
7012
|
+
case DeviceStatusType.MAINTENANCE:
|
|
7013
|
+
return "is-maintenance";
|
|
7014
|
+
// Yellow border
|
|
7015
|
+
case DeviceStatusType.FAILURE:
|
|
7016
|
+
return "is-failure";
|
|
7017
|
+
// Dark Red border
|
|
7018
|
+
case DeviceStatusType.POWER_OFF:
|
|
7019
|
+
return "is-power-off";
|
|
7020
|
+
// Light Red border
|
|
7021
|
+
case DeviceStatusType.OFFLINE:
|
|
7022
|
+
return "is-offline";
|
|
7023
|
+
// Dark Gray border
|
|
7024
|
+
case DeviceStatusType.NO_INFO:
|
|
7025
|
+
return "is-no-info";
|
|
7026
|
+
// Dark Orange border
|
|
7027
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
7028
|
+
return "is-not-installed";
|
|
7029
|
+
// Purple border
|
|
7030
|
+
default:
|
|
7031
|
+
return "";
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
function getTempRangeClass(entityObject) {
|
|
7035
|
+
if (entityObject.domain !== "temperature") return "";
|
|
7036
|
+
const currentTemp = Number(entityObject.val ?? entityObject.currentTemperature ?? entityObject.temperature) || 0;
|
|
7037
|
+
const tempMin = entityObject.temperatureMin ?? entityObject.minTemperature;
|
|
7038
|
+
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
7039
|
+
if (tempMin === void 0 || tempMax === void 0 || tempMin === null || tempMax === null) {
|
|
7040
|
+
return "";
|
|
7041
|
+
}
|
|
7042
|
+
if (currentTemp > tempMax) return "is-temp-hot";
|
|
7043
|
+
if (currentTemp < tempMin) return "is-temp-cold";
|
|
7044
|
+
return "is-temp-ok";
|
|
7045
|
+
}
|
|
6448
7046
|
function getStatusDotClass(deviceStatus) {
|
|
6449
7047
|
switch (deviceStatus) {
|
|
6450
7048
|
// --- Novos Status de Temperatura ---
|
|
@@ -7565,6 +8163,7 @@
|
|
|
7565
8163
|
};
|
|
7566
8164
|
const isTankDevice = deviceType === "TANK" || deviceType === "CAIXA_DAGUA";
|
|
7567
8165
|
const isTermostatoDevice = deviceType?.toUpperCase() === "TERMOSTATO";
|
|
8166
|
+
const isEnergyDeviceFlag = isEnergyDevice(deviceType);
|
|
7568
8167
|
const percentageForDisplay = isTankDevice ? (waterPercentage || 0) * 100 : perc;
|
|
7569
8168
|
const calculateTempStatus = () => {
|
|
7570
8169
|
if (temperatureStatus) return temperatureStatus;
|
|
@@ -7581,33 +8180,6 @@
|
|
|
7581
8180
|
tempStatus,
|
|
7582
8181
|
isOffline
|
|
7583
8182
|
});
|
|
7584
|
-
const getTemperatureTooltip = () => {
|
|
7585
|
-
if (!isTermostatoDevice) return "";
|
|
7586
|
-
const currentTemp = Number(val) || 0;
|
|
7587
|
-
const hasRange = temperatureMin !== void 0 && temperatureMax !== void 0 && temperatureMin !== null && temperatureMax !== null;
|
|
7588
|
-
if (isOffline) {
|
|
7589
|
-
return "Dispositivo offline";
|
|
7590
|
-
}
|
|
7591
|
-
if (!hasRange) {
|
|
7592
|
-
return `Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7593
|
-
Faixa n\xE3o configurada`;
|
|
7594
|
-
}
|
|
7595
|
-
const rangeText = `Faixa ideal: ${temperatureMin}\xB0C a ${temperatureMax}\xB0C`;
|
|
7596
|
-
if (tempStatus === "above") {
|
|
7597
|
-
return `ACIMA da faixa ideal
|
|
7598
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7599
|
-
${rangeText}`;
|
|
7600
|
-
} else if (tempStatus === "below") {
|
|
7601
|
-
return `ABAIXO da faixa ideal
|
|
7602
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7603
|
-
${rangeText}`;
|
|
7604
|
-
} else {
|
|
7605
|
-
return `DENTRO da faixa ideal
|
|
7606
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7607
|
-
${rangeText}`;
|
|
7608
|
-
}
|
|
7609
|
-
};
|
|
7610
|
-
const temperatureTooltip = getTemperatureTooltip();
|
|
7611
8183
|
const cardHTML = `
|
|
7612
8184
|
<div class="device-card-centered clickable ${cardEntity.status === "offline" ? "offline" : ""}"
|
|
7613
8185
|
data-entity-id="${entityId}"
|
|
@@ -7633,7 +8205,7 @@ ${rangeText}`;
|
|
|
7633
8205
|
` : ""}
|
|
7634
8206
|
</div>
|
|
7635
8207
|
|
|
7636
|
-
<img class="device-image
|
|
8208
|
+
<img class="device-image ${isTermostatoDevice ? "temp-tooltip-trigger" : ""}${isEnergyDeviceFlag ? " energy-tooltip-trigger" : ""}" src="${deviceImageUrl}" alt="${deviceType}" style="${isTermostatoDevice || isEnergyDeviceFlag ? "cursor: help;" : ""}" />
|
|
7637
8209
|
|
|
7638
8210
|
|
|
7639
8211
|
${customerName && String(customerName).trim() !== "" ? `
|
|
@@ -8197,6 +8769,33 @@ ${rangeText}`;
|
|
|
8197
8769
|
}
|
|
8198
8770
|
});
|
|
8199
8771
|
}
|
|
8772
|
+
const tempTooltipTrigger = enhancedCardElement.querySelector(".temp-tooltip-trigger");
|
|
8773
|
+
let tempTooltipCleanup = null;
|
|
8774
|
+
if (tempTooltipTrigger && isTermostatoDevice) {
|
|
8775
|
+
const tooltipEntityData = {
|
|
8776
|
+
val,
|
|
8777
|
+
temperatureMin,
|
|
8778
|
+
temperatureMax,
|
|
8779
|
+
labelOrName: cardEntity.name,
|
|
8780
|
+
name: cardEntity.name
|
|
8781
|
+
};
|
|
8782
|
+
tempTooltipCleanup = TempRangeTooltip.attach(tempTooltipTrigger, tooltipEntityData);
|
|
8783
|
+
}
|
|
8784
|
+
const energyTooltipTrigger = enhancedCardElement.querySelector(".energy-tooltip-trigger");
|
|
8785
|
+
let energyTooltipCleanup = null;
|
|
8786
|
+
if (energyTooltipTrigger && isEnergyDeviceFlag) {
|
|
8787
|
+
const energyTooltipData = {
|
|
8788
|
+
labelOrName: cardEntity.name,
|
|
8789
|
+
name: cardEntity.name,
|
|
8790
|
+
instantaneousPower: entityObject.instantaneousPower ?? entityObject.consumption_power ?? val,
|
|
8791
|
+
powerRanges: entityObject.powerRanges || entityObject.ranges
|
|
8792
|
+
};
|
|
8793
|
+
energyTooltipCleanup = EnergyRangeTooltip.attach(energyTooltipTrigger, energyTooltipData);
|
|
8794
|
+
}
|
|
8795
|
+
container._cleanup = () => {
|
|
8796
|
+
if (tempTooltipCleanup) tempTooltipCleanup();
|
|
8797
|
+
if (energyTooltipCleanup) energyTooltipCleanup();
|
|
8798
|
+
};
|
|
8200
8799
|
const jQueryLikeObject = {
|
|
8201
8800
|
get: (index) => index === 0 ? container : void 0,
|
|
8202
8801
|
0: container,
|
|
@@ -11178,7 +11777,7 @@ ${rangeText}`;
|
|
|
11178
11777
|
var zoomPluginLoaded = false;
|
|
11179
11778
|
var jsPdfLoaded = false;
|
|
11180
11779
|
var _jspdfPromise = null;
|
|
11181
|
-
var
|
|
11780
|
+
var cssInjected2 = false;
|
|
11182
11781
|
var STRINGS2 = {
|
|
11183
11782
|
"pt-BR": {
|
|
11184
11783
|
title: "Demanda",
|
|
@@ -11354,8 +11953,8 @@ ${rangeText}`;
|
|
|
11354
11953
|
}
|
|
11355
11954
|
return nextY;
|
|
11356
11955
|
}
|
|
11357
|
-
function
|
|
11358
|
-
if (
|
|
11956
|
+
function injectCSS2(styles) {
|
|
11957
|
+
if (cssInjected2) return;
|
|
11359
11958
|
const css = `
|
|
11360
11959
|
.myio-demand-modal-overlay {
|
|
11361
11960
|
position: fixed;
|
|
@@ -11750,7 +12349,7 @@ ${rangeText}`;
|
|
|
11750
12349
|
const style = document.createElement("style");
|
|
11751
12350
|
style.textContent = css;
|
|
11752
12351
|
document.head.appendChild(style);
|
|
11753
|
-
|
|
12352
|
+
cssInjected2 = true;
|
|
11754
12353
|
}
|
|
11755
12354
|
function formatDate2(date, locale) {
|
|
11756
12355
|
return date.toLocaleDateString(locale, {
|
|
@@ -11932,7 +12531,7 @@ ${rangeText}`;
|
|
|
11932
12531
|
const locale = params.locale || "pt-BR";
|
|
11933
12532
|
const strings = STRINGS2[locale] || STRINGS2["pt-BR"];
|
|
11934
12533
|
await loadExternalLibraries();
|
|
11935
|
-
|
|
12534
|
+
injectCSS2(styles);
|
|
11936
12535
|
const container = typeof params.container === "string" ? document.querySelector(params.container) : params.container || document.body;
|
|
11937
12536
|
if (!container) {
|
|
11938
12537
|
throw new Error("Container element not found");
|
|
@@ -21410,7 +22009,7 @@ ${rangeText}`;
|
|
|
21410
22009
|
placeholder = "Clique para selecionar per\xEDodo",
|
|
21411
22010
|
pickerOptions = {},
|
|
21412
22011
|
classNames = {},
|
|
21413
|
-
injectStyles = true,
|
|
22012
|
+
injectStyles: injectStyles2 = true,
|
|
21414
22013
|
showHelper = true
|
|
21415
22014
|
} = params;
|
|
21416
22015
|
validateId(containerId, "containerId");
|
|
@@ -21419,7 +22018,7 @@ ${rangeText}`;
|
|
|
21419
22018
|
if (!container) {
|
|
21420
22019
|
throw new Error(`[createInputDateRangePickerInsideDIV] Container '#${containerId}' not found`);
|
|
21421
22020
|
}
|
|
21422
|
-
if (
|
|
22021
|
+
if (injectStyles2) {
|
|
21423
22022
|
injectPremiumStyles();
|
|
21424
22023
|
}
|
|
21425
22024
|
let inputEl = document.getElementById(inputId);
|
|
@@ -21614,7 +22213,7 @@ ${rangeText}`;
|
|
|
21614
22213
|
modal.setAttribute("aria-labelledby", "goals-modal-title");
|
|
21615
22214
|
modal.innerHTML = generateModalHTML();
|
|
21616
22215
|
document.body.appendChild(modal);
|
|
21617
|
-
|
|
22216
|
+
injectStyles2();
|
|
21618
22217
|
attachEventListeners();
|
|
21619
22218
|
trapFocus(modal);
|
|
21620
22219
|
renderTabContent();
|
|
@@ -22367,7 +22966,7 @@ ${rangeText}`;
|
|
|
22367
22966
|
maximumFractionDigits: 2
|
|
22368
22967
|
}).format(value);
|
|
22369
22968
|
}
|
|
22370
|
-
function
|
|
22969
|
+
function injectStyles2() {
|
|
22371
22970
|
const styleId = "myio-goals-panel-styles";
|
|
22372
22971
|
if (document.getElementById(styleId)) return;
|
|
22373
22972
|
const style = document.createElement("style");
|
|
@@ -24624,7 +25223,7 @@ ${rangeText}`;
|
|
|
24624
25223
|
function getColors(theme) {
|
|
24625
25224
|
return theme === "dark" ? DARK_THEME2 : LIGHT_THEME2;
|
|
24626
25225
|
}
|
|
24627
|
-
async function fetchCustomerAttributes(customerId, token) {
|
|
25226
|
+
async function fetchCustomerAttributes(customerId, token, onError) {
|
|
24628
25227
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE`;
|
|
24629
25228
|
const response = await fetch(url, {
|
|
24630
25229
|
method: "GET",
|
|
@@ -24637,6 +25236,10 @@ ${rangeText}`;
|
|
|
24637
25236
|
if (response.status === 404 || response.status === 400) {
|
|
24638
25237
|
return { minTemperature: null, maxTemperature: null };
|
|
24639
25238
|
}
|
|
25239
|
+
if (onError) {
|
|
25240
|
+
onError({ status: response.status, message: `Failed to fetch attributes: ${response.status}` });
|
|
25241
|
+
return { minTemperature: null, maxTemperature: null };
|
|
25242
|
+
}
|
|
24640
25243
|
throw new Error(`Failed to fetch attributes: ${response.status}`);
|
|
24641
25244
|
}
|
|
24642
25245
|
const attributes = await response.json();
|
|
@@ -24653,7 +25256,7 @@ ${rangeText}`;
|
|
|
24653
25256
|
}
|
|
24654
25257
|
return { minTemperature, maxTemperature };
|
|
24655
25258
|
}
|
|
24656
|
-
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature) {
|
|
25259
|
+
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature, onError) {
|
|
24657
25260
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/SERVER_SCOPE`;
|
|
24658
25261
|
const attributes = {
|
|
24659
25262
|
minTemperature,
|
|
@@ -24668,6 +25271,10 @@ ${rangeText}`;
|
|
|
24668
25271
|
body: JSON.stringify(attributes)
|
|
24669
25272
|
});
|
|
24670
25273
|
if (!response.ok) {
|
|
25274
|
+
if (onError) {
|
|
25275
|
+
onError({ status: response.status, message: `Failed to save attributes: ${response.status}` });
|
|
25276
|
+
return;
|
|
25277
|
+
}
|
|
24671
25278
|
throw new Error(`Failed to save attributes: ${response.status}`);
|
|
24672
25279
|
}
|
|
24673
25280
|
}
|
|
@@ -25084,7 +25691,7 @@ ${rangeText}`;
|
|
|
25084
25691
|
state.successMessage = null;
|
|
25085
25692
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25086
25693
|
try {
|
|
25087
|
-
await saveCustomerAttributes(state.customerId, state.token, min, max);
|
|
25694
|
+
await saveCustomerAttributes(state.customerId, state.token, min, max, params.onError);
|
|
25088
25695
|
state.minTemperature = min;
|
|
25089
25696
|
state.maxTemperature = max;
|
|
25090
25697
|
state.isSaving = false;
|
|
@@ -25101,7 +25708,7 @@ ${rangeText}`;
|
|
|
25101
25708
|
}
|
|
25102
25709
|
};
|
|
25103
25710
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25104
|
-
fetchCustomerAttributes(state.customerId, state.token).then(({ minTemperature, maxTemperature }) => {
|
|
25711
|
+
fetchCustomerAttributes(state.customerId, state.token, params.onError).then(({ minTemperature, maxTemperature }) => {
|
|
25105
25712
|
state.minTemperature = minTemperature;
|
|
25106
25713
|
state.maxTemperature = maxTemperature;
|
|
25107
25714
|
state.isLoading = false;
|
|
@@ -27260,7 +27867,7 @@ ${rangeText}`;
|
|
|
27260
27867
|
</div>
|
|
27261
27868
|
`;
|
|
27262
27869
|
}
|
|
27263
|
-
function
|
|
27870
|
+
function injectStyles2() {
|
|
27264
27871
|
if (styleElement) return;
|
|
27265
27872
|
styleElement = document.createElement("style");
|
|
27266
27873
|
styleElement.id = `${widgetId}-styles`;
|
|
@@ -27741,7 +28348,7 @@ ${rangeText}`;
|
|
|
27741
28348
|
console.error(`[ConsumptionWidget] Container #${config.containerId} not found`);
|
|
27742
28349
|
return;
|
|
27743
28350
|
}
|
|
27744
|
-
|
|
28351
|
+
injectStyles2();
|
|
27745
28352
|
containerElement.innerHTML = renderHTML();
|
|
27746
28353
|
setupListeners();
|
|
27747
28354
|
setLoading(true);
|
|
@@ -28878,6 +29485,7 @@ ${rangeText}`;
|
|
|
28878
29485
|
exports.EXPORT_DOMAIN_ICONS = EXPORT_DOMAIN_ICONS;
|
|
28879
29486
|
exports.EXPORT_DOMAIN_LABELS = EXPORT_DOMAIN_LABELS;
|
|
28880
29487
|
exports.EXPORT_DOMAIN_UNITS = EXPORT_DOMAIN_UNITS;
|
|
29488
|
+
exports.EnergyRangeTooltip = EnergyRangeTooltip;
|
|
28881
29489
|
exports.MyIOChartModal = MyIOChartModal;
|
|
28882
29490
|
exports.MyIODraggableCard = MyIODraggableCard;
|
|
28883
29491
|
exports.MyIOSelectionStoreClass = MyIOSelectionStoreClass;
|
|
@@ -28885,6 +29493,7 @@ ${rangeText}`;
|
|
|
28885
29493
|
exports.POWER_LIMITS_DEVICE_TYPES = DEVICE_TYPES;
|
|
28886
29494
|
exports.POWER_LIMITS_STATUS_CONFIG = STATUS_CONFIG;
|
|
28887
29495
|
exports.POWER_LIMITS_TELEMETRY_TYPES = TELEMETRY_TYPES2;
|
|
29496
|
+
exports.TempRangeTooltip = TempRangeTooltip;
|
|
28888
29497
|
exports.addDetectionContext = addDetectionContext;
|
|
28889
29498
|
exports.addNamespace = addNamespace;
|
|
28890
29499
|
exports.aggregateByDay = aggregateByDay;
|