myio-js-library 0.1.180 → 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 +939 -328
- package/dist/index.d.cts +151 -1
- package/dist/index.js +937 -328
- package/dist/myio-js-library.umd.js +977 -363
- 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 ---
|
|
@@ -6970,29 +7568,34 @@
|
|
|
6970
7568
|
MyIOSelectionStore2.on("selection:change", onSelectionChange);
|
|
6971
7569
|
root._selectionListener = onSelectionChange;
|
|
6972
7570
|
}
|
|
6973
|
-
|
|
7571
|
+
const valueElement = root.querySelector(".myio-ho-card__value");
|
|
7572
|
+
if (entityObject.domain === "temperature" && valueElement) {
|
|
6974
7573
|
const showTooltip = (e) => {
|
|
6975
7574
|
TempRangeTooltip.show(root, state.entityObject, e);
|
|
6976
7575
|
};
|
|
6977
7576
|
const hideTooltip = () => {
|
|
6978
7577
|
TempRangeTooltip.hide();
|
|
6979
7578
|
};
|
|
6980
|
-
|
|
6981
|
-
|
|
7579
|
+
valueElement.style.cursor = "help";
|
|
7580
|
+
valueElement.addEventListener("mouseenter", showTooltip);
|
|
7581
|
+
valueElement.addEventListener("mouseleave", hideTooltip);
|
|
6982
7582
|
root._tempTooltipShowFn = showTooltip;
|
|
6983
7583
|
root._tempTooltipHideFn = hideTooltip;
|
|
7584
|
+
root._tooltipElement = valueElement;
|
|
6984
7585
|
}
|
|
6985
|
-
if (entityObject.domain === "energy") {
|
|
7586
|
+
if (entityObject.domain === "energy" && valueElement) {
|
|
6986
7587
|
const showEnergyTooltip = (e) => {
|
|
6987
7588
|
EnergyRangeTooltip.show(root, state.entityObject, e);
|
|
6988
7589
|
};
|
|
6989
7590
|
const hideEnergyTooltip = () => {
|
|
6990
7591
|
EnergyRangeTooltip.hide();
|
|
6991
7592
|
};
|
|
6992
|
-
|
|
6993
|
-
|
|
7593
|
+
valueElement.style.cursor = "help";
|
|
7594
|
+
valueElement.addEventListener("mouseenter", showEnergyTooltip);
|
|
7595
|
+
valueElement.addEventListener("mouseleave", hideEnergyTooltip);
|
|
6994
7596
|
root._energyTooltipShowFn = showEnergyTooltip;
|
|
6995
7597
|
root._energyTooltipHideFn = hideEnergyTooltip;
|
|
7598
|
+
root._tooltipElement = valueElement;
|
|
6996
7599
|
}
|
|
6997
7600
|
root._cleanup = () => {
|
|
6998
7601
|
document.removeEventListener("click", closeMenu);
|
|
@@ -7000,14 +7603,14 @@
|
|
|
7000
7603
|
if (MyIOSelectionStore2 && root._selectionListener) {
|
|
7001
7604
|
MyIOSelectionStore2.off("selection:change", root._selectionListener);
|
|
7002
7605
|
}
|
|
7003
|
-
if (root._tempTooltipShowFn) {
|
|
7004
|
-
root.removeEventListener("mouseenter", root._tempTooltipShowFn);
|
|
7005
|
-
root.removeEventListener("mouseleave", root._tempTooltipHideFn);
|
|
7606
|
+
if (root._tempTooltipShowFn && root._tooltipElement) {
|
|
7607
|
+
root._tooltipElement.removeEventListener("mouseenter", root._tempTooltipShowFn);
|
|
7608
|
+
root._tooltipElement.removeEventListener("mouseleave", root._tempTooltipHideFn);
|
|
7006
7609
|
TempRangeTooltip.hide();
|
|
7007
7610
|
}
|
|
7008
|
-
if (root._energyTooltipShowFn) {
|
|
7009
|
-
root.removeEventListener("mouseenter", root._energyTooltipShowFn);
|
|
7010
|
-
root.removeEventListener("mouseleave", root._energyTooltipHideFn);
|
|
7611
|
+
if (root._energyTooltipShowFn && root._tooltipElement) {
|
|
7612
|
+
root._tooltipElement.removeEventListener("mouseenter", root._energyTooltipShowFn);
|
|
7613
|
+
root._tooltipElement.removeEventListener("mouseleave", root._energyTooltipHideFn);
|
|
7011
7614
|
EnergyRangeTooltip.hide();
|
|
7012
7615
|
}
|
|
7013
7616
|
};
|
|
@@ -7560,6 +8163,7 @@
|
|
|
7560
8163
|
};
|
|
7561
8164
|
const isTankDevice = deviceType === "TANK" || deviceType === "CAIXA_DAGUA";
|
|
7562
8165
|
const isTermostatoDevice = deviceType?.toUpperCase() === "TERMOSTATO";
|
|
8166
|
+
const isEnergyDeviceFlag = isEnergyDevice(deviceType);
|
|
7563
8167
|
const percentageForDisplay = isTankDevice ? (waterPercentage || 0) * 100 : perc;
|
|
7564
8168
|
const calculateTempStatus = () => {
|
|
7565
8169
|
if (temperatureStatus) return temperatureStatus;
|
|
@@ -7576,33 +8180,6 @@
|
|
|
7576
8180
|
tempStatus,
|
|
7577
8181
|
isOffline
|
|
7578
8182
|
});
|
|
7579
|
-
const getTemperatureTooltip = () => {
|
|
7580
|
-
if (!isTermostatoDevice) return "";
|
|
7581
|
-
const currentTemp = Number(val) || 0;
|
|
7582
|
-
const hasRange = temperatureMin !== void 0 && temperatureMax !== void 0 && temperatureMin !== null && temperatureMax !== null;
|
|
7583
|
-
if (isOffline) {
|
|
7584
|
-
return "Dispositivo offline";
|
|
7585
|
-
}
|
|
7586
|
-
if (!hasRange) {
|
|
7587
|
-
return `Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7588
|
-
Faixa n\xE3o configurada`;
|
|
7589
|
-
}
|
|
7590
|
-
const rangeText = `Faixa ideal: ${temperatureMin}\xB0C a ${temperatureMax}\xB0C`;
|
|
7591
|
-
if (tempStatus === "above") {
|
|
7592
|
-
return `ACIMA da faixa ideal
|
|
7593
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7594
|
-
${rangeText}`;
|
|
7595
|
-
} else if (tempStatus === "below") {
|
|
7596
|
-
return `ABAIXO da faixa ideal
|
|
7597
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7598
|
-
${rangeText}`;
|
|
7599
|
-
} else {
|
|
7600
|
-
return `DENTRO da faixa ideal
|
|
7601
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7602
|
-
${rangeText}`;
|
|
7603
|
-
}
|
|
7604
|
-
};
|
|
7605
|
-
const temperatureTooltip = getTemperatureTooltip();
|
|
7606
8183
|
const cardHTML = `
|
|
7607
8184
|
<div class="device-card-centered clickable ${cardEntity.status === "offline" ? "offline" : ""}"
|
|
7608
8185
|
data-entity-id="${entityId}"
|
|
@@ -7628,7 +8205,7 @@ ${rangeText}`;
|
|
|
7628
8205
|
` : ""}
|
|
7629
8206
|
</div>
|
|
7630
8207
|
|
|
7631
|
-
<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;" : ""}" />
|
|
7632
8209
|
|
|
7633
8210
|
|
|
7634
8211
|
${customerName && String(customerName).trim() !== "" ? `
|
|
@@ -8192,6 +8769,33 @@ ${rangeText}`;
|
|
|
8192
8769
|
}
|
|
8193
8770
|
});
|
|
8194
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
|
+
};
|
|
8195
8799
|
const jQueryLikeObject = {
|
|
8196
8800
|
get: (index) => index === 0 ? container : void 0,
|
|
8197
8801
|
0: container,
|
|
@@ -11173,7 +11777,7 @@ ${rangeText}`;
|
|
|
11173
11777
|
var zoomPluginLoaded = false;
|
|
11174
11778
|
var jsPdfLoaded = false;
|
|
11175
11779
|
var _jspdfPromise = null;
|
|
11176
|
-
var
|
|
11780
|
+
var cssInjected2 = false;
|
|
11177
11781
|
var STRINGS2 = {
|
|
11178
11782
|
"pt-BR": {
|
|
11179
11783
|
title: "Demanda",
|
|
@@ -11349,8 +11953,8 @@ ${rangeText}`;
|
|
|
11349
11953
|
}
|
|
11350
11954
|
return nextY;
|
|
11351
11955
|
}
|
|
11352
|
-
function
|
|
11353
|
-
if (
|
|
11956
|
+
function injectCSS2(styles) {
|
|
11957
|
+
if (cssInjected2) return;
|
|
11354
11958
|
const css = `
|
|
11355
11959
|
.myio-demand-modal-overlay {
|
|
11356
11960
|
position: fixed;
|
|
@@ -11745,7 +12349,7 @@ ${rangeText}`;
|
|
|
11745
12349
|
const style = document.createElement("style");
|
|
11746
12350
|
style.textContent = css;
|
|
11747
12351
|
document.head.appendChild(style);
|
|
11748
|
-
|
|
12352
|
+
cssInjected2 = true;
|
|
11749
12353
|
}
|
|
11750
12354
|
function formatDate2(date, locale) {
|
|
11751
12355
|
return date.toLocaleDateString(locale, {
|
|
@@ -11927,7 +12531,7 @@ ${rangeText}`;
|
|
|
11927
12531
|
const locale = params.locale || "pt-BR";
|
|
11928
12532
|
const strings = STRINGS2[locale] || STRINGS2["pt-BR"];
|
|
11929
12533
|
await loadExternalLibraries();
|
|
11930
|
-
|
|
12534
|
+
injectCSS2(styles);
|
|
11931
12535
|
const container = typeof params.container === "string" ? document.querySelector(params.container) : params.container || document.body;
|
|
11932
12536
|
if (!container) {
|
|
11933
12537
|
throw new Error("Container element not found");
|
|
@@ -21405,7 +22009,7 @@ ${rangeText}`;
|
|
|
21405
22009
|
placeholder = "Clique para selecionar per\xEDodo",
|
|
21406
22010
|
pickerOptions = {},
|
|
21407
22011
|
classNames = {},
|
|
21408
|
-
injectStyles = true,
|
|
22012
|
+
injectStyles: injectStyles2 = true,
|
|
21409
22013
|
showHelper = true
|
|
21410
22014
|
} = params;
|
|
21411
22015
|
validateId(containerId, "containerId");
|
|
@@ -21414,7 +22018,7 @@ ${rangeText}`;
|
|
|
21414
22018
|
if (!container) {
|
|
21415
22019
|
throw new Error(`[createInputDateRangePickerInsideDIV] Container '#${containerId}' not found`);
|
|
21416
22020
|
}
|
|
21417
|
-
if (
|
|
22021
|
+
if (injectStyles2) {
|
|
21418
22022
|
injectPremiumStyles();
|
|
21419
22023
|
}
|
|
21420
22024
|
let inputEl = document.getElementById(inputId);
|
|
@@ -21609,7 +22213,7 @@ ${rangeText}`;
|
|
|
21609
22213
|
modal.setAttribute("aria-labelledby", "goals-modal-title");
|
|
21610
22214
|
modal.innerHTML = generateModalHTML();
|
|
21611
22215
|
document.body.appendChild(modal);
|
|
21612
|
-
|
|
22216
|
+
injectStyles2();
|
|
21613
22217
|
attachEventListeners();
|
|
21614
22218
|
trapFocus(modal);
|
|
21615
22219
|
renderTabContent();
|
|
@@ -22362,7 +22966,7 @@ ${rangeText}`;
|
|
|
22362
22966
|
maximumFractionDigits: 2
|
|
22363
22967
|
}).format(value);
|
|
22364
22968
|
}
|
|
22365
|
-
function
|
|
22969
|
+
function injectStyles2() {
|
|
22366
22970
|
const styleId = "myio-goals-panel-styles";
|
|
22367
22971
|
if (document.getElementById(styleId)) return;
|
|
22368
22972
|
const style = document.createElement("style");
|
|
@@ -24619,7 +25223,7 @@ ${rangeText}`;
|
|
|
24619
25223
|
function getColors(theme) {
|
|
24620
25224
|
return theme === "dark" ? DARK_THEME2 : LIGHT_THEME2;
|
|
24621
25225
|
}
|
|
24622
|
-
async function fetchCustomerAttributes(customerId, token) {
|
|
25226
|
+
async function fetchCustomerAttributes(customerId, token, onError) {
|
|
24623
25227
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE`;
|
|
24624
25228
|
const response = await fetch(url, {
|
|
24625
25229
|
method: "GET",
|
|
@@ -24632,6 +25236,10 @@ ${rangeText}`;
|
|
|
24632
25236
|
if (response.status === 404 || response.status === 400) {
|
|
24633
25237
|
return { minTemperature: null, maxTemperature: null };
|
|
24634
25238
|
}
|
|
25239
|
+
if (onError) {
|
|
25240
|
+
onError({ status: response.status, message: `Failed to fetch attributes: ${response.status}` });
|
|
25241
|
+
return { minTemperature: null, maxTemperature: null };
|
|
25242
|
+
}
|
|
24635
25243
|
throw new Error(`Failed to fetch attributes: ${response.status}`);
|
|
24636
25244
|
}
|
|
24637
25245
|
const attributes = await response.json();
|
|
@@ -24648,7 +25256,7 @@ ${rangeText}`;
|
|
|
24648
25256
|
}
|
|
24649
25257
|
return { minTemperature, maxTemperature };
|
|
24650
25258
|
}
|
|
24651
|
-
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature) {
|
|
25259
|
+
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature, onError) {
|
|
24652
25260
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/SERVER_SCOPE`;
|
|
24653
25261
|
const attributes = {
|
|
24654
25262
|
minTemperature,
|
|
@@ -24663,6 +25271,10 @@ ${rangeText}`;
|
|
|
24663
25271
|
body: JSON.stringify(attributes)
|
|
24664
25272
|
});
|
|
24665
25273
|
if (!response.ok) {
|
|
25274
|
+
if (onError) {
|
|
25275
|
+
onError({ status: response.status, message: `Failed to save attributes: ${response.status}` });
|
|
25276
|
+
return;
|
|
25277
|
+
}
|
|
24666
25278
|
throw new Error(`Failed to save attributes: ${response.status}`);
|
|
24667
25279
|
}
|
|
24668
25280
|
}
|
|
@@ -25079,7 +25691,7 @@ ${rangeText}`;
|
|
|
25079
25691
|
state.successMessage = null;
|
|
25080
25692
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25081
25693
|
try {
|
|
25082
|
-
await saveCustomerAttributes(state.customerId, state.token, min, max);
|
|
25694
|
+
await saveCustomerAttributes(state.customerId, state.token, min, max, params.onError);
|
|
25083
25695
|
state.minTemperature = min;
|
|
25084
25696
|
state.maxTemperature = max;
|
|
25085
25697
|
state.isSaving = false;
|
|
@@ -25096,7 +25708,7 @@ ${rangeText}`;
|
|
|
25096
25708
|
}
|
|
25097
25709
|
};
|
|
25098
25710
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25099
|
-
fetchCustomerAttributes(state.customerId, state.token).then(({ minTemperature, maxTemperature }) => {
|
|
25711
|
+
fetchCustomerAttributes(state.customerId, state.token, params.onError).then(({ minTemperature, maxTemperature }) => {
|
|
25100
25712
|
state.minTemperature = minTemperature;
|
|
25101
25713
|
state.maxTemperature = maxTemperature;
|
|
25102
25714
|
state.isLoading = false;
|
|
@@ -27255,7 +27867,7 @@ ${rangeText}`;
|
|
|
27255
27867
|
</div>
|
|
27256
27868
|
`;
|
|
27257
27869
|
}
|
|
27258
|
-
function
|
|
27870
|
+
function injectStyles2() {
|
|
27259
27871
|
if (styleElement) return;
|
|
27260
27872
|
styleElement = document.createElement("style");
|
|
27261
27873
|
styleElement.id = `${widgetId}-styles`;
|
|
@@ -27736,7 +28348,7 @@ ${rangeText}`;
|
|
|
27736
28348
|
console.error(`[ConsumptionWidget] Container #${config.containerId} not found`);
|
|
27737
28349
|
return;
|
|
27738
28350
|
}
|
|
27739
|
-
|
|
28351
|
+
injectStyles2();
|
|
27740
28352
|
containerElement.innerHTML = renderHTML();
|
|
27741
28353
|
setupListeners();
|
|
27742
28354
|
setLoading(true);
|
|
@@ -28873,6 +29485,7 @@ ${rangeText}`;
|
|
|
28873
29485
|
exports.EXPORT_DOMAIN_ICONS = EXPORT_DOMAIN_ICONS;
|
|
28874
29486
|
exports.EXPORT_DOMAIN_LABELS = EXPORT_DOMAIN_LABELS;
|
|
28875
29487
|
exports.EXPORT_DOMAIN_UNITS = EXPORT_DOMAIN_UNITS;
|
|
29488
|
+
exports.EnergyRangeTooltip = EnergyRangeTooltip;
|
|
28876
29489
|
exports.MyIOChartModal = MyIOChartModal;
|
|
28877
29490
|
exports.MyIODraggableCard = MyIODraggableCard;
|
|
28878
29491
|
exports.MyIOSelectionStoreClass = MyIOSelectionStoreClass;
|
|
@@ -28880,6 +29493,7 @@ ${rangeText}`;
|
|
|
28880
29493
|
exports.POWER_LIMITS_DEVICE_TYPES = DEVICE_TYPES;
|
|
28881
29494
|
exports.POWER_LIMITS_STATUS_CONFIG = STATUS_CONFIG;
|
|
28882
29495
|
exports.POWER_LIMITS_TELEMETRY_TYPES = TELEMETRY_TYPES2;
|
|
29496
|
+
exports.TempRangeTooltip = TempRangeTooltip;
|
|
28883
29497
|
exports.addDetectionContext = addDetectionContext;
|
|
28884
29498
|
exports.addNamespace = addNamespace;
|
|
28885
29499
|
exports.aggregateByDay = aggregateByDay;
|