myio-js-library 0.1.485 → 0.1.487
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 +286 -57
- package/dist/index.d.cts +8 -3
- package/dist/index.js +286 -57
- package/dist/myio-js-library.umd.js +286 -57
- 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.487",
|
|
1163
1163
|
description: "A clean, standalone JS SDK for MYIO projects",
|
|
1164
1164
|
license: "MIT",
|
|
1165
1165
|
repository: "github:gh-myio/myio-js-library",
|
|
@@ -62014,7 +62014,7 @@ var SettingsModalView = class {
|
|
|
62014
62014
|
<div class="customer-name-container">
|
|
62015
62015
|
<div class="customer-info-row">
|
|
62016
62016
|
<div class="device-type-icon-wrapper">
|
|
62017
|
-
${this.getDeviceTypeIcon(deviceType)}
|
|
62017
|
+
${this.getDeviceTypeIcon(deviceType ?? "")}
|
|
62018
62018
|
</div>
|
|
62019
62019
|
<div class="customer-info-content">
|
|
62020
62020
|
<div class="customer-name-label">Shopping</div>
|
|
@@ -62620,7 +62620,7 @@ var SettingsModalView = class {
|
|
|
62620
62620
|
not_installed: { text: "N\xE3o instalado", color: "#94a3b8" },
|
|
62621
62621
|
unknown: { text: "Sem informa\xE7\xE3o", color: "#94a3b8" }
|
|
62622
62622
|
};
|
|
62623
|
-
const statusInfo = statusMap[mapDeviceStatusToCardStatus(deviceStatus) || ""] || {
|
|
62623
|
+
const statusInfo = statusMap[mapDeviceStatusToCardStatus(deviceStatus ?? "") || ""] || {
|
|
62624
62624
|
text: "Desconhecido",
|
|
62625
62625
|
color: "#6b7280"
|
|
62626
62626
|
};
|
|
@@ -62713,6 +62713,13 @@ var SettingsModalView = class {
|
|
|
62713
62713
|
}
|
|
62714
62714
|
|
|
62715
62715
|
/* Header handled by ModalHeader (RFC-0121) */
|
|
62716
|
+
.myio-device-settings-modal .myio-modal-header__title {
|
|
62717
|
+
font-size: 14px;
|
|
62718
|
+
font-weight: 600;
|
|
62719
|
+
}
|
|
62720
|
+
.myio-device-settings-modal .myio-modal-header__icon {
|
|
62721
|
+
font-size: 15px;
|
|
62722
|
+
}
|
|
62716
62723
|
|
|
62717
62724
|
.myio-device-settings-modal.is-maximized {
|
|
62718
62725
|
width: 100vw !important;
|
|
@@ -89876,6 +89883,7 @@ var UserDetailTab = class {
|
|
|
89876
89883
|
// RFC-0197: Assignments section state
|
|
89877
89884
|
assignments = [];
|
|
89878
89885
|
availableRoles = [];
|
|
89886
|
+
availablePolicies = [];
|
|
89879
89887
|
assignmentsEl = null;
|
|
89880
89888
|
assignmentsVersion = 0;
|
|
89881
89889
|
constructor(config, user, callbacks) {
|
|
@@ -89969,11 +89977,11 @@ var UserDetailTab = class {
|
|
|
89969
89977
|
const section = document.createElement("div");
|
|
89970
89978
|
section.style.cssText = "margin-top:20px;border:1px solid var(--um-border);border-radius:10px;overflow:hidden;";
|
|
89971
89979
|
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
|
|
89980
|
+
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);";
|
|
89981
|
+
sectionHeader.innerHTML = `<span style="font-size:13px;font-weight:600;color:#fff;">\u{1F511} Fun\xE7\xF5es / Pap\xE9is</span>`;
|
|
89974
89982
|
const addBtn = document.createElement("button");
|
|
89975
89983
|
addBtn.className = "um-btn um-btn--secondary um-btn--sm";
|
|
89976
|
-
addBtn.textContent = "+
|
|
89984
|
+
addBtn.textContent = "+ Adicionar";
|
|
89977
89985
|
addBtn.addEventListener("click", () => this.showAssignForm());
|
|
89978
89986
|
sectionHeader.appendChild(addBtn);
|
|
89979
89987
|
section.appendChild(sectionHeader);
|
|
@@ -89988,12 +89996,14 @@ var UserDetailTab = class {
|
|
|
89988
89996
|
async loadAssignments() {
|
|
89989
89997
|
const userId = this.user.id.id;
|
|
89990
89998
|
try {
|
|
89991
|
-
const [assignRes, rolesRes] = await Promise.all([
|
|
89999
|
+
const [assignRes, rolesRes, policiesRes] = await Promise.all([
|
|
89992
90000
|
fetch(`${this.gcdrBase()}/authorization/users/${userId}/assignments`, { headers: this.gcdrHeaders() }),
|
|
89993
|
-
fetch(`${this.gcdrBase()}/roles?limit=100`, { headers: this.gcdrHeaders() })
|
|
90001
|
+
fetch(`${this.gcdrBase()}/roles?limit=100`, { headers: this.gcdrHeaders() }),
|
|
90002
|
+
fetch(`${this.gcdrBase()}/policies?limit=100`, { headers: this.gcdrHeaders() })
|
|
89994
90003
|
]);
|
|
89995
90004
|
this.assignments = assignRes.ok ? this.unwrapList(await assignRes.json()) : [];
|
|
89996
90005
|
this.availableRoles = rolesRes.ok ? this.unwrapList(await rolesRes.json()) : [];
|
|
90006
|
+
this.availablePolicies = policiesRes.ok ? this.unwrapList(await policiesRes.json()) : [];
|
|
89997
90007
|
this.renderAssignments();
|
|
89998
90008
|
} catch (err) {
|
|
89999
90009
|
console.error("[UserDetailTab] loadAssignments error", err);
|
|
@@ -90041,14 +90051,19 @@ var UserDetailTab = class {
|
|
|
90041
90051
|
overlay.style.zIndex = "100001";
|
|
90042
90052
|
const modal = document.createElement("div");
|
|
90043
90053
|
modal.className = "um-modal";
|
|
90044
|
-
modal.style.cssText = "
|
|
90054
|
+
modal.style.cssText = "width: min(820px, 92vw); max-height: 85vh; height: auto; aspect-ratio: unset; overflow: hidden; display: flex; flex-direction: column;";
|
|
90045
90055
|
const gcdrCid = window.MyIOOrchestrator?.gcdrCustomerId || "";
|
|
90046
90056
|
const scopeOptions = [
|
|
90047
|
-
{ value: "*", label: "* (global)" },
|
|
90048
|
-
...gcdrCid ? [{ value: `customer:${gcdrCid}`, label: `
|
|
90057
|
+
{ value: "*", label: "* (global \u2014 todos os clientes)" },
|
|
90058
|
+
...gcdrCid ? [{ value: `customer:${gcdrCid}`, label: `Cliente atual (${gcdrCid.slice(0, 8)}...)` }] : []
|
|
90049
90059
|
];
|
|
90050
90060
|
modal.innerHTML = `
|
|
90051
|
-
<
|
|
90061
|
+
<div style="display:flex;align-items:center;gap:10px;padding:14px 20px;background:var(--um-accent);border-bottom:1px solid var(--um-btn-2-border);flex-shrink:0;">
|
|
90062
|
+
<span style="font-size:15px;">\u{1F511}</span>
|
|
90063
|
+
<span style="flex:1;font-size:14px;font-weight:600;color:#fff;">Atribuir Fun\xE7\xE3o / Papel</span>
|
|
90064
|
+
<button type="button" class="assign-close" style="background:none;border:none;color:rgba(255,255,255,0.8);font-size:18px;cursor:pointer;padding:2px 6px;border-radius:4px;line-height:1;">\u2715</button>
|
|
90065
|
+
</div>
|
|
90066
|
+
<div style="padding:20px 24px;overflow-y:auto;flex:1;">
|
|
90052
90067
|
<div class="um-form" style="max-width:100%;">
|
|
90053
90068
|
<div class="um-form-group">
|
|
90054
90069
|
<label class="um-label">Fun\xE7\xE3o <span class="um-req">*</span></label>
|
|
@@ -90058,6 +90073,10 @@ var UserDetailTab = class {
|
|
|
90058
90073
|
</select>
|
|
90059
90074
|
<span class="um-field-error" data-for="roleId"></span>
|
|
90060
90075
|
</div>
|
|
90076
|
+
<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);">
|
|
90077
|
+
<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>
|
|
90078
|
+
<div class="um-assign-policies-list" style="display:flex;flex-direction:column;gap:6px;"></div>
|
|
90079
|
+
</div>
|
|
90061
90080
|
<div class="um-form-group">
|
|
90062
90081
|
<label class="um-label">Escopo <span class="um-req">*</span></label>
|
|
90063
90082
|
<select class="um-input" name="scope">
|
|
@@ -90077,13 +90096,38 @@ var UserDetailTab = class {
|
|
|
90077
90096
|
<button class="um-btn um-btn--primary assign-save">Atribuir</button>
|
|
90078
90097
|
</div>
|
|
90079
90098
|
</div>
|
|
90099
|
+
</div>
|
|
90080
90100
|
`;
|
|
90081
90101
|
overlay.appendChild(modal);
|
|
90082
90102
|
document.body.appendChild(overlay);
|
|
90103
|
+
const roleSelect = modal.querySelector("[name=roleId]");
|
|
90104
|
+
const policiesPreview = modal.querySelector(".um-assign-policies-preview");
|
|
90105
|
+
const policiesList = modal.querySelector(".um-assign-policies-list");
|
|
90106
|
+
roleSelect.addEventListener("change", () => {
|
|
90107
|
+
const role = this.availableRoles.find((r) => r.id === roleSelect.value);
|
|
90108
|
+
const policyRefs = role?.policies ?? role?.policyIds ?? [];
|
|
90109
|
+
if (!role || policyRefs.length === 0) {
|
|
90110
|
+
policiesPreview.style.display = "none";
|
|
90111
|
+
return;
|
|
90112
|
+
}
|
|
90113
|
+
const policyByKey = new Map(this.availablePolicies.flatMap((p) => [
|
|
90114
|
+
[p.key || p.id, p],
|
|
90115
|
+
[p.id, p]
|
|
90116
|
+
]));
|
|
90117
|
+
const matched = policyRefs.map((ref) => policyByKey.get(ref)).filter(Boolean);
|
|
90118
|
+
policiesList.innerHTML = matched.length > 0 ? matched.map((p) => `
|
|
90119
|
+
<div style="display:flex;align-items:flex-start;gap:8px;padding:6px 8px;background:var(--um-bg-input);border-radius:6px;">
|
|
90120
|
+
<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>
|
|
90121
|
+
${p.description ? `<span style="font-size:11px;color:var(--um-text-muted);padding-top:2px;">${this.esc(p.description)}</span>` : ""}
|
|
90122
|
+
</div>`).join("") : policyRefs.map((ref) => `
|
|
90123
|
+
<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("");
|
|
90124
|
+
policiesPreview.style.display = "block";
|
|
90125
|
+
});
|
|
90083
90126
|
const close = () => overlay.remove();
|
|
90084
90127
|
overlay.addEventListener("click", (e) => {
|
|
90085
90128
|
if (e.target === overlay) close();
|
|
90086
90129
|
});
|
|
90130
|
+
modal.querySelector(".assign-close").addEventListener("click", close);
|
|
90087
90131
|
modal.querySelector(".assign-cancel").addEventListener("click", close);
|
|
90088
90132
|
modal.querySelector(".assign-save").addEventListener("click", async () => {
|
|
90089
90133
|
const roleId = modal.querySelector("[name=roleId]").value.trim();
|
|
@@ -90697,7 +90741,8 @@ var RolesTab = class {
|
|
|
90697
90741
|
const item = document.createElement("div");
|
|
90698
90742
|
item.className = `gm-accordion-item${this.expandedId === r.id ? " gm-accordion-item--open" : ""}`;
|
|
90699
90743
|
const sysBadge = r.isSystem ? `<span class="gm-badge gm-badge--count">SISTEMA</span>` : "";
|
|
90700
|
-
const
|
|
90744
|
+
const policyKeys = r.policies ?? r.policyIds ?? [];
|
|
90745
|
+
const policyCount = policyKeys.length;
|
|
90701
90746
|
const policyBadge = `<span class="gm-badge gm-badge--domain">${policyCount} pol\xEDticas</span>`;
|
|
90702
90747
|
item.innerHTML = `
|
|
90703
90748
|
<div class="gm-accordion-header">
|
|
@@ -90737,20 +90782,26 @@ var RolesTab = class {
|
|
|
90737
90782
|
return item;
|
|
90738
90783
|
}
|
|
90739
90784
|
buildRolePoliciesHtml(r) {
|
|
90740
|
-
|
|
90785
|
+
const policyKeys = r.policies ?? r.policyIds ?? [];
|
|
90786
|
+
if (!policyKeys.length) {
|
|
90741
90787
|
return `<div class="gm-panel-section"><span class="gm-empty-inline">Nenhuma pol\xEDtica associada.</span></div>`;
|
|
90742
90788
|
}
|
|
90743
|
-
const
|
|
90744
|
-
|
|
90745
|
-
|
|
90789
|
+
const policyByKey = new Map(this.policies.flatMap((p) => [
|
|
90790
|
+
[p.key || p.id, p],
|
|
90791
|
+
[p.id, p]
|
|
90792
|
+
]));
|
|
90793
|
+
const items = policyKeys.map((ref) => {
|
|
90794
|
+
const p = policyByKey.get(ref);
|
|
90746
90795
|
if (!p)
|
|
90747
|
-
return `<div style="
|
|
90748
|
-
|
|
90796
|
+
return `<div style="padding:6px 0;border-bottom:1px solid var(--um-border-sub);">
|
|
90797
|
+
<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>
|
|
90798
|
+
</div>`;
|
|
90799
|
+
const allowStr = p.allow?.length ? p.allow.join(", ") : "\u2014";
|
|
90749
90800
|
return `<div style="padding:6px 0;border-bottom:1px solid var(--um-border-sub);">
|
|
90750
|
-
|
|
90751
|
-
|
|
90752
|
-
|
|
90753
|
-
|
|
90801
|
+
<div style="font-size:12px;font-weight:600;color:var(--um-text-secondary);">${this.esc(p.displayName)}</div>
|
|
90802
|
+
${p.description ? `<div style="font-size:11px;color:var(--um-text-faint);">${this.esc(p.description)}</div>` : ""}
|
|
90803
|
+
<div style="font-size:11px;color:var(--um-badge-user-text);margin-top:2px;">allow: ${this.esc(allowStr)}</div>
|
|
90804
|
+
</div>`;
|
|
90754
90805
|
}).join("");
|
|
90755
90806
|
return `<div class="gm-panel-section">
|
|
90756
90807
|
<div class="gm-panel-section-header"><span class="gm-panel-section-title">\u{1F4CB} Pol\xEDticas</span></div>
|
|
@@ -90766,10 +90817,12 @@ var RolesTab = class {
|
|
|
90766
90817
|
const modal = document.createElement("div");
|
|
90767
90818
|
modal.className = "um-modal";
|
|
90768
90819
|
modal.style.cssText = "padding: 24px; width: min(520px, 92vw); max-height: 80vh; height: auto; aspect-ratio: unset; overflow-y: auto; display: block;";
|
|
90820
|
+
const existingPolicies = existing?.policies ?? existing?.policyIds ?? [];
|
|
90769
90821
|
const policiesCheckboxes = this.policies.map((p) => {
|
|
90770
|
-
const
|
|
90822
|
+
const ref = p.key || p.id;
|
|
90823
|
+
const checked = existingPolicies.includes(ref) ? " checked" : "";
|
|
90771
90824
|
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(
|
|
90825
|
+
<input type="checkbox" class="um-role-policy-chk" value="${this.esc(ref)}"${checked} />
|
|
90773
90826
|
${this.esc(p.displayName)}${p.description ? ` <span style="color:var(--um-text-faint);">\u2014 ${this.esc(p.description)}</span>` : ""}
|
|
90774
90827
|
</label>`;
|
|
90775
90828
|
}).join("");
|
|
@@ -90813,14 +90866,14 @@ var RolesTab = class {
|
|
|
90813
90866
|
}
|
|
90814
90867
|
errEl.textContent = "";
|
|
90815
90868
|
const description = modal.querySelector("[name=description]").value.trim();
|
|
90816
|
-
const
|
|
90869
|
+
const policies = Array.from(
|
|
90817
90870
|
modal.querySelectorAll(".um-role-policy-chk:checked")
|
|
90818
90871
|
).map((c) => c.value);
|
|
90819
90872
|
const btn = modal.querySelector(".role-save");
|
|
90820
90873
|
btn.disabled = true;
|
|
90821
90874
|
btn.textContent = "...";
|
|
90822
90875
|
try {
|
|
90823
|
-
const body = { name, description: description || void 0,
|
|
90876
|
+
const body = { name, description: description || void 0, policies };
|
|
90824
90877
|
const url = isEdit ? `${this.gcdrBase()}/roles/${existing.id}` : `${this.gcdrBase()}/roles`;
|
|
90825
90878
|
const res = await fetch(url, {
|
|
90826
90879
|
method: isEdit ? "PUT" : "POST",
|
|
@@ -91107,6 +91160,13 @@ var UserManagementModalView = class {
|
|
|
91107
91160
|
}
|
|
91108
91161
|
// ── Styles ───────────────────────────────────────────────────────────────────
|
|
91109
91162
|
injectStyles() {
|
|
91163
|
+
if (!document.getElementById("um-font-nunito")) {
|
|
91164
|
+
const link = document.createElement("link");
|
|
91165
|
+
link.id = "um-font-nunito";
|
|
91166
|
+
link.rel = "stylesheet";
|
|
91167
|
+
link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700&display=swap";
|
|
91168
|
+
document.head.appendChild(link);
|
|
91169
|
+
}
|
|
91110
91170
|
if (document.getElementById("um-styles")) return;
|
|
91111
91171
|
const style = document.createElement("style");
|
|
91112
91172
|
style.id = "um-styles";
|
|
@@ -91125,12 +91185,12 @@ var UserManagementModalView = class {
|
|
|
91125
91185
|
--um-text-secondary: #374151;
|
|
91126
91186
|
--um-text-muted: #64748b;
|
|
91127
91187
|
--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: #
|
|
91188
|
+
--um-accent: #3f1a7d;
|
|
91189
|
+
--um-accent-hover: #5a2bab;
|
|
91190
|
+
--um-btn-2-bg: #f4effa;
|
|
91191
|
+
--um-btn-2-text: #3f1a7d;
|
|
91192
|
+
--um-btn-2-border: #c9a8e8;
|
|
91193
|
+
--um-btn-2-hover: #e8d8f5;
|
|
91134
91194
|
--um-btn-ghost-border: #e2e8f0;
|
|
91135
91195
|
--um-btn-ghost-hover: #f1f5f9;
|
|
91136
91196
|
--um-btn-ghost-text-hover:#475569;
|
|
@@ -91149,14 +91209,14 @@ var UserManagementModalView = class {
|
|
|
91149
91209
|
--um-toast-err-border: #ef4444;
|
|
91150
91210
|
--um-toast-err-text: #dc2626;
|
|
91151
91211
|
--um-spinner-border: #cbd5e1;
|
|
91152
|
-
--um-spinner-top: #
|
|
91212
|
+
--um-spinner-top: #3f1a7d;
|
|
91153
91213
|
--um-toggle-off: #cbd5e1;
|
|
91154
|
-
--um-notice-bg: #
|
|
91155
|
-
--um-notice-border: #
|
|
91214
|
+
--um-notice-bg: #f4effa;
|
|
91215
|
+
--um-notice-border: #c9a8e8;
|
|
91156
91216
|
--um-shadow: 0 32px 80px rgba(0,0,0,0.15);
|
|
91157
91217
|
--um-row-highlight: #f0fdf4;
|
|
91158
|
-
--um-gm-badge-domain-bg: #
|
|
91159
|
-
--um-gm-badge-domain-txt: #
|
|
91218
|
+
--um-gm-badge-domain-bg: #f4effa;
|
|
91219
|
+
--um-gm-badge-domain-txt: #3f1a7d;
|
|
91160
91220
|
--um-gm-badge-count-bg: #f1f5f9;
|
|
91161
91221
|
--um-gm-badge-count-txt: #64748b;
|
|
91162
91222
|
--um-gm-form-card-bg: #f8fafc;
|
|
@@ -91185,12 +91245,12 @@ var UserManagementModalView = class {
|
|
|
91185
91245
|
--um-text-secondary: #c4ccd9;
|
|
91186
91246
|
--um-text-muted: #64748b;
|
|
91187
91247
|
--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: #
|
|
91248
|
+
--um-accent: #a78bdb;
|
|
91249
|
+
--um-accent-hover: #c3a8f0;
|
|
91250
|
+
--um-btn-2-bg: #2a1a45;
|
|
91251
|
+
--um-btn-2-text: #c3a8f0;
|
|
91252
|
+
--um-btn-2-border: #4a2a80;
|
|
91253
|
+
--um-btn-2-hover: #3a2060;
|
|
91194
91254
|
--um-btn-ghost-border: #2a3352;
|
|
91195
91255
|
--um-btn-ghost-hover: #1a2235;
|
|
91196
91256
|
--um-btn-ghost-text-hover:#94a3b8;
|
|
@@ -91209,14 +91269,14 @@ var UserManagementModalView = class {
|
|
|
91209
91269
|
--um-toast-err-border: #ef4444;
|
|
91210
91270
|
--um-toast-err-text: #f87171;
|
|
91211
91271
|
--um-spinner-border: #2a3352;
|
|
91212
|
-
--um-spinner-top: #
|
|
91272
|
+
--um-spinner-top: #a78bdb;
|
|
91213
91273
|
--um-toggle-off: #2a3352;
|
|
91214
|
-
--um-notice-bg: #
|
|
91215
|
-
--um-notice-border: #
|
|
91274
|
+
--um-notice-bg: #1e1235;
|
|
91275
|
+
--um-notice-border: #4a2a80;
|
|
91216
91276
|
--um-shadow: 0 32px 80px rgba(0,0,0,0.6);
|
|
91217
91277
|
--um-row-highlight: #0e2a1e;
|
|
91218
|
-
--um-gm-badge-domain-bg: #
|
|
91219
|
-
--um-gm-badge-domain-txt: #
|
|
91278
|
+
--um-gm-badge-domain-bg: #2a1a45;
|
|
91279
|
+
--um-gm-badge-domain-txt: #c3a8f0;
|
|
91220
91280
|
--um-gm-badge-count-bg: #1e2d4a;
|
|
91221
91281
|
--um-gm-badge-count-txt: #94a3b8;
|
|
91222
91282
|
--um-gm-form-card-bg: #0f1829;
|
|
@@ -91230,6 +91290,7 @@ var UserManagementModalView = class {
|
|
|
91230
91290
|
/* \u2500\u2500 Component styles (theme-agnostic via variables) \u2500\u2500 */
|
|
91231
91291
|
.um-modal {
|
|
91232
91292
|
background: var(--um-modal-bg);
|
|
91293
|
+
font-family: 'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
91233
91294
|
border-radius: 14px; width: 92vw; max-width: 960px;
|
|
91234
91295
|
--modal-header-radius: 14px 14px 0 0;
|
|
91235
91296
|
aspect-ratio: 16/9; display: flex; flex-direction: column;
|
|
@@ -91239,6 +91300,20 @@ var UserManagementModalView = class {
|
|
|
91239
91300
|
|
|
91240
91301
|
/* Header handled by ModalHeader (RFC-0121) */
|
|
91241
91302
|
|
|
91303
|
+
/* Force MyIO purple header regardless of light/dark theme \u2014 overrides myio-modal-header--light */
|
|
91304
|
+
.um-modal .myio-modal-header--light {
|
|
91305
|
+
background: #3f1a7d !important;
|
|
91306
|
+
border-bottom-color: #2e1260 !important;
|
|
91307
|
+
}
|
|
91308
|
+
.um-modal .myio-modal-header--light .myio-modal-header__title { color: #fff !important; }
|
|
91309
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn { color: rgba(255,255,255,0.8) !important; }
|
|
91310
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn:hover {
|
|
91311
|
+
background: rgba(255,255,255,0.15) !important; color: #fff !important;
|
|
91312
|
+
}
|
|
91313
|
+
.um-modal .myio-modal-header--light .myio-modal-header__btn--close:hover {
|
|
91314
|
+
background: rgba(239,68,68,0.3) !important; color: #fecaca !important;
|
|
91315
|
+
}
|
|
91316
|
+
|
|
91242
91317
|
/* Maximize button \u2014 CSS window icon (emoji renders as plain square on some platforms) */
|
|
91243
91318
|
#um-modal-maximize { font-size: 0 !important; position: relative; }
|
|
91244
91319
|
#um-modal-maximize::before {
|
|
@@ -91389,7 +91464,7 @@ var UserManagementModalView = class {
|
|
|
91389
91464
|
.um-check-label { font-size: 13px; color: var(--um-text-secondary); cursor: pointer; display: flex; align-items: center; gap: 8px; }
|
|
91390
91465
|
.um-form-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }
|
|
91391
91466
|
|
|
91392
|
-
.um-detail-card {
|
|
91467
|
+
.um-detail-card { width: 100%; }
|
|
91393
91468
|
.um-detail-section { border: 1px solid var(--um-border); border-radius: 10px; overflow: hidden; margin-bottom: 20px; }
|
|
91394
91469
|
.um-detail-row {
|
|
91395
91470
|
display: flex; align-items: flex-start; gap: 16px;
|
|
@@ -135492,6 +135567,50 @@ var STYLES3 = `
|
|
|
135492
135567
|
font-size: 12px; font-weight: 600; color: #e67e22;
|
|
135493
135568
|
background: #fef3e8; border-radius: 4px; padding: 1px 6px;
|
|
135494
135569
|
}
|
|
135570
|
+
/* Collapse/expand */
|
|
135571
|
+
#${MODAL_ID3} .abm-device-card.collapsed .abm-rule-list { display: none; }
|
|
135572
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-rule-group-devices,
|
|
135573
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-rule-detail-wrap { display: none; }
|
|
135574
|
+
#${MODAL_ID3} .abm-chevron {
|
|
135575
|
+
font-size: 11px; color: #94a3b8; transition: transform 0.18s; flex-shrink: 0; user-select: none;
|
|
135576
|
+
}
|
|
135577
|
+
#${MODAL_ID3} .abm-device-card.collapsed .abm-chevron,
|
|
135578
|
+
#${MODAL_ID3} .abm-rule-group.collapsed .abm-chevron { transform: rotate(-90deg); }
|
|
135579
|
+
#${MODAL_ID3} .abm-device-header { cursor: pointer; }
|
|
135580
|
+
#${MODAL_ID3} .abm-device-header:hover { background: #f0f9f7; }
|
|
135581
|
+
#${MODAL_ID3} .abm-rule-group-header { cursor: pointer; }
|
|
135582
|
+
#${MODAL_ID3} .abm-rule-group-header:hover { background: #e6f4f1; }
|
|
135583
|
+
/* Alarm badge */
|
|
135584
|
+
#${MODAL_ID3} .abm-alarm-badge {
|
|
135585
|
+
display: inline-flex; align-items: center; gap: 3px;
|
|
135586
|
+
background: #fee2e2; color: #b91c1c; border-radius: 10px;
|
|
135587
|
+
font-size: 10px; font-weight: 700; padding: 1px 7px; flex-shrink: 0;
|
|
135588
|
+
}
|
|
135589
|
+
#${MODAL_ID3} .abm-alarm-badge.zero { background: #f0f9f7; color: #6b7280; }
|
|
135590
|
+
/* Filter bar */
|
|
135591
|
+
#${MODAL_ID3} .abm-filter-bar {
|
|
135592
|
+
display: flex; gap: 8px; align-items: center; margin-bottom: 14px;
|
|
135593
|
+
padding: 10px 12px; background: #f8faf9; border: 1px solid #e0eceb; border-radius: 8px;
|
|
135594
|
+
}
|
|
135595
|
+
#${MODAL_ID3} .abm-filter-input {
|
|
135596
|
+
flex: 1; border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 10px;
|
|
135597
|
+
font-size: 12px; outline: none; transition: border-color 0.15s;
|
|
135598
|
+
}
|
|
135599
|
+
#${MODAL_ID3} .abm-filter-input:focus { border-color: ${TEAL2}; }
|
|
135600
|
+
#${MODAL_ID3} .abm-filter-select {
|
|
135601
|
+
border: 1px solid #d1d5db; border-radius: 6px; padding: 5px 8px;
|
|
135602
|
+
font-size: 12px; outline: none; min-width: 140px; max-width: 220px;
|
|
135603
|
+
background: #fff; cursor: pointer;
|
|
135604
|
+
}
|
|
135605
|
+
#${MODAL_ID3} .abm-filter-count {
|
|
135606
|
+
font-size: 11px; color: #64748b; white-space: nowrap; flex-shrink: 0;
|
|
135607
|
+
}
|
|
135608
|
+
#${MODAL_ID3} .abm-filter-clear {
|
|
135609
|
+
background: none; border: 1px solid #e0eceb; border-radius: 6px; cursor: pointer;
|
|
135610
|
+
font-size: 11px; color: #64748b; padding: 4px 8px; white-space: nowrap; flex-shrink: 0;
|
|
135611
|
+
transition: background 0.12s;
|
|
135612
|
+
}
|
|
135613
|
+
#${MODAL_ID3} .abm-filter-clear:hover { background: #f0f4f3; color: #1e293b; }
|
|
135495
135614
|
/* Confirmation modal \u2014 value edit overwrite warning */
|
|
135496
135615
|
.abm-confirm-overlay {
|
|
135497
135616
|
position: fixed; inset: 0;
|
|
@@ -135922,6 +136041,8 @@ function bindRuleEditEvents(card, bundle, gcdrTenantId, baseUrl, getViewMode) {
|
|
|
135922
136041
|
if (!ruleId) return;
|
|
135923
136042
|
const rule = bundle.rules[ruleId];
|
|
135924
136043
|
if (!rule) return;
|
|
136044
|
+
editBtn.closest(".abm-device-card")?.classList.remove("collapsed");
|
|
136045
|
+
editBtn.closest(".abm-rule-group")?.classList.remove("collapsed");
|
|
135925
136046
|
const viewMode = getViewMode();
|
|
135926
136047
|
if (viewMode === "por-regra") {
|
|
135927
136048
|
const ruleGroup = editBtn.closest(".abm-rule-group");
|
|
@@ -135940,13 +136061,109 @@ function bindRuleEditEvents(card, bundle, gcdrTenantId, baseUrl, getViewMode) {
|
|
|
135940
136061
|
openGranularValueEdit(ruleItem, rule, device, bundle, gcdrTenantId, baseUrl);
|
|
135941
136062
|
});
|
|
135942
136063
|
}
|
|
136064
|
+
function bindCollapseEvents(card) {
|
|
136065
|
+
card.querySelectorAll(".abm-device-header").forEach((header) => {
|
|
136066
|
+
header.addEventListener("click", (e) => {
|
|
136067
|
+
if (e.target.closest("button")) return;
|
|
136068
|
+
header.closest(".abm-device-card")?.classList.toggle("collapsed");
|
|
136069
|
+
});
|
|
136070
|
+
});
|
|
136071
|
+
card.querySelectorAll(".abm-rule-group-header").forEach((header) => {
|
|
136072
|
+
header.addEventListener("click", (e) => {
|
|
136073
|
+
if (e.target.closest("button")) return;
|
|
136074
|
+
header.closest(".abm-rule-group")?.classList.toggle("collapsed");
|
|
136075
|
+
});
|
|
136076
|
+
});
|
|
136077
|
+
}
|
|
136078
|
+
function bindFilterBar(card, bundle, getViewMode) {
|
|
136079
|
+
const input = card.querySelector("#abm-filter-input");
|
|
136080
|
+
const select = card.querySelector("#abm-filter-select");
|
|
136081
|
+
const countEl = card.querySelector("#abm-filter-count");
|
|
136082
|
+
const clearBtn = card.querySelector("#abm-filter-clear");
|
|
136083
|
+
if (!input) return;
|
|
136084
|
+
const updateSelectOptions = (text) => {
|
|
136085
|
+
if (!select) return;
|
|
136086
|
+
const lower = text.toLowerCase();
|
|
136087
|
+
const types = /* @__PURE__ */ new Set();
|
|
136088
|
+
bundle.devices.forEach((d) => {
|
|
136089
|
+
const name = (d.displayName || d.name).toLowerCase();
|
|
136090
|
+
if (!lower || name.includes(lower) || d.type.toLowerCase().includes(lower)) {
|
|
136091
|
+
types.add(d.type);
|
|
136092
|
+
}
|
|
136093
|
+
});
|
|
136094
|
+
const prev = new Set(Array.from(select.selectedOptions).map((o) => o.value));
|
|
136095
|
+
select.innerHTML = Array.from(types).sort().map(
|
|
136096
|
+
(t) => `<option value="${escHtml3(t)}"${prev.has(t) ? " selected" : ""}>${escHtml3(t)}</option>`
|
|
136097
|
+
).join("");
|
|
136098
|
+
select.size = Math.min(types.size, 4) || 1;
|
|
136099
|
+
};
|
|
136100
|
+
const applyFilter = () => {
|
|
136101
|
+
const text = input.value.toLowerCase().trim();
|
|
136102
|
+
const selectedTypes = new Set(Array.from(select?.selectedOptions ?? []).map((o) => o.value));
|
|
136103
|
+
const mode = getViewMode();
|
|
136104
|
+
if (mode === "granular") {
|
|
136105
|
+
let visible = 0;
|
|
136106
|
+
card.querySelectorAll(".abm-device-card").forEach((dc) => {
|
|
136107
|
+
const name = (dc.querySelector(".abm-device-name")?.textContent ?? "").toLowerCase();
|
|
136108
|
+
const type = dc.querySelector(".abm-device-type")?.textContent ?? "";
|
|
136109
|
+
const ruleNames = Array.from(dc.querySelectorAll(".abm-rule-name")).map((el2) => (el2.textContent ?? "").toLowerCase());
|
|
136110
|
+
const matchText = !text || name.includes(text) || type.toLowerCase().includes(text) || ruleNames.some((r) => r.includes(text));
|
|
136111
|
+
const matchType = selectedTypes.size === 0 || selectedTypes.has(type);
|
|
136112
|
+
dc.style.display = matchText && matchType ? "" : "none";
|
|
136113
|
+
if (matchText && matchType) visible++;
|
|
136114
|
+
});
|
|
136115
|
+
if (countEl) countEl.textContent = `${visible} dispositivo(s)`;
|
|
136116
|
+
} else {
|
|
136117
|
+
let visible = 0;
|
|
136118
|
+
card.querySelectorAll(".abm-rule-group").forEach((rg) => {
|
|
136119
|
+
const ruleName = (rg.querySelector(".abm-rule-group-name")?.textContent ?? "").toLowerCase();
|
|
136120
|
+
const deviceTexts = Array.from(rg.querySelectorAll(".abm-rule-group-device span")).map((el2) => (el2.textContent ?? "").toLowerCase());
|
|
136121
|
+
const matchText = !text || ruleName.includes(text) || deviceTexts.some((t) => t.includes(text));
|
|
136122
|
+
rg.style.display = matchText ? "" : "none";
|
|
136123
|
+
if (matchText) visible++;
|
|
136124
|
+
});
|
|
136125
|
+
if (countEl) countEl.textContent = `${visible} regra(s)`;
|
|
136126
|
+
}
|
|
136127
|
+
updateSelectOptions(text);
|
|
136128
|
+
};
|
|
136129
|
+
input.addEventListener("input", applyFilter);
|
|
136130
|
+
select?.addEventListener("change", applyFilter);
|
|
136131
|
+
clearBtn?.addEventListener("click", () => {
|
|
136132
|
+
input.value = "";
|
|
136133
|
+
if (select) Array.from(select.options).forEach((o) => {
|
|
136134
|
+
o.selected = false;
|
|
136135
|
+
});
|
|
136136
|
+
applyFilter();
|
|
136137
|
+
});
|
|
136138
|
+
updateSelectOptions("");
|
|
136139
|
+
const totalDevices = bundle.devices.length;
|
|
136140
|
+
if (countEl) countEl.textContent = `${totalDevices} dispositivo(s)`;
|
|
136141
|
+
}
|
|
136142
|
+
var _OFFLINE_ALARM_TYPES = ["DEVICE OFFLINE", "DISPOSITIVO OFFLINE"];
|
|
136143
|
+
function _getActiveAlarmCount(gcdrDeviceId) {
|
|
136144
|
+
const aso = window.AlarmServiceOrchestrator;
|
|
136145
|
+
if (!aso?.deviceAlarmMap) return 0;
|
|
136146
|
+
const alarms = aso.deviceAlarmMap.get(gcdrDeviceId) || [];
|
|
136147
|
+
const showOffline = window.MyIOOrchestrator?.showOfflineAlarms === true;
|
|
136148
|
+
return showOffline ? alarms.length : alarms.filter((a) => {
|
|
136149
|
+
const t = (a.title ?? "").toUpperCase();
|
|
136150
|
+
return !(_OFFLINE_ALARM_TYPES.some((ex) => t.startsWith(ex)) || a.alarmType === "connectivity");
|
|
136151
|
+
}).length;
|
|
136152
|
+
}
|
|
136153
|
+
function _alarmBadgeHtml(count) {
|
|
136154
|
+
if (count === 0) return `<span class="abm-alarm-badge zero">0 \u{1F514}</span>`;
|
|
136155
|
+
return `<span class="abm-alarm-badge">\u{1F534} ${count}</span>`;
|
|
136156
|
+
}
|
|
135943
136157
|
function renderDevice(device, rules, viewMode = "granular") {
|
|
135944
136158
|
const deviceRules = (device.ruleIds ?? []).map((rid) => rules[rid]).filter(Boolean);
|
|
136159
|
+
const alarmCount = _getActiveAlarmCount(device.id);
|
|
135945
136160
|
return `
|
|
135946
|
-
<div class="abm-device-card">
|
|
136161
|
+
<div class="abm-device-card collapsed" data-device-id="${escHtml3(device.id)}">
|
|
135947
136162
|
<div class="abm-device-header">
|
|
136163
|
+
<span class="abm-chevron">\u25BE</span>
|
|
135948
136164
|
<span style="font-size:16px;">\u{1F4E1}</span>
|
|
135949
136165
|
<span class="abm-device-name">${escHtml3(device.displayName || device.name)}</span>
|
|
136166
|
+
${_alarmBadgeHtml(alarmCount)}
|
|
135950
136167
|
<span class="abm-device-type">${escHtml3(device.type)}</span>
|
|
135951
136168
|
</div>
|
|
135952
136169
|
<ul class="abm-rule-list">
|
|
@@ -135973,11 +136190,14 @@ function renderByRuleView(bundle) {
|
|
|
135973
136190
|
for (const [baseRuleId, devs] of ruleDevicesMap) {
|
|
135974
136191
|
const baseRule = rules[baseRuleId];
|
|
135975
136192
|
if (!baseRule) continue;
|
|
136193
|
+
const groupAlarmCount = devs.reduce((sum, d) => sum + _getActiveAlarmCount(d.id), 0);
|
|
135976
136194
|
groups += `
|
|
135977
|
-
<div class="abm-rule-group">
|
|
136195
|
+
<div class="abm-rule-group collapsed" data-rule-id="${escHtml3(baseRuleId)}">
|
|
135978
136196
|
<div class="abm-rule-group-header">
|
|
136197
|
+
<span class="abm-chevron">\u25BE</span>
|
|
135979
136198
|
<span style="font-size:16px;">\u{1F514}</span>
|
|
135980
136199
|
<span class="abm-rule-group-name">${escHtml3(baseRule.name)}</span>
|
|
136200
|
+
${_alarmBadgeHtml(groupAlarmCount)}
|
|
135981
136201
|
<button class="abm-edit-rule-btn" data-edit-rule="${escHtml3(baseRuleId)}" title="Editar dias/hor\xE1rio">\u270F\uFE0F</button>
|
|
135982
136202
|
</div>
|
|
135983
136203
|
<div class="abm-rule-detail" style="padding:8px 14px;" data-rule-id="${escHtml3(baseRuleId)}">
|
|
@@ -136041,7 +136261,6 @@ function renderBundle(bundle, viewMode = "granular") {
|
|
|
136041
136261
|
<div class="abm-summary-bar">
|
|
136042
136262
|
<div class="abm-summary-item"><div class="abm-summary-num">${deviceCount}</div><div class="abm-summary-label">Dispositivos</div></div>
|
|
136043
136263
|
<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
136264
|
</div>
|
|
136046
136265
|
${renderByRuleView(bundle)}
|
|
136047
136266
|
`;
|
|
@@ -136075,10 +136294,6 @@ function renderBundle(bundle, viewMode = "granular") {
|
|
|
136075
136294
|
<div class="abm-summary-num">${ruleCount}</div>
|
|
136076
136295
|
<div class="abm-summary-label">Regras</div>
|
|
136077
136296
|
</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
136297
|
</div>
|
|
136083
136298
|
${groups}
|
|
136084
136299
|
`;
|
|
@@ -136169,7 +136384,21 @@ async function openAlarmBundleMapModal(params) {
|
|
|
136169
136384
|
const customerName = bundle.customer.displayName || bundle.customer.name || "";
|
|
136170
136385
|
const rerenderBundle = () => {
|
|
136171
136386
|
render3(renderBundle(bundle, viewMode), customerName, true);
|
|
136387
|
+
const body = card.querySelector(".abm-body");
|
|
136388
|
+
if (body) {
|
|
136389
|
+
const filterBarEl = document.createElement("div");
|
|
136390
|
+
filterBarEl.className = "abm-filter-bar";
|
|
136391
|
+
filterBarEl.innerHTML = `
|
|
136392
|
+
<input class="abm-filter-input" type="text" id="abm-filter-input" placeholder="Buscar dispositivo, regra, tipo..." />
|
|
136393
|
+
<select class="abm-filter-select" id="abm-filter-select" multiple size="1"></select>
|
|
136394
|
+
<span class="abm-filter-count" id="abm-filter-count"></span>
|
|
136395
|
+
<button class="abm-filter-clear" id="abm-filter-clear" type="button">\u2715 Limpar</button>
|
|
136396
|
+
`;
|
|
136397
|
+
body.insertBefore(filterBarEl, body.firstChild);
|
|
136398
|
+
}
|
|
136172
136399
|
bindRuleEditEvents(card, bundle, params.gcdrTenantId, baseUrl, () => viewMode);
|
|
136400
|
+
bindCollapseEvents(card);
|
|
136401
|
+
bindFilterBar(card, bundle, () => viewMode);
|
|
136173
136402
|
card.querySelectorAll("[data-view]").forEach((btn) => {
|
|
136174
136403
|
btn.addEventListener("click", () => {
|
|
136175
136404
|
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;
|