myio-js-library 0.1.490 → 0.1.491
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 +585 -31
- package/dist/index.js +585 -31
- package/dist/myio-js-library.umd.js +585 -31
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1162,7 +1162,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1162
1162
|
// package.json
|
|
1163
1163
|
var package_default = {
|
|
1164
1164
|
name: "myio-js-library",
|
|
1165
|
-
version: "0.1.
|
|
1165
|
+
version: "0.1.491",
|
|
1166
1166
|
description: "A clean, standalone JS SDK for MYIO projects",
|
|
1167
1167
|
license: "MIT",
|
|
1168
1168
|
repository: "github:gh-myio/myio-js-library",
|
|
@@ -84027,7 +84027,10 @@ function openUpsellModal(params) {
|
|
|
84027
84027
|
bulkRelationModal: { open: false, target: "CUSTOMER", selectedAssetId: "", selectedAssetName: "", search: "", newAssetName: "", assetsLoaded: false, overrideCustomerId: "", overrideCustomerName: "", customerSearch: "", customerPickerOpen: false },
|
|
84028
84028
|
checkFixLoading: false,
|
|
84029
84029
|
checkFixReport: null,
|
|
84030
|
-
checkFixFilter: "all"
|
|
84030
|
+
checkFixFilter: "all",
|
|
84031
|
+
checkFixSort: { field: "name", order: "asc" },
|
|
84032
|
+
checkFixAdvancedFilter: { statuses: [], connStatuses: [], domains: [], missingIngestionId: false, missingCentralSlave: false },
|
|
84033
|
+
checkFixFilterOpen: false
|
|
84031
84034
|
};
|
|
84032
84035
|
const savedTheme = localStorage.getItem("myio-upsell-modal-theme");
|
|
84033
84036
|
if (savedTheme) state6.theme = savedTheme;
|
|
@@ -84166,6 +84169,12 @@ function renderModal4(container, state6, modalId, t, error) {
|
|
|
84166
84169
|
font-size: 14px; font-weight: 500; font-family: 'Roboto', Arial, sans-serif;
|
|
84167
84170
|
display: flex; align-items: center; gap: 6px;
|
|
84168
84171
|
" ${!state6.selectedCustomer ? 'disabled title="Selecione um Customer primeiro"' : ""}>\u{1F517} For\xE7ar Rela\xE7\xE3o (${state6.selectedDevices.length})</button>
|
|
84172
|
+
<button id="${modalId}-clear-gcdr-ids" style="
|
|
84173
|
+
background: #dc2626; color: white; border: none;
|
|
84174
|
+
padding: 8px 16px; border-radius: 6px; cursor: pointer;
|
|
84175
|
+
font-size: 14px; font-weight: 500; font-family: 'Roboto', Arial, sans-serif;
|
|
84176
|
+
display: flex; align-items: center; gap: 6px;
|
|
84177
|
+
" ${!state6.selectedCustomer ? 'disabled title="Selecione um Customer primeiro"' : ""}>\u{1F9F9} Clear GCDR IDs</button>
|
|
84169
84178
|
<button id="${modalId}-custom-shortcut" style="
|
|
84170
84179
|
background: #ef4444; color: white; border: none;
|
|
84171
84180
|
padding: 8px 16px; border-radius: 6px; cursor: pointer;
|
|
@@ -84832,6 +84841,29 @@ function renderStep1(state6, modalId, colors2, t) {
|
|
|
84832
84841
|
</div>
|
|
84833
84842
|
`;
|
|
84834
84843
|
}
|
|
84844
|
+
function _buildCfStatusDetail(r) {
|
|
84845
|
+
if (r.status === "ok") return "";
|
|
84846
|
+
const lines = [];
|
|
84847
|
+
if (r.status === "mismatch") {
|
|
84848
|
+
if (r.actual.type !== r.inferred.deviceType)
|
|
84849
|
+
lines.push(`TYPE: actual="${r.actual.type}" \u2260 expected="${r.inferred.deviceType}"`);
|
|
84850
|
+
if (r.actual.deviceType !== r.inferred.deviceType)
|
|
84851
|
+
lines.push(`deviceType: actual="${r.actual.deviceType}" \u2260 expected="${r.inferred.deviceType}"`);
|
|
84852
|
+
if (r.actual.deviceProfile !== r.inferred.deviceProfile)
|
|
84853
|
+
lines.push(`deviceProfile: actual="${r.actual.deviceProfile}" \u2260 expected="${r.inferred.deviceProfile}"`);
|
|
84854
|
+
} else if (r.status === "missing") {
|
|
84855
|
+
if (!r.actual.type) lines.push("TYPE: n\xE3o definido");
|
|
84856
|
+
if (!r.actual.deviceType) lines.push("deviceType: n\xE3o definido");
|
|
84857
|
+
if (!r.actual.deviceProfile) lines.push("deviceProfile: n\xE3o definido");
|
|
84858
|
+
} else if (r.status === "undefined") {
|
|
84859
|
+
lines.push(`Nome n\xE3o permite inferir o tipo de dispositivo: "${r.deviceName}"`);
|
|
84860
|
+
lines.push("Use Check & Fix manual ou ajuste o nome do dispositivo.");
|
|
84861
|
+
}
|
|
84862
|
+
if (!r.ingestionId) lines.push("ingestionId: ausente (n\xE3o integrado ao backend de ingest\xE3o)");
|
|
84863
|
+
if (!r.centralId) lines.push("centralId: ausente");
|
|
84864
|
+
if (r.connStatus === "offline") lines.push("Dispositivo offline no momento");
|
|
84865
|
+
return lines.join("\n") || r.status;
|
|
84866
|
+
}
|
|
84835
84867
|
function renderCheckFixRow(r, state6, modalId, colors2, dupPairIds, dupIngestionIds) {
|
|
84836
84868
|
const isSelectedSingle = state6.deviceSelectionMode === "single" && getEntityId(state6.selectedDevice) === r.deviceId;
|
|
84837
84869
|
const isSelectedMulti = state6.deviceSelectionMode === "multi" && state6.selectedDevices.some((d) => getEntityId(d) === r.deviceId);
|
|
@@ -84895,7 +84927,10 @@ function renderCheckFixRow(r, state6, modalId, colors2, dupPairIds, dupIngestion
|
|
|
84895
84927
|
<td style="${cell(dupIngestionIds.has(r.deviceId) ? "bad" : "none")} font-size:9px; font-family:monospace; max-width:110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${r.ingestionId || ""}">${r.ingestionId || dash}</td>
|
|
84896
84928
|
<td style="${cell(dupPairIds.has(r.deviceId) ? "bad" : "none")} font-size:9px; font-family:monospace; max-width:80px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${r.centralId || ""}">${r.centralId || dash}</td>
|
|
84897
84929
|
<td style="${cell(dupPairIds.has(r.deviceId) ? "bad" : "none")} font-size:9px; font-family:monospace; max-width:50px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${r.slaveId || dash}</td>
|
|
84898
|
-
<td style="padding:4px 6px; font-size:10px; color:${STATUS_COLOR[r.status]}; font-weight:700; white-space:nowrap;
|
|
84930
|
+
<td style="padding:4px 6px; font-size:10px; color:${STATUS_COLOR[r.status]}; font-weight:700; white-space:nowrap; cursor:${r.status !== "ok" ? "help" : "default"};"
|
|
84931
|
+
${r.status !== "ok" ? `data-cf-status="${r.status}" data-cf-device="${encodeURIComponent(r.deviceName)}" data-cf-detail="${encodeURIComponent(_buildCfStatusDetail(r))}"` : ""}>
|
|
84932
|
+
${STATUS_ICON[r.status]} ${r.status}
|
|
84933
|
+
</td>
|
|
84899
84934
|
</tr>`;
|
|
84900
84935
|
}
|
|
84901
84936
|
function renderStep2(state6, modalId, colors2, t) {
|
|
@@ -85182,7 +85217,42 @@ function renderStep2(state6, modalId, colors2, t) {
|
|
|
85182
85217
|
const multiCol = state6.deviceSelectionMode === "multi";
|
|
85183
85218
|
if (state6.checkFixReport) {
|
|
85184
85219
|
const idToRecord = new Map(state6.checkFixReport.records.map((r) => [r.deviceId, r]));
|
|
85185
|
-
|
|
85220
|
+
let cfRows = sortedDevices.map((d) => idToRecord.get(getEntityId(d))).filter((r) => r !== void 0).filter((r) => state6.checkFixFilter === "all" || r.status === state6.checkFixFilter);
|
|
85221
|
+
const af = state6.checkFixAdvancedFilter;
|
|
85222
|
+
if (af.statuses.length > 0) cfRows = cfRows.filter((r) => af.statuses.includes(r.status));
|
|
85223
|
+
if (af.connStatuses.length > 0) cfRows = cfRows.filter((r) => af.connStatuses.includes(r.connStatus || "null"));
|
|
85224
|
+
if (af.domains.length > 0) cfRows = cfRows.filter((r) => af.domains.includes(r.domain || "null"));
|
|
85225
|
+
if (af.missingIngestionId) cfRows = cfRows.filter((r) => !r.ingestionId);
|
|
85226
|
+
if (af.missingCentralSlave) cfRows = cfRows.filter((r) => !r.centralId || r.slaveId == null);
|
|
85227
|
+
const cfSortField = state6.checkFixSort.field;
|
|
85228
|
+
const cfSortOrder = state6.checkFixSort.order;
|
|
85229
|
+
cfRows = [...cfRows].sort((a, b) => {
|
|
85230
|
+
let va = "", vb = "";
|
|
85231
|
+
if (cfSortField === "name") {
|
|
85232
|
+
va = a.deviceName || "";
|
|
85233
|
+
vb = b.deviceName || "";
|
|
85234
|
+
} else if (cfSortField === "status") {
|
|
85235
|
+
va = a.status || "";
|
|
85236
|
+
vb = b.status || "";
|
|
85237
|
+
} else if (cfSortField === "connStatus") {
|
|
85238
|
+
va = a.connStatus || "";
|
|
85239
|
+
vb = b.connStatus || "";
|
|
85240
|
+
} else if (cfSortField === "deviceType") {
|
|
85241
|
+
va = a.actual.deviceType || "";
|
|
85242
|
+
vb = b.actual.deviceType || "";
|
|
85243
|
+
} else if (cfSortField === "deviceProfile") {
|
|
85244
|
+
va = a.actual.deviceProfile || "";
|
|
85245
|
+
vb = b.actual.deviceProfile || "";
|
|
85246
|
+
} else if (cfSortField === "ingestionId") {
|
|
85247
|
+
va = a.ingestionId || "";
|
|
85248
|
+
vb = b.ingestionId || "";
|
|
85249
|
+
} else if (cfSortField === "domain") {
|
|
85250
|
+
va = a.domain || "";
|
|
85251
|
+
vb = b.domain || "";
|
|
85252
|
+
}
|
|
85253
|
+
const cmp = va.toLowerCase().localeCompare(vb.toLowerCase());
|
|
85254
|
+
return cfSortOrder === "asc" ? cmp : -cmp;
|
|
85255
|
+
});
|
|
85186
85256
|
const pairCount = /* @__PURE__ */ new Map();
|
|
85187
85257
|
cfRows.forEach((r) => {
|
|
85188
85258
|
if (r.centralId && r.slaveId != null) {
|
|
@@ -85207,27 +85277,115 @@ function renderStep2(state6, modalId, colors2, t) {
|
|
|
85207
85277
|
if (ids.length > 1) ids.forEach((id) => dupIngestionIds.add(id));
|
|
85208
85278
|
});
|
|
85209
85279
|
const colSpan = multiCol ? 18 : 17;
|
|
85280
|
+
const cfSortHeader = (field, label, rowspan = 1, extraStyle = "") => {
|
|
85281
|
+
const isActive = state6.checkFixSort.field === field;
|
|
85282
|
+
const arrow = isActive ? state6.checkFixSort.order === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
|
|
85283
|
+
return `<th ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} id="${modalId}-cf-sort-${field}" data-cf-sort="${field}" style="${thStyle(extraStyle)} cursor:pointer; user-select:none; ${isActive ? `background:rgba(62,26,125,0.18);` : ""}">
|
|
85284
|
+
<span style="display:flex;align-items:center;gap:3px;white-space:nowrap;">${label}<span style="font-size:7px;color:${isActive ? MYIO_PURPLE : colors2.textMuted};">${arrow}</span></span>
|
|
85285
|
+
</th>`;
|
|
85286
|
+
};
|
|
85287
|
+
const allDomains = [...new Set(state6.checkFixReport.records.map((r) => r.domain || "null"))].sort();
|
|
85288
|
+
const allConns = [...new Set(state6.checkFixReport.records.map((r) => r.connStatus || "null"))].sort();
|
|
85289
|
+
const hasAdvFilter = af.statuses.length > 0 || af.connStatuses.length > 0 || af.domains.length > 0 || af.missingIngestionId || af.missingCentralSlave;
|
|
85290
|
+
const filterPanel = state6.checkFixFilterOpen ? `
|
|
85291
|
+
<div id="${modalId}-cf-filter-panel" style="
|
|
85292
|
+
position:absolute; top:calc(100% + 4px); right:0; z-index:200;
|
|
85293
|
+
background:${colors2.cardBg}; border:1px solid ${colors2.border}; border-radius:10px;
|
|
85294
|
+
box-shadow:0 8px 32px rgba(0,0,0,0.22); padding:16px; min-width:300px;
|
|
85295
|
+
font-size:11px; color:${colors2.text};
|
|
85296
|
+
">
|
|
85297
|
+
<div style="font-weight:700; font-size:12px; margin-bottom:12px; color:${colors2.text};">\u{1F527} Filtros Avan\xE7ados \u2014 Check & Fix</div>
|
|
85298
|
+
<div style="margin-bottom:10px;">
|
|
85299
|
+
<div style="font-weight:600; margin-bottom:4px; color:${colors2.textMuted}; text-transform:uppercase; font-size:9px;">Status</div>
|
|
85300
|
+
<div style="display:flex;gap:6px;flex-wrap:wrap;">
|
|
85301
|
+
${["ok", "mismatch", "missing", "undefined"].map((s) => {
|
|
85302
|
+
const icons = { ok: "\u2705", mismatch: "\u26A0\uFE0F", missing: "\u274C", undefined: "\u2753" };
|
|
85303
|
+
const active = af.statuses.includes(s);
|
|
85304
|
+
return `<button data-cf-flt-status="${s}" style="padding:3px 8px;border-radius:4px;font-size:10px;cursor:pointer;border:1px solid ${active ? MYIO_PURPLE : colors2.border};background:${active ? MYIO_PURPLE : colors2.inputBg};color:${active ? "white" : colors2.text};">${icons[s]} ${s}</button>`;
|
|
85305
|
+
}).join("")}
|
|
85306
|
+
</div>
|
|
85307
|
+
</div>
|
|
85308
|
+
<div style="margin-bottom:10px;">
|
|
85309
|
+
<div style="font-weight:600; margin-bottom:4px; color:${colors2.textMuted}; text-transform:uppercase; font-size:9px;">Conn. Status</div>
|
|
85310
|
+
<div style="display:flex;gap:6px;flex-wrap:wrap;">
|
|
85311
|
+
${allConns.map((c) => {
|
|
85312
|
+
const active = af.connStatuses.includes(c);
|
|
85313
|
+
return `<button data-cf-flt-conn="${c}" style="padding:3px 8px;border-radius:4px;font-size:10px;cursor:pointer;border:1px solid ${active ? MYIO_PURPLE : colors2.border};background:${active ? MYIO_PURPLE : colors2.inputBg};color:${active ? "white" : colors2.text};">${c}</button>`;
|
|
85314
|
+
}).join("")}
|
|
85315
|
+
</div>
|
|
85316
|
+
</div>
|
|
85317
|
+
<div style="margin-bottom:10px;">
|
|
85318
|
+
<div style="font-weight:600; margin-bottom:4px; color:${colors2.textMuted}; text-transform:uppercase; font-size:9px;">Domain</div>
|
|
85319
|
+
<div style="display:flex;gap:6px;flex-wrap:wrap;">
|
|
85320
|
+
${allDomains.map((d) => {
|
|
85321
|
+
const active = af.domains.includes(d);
|
|
85322
|
+
return `<button data-cf-flt-domain="${d}" style="padding:3px 8px;border-radius:4px;font-size:10px;cursor:pointer;border:1px solid ${active ? MYIO_PURPLE : colors2.border};background:${active ? MYIO_PURPLE : colors2.inputBg};color:${active ? "white" : colors2.text};">${d}</button>`;
|
|
85323
|
+
}).join("")}
|
|
85324
|
+
</div>
|
|
85325
|
+
</div>
|
|
85326
|
+
<div style="margin-bottom:12px;display:flex;gap:12px;flex-wrap:wrap;">
|
|
85327
|
+
<label style="display:flex;align-items:center;gap:5px;cursor:pointer;">
|
|
85328
|
+
<input type="checkbox" id="${modalId}-cf-flt-noing" ${af.missingIngestionId ? "checked" : ""} style="accent-color:${MYIO_PURPLE};"/>
|
|
85329
|
+
<span>Sem ingestionId</span>
|
|
85330
|
+
</label>
|
|
85331
|
+
<label style="display:flex;align-items:center;gap:5px;cursor:pointer;">
|
|
85332
|
+
<input type="checkbox" id="${modalId}-cf-flt-nocentral" ${af.missingCentralSlave ? "checked" : ""} style="accent-color:${MYIO_PURPLE};"/>
|
|
85333
|
+
<span>Sem centralId/slaveId</span>
|
|
85334
|
+
</label>
|
|
85335
|
+
</div>
|
|
85336
|
+
<div style="display:flex;gap:8px;justify-content:flex-end;">
|
|
85337
|
+
<button id="${modalId}-cf-flt-clear" style="padding:5px 12px;border-radius:5px;font-size:11px;cursor:pointer;background:transparent;border:1px solid ${colors2.border};color:${colors2.textMuted};">Limpar</button>
|
|
85338
|
+
<button id="${modalId}-cf-flt-close" style="padding:5px 12px;border-radius:5px;font-size:11px;cursor:pointer;background:${MYIO_PURPLE};border:none;color:white;font-weight:600;">Fechar</button>
|
|
85339
|
+
</div>
|
|
85340
|
+
</div>
|
|
85341
|
+
` : "";
|
|
85210
85342
|
return `
|
|
85343
|
+
<div style="position:relative;">
|
|
85344
|
+
<div style="display:flex;align-items:center;gap:6px;margin-bottom:6px;flex-wrap:wrap;">
|
|
85345
|
+
<span style="font-size:10px;color:${colors2.textMuted};">${cfRows.length} / ${state6.checkFixReport.records.length} registros</span>
|
|
85346
|
+
<div style="position:relative;margin-left:auto;">
|
|
85347
|
+
<button id="${modalId}-cf-filter-btn" style="padding:3px 10px;border-radius:5px;font-size:10px;cursor:pointer;border:1px solid ${hasAdvFilter ? MYIO_PURPLE : colors2.border};background:${hasAdvFilter ? MYIO_PURPLE : colors2.inputBg};color:${hasAdvFilter ? "white" : colors2.text};font-weight:${hasAdvFilter ? "700" : "400"};">
|
|
85348
|
+
\u{1F527} Filtros${hasAdvFilter ? ` (${af.statuses.length + af.connStatuses.length + af.domains.length + (af.missingIngestionId ? 1 : 0) + (af.missingCentralSlave ? 1 : 0)})` : ""}
|
|
85349
|
+
</button>
|
|
85350
|
+
${filterPanel}
|
|
85351
|
+
</div>
|
|
85352
|
+
</div>
|
|
85211
85353
|
<div id="${modalId}-device-list" style="
|
|
85212
85354
|
overflow-x:auto; max-height:${gridHeight};
|
|
85213
85355
|
border:1px solid ${colors2.border}; border-radius:8px; background:${colors2.surface};
|
|
85214
85356
|
">
|
|
85215
|
-
<table style="border-collapse:collapse;
|
|
85357
|
+
<table style="border-collapse:collapse; table-layout:fixed; width:100%; min-width:1100px;">
|
|
85358
|
+
<colgroup>
|
|
85359
|
+
${multiCol ? `<col style="width:28px"/>` : ""}
|
|
85360
|
+
<col style="width:150px"/>
|
|
85361
|
+
<col style="width:95px"/>
|
|
85362
|
+
<col style="width:70px"/><col style="width:70px"/>
|
|
85363
|
+
<col style="width:90px"/><col style="width:90px"/>
|
|
85364
|
+
<col style="width:90px"/><col style="width:90px"/>
|
|
85365
|
+
<col style="width:85px"/>
|
|
85366
|
+
<col style="width:110px"/>
|
|
85367
|
+
<col style="width:70px"/>
|
|
85368
|
+
<col style="width:110px"/>
|
|
85369
|
+
<col style="width:110px"/>
|
|
85370
|
+
<col style="width:80px"/>
|
|
85371
|
+
<col style="width:50px"/>
|
|
85372
|
+
<col style="width:90px"/>
|
|
85373
|
+
</colgroup>
|
|
85216
85374
|
<thead>
|
|
85217
85375
|
<tr>
|
|
85218
85376
|
${multiCol ? `<th rowspan="2" style="${thStyle("width:28px")}">\u2611</th>` : ""}
|
|
85219
|
-
|
|
85377
|
+
${cfSortHeader("name", "Name", 2, "min-width:140px")}
|
|
85220
85378
|
<th rowspan="2" style="${thStyle("min-width:90px")}">Label</th>
|
|
85221
85379
|
<th colspan="2" style="${thStyle("text-align:center")}">TYPE</th>
|
|
85222
85380
|
<th colspan="2" style="${thStyle("text-align:center")}">DevType</th>
|
|
85223
85381
|
<th colspan="2" style="${thStyle("text-align:center")}">DevProfile</th>
|
|
85224
85382
|
<th colspan="2" style="${thStyle("text-align:center")}">Last Telemetry</th>
|
|
85225
|
-
|
|
85383
|
+
${cfSortHeader("connStatus", "Conn.", 2, "min-width:65px")}
|
|
85226
85384
|
<th rowspan="2" style="${thStyle("min-width:110px")}">gcdrId</th>
|
|
85227
|
-
|
|
85385
|
+
${cfSortHeader("ingestionId", "ingestionId", 2, "min-width:110px")}
|
|
85228
85386
|
<th rowspan="2" style="${thStyle("min-width:80px")}">centralId</th>
|
|
85229
85387
|
<th rowspan="2" style="${thStyle("min-width:50px")}">slave</th>
|
|
85230
|
-
|
|
85388
|
+
${cfSortHeader("status", "Result", 2)}
|
|
85231
85389
|
</tr>
|
|
85232
85390
|
<tr>
|
|
85233
85391
|
<th style="${thStyle()}">Exp</th><th style="${thStyle()}">Act</th>
|
|
@@ -85241,6 +85399,7 @@ function renderStep2(state6, modalId, colors2, t) {
|
|
|
85241
85399
|
${cfRows.length === 0 ? `<tr><td colspan="${colSpan}" style="padding:20px; text-align:center; color:${colors2.textMuted};">${t.noResults}</td></tr>` : cfRows.map((r) => renderCheckFixRow(r, state6, modalId, colors2, dupPairIds, dupIngestionIds)).join("")}
|
|
85242
85400
|
</tbody>
|
|
85243
85401
|
</table>
|
|
85402
|
+
</div>
|
|
85244
85403
|
</div>`;
|
|
85245
85404
|
}
|
|
85246
85405
|
return `
|
|
@@ -86125,6 +86284,309 @@ function openRelationsDetailPanel(deviceId, deviceName, direction, rels, state6,
|
|
|
86125
86284
|
renderPanel();
|
|
86126
86285
|
void t;
|
|
86127
86286
|
}
|
|
86287
|
+
function _setupCfStatusTooltip(container, modalId, colors2) {
|
|
86288
|
+
const TOOLTIP_ID = `${modalId}-cf-status-tip`;
|
|
86289
|
+
let destroyTimer = null;
|
|
86290
|
+
function ensureTip() {
|
|
86291
|
+
let tip2 = document.getElementById(TOOLTIP_ID);
|
|
86292
|
+
if (tip2) return tip2;
|
|
86293
|
+
tip2 = document.createElement("div");
|
|
86294
|
+
tip2.id = TOOLTIP_ID;
|
|
86295
|
+
tip2.style.cssText = `
|
|
86296
|
+
position:fixed; z-index:99990; display:none;
|
|
86297
|
+
background:${colors2.cardBg}; border:1px solid ${colors2.border};
|
|
86298
|
+
border-radius:10px; box-shadow:0 8px 28px rgba(0,0,0,0.26);
|
|
86299
|
+
padding:12px 14px; max-width:340px; font-size:11px; color:${colors2.text};
|
|
86300
|
+
line-height:1.6; pointer-events:auto;
|
|
86301
|
+
`;
|
|
86302
|
+
document.body.appendChild(tip2);
|
|
86303
|
+
return tip2;
|
|
86304
|
+
}
|
|
86305
|
+
function showTip(el2, status, deviceName, detail) {
|
|
86306
|
+
if (destroyTimer) {
|
|
86307
|
+
clearTimeout(destroyTimer);
|
|
86308
|
+
destroyTimer = null;
|
|
86309
|
+
}
|
|
86310
|
+
const tip2 = ensureTip();
|
|
86311
|
+
const STATUS_LABEL = { mismatch: "\u26A0\uFE0F Mismatch", missing: "\u274C Missing", undefined: "\u2753 Undefined" };
|
|
86312
|
+
const STATUS_COLOR_TIP = { mismatch: colors2.warning, missing: colors2.danger, undefined: colors2.textMuted };
|
|
86313
|
+
const lines = detail.split("\n").filter(Boolean);
|
|
86314
|
+
tip2.innerHTML = `
|
|
86315
|
+
<div style="font-weight:700; font-size:12px; color:${STATUS_COLOR_TIP[status] || colors2.text}; margin-bottom:6px;">${STATUS_LABEL[status] || status}</div>
|
|
86316
|
+
<div style="font-size:10px; color:${colors2.textMuted}; margin-bottom:8px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${deviceName}">${deviceName}</div>
|
|
86317
|
+
<div style="border-top:1px solid ${colors2.border}; padding-top:8px;">
|
|
86318
|
+
${lines.map((l) => `<div style="margin-bottom:3px; font-family:monospace; font-size:10px;">${l}</div>`).join("")}
|
|
86319
|
+
</div>
|
|
86320
|
+
`;
|
|
86321
|
+
const rect = el2.getBoundingClientRect();
|
|
86322
|
+
const tipW = 340, tipH = 80;
|
|
86323
|
+
let left = rect.left;
|
|
86324
|
+
let top = rect.bottom + 6;
|
|
86325
|
+
if (left + tipW > window.innerWidth - 10) left = window.innerWidth - tipW - 10;
|
|
86326
|
+
if (top + tipH > window.innerHeight - 10) top = rect.top - tipH - 6;
|
|
86327
|
+
tip2.style.left = `${left}px`;
|
|
86328
|
+
tip2.style.top = `${top}px`;
|
|
86329
|
+
tip2.style.display = "block";
|
|
86330
|
+
}
|
|
86331
|
+
function hideTip(force = false) {
|
|
86332
|
+
if (force) {
|
|
86333
|
+
const tip2 = document.getElementById(TOOLTIP_ID);
|
|
86334
|
+
if (tip2) tip2.style.display = "none";
|
|
86335
|
+
if (destroyTimer) {
|
|
86336
|
+
clearTimeout(destroyTimer);
|
|
86337
|
+
destroyTimer = null;
|
|
86338
|
+
}
|
|
86339
|
+
return;
|
|
86340
|
+
}
|
|
86341
|
+
destroyTimer = setTimeout(() => {
|
|
86342
|
+
const tip2 = document.getElementById(TOOLTIP_ID);
|
|
86343
|
+
if (tip2) tip2.style.display = "none";
|
|
86344
|
+
destroyTimer = null;
|
|
86345
|
+
}, 2e3);
|
|
86346
|
+
}
|
|
86347
|
+
container.querySelectorAll("[data-cf-status]").forEach((cell) => {
|
|
86348
|
+
const el2 = cell;
|
|
86349
|
+
const status = el2.dataset.cfStatus;
|
|
86350
|
+
const device = decodeURIComponent(el2.dataset.cfDevice || "");
|
|
86351
|
+
const detail = decodeURIComponent(el2.dataset.cfDetail || "");
|
|
86352
|
+
el2.addEventListener("mouseenter", () => showTip(el2, status, device, detail));
|
|
86353
|
+
el2.addEventListener("mouseleave", () => hideTip());
|
|
86354
|
+
el2.addEventListener("focus", () => {
|
|
86355
|
+
if (destroyTimer) {
|
|
86356
|
+
clearTimeout(destroyTimer);
|
|
86357
|
+
destroyTimer = null;
|
|
86358
|
+
}
|
|
86359
|
+
showTip(el2, status, device, detail);
|
|
86360
|
+
});
|
|
86361
|
+
el2.addEventListener("blur", () => hideTip());
|
|
86362
|
+
});
|
|
86363
|
+
const tip = ensureTip();
|
|
86364
|
+
tip.addEventListener("mouseenter", () => {
|
|
86365
|
+
if (destroyTimer) {
|
|
86366
|
+
clearTimeout(destroyTimer);
|
|
86367
|
+
destroyTimer = null;
|
|
86368
|
+
}
|
|
86369
|
+
});
|
|
86370
|
+
tip.addEventListener("mouseleave", () => hideTip());
|
|
86371
|
+
}
|
|
86372
|
+
var GCDR_CLEAR_DEVICE_KEYS = ["gcdrDeviceId", "gcdrId", "gcdrSyncAt", "gcdrAssetId", "gcdrCustomerId"];
|
|
86373
|
+
var GCDR_CLEAR_ASSET_KEYS = ["gcdrAssetId", "gcdrId", "gcdrSyncAt", "gcdrParentAssetId", "gcdrCustomerId"];
|
|
86374
|
+
async function openClearGcdrIdsModal(state6) {
|
|
86375
|
+
if (!state6.selectedCustomer) return;
|
|
86376
|
+
const customerId = getEntityId(state6.selectedCustomer);
|
|
86377
|
+
const customerName = state6.selectedCustomer.name || state6.selectedCustomer.title || customerId;
|
|
86378
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
86379
|
+
const overlay = document.createElement("div");
|
|
86380
|
+
overlay.style.cssText = `
|
|
86381
|
+
position:fixed; inset:0; z-index:99999;
|
|
86382
|
+
background:rgba(0,0,0,0.55); backdrop-filter:blur(4px);
|
|
86383
|
+
display:flex; align-items:center; justify-content:center;
|
|
86384
|
+
font-family:'Roboto',Inter,system-ui,sans-serif;
|
|
86385
|
+
`;
|
|
86386
|
+
overlay.addEventListener("click", (e) => {
|
|
86387
|
+
if (e.target === overlay) close();
|
|
86388
|
+
});
|
|
86389
|
+
document.body.appendChild(overlay);
|
|
86390
|
+
function close() {
|
|
86391
|
+
if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
|
86392
|
+
}
|
|
86393
|
+
function renderShell(bodyHtml, footerHtml) {
|
|
86394
|
+
overlay.innerHTML = `
|
|
86395
|
+
<div style="
|
|
86396
|
+
background:#1e1e2e; color:#e5e7eb; border:1px solid rgba(255,255,255,0.1);
|
|
86397
|
+
border-radius:14px; box-shadow:0 16px 48px rgba(0,0,0,0.4);
|
|
86398
|
+
max-width:860px; width:92%; max-height:85vh; display:flex; flex-direction:column;
|
|
86399
|
+
">
|
|
86400
|
+
<div style="padding:18px 22px; border-bottom:1px solid rgba(255,255,255,0.08); display:flex; justify-content:space-between; align-items:flex-start; flex-shrink:0;">
|
|
86401
|
+
<div>
|
|
86402
|
+
<div style="font-size:16px; font-weight:700; color:#f9fafb;">\u{1F9F9} Clear GCDR IDs</div>
|
|
86403
|
+
<div style="font-size:12px; color:#9ca3af; margin-top:2px;">Customer: ${customerName}</div>
|
|
86404
|
+
</div>
|
|
86405
|
+
<button id="gcdr-clear-x" style="background:none;border:none;color:#9ca3af;font-size:20px;cursor:pointer;padding:4px;line-height:1;">\u2715</button>
|
|
86406
|
+
</div>
|
|
86407
|
+
<div id="gcdr-clear-body" style="padding:18px 22px; overflow-y:auto; flex:1;">${bodyHtml}</div>
|
|
86408
|
+
<div id="gcdr-clear-footer" style="padding:14px 22px; border-top:1px solid rgba(255,255,255,0.08); display:flex; justify-content:flex-end; gap:10px; flex-shrink:0;">${footerHtml}</div>
|
|
86409
|
+
</div>`;
|
|
86410
|
+
overlay.querySelector("#gcdr-clear-x")?.addEventListener("click", close);
|
|
86411
|
+
}
|
|
86412
|
+
function btn(id, label, primary = false, disabled = false) {
|
|
86413
|
+
return `<button id="${id}" style="
|
|
86414
|
+
padding:8px 18px; border-radius:6px; font-size:13px; font-weight:600; cursor:${disabled ? "not-allowed" : "pointer"};
|
|
86415
|
+
${primary ? "background:#dc2626; color:white; border:none;" : "background:transparent; color:#9ca3af; border:1px solid rgba(255,255,255,0.15);"}
|
|
86416
|
+
opacity:${disabled ? "0.5" : "1"};
|
|
86417
|
+
" ${disabled ? "disabled" : ""}>${label}</button>`;
|
|
86418
|
+
}
|
|
86419
|
+
function progressHtml(phase, done, total) {
|
|
86420
|
+
const pct = total > 0 ? Math.round(done / total * 100) : 0;
|
|
86421
|
+
return `
|
|
86422
|
+
<div style="padding:8px 0;">
|
|
86423
|
+
<div style="font-size:13px; font-weight:600; color:#d1d5db; margin-bottom:14px;">\u23F3 ${phase}</div>
|
|
86424
|
+
<div style="background:rgba(255,255,255,0.1); border-radius:8px; height:8px; overflow:hidden; margin-bottom:6px;">
|
|
86425
|
+
<div style="background:#dc2626; height:100%; width:${pct}%; border-radius:8px; transition:width 0.2s;"></div>
|
|
86426
|
+
</div>
|
|
86427
|
+
<div style="display:flex; justify-content:space-between; font-size:12px; color:#9ca3af;">
|
|
86428
|
+
<span>${done} / ${total} entidades</span><span style="font-weight:700; color:#dc2626;">${pct}%</span>
|
|
86429
|
+
</div>
|
|
86430
|
+
</div>`;
|
|
86431
|
+
}
|
|
86432
|
+
function keyBadges(present, keys) {
|
|
86433
|
+
return keys.filter((k) => present[k]).map((k) => `<span style="font-size:9px; background:rgba(220,38,38,0.25); color:#fca5a5; padding:1px 5px; border-radius:3px; margin:1px; display:inline-block;">${k}</span>`).join("");
|
|
86434
|
+
}
|
|
86435
|
+
function tableHtml(rows, keys) {
|
|
86436
|
+
if (rows.length === 0) return '<div style="font-size:12px;color:#6b7280;padding:6px 0;">Nenhum item a limpar.</div>';
|
|
86437
|
+
return `<div style="overflow-x:auto; margin-top:4px;">
|
|
86438
|
+
<table style="border-collapse:collapse; width:100%; font-size:11px;">
|
|
86439
|
+
<thead><tr>
|
|
86440
|
+
<th style="text-align:left; padding:5px 8px; border-bottom:1px solid rgba(255,255,255,0.08); color:#9ca3af; font-weight:600;">Nome TB</th>
|
|
86441
|
+
<th style="text-align:left; padding:5px 8px; border-bottom:1px solid rgba(255,255,255,0.08); color:#9ca3af; font-weight:600;">Chaves a remover</th>
|
|
86442
|
+
</tr></thead>
|
|
86443
|
+
<tbody>${rows.map((r) => `<tr>
|
|
86444
|
+
<td style="padding:5px 8px; border-bottom:1px solid rgba(255,255,255,0.05); color:#d1d5db;" title="${r.tbId}">
|
|
86445
|
+
${r.name}<br><span style="color:#6b7280; font-family:monospace; font-size:9px;">${r.tbId.substring(0, 8)}\u2026</span>
|
|
86446
|
+
</td>
|
|
86447
|
+
<td style="padding:5px 8px; border-bottom:1px solid rgba(255,255,255,0.05);">${keyBadges(r.present, keys)}</td>
|
|
86448
|
+
</tr>`).join("")}</tbody>
|
|
86449
|
+
</table>
|
|
86450
|
+
</div>`;
|
|
86451
|
+
}
|
|
86452
|
+
function previewHtml(deviceRows, assetRows) {
|
|
86453
|
+
const devToClear = deviceRows.filter((r) => r.hasAny);
|
|
86454
|
+
const assetToClear = assetRows.filter((r) => r.hasAny);
|
|
86455
|
+
const badge = (txt, danger = false) => `<span style="font-size:11px; padding:3px 10px; border-radius:4px; background:${danger ? "rgba(220,38,38,0.2)" : "rgba(255,255,255,0.07)"}; color:${danger ? "#fca5a5" : "#9ca3af"};">${txt}</span>`;
|
|
86456
|
+
return `
|
|
86457
|
+
<div style="display:flex; gap:8px; flex-wrap:wrap; margin-bottom:14px;">
|
|
86458
|
+
${badge(`\u{1F9F9} ${devToClear.length} devices a limpar`, devToClear.length > 0)}
|
|
86459
|
+
${badge(`\u2713 ${deviceRows.length - devToClear.length} devices j\xE1 limpos`)}
|
|
86460
|
+
${badge(`\u{1F9F9} ${assetToClear.length} assets a limpar`, assetToClear.length > 0)}
|
|
86461
|
+
${badge(`\u2713 ${assetRows.length - assetToClear.length} assets j\xE1 limpos`)}
|
|
86462
|
+
</div>
|
|
86463
|
+
<div style="font-size:10px; font-weight:700; color:#9ca3af; text-transform:uppercase; letter-spacing:.5px; margin-bottom:4px;">
|
|
86464
|
+
\u{1F4DF} Devices (${deviceRows.length})
|
|
86465
|
+
<span style="font-size:9px; font-weight:400; text-transform:none; margin-left:6px;">chaves: ${GCDR_CLEAR_DEVICE_KEYS.join(", ")}</span>
|
|
86466
|
+
</div>
|
|
86467
|
+
${tableHtml(devToClear, GCDR_CLEAR_DEVICE_KEYS)}
|
|
86468
|
+
<div style="font-size:10px; font-weight:700; color:#9ca3af; text-transform:uppercase; letter-spacing:.5px; margin:14px 0 4px;">
|
|
86469
|
+
\u{1F4C1} Assets (${assetRows.length})
|
|
86470
|
+
<span style="font-size:9px; font-weight:400; text-transform:none; margin-left:6px;">chaves: ${GCDR_CLEAR_ASSET_KEYS.join(", ")}</span>
|
|
86471
|
+
</div>
|
|
86472
|
+
${tableHtml(assetToClear, GCDR_CLEAR_ASSET_KEYS)}
|
|
86473
|
+
${devToClear.length + assetToClear.length === 0 ? '<div style="text-align:center; color:#6b7280; padding:16px 0; font-size:13px;">\u2705 Nenhum device ou asset possui essas chaves. Nada a limpar.</div>' : ""}`;
|
|
86474
|
+
}
|
|
86475
|
+
renderShell(progressHtml("Buscando devices e assets\u2026", 0, 0), "");
|
|
86476
|
+
try {
|
|
86477
|
+
const [devicesResp, assetsResp] = await Promise.all([
|
|
86478
|
+
tbFetch(state6, `/api/customer/${customerId}/devices?pageSize=1000&page=0`),
|
|
86479
|
+
tbFetch(state6, `/api/customer/${customerId}/assets?pageSize=1000&page=0`)
|
|
86480
|
+
]);
|
|
86481
|
+
const tbDevices = devicesResp.data || [];
|
|
86482
|
+
const tbAssets = assetsResp.data || [];
|
|
86483
|
+
const total = tbDevices.length + tbAssets.length;
|
|
86484
|
+
const deviceRows = [];
|
|
86485
|
+
const assetRows = [];
|
|
86486
|
+
async function processBatch(items, entityType, keysToCheck, targetRows, fetchAttrs) {
|
|
86487
|
+
const chunks = [];
|
|
86488
|
+
for (let i = 0; i < items.length; i += 10) chunks.push(items.slice(i, i + 10));
|
|
86489
|
+
for (let ci = 0; ci < chunks.length; ci++) {
|
|
86490
|
+
if (ci > 0) await sleep(800);
|
|
86491
|
+
await Promise.all(chunks[ci].map(async (entity) => {
|
|
86492
|
+
const tbId = entity.id?.id || "";
|
|
86493
|
+
const name = entity.name || entity.label || tbId;
|
|
86494
|
+
let present = {};
|
|
86495
|
+
try {
|
|
86496
|
+
const attrs = await fetchAttrs(tbId);
|
|
86497
|
+
for (const k of keysToCheck) present[k] = attrs[k] != null && attrs[k] !== "";
|
|
86498
|
+
} catch {
|
|
86499
|
+
}
|
|
86500
|
+
targetRows.push({ tbId, name, entityType, present, hasAny: keysToCheck.some((k) => present[k]) });
|
|
86501
|
+
}));
|
|
86502
|
+
const done = deviceRows.length + assetRows.length;
|
|
86503
|
+
const bodyEl = overlay.querySelector("#gcdr-clear-body");
|
|
86504
|
+
if (bodyEl) bodyEl.innerHTML = progressHtml(`Lendo SERVER_SCOPE (${entityType})\u2026`, done, total);
|
|
86505
|
+
}
|
|
86506
|
+
}
|
|
86507
|
+
const fetchDeviceAttrs = async (id) => {
|
|
86508
|
+
const data = await tbFetch(
|
|
86509
|
+
state6,
|
|
86510
|
+
`/api/plugins/telemetry/DEVICE/${id}/values/attributes/SERVER_SCOPE`
|
|
86511
|
+
);
|
|
86512
|
+
return Object.fromEntries(data.map((a) => [a.key, a.value]));
|
|
86513
|
+
};
|
|
86514
|
+
const fetchAssetAttrs = async (id) => {
|
|
86515
|
+
const data = await tbFetch(
|
|
86516
|
+
state6,
|
|
86517
|
+
`/api/plugins/telemetry/ASSET/${id}/values/attributes/SERVER_SCOPE`
|
|
86518
|
+
);
|
|
86519
|
+
return Object.fromEntries(data.map((a) => [a.key, a.value]));
|
|
86520
|
+
};
|
|
86521
|
+
await processBatch(tbDevices, "DEVICE", GCDR_CLEAR_DEVICE_KEYS, deviceRows, fetchDeviceAttrs);
|
|
86522
|
+
await processBatch(tbAssets, "ASSET", GCDR_CLEAR_ASSET_KEYS, assetRows, fetchAssetAttrs);
|
|
86523
|
+
const devToClear = deviceRows.filter((r) => r.hasAny);
|
|
86524
|
+
const assetToClear = assetRows.filter((r) => r.hasAny);
|
|
86525
|
+
const totalToClear = devToClear.length + assetToClear.length;
|
|
86526
|
+
renderShell(
|
|
86527
|
+
previewHtml(deviceRows, assetRows),
|
|
86528
|
+
btn("gcdr-clear-cancel", "Cancelar") + btn("gcdr-clear-apply", `\u{1F9F9} Limpar ${totalToClear} entidade${totalToClear !== 1 ? "s" : ""}`, true, totalToClear === 0)
|
|
86529
|
+
);
|
|
86530
|
+
overlay.querySelector("#gcdr-clear-cancel")?.addEventListener("click", close);
|
|
86531
|
+
overlay.querySelector("#gcdr-clear-apply")?.addEventListener("click", async () => {
|
|
86532
|
+
let done3 = 0;
|
|
86533
|
+
overlay.querySelector("#gcdr-clear-footer").innerHTML = "";
|
|
86534
|
+
overlay.querySelector("#gcdr-clear-body").innerHTML = progressHtml("Removendo atributos GCDR\u2026", 0, totalToClear);
|
|
86535
|
+
async function execClear(rows, keys, entityType) {
|
|
86536
|
+
const results = [];
|
|
86537
|
+
const chunks = [];
|
|
86538
|
+
for (let i = 0; i < rows.length; i += 10) chunks.push(rows.slice(i, i + 10));
|
|
86539
|
+
for (let ci = 0; ci < chunks.length; ci++) {
|
|
86540
|
+
if (ci > 0) await sleep(800);
|
|
86541
|
+
await Promise.all(chunks[ci].map(async (row) => {
|
|
86542
|
+
const keysToDelete = keys.filter((k) => row.present[k]);
|
|
86543
|
+
try {
|
|
86544
|
+
await tbDelete(state6, `/api/plugins/telemetry/${entityType}/${row.tbId}/values/attributes/SERVER_SCOPE?keys=${encodeURIComponent(keysToDelete.join(","))}`);
|
|
86545
|
+
results.push({ name: row.name, ok: true, cleared: keysToDelete });
|
|
86546
|
+
} catch (err2) {
|
|
86547
|
+
results.push({ name: row.name, ok: false, error: err2.message });
|
|
86548
|
+
}
|
|
86549
|
+
done3++;
|
|
86550
|
+
const progEl = overlay.querySelector("#gcdr-clear-body");
|
|
86551
|
+
if (progEl) progEl.innerHTML = progressHtml("Removendo atributos GCDR\u2026", done3, totalToClear);
|
|
86552
|
+
}));
|
|
86553
|
+
}
|
|
86554
|
+
return results;
|
|
86555
|
+
}
|
|
86556
|
+
const devResults = await execClear(devToClear, GCDR_CLEAR_DEVICE_KEYS, "DEVICE");
|
|
86557
|
+
const assetResults = await execClear(assetToClear, GCDR_CLEAR_ASSET_KEYS, "ASSET");
|
|
86558
|
+
const allResults = [...devResults, ...assetResults];
|
|
86559
|
+
const ok = allResults.filter((r) => r.ok).length;
|
|
86560
|
+
const err = allResults.filter((r) => !r.ok).length;
|
|
86561
|
+
const resultHtml = `
|
|
86562
|
+
<div style="display:flex; gap:8px; margin-bottom:14px;">
|
|
86563
|
+
<span style="font-size:12px; padding:3px 10px; border-radius:4px; background:rgba(16,185,129,0.2); color:#6ee7b7;">\u2713 ${ok} limpos</span>
|
|
86564
|
+
${err > 0 ? `<span style="font-size:12px; padding:3px 10px; border-radius:4px; background:rgba(220,38,38,0.2); color:#fca5a5;">\u2717 ${err} erros</span>` : ""}
|
|
86565
|
+
</div>
|
|
86566
|
+
${[{ title: "\u{1F4DF} Devices", results: devResults }, { title: "\u{1F4C1} Assets", results: assetResults }].filter((s) => s.results.length > 0).map((s) => `
|
|
86567
|
+
<div style="font-size:10px; font-weight:700; color:#9ca3af; text-transform:uppercase; margin:10px 0 4px;">${s.title}</div>
|
|
86568
|
+
<ul style="list-style:none; margin:0; padding:0;">
|
|
86569
|
+
${s.results.map((r) => `
|
|
86570
|
+
<li style="display:flex; align-items:flex-start; gap:8px; padding:5px 0; border-bottom:1px solid rgba(255,255,255,0.05);">
|
|
86571
|
+
<span>${r.ok ? "\u2705" : "\u274C"}</span>
|
|
86572
|
+
<div>
|
|
86573
|
+
<div style="font-size:11px; color:#d1d5db;">${r.name}</div>
|
|
86574
|
+
<div style="font-size:10px; color:${r.ok ? "#6ee7b7" : "#fca5a5"};">
|
|
86575
|
+
${r.ok ? `Removidas: ${r.cleared?.join(", ")}` : r.error}
|
|
86576
|
+
</div>
|
|
86577
|
+
</div>
|
|
86578
|
+
</li>`).join("")}
|
|
86579
|
+
</ul>`).join("")}`;
|
|
86580
|
+
overlay.querySelector("#gcdr-clear-body").innerHTML = resultHtml;
|
|
86581
|
+
overlay.querySelector("#gcdr-clear-footer").innerHTML = btn("gcdr-clear-done", "Fechar");
|
|
86582
|
+
overlay.querySelector("#gcdr-clear-done")?.addEventListener("click", close);
|
|
86583
|
+
});
|
|
86584
|
+
} catch (err) {
|
|
86585
|
+
overlay.querySelector("#gcdr-clear-body").innerHTML = `<div style="color:#fca5a5; font-size:13px; padding:8px 0;">\u274C ${err.message}</div>`;
|
|
86586
|
+
overlay.querySelector("#gcdr-clear-footer").innerHTML = btn("gcdr-clear-err-close", "Fechar");
|
|
86587
|
+
overlay.querySelector("#gcdr-clear-err-close")?.addEventListener("click", close);
|
|
86588
|
+
}
|
|
86589
|
+
}
|
|
86128
86590
|
function setupEventListeners3(container, state6, modalId, t, onClose) {
|
|
86129
86591
|
const closeHandler = () => closeModal(container, onClose);
|
|
86130
86592
|
const overlay = container.querySelector(".myio-upsell-modal-overlay");
|
|
@@ -86324,6 +86786,17 @@ function setupEventListeners3(container, state6, modalId, t, onClose) {
|
|
|
86324
86786
|
if (e.key === "Escape") closeHandler();
|
|
86325
86787
|
};
|
|
86326
86788
|
document.addEventListener("keydown", escHandler);
|
|
86789
|
+
const cfFilterPanelCloseHandler = (e) => {
|
|
86790
|
+
if (!state6.checkFixFilterOpen) return;
|
|
86791
|
+
const btn = document.getElementById(`${modalId}-cf-filter-btn`);
|
|
86792
|
+
const panel = document.getElementById(`${modalId}-cf-filter-panel`);
|
|
86793
|
+
if (btn && !btn.contains(e.target) && panel && !panel.contains(e.target)) {
|
|
86794
|
+
state6.checkFixFilterOpen = false;
|
|
86795
|
+
renderModal4(container, state6, modalId, t);
|
|
86796
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86797
|
+
}
|
|
86798
|
+
};
|
|
86799
|
+
document.addEventListener("click", cfFilterPanelCloseHandler);
|
|
86327
86800
|
document.getElementById(`${modalId}-load-relations`)?.addEventListener("click", () => {
|
|
86328
86801
|
void loadDeviceRelations(state6, container, modalId, t, onClose);
|
|
86329
86802
|
});
|
|
@@ -86470,6 +86943,82 @@ function setupEventListeners3(container, state6, modalId, t, onClose) {
|
|
|
86470
86943
|
renderModal4(container, state6, modalId, t);
|
|
86471
86944
|
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86472
86945
|
});
|
|
86946
|
+
container.querySelectorAll("[data-cf-sort]").forEach((el2) => {
|
|
86947
|
+
el2.addEventListener("click", () => {
|
|
86948
|
+
const field = el2.dataset.cfSort;
|
|
86949
|
+
if (state6.checkFixSort.field === field) {
|
|
86950
|
+
state6.checkFixSort.order = state6.checkFixSort.order === "asc" ? "desc" : "asc";
|
|
86951
|
+
} else {
|
|
86952
|
+
state6.checkFixSort = { field, order: "asc" };
|
|
86953
|
+
}
|
|
86954
|
+
const listEl = document.getElementById(`${modalId}-device-list`);
|
|
86955
|
+
const savedScroll = listEl ? listEl.scrollTop : 0;
|
|
86956
|
+
renderModal4(container, state6, modalId, t);
|
|
86957
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86958
|
+
const elAfter = document.getElementById(`${modalId}-device-list`);
|
|
86959
|
+
if (elAfter) elAfter.scrollTop = savedScroll;
|
|
86960
|
+
});
|
|
86961
|
+
});
|
|
86962
|
+
document.getElementById(`${modalId}-cf-filter-btn`)?.addEventListener("click", (e) => {
|
|
86963
|
+
e.stopPropagation();
|
|
86964
|
+
state6.checkFixFilterOpen = !state6.checkFixFilterOpen;
|
|
86965
|
+
renderModal4(container, state6, modalId, t);
|
|
86966
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86967
|
+
});
|
|
86968
|
+
document.getElementById(`${modalId}-cf-flt-close`)?.addEventListener("click", () => {
|
|
86969
|
+
state6.checkFixFilterOpen = false;
|
|
86970
|
+
renderModal4(container, state6, modalId, t);
|
|
86971
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86972
|
+
});
|
|
86973
|
+
document.getElementById(`${modalId}-cf-flt-clear`)?.addEventListener("click", () => {
|
|
86974
|
+
state6.checkFixAdvancedFilter = { statuses: [], connStatuses: [], domains: [], missingIngestionId: false, missingCentralSlave: false };
|
|
86975
|
+
renderModal4(container, state6, modalId, t);
|
|
86976
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86977
|
+
});
|
|
86978
|
+
document.getElementById(`${modalId}-cf-flt-noing`)?.addEventListener("change", (e) => {
|
|
86979
|
+
state6.checkFixAdvancedFilter.missingIngestionId = e.target.checked;
|
|
86980
|
+
renderModal4(container, state6, modalId, t);
|
|
86981
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86982
|
+
});
|
|
86983
|
+
document.getElementById(`${modalId}-cf-flt-nocentral`)?.addEventListener("change", (e) => {
|
|
86984
|
+
state6.checkFixAdvancedFilter.missingCentralSlave = e.target.checked;
|
|
86985
|
+
renderModal4(container, state6, modalId, t);
|
|
86986
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86987
|
+
});
|
|
86988
|
+
const cfFilterPanel = document.getElementById(`${modalId}-cf-filter-panel`);
|
|
86989
|
+
if (cfFilterPanel) {
|
|
86990
|
+
cfFilterPanel.querySelectorAll("[data-cf-flt-status]").forEach((btn) => {
|
|
86991
|
+
btn.addEventListener("click", () => {
|
|
86992
|
+
const s = btn.dataset.cfFltStatus;
|
|
86993
|
+
const idx = state6.checkFixAdvancedFilter.statuses.indexOf(s);
|
|
86994
|
+
if (idx >= 0) state6.checkFixAdvancedFilter.statuses.splice(idx, 1);
|
|
86995
|
+
else state6.checkFixAdvancedFilter.statuses.push(s);
|
|
86996
|
+
renderModal4(container, state6, modalId, t);
|
|
86997
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
86998
|
+
});
|
|
86999
|
+
});
|
|
87000
|
+
cfFilterPanel.querySelectorAll("[data-cf-flt-conn]").forEach((btn) => {
|
|
87001
|
+
btn.addEventListener("click", () => {
|
|
87002
|
+
const c = btn.dataset.cfFltConn;
|
|
87003
|
+
const idx = state6.checkFixAdvancedFilter.connStatuses.indexOf(c);
|
|
87004
|
+
if (idx >= 0) state6.checkFixAdvancedFilter.connStatuses.splice(idx, 1);
|
|
87005
|
+
else state6.checkFixAdvancedFilter.connStatuses.push(c);
|
|
87006
|
+
renderModal4(container, state6, modalId, t);
|
|
87007
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
87008
|
+
});
|
|
87009
|
+
});
|
|
87010
|
+
cfFilterPanel.querySelectorAll("[data-cf-flt-domain]").forEach((btn) => {
|
|
87011
|
+
btn.addEventListener("click", () => {
|
|
87012
|
+
const d = btn.dataset.cfFltDomain;
|
|
87013
|
+
const idx = state6.checkFixAdvancedFilter.domains.indexOf(d);
|
|
87014
|
+
if (idx >= 0) state6.checkFixAdvancedFilter.domains.splice(idx, 1);
|
|
87015
|
+
else state6.checkFixAdvancedFilter.domains.push(d);
|
|
87016
|
+
renderModal4(container, state6, modalId, t);
|
|
87017
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
87018
|
+
});
|
|
87019
|
+
});
|
|
87020
|
+
}
|
|
87021
|
+
_setupCfStatusTooltip(container, modalId, getThemeColors5(state6.theme));
|
|
86473
87022
|
document.getElementById(`${modalId}-mode-single`)?.addEventListener("click", () => {
|
|
86474
87023
|
if (state6.deviceSelectionMode !== "single") {
|
|
86475
87024
|
state6.deviceSelectionMode = "single";
|
|
@@ -86545,26 +87094,22 @@ function setupEventListeners3(container, state6, modalId, t, onClose) {
|
|
|
86545
87094
|
if (!deviceId) return;
|
|
86546
87095
|
const device = state6.devices.find((d) => d.id?.id === deviceId);
|
|
86547
87096
|
if (!device) return;
|
|
86548
|
-
|
|
86549
|
-
|
|
86550
|
-
if (
|
|
86551
|
-
|
|
86552
|
-
state6.selectedDevices.push(device);
|
|
86553
|
-
}
|
|
86554
|
-
} else {
|
|
86555
|
-
state6.selectedDevices = state6.selectedDevices.filter((d) => d.id?.id !== deviceId);
|
|
87097
|
+
const isChecked = input.checked;
|
|
87098
|
+
if (isChecked) {
|
|
87099
|
+
if (!state6.selectedDevices.some((d) => d.id?.id === deviceId)) {
|
|
87100
|
+
state6.selectedDevices.push(device);
|
|
86556
87101
|
}
|
|
86557
|
-
|
|
86558
|
-
|
|
86559
|
-
|
|
86560
|
-
|
|
86561
|
-
|
|
86562
|
-
|
|
86563
|
-
|
|
86564
|
-
|
|
86565
|
-
|
|
86566
|
-
|
|
86567
|
-
|
|
87102
|
+
} else {
|
|
87103
|
+
state6.selectedDevices = state6.selectedDevices.filter((d) => d.id?.id !== deviceId);
|
|
87104
|
+
}
|
|
87105
|
+
const listEl = document.getElementById(`${modalId}-device-list`);
|
|
87106
|
+
const savedScroll = listEl ? listEl.scrollTop : 0;
|
|
87107
|
+
const containerScrollTop = container.scrollTop;
|
|
87108
|
+
renderModal4(container, state6, modalId, t);
|
|
87109
|
+
setupEventListeners3(container, state6, modalId, t, onClose);
|
|
87110
|
+
const elAfter = document.getElementById(`${modalId}-device-list`);
|
|
87111
|
+
if (elAfter) elAfter.scrollTop = savedScroll;
|
|
87112
|
+
container.scrollTop = containerScrollTop;
|
|
86568
87113
|
};
|
|
86569
87114
|
});
|
|
86570
87115
|
document.getElementById(`${modalId}-bulk-attr`)?.addEventListener("click", () => {
|
|
@@ -86683,6 +87228,13 @@ function setupEventListeners3(container, state6, modalId, t, onClose) {
|
|
|
86683
87228
|
if (!state6.selectedCustomer || state6.selectedDevices.length === 0) return;
|
|
86684
87229
|
await handleBulkSyncIngestionId(state6, container, modalId, t, onClose);
|
|
86685
87230
|
});
|
|
87231
|
+
document.getElementById(`${modalId}-clear-gcdr-ids`)?.addEventListener("click", () => {
|
|
87232
|
+
if (!state6.selectedCustomer) {
|
|
87233
|
+
alert("Selecione um Customer primeiro no Step 1");
|
|
87234
|
+
return;
|
|
87235
|
+
}
|
|
87236
|
+
void openClearGcdrIdsModal(state6);
|
|
87237
|
+
});
|
|
86686
87238
|
document.getElementById(`${modalId}-bulk-relation`)?.addEventListener("click", () => {
|
|
86687
87239
|
if (!state6.selectedCustomer) {
|
|
86688
87240
|
alert("Selecione um Customer primeiro no Step 1");
|
|
@@ -87187,7 +87739,9 @@ function filterDeviceListVisual(container, devices, search, filters, sort) {
|
|
|
87187
87739
|
return;
|
|
87188
87740
|
}
|
|
87189
87741
|
const matchesSearch = !search || device.name?.toLowerCase().includes(search) || device.label?.toLowerCase().includes(search) || device.type?.toLowerCase().includes(search) || device.serverAttrs?.deviceType?.toLowerCase().includes(search) || device.serverAttrs?.deviceProfile?.toLowerCase().includes(search);
|
|
87190
|
-
|
|
87742
|
+
const el2 = item;
|
|
87743
|
+
const isTableRow = el2.tagName === "TR";
|
|
87744
|
+
el2.style.display = matchesSearch ? isTableRow ? "" : "flex" : "none";
|
|
87191
87745
|
});
|
|
87192
87746
|
}
|
|
87193
87747
|
async function tbFetch(state6, path) {
|
|
@@ -88801,7 +89355,7 @@ var UserListTab = class {
|
|
|
88801
89355
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
88802
89356
|
try {
|
|
88803
89357
|
const searchRes = await fetch(
|
|
88804
|
-
`${base}/
|
|
89358
|
+
`${base}/users?search=${encodeURIComponent(user.email)}&customerId=${encodeURIComponent(this.config.customerId)}&limit=10`,
|
|
88805
89359
|
{ headers: this.gcdrHeaders() }
|
|
88806
89360
|
);
|
|
88807
89361
|
let gcdrUser = null;
|
|
@@ -88811,7 +89365,7 @@ var UserListTab = class {
|
|
|
88811
89365
|
gcdrUser = items.find((u) => u.email?.toLowerCase() === user.email.toLowerCase()) ?? null;
|
|
88812
89366
|
}
|
|
88813
89367
|
if (!gcdrUser) {
|
|
88814
|
-
const createRes = await fetch(`${base}/
|
|
89368
|
+
const createRes = await fetch(`${base}/users`, {
|
|
88815
89369
|
method: "POST",
|
|
88816
89370
|
headers: this.gcdrHeaders(),
|
|
88817
89371
|
body: JSON.stringify({
|