myio-js-library 0.1.485 → 0.1.486
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 +256 -49
- package/dist/index.d.cts +8 -3
- package/dist/index.js +256 -49
- package/dist/myio-js-library.umd.js +256 -49
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1159,7 +1159,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1159
1159
|
// package.json
|
|
1160
1160
|
var package_default = {
|
|
1161
1161
|
name: "myio-js-library",
|
|
1162
|
-
version: "0.1.
|
|
1162
|
+
version: "0.1.486",
|
|
1163
1163
|
description: "A clean, standalone JS SDK for MYIO projects",
|
|
1164
1164
|
license: "MIT",
|
|
1165
1165
|
repository: "github:gh-myio/myio-js-library",
|
|
@@ -89876,6 +89876,7 @@ var UserDetailTab = class {
|
|
|
89876
89876
|
// RFC-0197: Assignments section state
|
|
89877
89877
|
assignments = [];
|
|
89878
89878
|
availableRoles = [];
|
|
89879
|
+
availablePolicies = [];
|
|
89879
89880
|
assignmentsEl = null;
|
|
89880
89881
|
assignmentsVersion = 0;
|
|
89881
89882
|
constructor(config, user, callbacks) {
|
|
@@ -89969,8 +89970,8 @@ var UserDetailTab = class {
|
|
|
89969
89970
|
const section = document.createElement("div");
|
|
89970
89971
|
section.style.cssText = "margin-top:20px;border:1px solid var(--um-border);border-radius:10px;overflow:hidden;";
|
|
89971
89972
|
const sectionHeader = document.createElement("div");
|
|
89972
|
-
sectionHeader.style.cssText = "display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:var(--um-
|
|
89973
|
-
sectionHeader.innerHTML = `<span style="font-size:13px;font-weight:600;color
|
|
89973
|
+
sectionHeader.style.cssText = "display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:var(--um-accent);border-bottom:1px solid var(--um-btn-2-border);";
|
|
89974
|
+
sectionHeader.innerHTML = `<span style="font-size:13px;font-weight:600;color:#fff;">\u{1F511} Atribui\xE7\xF5es de Fun\xE7\xF5es</span>`;
|
|
89974
89975
|
const addBtn = document.createElement("button");
|
|
89975
89976
|
addBtn.className = "um-btn um-btn--secondary um-btn--sm";
|
|
89976
89977
|
addBtn.textContent = "+ Atribuir Fun\xE7\xE3o";
|
|
@@ -89988,12 +89989,14 @@ var UserDetailTab = class {
|
|
|
89988
89989
|
async loadAssignments() {
|
|
89989
89990
|
const userId = this.user.id.id;
|
|
89990
89991
|
try {
|
|
89991
|
-
const [assignRes, rolesRes] = await Promise.all([
|
|
89992
|
+
const [assignRes, rolesRes, policiesRes] = await Promise.all([
|
|
89992
89993
|
fetch(`${this.gcdrBase()}/authorization/users/${userId}/assignments`, { headers: this.gcdrHeaders() }),
|
|
89993
|
-
fetch(`${this.gcdrBase()}/roles?limit=100`, { headers: this.gcdrHeaders() })
|
|
89994
|
+
fetch(`${this.gcdrBase()}/roles?limit=100`, { headers: this.gcdrHeaders() }),
|
|
89995
|
+
fetch(`${this.gcdrBase()}/policies?limit=100`, { headers: this.gcdrHeaders() })
|
|
89994
89996
|
]);
|
|
89995
89997
|
this.assignments = assignRes.ok ? this.unwrapList(await assignRes.json()) : [];
|
|
89996
89998
|
this.availableRoles = rolesRes.ok ? this.unwrapList(await rolesRes.json()) : [];
|
|
89999
|
+
this.availablePolicies = policiesRes.ok ? this.unwrapList(await policiesRes.json()) : [];
|
|
89997
90000
|
this.renderAssignments();
|
|
89998
90001
|
} catch (err) {
|
|
89999
90002
|
console.error("[UserDetailTab] loadAssignments error", err);
|
|
@@ -90058,6 +90061,10 @@ var UserDetailTab = class {
|
|
|
90058
90061
|
</select>
|
|
90059
90062
|
<span class="um-field-error" data-for="roleId"></span>
|
|
90060
90063
|
</div>
|
|
90064
|
+
<div class="um-assign-policies-preview" style="display:none;border:1px solid var(--um-border);border-radius:8px;padding:12px;background:var(--um-bg-surface);">
|
|
90065
|
+
<div style="font-size:11px;font-weight:600;color:var(--um-text-muted);text-transform:uppercase;letter-spacing:0.05em;margin-bottom:8px;">Pol\xEDticas inclu\xEDdas</div>
|
|
90066
|
+
<div class="um-assign-policies-list" style="display:flex;flex-direction:column;gap:6px;"></div>
|
|
90067
|
+
</div>
|
|
90061
90068
|
<div class="um-form-group">
|
|
90062
90069
|
<label class="um-label">Escopo <span class="um-req">*</span></label>
|
|
90063
90070
|
<select class="um-input" name="scope">
|
|
@@ -90080,6 +90087,29 @@ var UserDetailTab = class {
|
|
|
90080
90087
|
`;
|
|
90081
90088
|
overlay.appendChild(modal);
|
|
90082
90089
|
document.body.appendChild(overlay);
|
|
90090
|
+
const roleSelect = modal.querySelector("[name=roleId]");
|
|
90091
|
+
const policiesPreview = modal.querySelector(".um-assign-policies-preview");
|
|
90092
|
+
const policiesList = modal.querySelector(".um-assign-policies-list");
|
|
90093
|
+
roleSelect.addEventListener("change", () => {
|
|
90094
|
+
const role = this.availableRoles.find((r) => r.id === roleSelect.value);
|
|
90095
|
+
const policyRefs = role?.policies ?? role?.policyIds ?? [];
|
|
90096
|
+
if (!role || policyRefs.length === 0) {
|
|
90097
|
+
policiesPreview.style.display = "none";
|
|
90098
|
+
return;
|
|
90099
|
+
}
|
|
90100
|
+
const policyByKey = new Map(this.availablePolicies.flatMap((p) => [
|
|
90101
|
+
[p.key || p.id, p],
|
|
90102
|
+
[p.id, p]
|
|
90103
|
+
]));
|
|
90104
|
+
const matched = policyRefs.map((ref) => policyByKey.get(ref)).filter(Boolean);
|
|
90105
|
+
policiesList.innerHTML = matched.length > 0 ? matched.map((p) => `
|
|
90106
|
+
<div style="display:flex;align-items:flex-start;gap:8px;padding:6px 8px;background:var(--um-bg-input);border-radius:6px;">
|
|
90107
|
+
<span style="font-size:11px;font-weight:600;background:var(--um-btn-2-bg);color:var(--um-btn-2-text);border:1px solid var(--um-btn-2-border);border-radius:9999px;padding:2px 8px;white-space:nowrap;">${this.esc(p.displayName)}</span>
|
|
90108
|
+
${p.description ? `<span style="font-size:11px;color:var(--um-text-muted);padding-top:2px;">${this.esc(p.description)}</span>` : ""}
|
|
90109
|
+
</div>`).join("") : policyRefs.map((ref) => `
|
|
90110
|
+
<span style="font-size:11px;font-family:monospace;background:var(--um-btn-2-bg);color:var(--um-btn-2-text);border:1px solid var(--um-btn-2-border);border-radius:9999px;padding:2px 8px;">${this.esc(ref)}</span>`).join("");
|
|
90111
|
+
policiesPreview.style.display = "block";
|
|
90112
|
+
});
|
|
90083
90113
|
const close = () => overlay.remove();
|
|
90084
90114
|
overlay.addEventListener("click", (e) => {
|
|
90085
90115
|
if (e.target === overlay) close();
|
|
@@ -90697,7 +90727,8 @@ var RolesTab = class {
|
|
|
90697
90727
|
const item = document.createElement("div");
|
|
90698
90728
|
item.className = `gm-accordion-item${this.expandedId === r.id ? " gm-accordion-item--open" : ""}`;
|
|
90699
90729
|
const sysBadge = r.isSystem ? `<span class="gm-badge gm-badge--count">SISTEMA</span>` : "";
|
|
90700
|
-
const
|
|
90730
|
+
const policyKeys = r.policies ?? r.policyIds ?? [];
|
|
90731
|
+
const policyCount = policyKeys.length;
|
|
90701
90732
|
const policyBadge = `<span class="gm-badge gm-badge--domain">${policyCount} pol\xEDticas</span>`;
|
|
90702
90733
|
item.innerHTML = `
|
|
90703
90734
|
<div class="gm-accordion-header">
|
|
@@ -90737,20 +90768,26 @@ var RolesTab = class {
|
|
|
90737
90768
|
return item;
|
|
90738
90769
|
}
|
|
90739
90770
|
buildRolePoliciesHtml(r) {
|
|
90740
|
-
|
|
90771
|
+
const policyKeys = r.policies ?? r.policyIds ?? [];
|
|
90772
|
+
if (!policyKeys.length) {
|
|
90741
90773
|
return `<div class="gm-panel-section"><span class="gm-empty-inline">Nenhuma pol\xEDtica associada.</span></div>`;
|
|
90742
90774
|
}
|
|
90743
|
-
const
|
|
90744
|
-
|
|
90745
|
-
|
|
90775
|
+
const policyByKey = new Map(this.policies.flatMap((p) => [
|
|
90776
|
+
[p.key || p.id, p],
|
|
90777
|
+
[p.id, p]
|
|
90778
|
+
]));
|
|
90779
|
+
const items = policyKeys.map((ref) => {
|
|
90780
|
+
const p = policyByKey.get(ref);
|
|
90746
90781
|
if (!p)
|
|
90747
|
-
return `<div style="
|
|
90748
|
-
|
|
90782
|
+
return `<div style="padding:6px 0;border-bottom:1px solid var(--um-border-sub);">
|
|
90783
|
+
<span style="font-size:11px;font-family:monospace;background:var(--um-btn-2-bg);color:var(--um-btn-2-text);border:1px solid var(--um-btn-2-border);border-radius:9999px;padding:2px 8px;">${this.esc(ref)}</span>
|
|
90784
|
+
</div>`;
|
|
90785
|
+
const allowStr = p.allow?.length ? p.allow.join(", ") : "\u2014";
|
|
90749
90786
|
return `<div style="padding:6px 0;border-bottom:1px solid var(--um-border-sub);">
|
|
90750
|
-
|
|
90751
|
-
|
|
90752
|
-
|
|
90753
|
-
|
|
90787
|
+
<div style="font-size:12px;font-weight:600;color:var(--um-text-secondary);">${this.esc(p.displayName)}</div>
|
|
90788
|
+
${p.description ? `<div style="font-size:11px;color:var(--um-text-faint);">${this.esc(p.description)}</div>` : ""}
|
|
90789
|
+
<div style="font-size:11px;color:var(--um-badge-user-text);margin-top:2px;">allow: ${this.esc(allowStr)}</div>
|
|
90790
|
+
</div>`;
|
|
90754
90791
|
}).join("");
|
|
90755
90792
|
return `<div class="gm-panel-section">
|
|
90756
90793
|
<div class="gm-panel-section-header"><span class="gm-panel-section-title">\u{1F4CB} Pol\xEDticas</span></div>
|
|
@@ -90766,10 +90803,12 @@ var RolesTab = class {
|
|
|
90766
90803
|
const modal = document.createElement("div");
|
|
90767
90804
|
modal.className = "um-modal";
|
|
90768
90805
|
modal.style.cssText = "padding: 24px; width: min(520px, 92vw); max-height: 80vh; height: auto; aspect-ratio: unset; overflow-y: auto; display: block;";
|
|
90806
|
+
const existingPolicies = existing?.policies ?? existing?.policyIds ?? [];
|
|
90769
90807
|
const policiesCheckboxes = this.policies.map((p) => {
|
|
90770
|
-
const
|
|
90808
|
+
const ref = p.key || p.id;
|
|
90809
|
+
const checked = existingPolicies.includes(ref) ? " checked" : "";
|
|
90771
90810
|
return `<label style="display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px;color:var(--um-text-secondary);cursor:pointer;">
|
|
90772
|
-
<input type="checkbox" class="um-role-policy-chk" value="${this.esc(
|
|
90811
|
+
<input type="checkbox" class="um-role-policy-chk" value="${this.esc(ref)}"${checked} />
|
|
90773
90812
|
${this.esc(p.displayName)}${p.description ? ` <span style="color:var(--um-text-faint);">\u2014 ${this.esc(p.description)}</span>` : ""}
|
|
90774
90813
|
</label>`;
|
|
90775
90814
|
}).join("");
|
|
@@ -90813,14 +90852,14 @@ var RolesTab = class {
|
|
|
90813
90852
|
}
|
|
90814
90853
|
errEl.textContent = "";
|
|
90815
90854
|
const description = modal.querySelector("[name=description]").value.trim();
|
|
90816
|
-
const
|
|
90855
|
+
const policies = Array.from(
|
|
90817
90856
|
modal.querySelectorAll(".um-role-policy-chk:checked")
|
|
90818
90857
|
).map((c) => c.value);
|
|
90819
90858
|
const btn = modal.querySelector(".role-save");
|
|
90820
90859
|
btn.disabled = true;
|
|
90821
90860
|
btn.textContent = "...";
|
|
90822
90861
|
try {
|
|
90823
|
-
const body = { name, description: description || void 0,
|
|
90862
|
+
const body = { name, description: description || void 0, policies };
|
|
90824
90863
|
const url = isEdit ? `${this.gcdrBase()}/roles/${existing.id}` : `${this.gcdrBase()}/roles`;
|
|
90825
90864
|
const res = await fetch(url, {
|
|
90826
90865
|
method: isEdit ? "PUT" : "POST",
|
|
@@ -91125,12 +91164,12 @@ var UserManagementModalView = class {
|
|
|
91125
91164
|
--um-text-secondary: #374151;
|
|
91126
91165
|
--um-text-muted: #64748b;
|
|
91127
91166
|
--um-text-faint: #94a3b8;
|
|
91128
|
-
--um-accent: #
|
|
91129
|
-
--um-accent-hover: #
|
|
91130
|
-
--um-btn-2-bg: #
|
|
91131
|
-
--um-btn-2-text: #
|
|
91132
|
-
--um-btn-2-border: #
|
|
91133
|
-
--um-btn-2-hover: #
|
|
91167
|
+
--um-accent: #3f1a7d;
|
|
91168
|
+
--um-accent-hover: #5a2bab;
|
|
91169
|
+
--um-btn-2-bg: #f4effa;
|
|
91170
|
+
--um-btn-2-text: #3f1a7d;
|
|
91171
|
+
--um-btn-2-border: #c9a8e8;
|
|
91172
|
+
--um-btn-2-hover: #e8d8f5;
|
|
91134
91173
|
--um-btn-ghost-border: #e2e8f0;
|
|
91135
91174
|
--um-btn-ghost-hover: #f1f5f9;
|
|
91136
91175
|
--um-btn-ghost-text-hover:#475569;
|
|
@@ -91149,14 +91188,14 @@ var UserManagementModalView = class {
|
|
|
91149
91188
|
--um-toast-err-border: #ef4444;
|
|
91150
91189
|
--um-toast-err-text: #dc2626;
|
|
91151
91190
|
--um-spinner-border: #cbd5e1;
|
|
91152
|
-
--um-spinner-top: #
|
|
91191
|
+
--um-spinner-top: #3f1a7d;
|
|
91153
91192
|
--um-toggle-off: #cbd5e1;
|
|
91154
|
-
--um-notice-bg: #
|
|
91155
|
-
--um-notice-border: #
|
|
91193
|
+
--um-notice-bg: #f4effa;
|
|
91194
|
+
--um-notice-border: #c9a8e8;
|
|
91156
91195
|
--um-shadow: 0 32px 80px rgba(0,0,0,0.15);
|
|
91157
91196
|
--um-row-highlight: #f0fdf4;
|
|
91158
|
-
--um-gm-badge-domain-bg: #
|
|
91159
|
-
--um-gm-badge-domain-txt: #
|
|
91197
|
+
--um-gm-badge-domain-bg: #f4effa;
|
|
91198
|
+
--um-gm-badge-domain-txt: #3f1a7d;
|
|
91160
91199
|
--um-gm-badge-count-bg: #f1f5f9;
|
|
91161
91200
|
--um-gm-badge-count-txt: #64748b;
|
|
91162
91201
|
--um-gm-form-card-bg: #f8fafc;
|
|
@@ -91185,12 +91224,12 @@ var UserManagementModalView = class {
|
|
|
91185
91224
|
--um-text-secondary: #c4ccd9;
|
|
91186
91225
|
--um-text-muted: #64748b;
|
|
91187
91226
|
--um-text-faint: #475569;
|
|
91188
|
-
--um-accent: #
|
|
91189
|
-
--um-accent-hover: #
|
|
91190
|
-
--um-btn-2-bg: #
|
|
91191
|
-
--um-btn-2-text: #
|
|
91192
|
-
--um-btn-2-border: #
|
|
91193
|
-
--um-btn-2-hover: #
|
|
91227
|
+
--um-accent: #a78bdb;
|
|
91228
|
+
--um-accent-hover: #c3a8f0;
|
|
91229
|
+
--um-btn-2-bg: #2a1a45;
|
|
91230
|
+
--um-btn-2-text: #c3a8f0;
|
|
91231
|
+
--um-btn-2-border: #4a2a80;
|
|
91232
|
+
--um-btn-2-hover: #3a2060;
|
|
91194
91233
|
--um-btn-ghost-border: #2a3352;
|
|
91195
91234
|
--um-btn-ghost-hover: #1a2235;
|
|
91196
91235
|
--um-btn-ghost-text-hover:#94a3b8;
|
|
@@ -91209,14 +91248,14 @@ var UserManagementModalView = class {
|
|
|
91209
91248
|
--um-toast-err-border: #ef4444;
|
|
91210
91249
|
--um-toast-err-text: #f87171;
|
|
91211
91250
|
--um-spinner-border: #2a3352;
|
|
91212
|
-
--um-spinner-top: #
|
|
91251
|
+
--um-spinner-top: #a78bdb;
|
|
91213
91252
|
--um-toggle-off: #2a3352;
|
|
91214
|
-
--um-notice-bg: #
|
|
91215
|
-
--um-notice-border: #
|
|
91253
|
+
--um-notice-bg: #1e1235;
|
|
91254
|
+
--um-notice-border: #4a2a80;
|
|
91216
91255
|
--um-shadow: 0 32px 80px rgba(0,0,0,0.6);
|
|
91217
91256
|
--um-row-highlight: #0e2a1e;
|
|
91218
|
-
--um-gm-badge-domain-bg: #
|
|
91219
|
-
--um-gm-badge-domain-txt: #
|
|
91257
|
+
--um-gm-badge-domain-bg: #2a1a45;
|
|
91258
|
+
--um-gm-badge-domain-txt: #c3a8f0;
|
|
91220
91259
|
--um-gm-badge-count-bg: #1e2d4a;
|
|
91221
91260
|
--um-gm-badge-count-txt: #94a3b8;
|
|
91222
91261
|
--um-gm-form-card-bg: #0f1829;
|
|
@@ -91239,6 +91278,20 @@ var UserManagementModalView = class {
|
|
|
91239
91278
|
|
|
91240
91279
|
/* Header handled by ModalHeader (RFC-0121) */
|
|
91241
91280
|
|
|
91281
|
+
/* Force MyIO purple header regardless of light/dark theme \u2014 overrides myio-modal-header--light */
|
|
91282
|
+
.um-modal .myio-modal-header--light {
|
|
91283
|
+
background: #3f1a7d !important;
|
|
91284
|
+
border-bottom-color: #2e1260 !important;
|
|
91285
|
+
}
|
|
91286
|
+
.um-modal .myio-modal-header--light .myio-modal-header__title { color: #fff !important; }
|
|
91287
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn { color: rgba(255,255,255,0.8) !important; }
|
|
91288
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn:hover {
|
|
91289
|
+
background: rgba(255,255,255,0.15) !important; color: #fff !important;
|
|
91290
|
+
}
|
|
91291
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn--close:hover {
|
|
91292
|
+
background: rgba(239,68,68,0.3) !important; color: #fecaca !important;
|
|
91293
|
+
}
|
|
91294
|
+
|
|
91242
91295
|
/* Maximize button \u2014 CSS window icon (emoji renders as plain square on some platforms) */
|
|
91243
91296
|
#um-modal-maximize { font-size: 0 !important; position: relative; }
|
|
91244
91297
|
#um-modal-maximize::before {
|
|
@@ -135492,6 +135545,50 @@ var STYLES3 = `
|
|
|
135492
135545
|
font-size: 12px; font-weight: 600; color: #e67e22;
|
|
135493
135546
|
background: #fef3e8; border-radius: 4px; padding: 1px 6px;
|
|
135494
135547
|
}
|
|
135548
|
+
/* Collapse/expand */
|
|
135549
|
+
#${MODAL_ID3} .abm-device-card.collapsed .abm-rule-list { display: none; }
|
|
135550
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-rule-group-devices,
|
|
135551
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-rule-detail-wrap { display: none; }
|
|
135552
|
+
#${MODAL_ID3} .abm-chevron {
|
|
135553
|
+
font-size: 11px; color: #94a3b8; transition: transform 0.18s; flex-shrink: 0; user-select: none;
|
|
135554
|
+
}
|
|
135555
|
+
#${MODAL_ID3} .abm-device-card.collapsed .abm-chevron,
|
|
135556
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-chevron { transform: rotate(-90deg); }
|
|
135557
|
+
#${MODAL_ID3} .abm-device-header { cursor: pointer; }
|
|
135558
|
+
#${MODAL_ID3} .abm-device-header:hover { background: #f0f9f7; }
|
|
135559
|
+
#${MODAL_ID3} .abm-rule-group-header { cursor: pointer; }
|
|
135560
|
+
#${MODAL_ID3} .abm-rule-group-header:hover { background: #e6f4f1; }
|
|
135561
|
+
/* Alarm badge */
|
|
135562
|
+
#${MODAL_ID3} .abm-alarm-badge {
|
|
135563
|
+
display: inline-flex; align-items: center; gap: 3px;
|
|
135564
|
+
background: #fee2e2; color: #b91c1c; border-radius: 10px;
|
|
135565
|
+
font-size: 10px; font-weight: 700; padding: 1px 7px; flex-shrink: 0;
|
|
135566
|
+
}
|
|
135567
|
+
#${MODAL_ID3} .abm-alarm-badge.zero { background: #f0f9f7; color: #6b7280; }
|
|
135568
|
+
/* Filter bar */
|
|
135569
|
+
#${MODAL_ID3} .abm-filter-bar {
|
|
135570
|
+
display: flex; gap: 8px; align-items: center; margin-bottom: 14px;
|
|
135571
|
+
padding: 10px 12px; background: #f8faf9; border: 1px solid #e0eceb; border-radius: 8px;
|
|
135572
|
+
}
|
|
135573
|
+
#${MODAL_ID3} .abm-filter-input {
|
|
135574
|
+
flex: 1; border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 10px;
|
|
135575
|
+
font-size: 12px; outline: none; transition: border-color 0.15s;
|
|
135576
|
+
}
|
|
135577
|
+
#${MODAL_ID3} .abm-filter-input:focus { border-color: ${TEAL2}; }
|
|
135578
|
+
#${MODAL_ID3} .abm-filter-select {
|
|
135579
|
+
border: 1px solid #d1d5db; border-radius: 6px; padding: 5px 8px;
|
|
135580
|
+
font-size: 12px; outline: none; min-width: 140px; max-width: 220px;
|
|
135581
|
+
background: #fff; cursor: pointer;
|
|
135582
|
+
}
|
|
135583
|
+
#${MODAL_ID3} .abm-filter-count {
|
|
135584
|
+
font-size: 11px; color: #64748b; white-space: nowrap; flex-shrink: 0;
|
|
135585
|
+
}
|
|
135586
|
+
#${MODAL_ID3} .abm-filter-clear {
|
|
135587
|
+
background: none; border: 1px solid #e0eceb; border-radius: 6px; cursor: pointer;
|
|
135588
|
+
font-size: 11px; color: #64748b; padding: 4px 8px; white-space: nowrap; flex-shrink: 0;
|
|
135589
|
+
transition: background 0.12s;
|
|
135590
|
+
}
|
|
135591
|
+
#${MODAL_ID3} .abm-filter-clear:hover { background: #f0f4f3; color: #1e293b; }
|
|
135495
135592
|
/* Confirmation modal \u2014 value edit overwrite warning */
|
|
135496
135593
|
.abm-confirm-overlay {
|
|
135497
135594
|
position: fixed; inset: 0;
|
|
@@ -135922,6 +136019,8 @@ function bindRuleEditEvents(card, bundle, gcdrTenantId, baseUrl, getViewMode) {
|
|
|
135922
136019
|
if (!ruleId) return;
|
|
135923
136020
|
const rule = bundle.rules[ruleId];
|
|
135924
136021
|
if (!rule) return;
|
|
136022
|
+
editBtn.closest(".abm-device-card")?.classList.remove("collapsed");
|
|
136023
|
+
editBtn.closest(".abm-rule-group")?.classList.remove("collapsed");
|
|
135925
136024
|
const viewMode = getViewMode();
|
|
135926
136025
|
if (viewMode === "por-regra") {
|
|
135927
136026
|
const ruleGroup = editBtn.closest(".abm-rule-group");
|
|
@@ -135940,13 +136039,109 @@ function bindRuleEditEvents(card, bundle, gcdrTenantId, baseUrl, getViewMode) {
|
|
|
135940
136039
|
openGranularValueEdit(ruleItem, rule, device, bundle, gcdrTenantId, baseUrl);
|
|
135941
136040
|
});
|
|
135942
136041
|
}
|
|
136042
|
+
function bindCollapseEvents(card) {
|
|
136043
|
+
card.querySelectorAll(".abm-device-header").forEach((header) => {
|
|
136044
|
+
header.addEventListener("click", (e) => {
|
|
136045
|
+
if (e.target.closest("button")) return;
|
|
136046
|
+
header.closest(".abm-device-card")?.classList.toggle("collapsed");
|
|
136047
|
+
});
|
|
136048
|
+
});
|
|
136049
|
+
card.querySelectorAll(".abm-rule-group-header").forEach((header) => {
|
|
136050
|
+
header.addEventListener("click", (e) => {
|
|
136051
|
+
if (e.target.closest("button")) return;
|
|
136052
|
+
header.closest(".abm-rule-group")?.classList.toggle("collapsed");
|
|
136053
|
+
});
|
|
136054
|
+
});
|
|
136055
|
+
}
|
|
136056
|
+
function bindFilterBar(card, bundle, getViewMode) {
|
|
136057
|
+
const input = card.querySelector("#abm-filter-input");
|
|
136058
|
+
const select = card.querySelector("#abm-filter-select");
|
|
136059
|
+
const countEl = card.querySelector("#abm-filter-count");
|
|
136060
|
+
const clearBtn = card.querySelector("#abm-filter-clear");
|
|
136061
|
+
if (!input) return;
|
|
136062
|
+
const updateSelectOptions = (text) => {
|
|
136063
|
+
if (!select) return;
|
|
136064
|
+
const lower = text.toLowerCase();
|
|
136065
|
+
const types = /* @__PURE__ */ new Set();
|
|
136066
|
+
bundle.devices.forEach((d) => {
|
|
136067
|
+
const name = (d.displayName || d.name).toLowerCase();
|
|
136068
|
+
if (!lower || name.includes(lower) || d.type.toLowerCase().includes(lower)) {
|
|
136069
|
+
types.add(d.type);
|
|
136070
|
+
}
|
|
136071
|
+
});
|
|
136072
|
+
const prev = new Set(Array.from(select.selectedOptions).map((o) => o.value));
|
|
136073
|
+
select.innerHTML = Array.from(types).sort().map(
|
|
136074
|
+
(t) => `<option value="${escHtml3(t)}"${prev.has(t) ? " selected" : ""}>${escHtml3(t)}</option>`
|
|
136075
|
+
).join("");
|
|
136076
|
+
select.size = Math.min(types.size, 4) || 1;
|
|
136077
|
+
};
|
|
136078
|
+
const applyFilter = () => {
|
|
136079
|
+
const text = input.value.toLowerCase().trim();
|
|
136080
|
+
const selectedTypes = new Set(Array.from(select?.selectedOptions ?? []).map((o) => o.value));
|
|
136081
|
+
const mode = getViewMode();
|
|
136082
|
+
if (mode === "granular") {
|
|
136083
|
+
let visible = 0;
|
|
136084
|
+
card.querySelectorAll(".abm-device-card").forEach((dc) => {
|
|
136085
|
+
const name = (dc.querySelector(".abm-device-name")?.textContent ?? "").toLowerCase();
|
|
136086
|
+
const type = dc.querySelector(".abm-device-type")?.textContent ?? "";
|
|
136087
|
+
const ruleNames = Array.from(dc.querySelectorAll(".abm-rule-name")).map((el2) => (el2.textContent ?? "").toLowerCase());
|
|
136088
|
+
const matchText = !text || name.includes(text) || type.toLowerCase().includes(text) || ruleNames.some((r) => r.includes(text));
|
|
136089
|
+
const matchType = selectedTypes.size === 0 || selectedTypes.has(type);
|
|
136090
|
+
dc.style.display = matchText && matchType ? "" : "none";
|
|
136091
|
+
if (matchText && matchType) visible++;
|
|
136092
|
+
});
|
|
136093
|
+
if (countEl) countEl.textContent = `${visible} dispositivo(s)`;
|
|
136094
|
+
} else {
|
|
136095
|
+
let visible = 0;
|
|
136096
|
+
card.querySelectorAll(".abm-rule-group").forEach((rg) => {
|
|
136097
|
+
const ruleName = (rg.querySelector(".abm-rule-group-name")?.textContent ?? "").toLowerCase();
|
|
136098
|
+
const deviceTexts = Array.from(rg.querySelectorAll(".abm-rule-group-device span")).map((el2) => (el2.textContent ?? "").toLowerCase());
|
|
136099
|
+
const matchText = !text || ruleName.includes(text) || deviceTexts.some((t) => t.includes(text));
|
|
136100
|
+
rg.style.display = matchText ? "" : "none";
|
|
136101
|
+
if (matchText) visible++;
|
|
136102
|
+
});
|
|
136103
|
+
if (countEl) countEl.textContent = `${visible} regra(s)`;
|
|
136104
|
+
}
|
|
136105
|
+
updateSelectOptions(text);
|
|
136106
|
+
};
|
|
136107
|
+
input.addEventListener("input", applyFilter);
|
|
136108
|
+
select?.addEventListener("change", applyFilter);
|
|
136109
|
+
clearBtn?.addEventListener("click", () => {
|
|
136110
|
+
input.value = "";
|
|
136111
|
+
if (select) Array.from(select.options).forEach((o) => {
|
|
136112
|
+
o.selected = false;
|
|
136113
|
+
});
|
|
136114
|
+
applyFilter();
|
|
136115
|
+
});
|
|
136116
|
+
updateSelectOptions("");
|
|
136117
|
+
const totalDevices = bundle.devices.length;
|
|
136118
|
+
if (countEl) countEl.textContent = `${totalDevices} dispositivo(s)`;
|
|
136119
|
+
}
|
|
136120
|
+
var _OFFLINE_ALARM_TYPES = ["DEVICE OFFLINE", "DISPOSITIVO OFFLINE"];
|
|
136121
|
+
function _getActiveAlarmCount(gcdrDeviceId) {
|
|
136122
|
+
const aso = window.AlarmServiceOrchestrator;
|
|
136123
|
+
if (!aso?.deviceAlarmMap) return 0;
|
|
136124
|
+
const alarms = aso.deviceAlarmMap.get(gcdrDeviceId) || [];
|
|
136125
|
+
const showOffline = window.MyIOOrchestrator?.showOfflineAlarms === true;
|
|
136126
|
+
return showOffline ? alarms.length : alarms.filter((a) => {
|
|
136127
|
+
const t = (a.title ?? "").toUpperCase();
|
|
136128
|
+
return !(_OFFLINE_ALARM_TYPES.some((ex) => t.startsWith(ex)) || a.alarmType === "connectivity");
|
|
136129
|
+
}).length;
|
|
136130
|
+
}
|
|
136131
|
+
function _alarmBadgeHtml(count) {
|
|
136132
|
+
if (count === 0) return `<span class="abm-alarm-badge zero">0 \u{1F514}</span>`;
|
|
136133
|
+
return `<span class="abm-alarm-badge">\u{1F534} ${count}</span>`;
|
|
136134
|
+
}
|
|
135943
136135
|
function renderDevice(device, rules, viewMode = "granular") {
|
|
135944
136136
|
const deviceRules = (device.ruleIds ?? []).map((rid) => rules[rid]).filter(Boolean);
|
|
136137
|
+
const alarmCount = _getActiveAlarmCount(device.id);
|
|
135945
136138
|
return `
|
|
135946
|
-
<div class="abm-device-card">
|
|
136139
|
+
<div class="abm-device-card collapsed" data-device-id="${escHtml3(device.id)}">
|
|
135947
136140
|
<div class="abm-device-header">
|
|
136141
|
+
<span class="abm-chevron">\u25BE</span>
|
|
135948
136142
|
<span style="font-size:16px;">\u{1F4E1}</span>
|
|
135949
136143
|
<span class="abm-device-name">${escHtml3(device.displayName || device.name)}</span>
|
|
136144
|
+
${_alarmBadgeHtml(alarmCount)}
|
|
135950
136145
|
<span class="abm-device-type">${escHtml3(device.type)}</span>
|
|
135951
136146
|
</div>
|
|
135952
136147
|
<ul class="abm-rule-list">
|
|
@@ -135973,11 +136168,14 @@ function renderByRuleView(bundle) {
|
|
|
135973
136168
|
for (const [baseRuleId, devs] of ruleDevicesMap) {
|
|
135974
136169
|
const baseRule = rules[baseRuleId];
|
|
135975
136170
|
if (!baseRule) continue;
|
|
136171
|
+
const groupAlarmCount = devs.reduce((sum, d) => sum + _getActiveAlarmCount(d.id), 0);
|
|
135976
136172
|
groups += `
|
|
135977
|
-
<div class="abm-rule-group">
|
|
136173
|
+
<div class="abm-rule-group collapsed" data-rule-id="${escHtml3(baseRuleId)}">
|
|
135978
136174
|
<div class="abm-rule-group-header">
|
|
136175
|
+
<span class="abm-chevron">\u25BE</span>
|
|
135979
136176
|
<span style="font-size:16px;">\u{1F514}</span>
|
|
135980
136177
|
<span class="abm-rule-group-name">${escHtml3(baseRule.name)}</span>
|
|
136178
|
+
${_alarmBadgeHtml(groupAlarmCount)}
|
|
135981
136179
|
<button class="abm-edit-rule-btn" data-edit-rule="${escHtml3(baseRuleId)}" title="Editar dias/hor\xE1rio">\u270F\uFE0F</button>
|
|
135982
136180
|
</div>
|
|
135983
136181
|
<div class="abm-rule-detail" style="padding:8px 14px;" data-rule-id="${escHtml3(baseRuleId)}">
|
|
@@ -136041,7 +136239,6 @@ function renderBundle(bundle, viewMode = "granular") {
|
|
|
136041
136239
|
<div class="abm-summary-bar">
|
|
136042
136240
|
<div class="abm-summary-item"><div class="abm-summary-num">${deviceCount}</div><div class="abm-summary-label">Dispositivos</div></div>
|
|
136043
136241
|
<div class="abm-summary-item"><div class="abm-summary-num">${ruleCount}</div><div class="abm-summary-label">Regras</div></div>
|
|
136044
|
-
<div class="abm-summary-item"><div class="abm-summary-num">${assets.length}</div><div class="abm-summary-label">Assets</div></div>
|
|
136045
136242
|
</div>
|
|
136046
136243
|
${renderByRuleView(bundle)}
|
|
136047
136244
|
`;
|
|
@@ -136075,10 +136272,6 @@ function renderBundle(bundle, viewMode = "granular") {
|
|
|
136075
136272
|
<div class="abm-summary-num">${ruleCount}</div>
|
|
136076
136273
|
<div class="abm-summary-label">Regras</div>
|
|
136077
136274
|
</div>
|
|
136078
|
-
<div class="abm-summary-item">
|
|
136079
|
-
<div class="abm-summary-num">${assets.length}</div>
|
|
136080
|
-
<div class="abm-summary-label">Assets</div>
|
|
136081
|
-
</div>
|
|
136082
136275
|
</div>
|
|
136083
136276
|
${groups}
|
|
136084
136277
|
`;
|
|
@@ -136169,7 +136362,21 @@ async function openAlarmBundleMapModal(params) {
|
|
|
136169
136362
|
const customerName = bundle.customer.displayName || bundle.customer.name || "";
|
|
136170
136363
|
const rerenderBundle = () => {
|
|
136171
136364
|
render3(renderBundle(bundle, viewMode), customerName, true);
|
|
136365
|
+
const body = card.querySelector(".abm-body");
|
|
136366
|
+
if (body) {
|
|
136367
|
+
const filterBarEl = document.createElement("div");
|
|
136368
|
+
filterBarEl.className = "abm-filter-bar";
|
|
136369
|
+
filterBarEl.innerHTML = `
|
|
136370
|
+
<input class="abm-filter-input" type="text" id="abm-filter-input" placeholder="Buscar dispositivo, regra, tipo..." />
|
|
136371
|
+
<select class="abm-filter-select" id="abm-filter-select" multiple size="1"></select>
|
|
136372
|
+
<span class="abm-filter-count" id="abm-filter-count"></span>
|
|
136373
|
+
<button class="abm-filter-clear" id="abm-filter-clear" type="button">\u2715 Limpar</button>
|
|
136374
|
+
`;
|
|
136375
|
+
body.insertBefore(filterBarEl, body.firstChild);
|
|
136376
|
+
}
|
|
136172
136377
|
bindRuleEditEvents(card, bundle, params.gcdrTenantId, baseUrl, () => viewMode);
|
|
136378
|
+
bindCollapseEvents(card);
|
|
136379
|
+
bindFilterBar(card, bundle, () => viewMode);
|
|
136173
136380
|
card.querySelectorAll("[data-view]").forEach((btn) => {
|
|
136174
136381
|
btn.addEventListener("click", () => {
|
|
136175
136382
|
const newMode = btn.getAttribute("data-view");
|
package/dist/index.d.cts
CHANGED
|
@@ -10435,11 +10435,12 @@ interface TBUserPage {
|
|
|
10435
10435
|
}
|
|
10436
10436
|
interface GCDRPolicy {
|
|
10437
10437
|
id: string;
|
|
10438
|
+
key?: string;
|
|
10438
10439
|
displayName: string;
|
|
10439
10440
|
description?: string;
|
|
10440
10441
|
allow: string[];
|
|
10441
10442
|
deny: string[];
|
|
10442
|
-
riskLevel?: 'LOW' | 'MEDIUM' | 'HIGH';
|
|
10443
|
+
riskLevel?: 'low' | 'medium' | 'high' | 'critical' | 'LOW' | 'MEDIUM' | 'HIGH';
|
|
10443
10444
|
/** System policies are immutable */
|
|
10444
10445
|
isSystem?: boolean;
|
|
10445
10446
|
createdAt?: string;
|
|
@@ -10447,10 +10448,14 @@ interface GCDRPolicy {
|
|
|
10447
10448
|
}
|
|
10448
10449
|
interface GCDRRole {
|
|
10449
10450
|
id: string;
|
|
10451
|
+
key?: string;
|
|
10450
10452
|
displayName: string;
|
|
10451
10453
|
description?: string;
|
|
10452
|
-
/**
|
|
10453
|
-
|
|
10454
|
+
/** Policy keys as returned by the GCDR API (e.g. "policy:alarm-management") */
|
|
10455
|
+
policies?: string[];
|
|
10456
|
+
/** Legacy field — use `policies` instead */
|
|
10457
|
+
policyIds?: string[];
|
|
10458
|
+
riskLevel?: 'low' | 'medium' | 'high' | 'critical';
|
|
10454
10459
|
isSystem?: boolean;
|
|
10455
10460
|
createdAt?: string;
|
|
10456
10461
|
updatedAt?: string;
|