@robertraaijmakers/pptb-securityplugin 0.1.4 → 0.1.6-beta.0
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/app.js +676 -154
- package/dist/app.js.map +2 -2
- package/dist/index.css +59 -0
- package/dist/index.html +59 -0
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
- package/dist/npm-shrinkwrap.json +0 -490
- package/dist/styles.css +0 -754
package/dist/app.js
CHANGED
|
@@ -14758,13 +14758,39 @@ ${logTarget.textContent}`;
|
|
|
14758
14758
|
"delete",
|
|
14759
14759
|
"append",
|
|
14760
14760
|
"appendto",
|
|
14761
|
-
"assign"
|
|
14761
|
+
"assign",
|
|
14762
|
+
"share"
|
|
14762
14763
|
];
|
|
14764
|
+
var privilegeLabels = {
|
|
14765
|
+
create: "Create",
|
|
14766
|
+
read: "Read",
|
|
14767
|
+
write: "Write",
|
|
14768
|
+
delete: "Delete",
|
|
14769
|
+
append: "Append",
|
|
14770
|
+
appendto: "Append To",
|
|
14771
|
+
assign: "Assign",
|
|
14772
|
+
share: "Share"
|
|
14773
|
+
};
|
|
14763
14774
|
var levelOptions = [
|
|
14764
14775
|
{ level: "user", icon: "\u{1F464}", label: "User", className: "level-user" },
|
|
14765
|
-
{
|
|
14766
|
-
|
|
14767
|
-
|
|
14776
|
+
{
|
|
14777
|
+
level: "businessUnit",
|
|
14778
|
+
icon: "\u{1F3E2}",
|
|
14779
|
+
label: "Business Unit",
|
|
14780
|
+
className: "level-businessUnit"
|
|
14781
|
+
},
|
|
14782
|
+
{
|
|
14783
|
+
level: "parentChild",
|
|
14784
|
+
icon: "\u{1F9E9}",
|
|
14785
|
+
label: "Parent: Child BU",
|
|
14786
|
+
className: "level-parentChild"
|
|
14787
|
+
},
|
|
14788
|
+
{
|
|
14789
|
+
level: "organization",
|
|
14790
|
+
icon: "\u{1F310}",
|
|
14791
|
+
label: "Organization",
|
|
14792
|
+
className: "level-organization"
|
|
14793
|
+
},
|
|
14768
14794
|
{ level: "none", icon: "\u26D4", label: "None", className: "level-none" }
|
|
14769
14795
|
];
|
|
14770
14796
|
var levelColorMap = {
|
|
@@ -14789,6 +14815,10 @@ ${logTarget.textContent}`;
|
|
|
14789
14815
|
loadingDashboardRoleTeamCounts: "Loading teams per role",
|
|
14790
14816
|
loadingDashboardFilters: "Preparing dashboard filters",
|
|
14791
14817
|
tableTitlePrivileges: "Privileges",
|
|
14818
|
+
bulkUpdateSelect: "Set visible...",
|
|
14819
|
+
bulkUpdateApply: "Set",
|
|
14820
|
+
bulkUpdateNoRights: "No visible rights in this column",
|
|
14821
|
+
bulkUpdateNoSelection: "Select a level first",
|
|
14792
14822
|
roleFilterAll: "All roles",
|
|
14793
14823
|
statusAssigned: "Assigned",
|
|
14794
14824
|
statusNotAssigned: "Not assigned",
|
|
@@ -14889,6 +14919,15 @@ ${logTarget.textContent}`;
|
|
|
14889
14919
|
function formatCachedPrivileges(privilegeCount, rolePrivilegeCount, roleCount) {
|
|
14890
14920
|
return `Cached ${privilegeCount} privileges and ${rolePrivilegeCount} role privilege rows for ${roleCount} roles.`;
|
|
14891
14921
|
}
|
|
14922
|
+
function formatBulkUpdatedVisible(privilegeLabel, levelLabel, updatedCount, skippedCount) {
|
|
14923
|
+
if (skippedCount > 0) {
|
|
14924
|
+
return `Bulk set ${privilegeLabel} to ${levelLabel} for ${updatedCount} visible rows (${skippedCount} skipped).`;
|
|
14925
|
+
}
|
|
14926
|
+
return `Bulk set ${privilegeLabel} to ${levelLabel} for ${updatedCount} visible rows.`;
|
|
14927
|
+
}
|
|
14928
|
+
function formatBulkUpdateNoRows(privilegeLabel) {
|
|
14929
|
+
return `No visible rows with editable ${privilegeLabel} rights.`;
|
|
14930
|
+
}
|
|
14892
14931
|
function formatRoleAssignmentLogUsers(action, roleName, userNames) {
|
|
14893
14932
|
const verb = action === "add" ? "Added" : "Removed";
|
|
14894
14933
|
const prep = action === "add" ? "to" : "from";
|
|
@@ -14990,7 +15029,8 @@ ${logTarget.textContent}`;
|
|
|
14990
15029
|
delete: "",
|
|
14991
15030
|
append: "",
|
|
14992
15031
|
appendto: "",
|
|
14993
|
-
assign: ""
|
|
15032
|
+
assign: "",
|
|
15033
|
+
share: ""
|
|
14994
15034
|
},
|
|
14995
15035
|
eventsHooked: false,
|
|
14996
15036
|
readyToastShown: false,
|
|
@@ -15002,56 +15042,130 @@ ${logTarget.textContent}`;
|
|
|
15002
15042
|
}
|
|
15003
15043
|
};
|
|
15004
15044
|
var elements2 = {
|
|
15005
|
-
connectionBadge: document.getElementById(
|
|
15045
|
+
connectionBadge: document.getElementById(
|
|
15046
|
+
"connection-badge"
|
|
15047
|
+
),
|
|
15006
15048
|
filterMode: document.getElementById("filter-mode"),
|
|
15007
15049
|
roleSelect: document.getElementById("role-select"),
|
|
15008
15050
|
entitySelect: document.getElementById("entity-select"),
|
|
15009
|
-
roleSelectControl: document.getElementById(
|
|
15010
|
-
|
|
15051
|
+
roleSelectControl: document.getElementById(
|
|
15052
|
+
"role-select-control"
|
|
15053
|
+
),
|
|
15054
|
+
entitySelectControl: document.getElementById(
|
|
15055
|
+
"entity-select-control"
|
|
15056
|
+
),
|
|
15011
15057
|
rightsFilter: document.getElementById("rights-filter"),
|
|
15012
|
-
roleFilterControl: document.getElementById(
|
|
15013
|
-
|
|
15058
|
+
roleFilterControl: document.getElementById(
|
|
15059
|
+
"role-filter-control"
|
|
15060
|
+
),
|
|
15061
|
+
roleFilterButton: document.getElementById(
|
|
15062
|
+
"role-filter-button"
|
|
15063
|
+
),
|
|
15014
15064
|
roleFilterMenu: document.getElementById("role-filter-menu"),
|
|
15015
15065
|
roleFilterList: document.getElementById("role-filter-list"),
|
|
15016
|
-
roleFilterAll: document.getElementById(
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15066
|
+
roleFilterAll: document.getElementById(
|
|
15067
|
+
"role-filter-all"
|
|
15068
|
+
),
|
|
15069
|
+
roleFilterNone: document.getElementById(
|
|
15070
|
+
"role-filter-none"
|
|
15071
|
+
),
|
|
15072
|
+
rolesCustomOnlyGlobal: document.getElementById(
|
|
15073
|
+
"roles-custom-only-global"
|
|
15074
|
+
),
|
|
15075
|
+
tabButtons: Array.from(
|
|
15076
|
+
document.querySelectorAll(".tab-button")
|
|
15077
|
+
),
|
|
15020
15078
|
tabPrivileges: document.getElementById("tab-privileges"),
|
|
15021
15079
|
tabAssignments: document.getElementById("tab-assignments"),
|
|
15022
15080
|
tabDashboard: document.getElementById("tab-dashboard"),
|
|
15023
|
-
assignmentMode: document.getElementById(
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15081
|
+
assignmentMode: document.getElementById(
|
|
15082
|
+
"assignment-mode"
|
|
15083
|
+
),
|
|
15084
|
+
assignmentRoleSelect: document.getElementById(
|
|
15085
|
+
"assignment-role-select"
|
|
15086
|
+
),
|
|
15087
|
+
assignmentUserSelect: document.getElementById(
|
|
15088
|
+
"assignment-user-select"
|
|
15089
|
+
),
|
|
15090
|
+
assignmentTeamSelect: document.getElementById(
|
|
15091
|
+
"assignment-team-select"
|
|
15092
|
+
),
|
|
15093
|
+
assignmentRoleControl: document.getElementById(
|
|
15094
|
+
"assignment-role-control"
|
|
15095
|
+
),
|
|
15096
|
+
assignmentUserControl: document.getElementById(
|
|
15097
|
+
"assignment-user-control"
|
|
15098
|
+
),
|
|
15099
|
+
assignmentTeamControl: document.getElementById(
|
|
15100
|
+
"assignment-team-control"
|
|
15101
|
+
),
|
|
15102
|
+
assignmentTitle: document.getElementById(
|
|
15103
|
+
"assignment-title"
|
|
15104
|
+
),
|
|
15031
15105
|
assignmentAdd: document.getElementById("assignment-add"),
|
|
15032
|
-
assignmentRemove: document.getElementById(
|
|
15033
|
-
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15106
|
+
assignmentRemove: document.getElementById(
|
|
15107
|
+
"assignment-remove"
|
|
15108
|
+
),
|
|
15109
|
+
assignmentCount: document.getElementById(
|
|
15110
|
+
"assignment-count"
|
|
15111
|
+
),
|
|
15112
|
+
assignmentSelectAll: document.getElementById(
|
|
15113
|
+
"assignment-select-all"
|
|
15114
|
+
),
|
|
15115
|
+
assignmentClear: document.getElementById(
|
|
15116
|
+
"assignment-clear"
|
|
15117
|
+
),
|
|
15118
|
+
assignmentStatus: document.getElementById(
|
|
15119
|
+
"assignment-status"
|
|
15120
|
+
),
|
|
15121
|
+
assignmentTableBody: document.getElementById(
|
|
15122
|
+
"assignment-table-body"
|
|
15123
|
+
),
|
|
15038
15124
|
assignmentSortButtons: Array.from(
|
|
15039
15125
|
document.querySelectorAll("[data-assign-sort]")
|
|
15040
15126
|
),
|
|
15041
|
-
assignmentFilterAssigned: document.getElementById(
|
|
15042
|
-
|
|
15043
|
-
|
|
15044
|
-
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15054
|
-
|
|
15127
|
+
assignmentFilterAssigned: document.getElementById(
|
|
15128
|
+
"assignment-filter-assigned"
|
|
15129
|
+
),
|
|
15130
|
+
assignmentSearch: document.getElementById(
|
|
15131
|
+
"assignment-search"
|
|
15132
|
+
),
|
|
15133
|
+
controlsPrivileges: document.getElementById(
|
|
15134
|
+
"controls-privileges"
|
|
15135
|
+
),
|
|
15136
|
+
controlsAssignments: document.getElementById(
|
|
15137
|
+
"controls-assignments"
|
|
15138
|
+
),
|
|
15139
|
+
controlsDashboard: document.getElementById(
|
|
15140
|
+
"controls-dashboard"
|
|
15141
|
+
),
|
|
15142
|
+
dashboardUserStatus: document.getElementById(
|
|
15143
|
+
"dashboard-user-status"
|
|
15144
|
+
),
|
|
15145
|
+
dashboardUserType: document.getElementById(
|
|
15146
|
+
"dashboard-user-type"
|
|
15147
|
+
),
|
|
15148
|
+
dashboardBusinessUnitSelect: document.getElementById(
|
|
15149
|
+
"dashboard-bu-select"
|
|
15150
|
+
),
|
|
15151
|
+
dashboardRoleSelect: document.getElementById(
|
|
15152
|
+
"dashboard-role-select"
|
|
15153
|
+
),
|
|
15154
|
+
dashboardTeamSelect: document.getElementById(
|
|
15155
|
+
"dashboard-team-select"
|
|
15156
|
+
),
|
|
15157
|
+
dashboardExport: document.getElementById(
|
|
15158
|
+
"dashboard-export"
|
|
15159
|
+
),
|
|
15160
|
+
dashboardLoading: document.getElementById(
|
|
15161
|
+
"dashboard-loading"
|
|
15162
|
+
),
|
|
15163
|
+
dashboardLoadingBar: document.getElementById(
|
|
15164
|
+
"dashboard-loading-bar"
|
|
15165
|
+
),
|
|
15166
|
+
dashboardLoadingText: document.getElementById(
|
|
15167
|
+
"dashboard-loading-text"
|
|
15168
|
+
),
|
|
15055
15169
|
dashboardChartCards: Array.from(
|
|
15056
15170
|
document.querySelectorAll("[data-dashboard-chart]")
|
|
15057
15171
|
),
|
|
@@ -15059,38 +15173,84 @@ ${logTarget.textContent}`;
|
|
|
15059
15173
|
document.querySelectorAll(".chart-expand")
|
|
15060
15174
|
),
|
|
15061
15175
|
chartModal: document.getElementById("chart-modal"),
|
|
15062
|
-
chartModalTitle: document.getElementById(
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15176
|
+
chartModalTitle: document.getElementById(
|
|
15177
|
+
"chart-modal-title"
|
|
15178
|
+
),
|
|
15179
|
+
chartModalCanvas: document.getElementById(
|
|
15180
|
+
"chart-modal-canvas"
|
|
15181
|
+
),
|
|
15182
|
+
chartModalClose: document.getElementById(
|
|
15183
|
+
"chart-modal-close"
|
|
15184
|
+
),
|
|
15185
|
+
chartModalBackdrop: document.querySelector(
|
|
15186
|
+
"[data-modal-close='true']"
|
|
15187
|
+
),
|
|
15066
15188
|
chartModalBody: document.querySelector(".modal-body"),
|
|
15067
|
-
metricHumanActive: document.getElementById(
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
|
|
15076
|
-
|
|
15077
|
-
|
|
15078
|
-
|
|
15189
|
+
metricHumanActive: document.getElementById(
|
|
15190
|
+
"metric-human-active"
|
|
15191
|
+
),
|
|
15192
|
+
metricHumanInactive: document.getElementById(
|
|
15193
|
+
"metric-human-inactive"
|
|
15194
|
+
),
|
|
15195
|
+
metricAppActive: document.getElementById(
|
|
15196
|
+
"metric-app-active"
|
|
15197
|
+
),
|
|
15198
|
+
metricAppInactive: document.getElementById(
|
|
15199
|
+
"metric-app-inactive"
|
|
15200
|
+
),
|
|
15201
|
+
metricCustomRoles: document.getElementById(
|
|
15202
|
+
"metric-custom-roles"
|
|
15203
|
+
),
|
|
15204
|
+
metricManagedRoles: document.getElementById(
|
|
15205
|
+
"metric-managed-roles"
|
|
15206
|
+
),
|
|
15207
|
+
metricRolesWithoutUsers: document.getElementById(
|
|
15208
|
+
"metric-roles-without-users"
|
|
15209
|
+
),
|
|
15210
|
+
metricTotalTeams: document.getElementById(
|
|
15211
|
+
"metric-total-teams"
|
|
15212
|
+
),
|
|
15213
|
+
chartUsersByRole: document.getElementById(
|
|
15214
|
+
"chart-users-by-role"
|
|
15215
|
+
),
|
|
15216
|
+
chartTeamsByRole: document.getElementById(
|
|
15217
|
+
"chart-teams-by-role"
|
|
15218
|
+
),
|
|
15219
|
+
chartUsersByBusinessUnit: document.getElementById(
|
|
15220
|
+
"chart-users-by-bu"
|
|
15221
|
+
),
|
|
15222
|
+
chartUsersByTeam: document.getElementById(
|
|
15223
|
+
"chart-users-by-team"
|
|
15224
|
+
),
|
|
15079
15225
|
applyBtn: document.getElementById("apply-btn"),
|
|
15080
15226
|
undoBtn: document.getElementById("undo-btn"),
|
|
15081
15227
|
refreshBtn: document.getElementById("refresh-btn"),
|
|
15082
15228
|
pendingCount: document.getElementById("pending-count"),
|
|
15083
15229
|
tableTitle: document.getElementById("table-title"),
|
|
15084
|
-
privilegesTable: document.querySelector(
|
|
15085
|
-
|
|
15230
|
+
privilegesTable: document.querySelector(
|
|
15231
|
+
"#privileges-table tbody"
|
|
15232
|
+
),
|
|
15233
|
+
privilegesTableRoot: document.getElementById(
|
|
15234
|
+
"privileges-table"
|
|
15235
|
+
),
|
|
15086
15236
|
tableLoading: document.getElementById("table-loading"),
|
|
15087
15237
|
tableEmpty: document.getElementById("table-empty"),
|
|
15088
15238
|
loadingBar: document.getElementById("loading-bar"),
|
|
15089
15239
|
loadingText: document.getElementById("loading-text"),
|
|
15090
15240
|
log: document.getElementById("log"),
|
|
15091
15241
|
themeToggle: document.getElementById("theme-toggle"),
|
|
15092
|
-
sortButtons: Array.from(
|
|
15093
|
-
|
|
15242
|
+
sortButtons: Array.from(
|
|
15243
|
+
document.querySelectorAll(".sort-button")
|
|
15244
|
+
),
|
|
15245
|
+
bulkSelects: Array.from(
|
|
15246
|
+
document.querySelectorAll("[data-bulk-select]")
|
|
15247
|
+
),
|
|
15248
|
+
bulkApplyButtons: Array.from(
|
|
15249
|
+
document.querySelectorAll("[data-bulk-apply]")
|
|
15250
|
+
),
|
|
15251
|
+
filterSelects: Array.from(
|
|
15252
|
+
document.querySelectorAll(".filter-select")
|
|
15253
|
+
)
|
|
15094
15254
|
};
|
|
15095
15255
|
initLogger(elements2.log);
|
|
15096
15256
|
function setTableTitle(text) {
|
|
@@ -15400,10 +15560,16 @@ ${logTarget.textContent}`;
|
|
|
15400
15560
|
elements2.tabDashboard.classList.toggle("hidden", tab !== "dashboard");
|
|
15401
15561
|
}
|
|
15402
15562
|
if (elements2.controlsPrivileges) {
|
|
15403
|
-
elements2.controlsPrivileges.classList.toggle(
|
|
15563
|
+
elements2.controlsPrivileges.classList.toggle(
|
|
15564
|
+
"hidden",
|
|
15565
|
+
tab !== "privileges"
|
|
15566
|
+
);
|
|
15404
15567
|
}
|
|
15405
15568
|
if (elements2.controlsAssignments) {
|
|
15406
|
-
elements2.controlsAssignments.classList.toggle(
|
|
15569
|
+
elements2.controlsAssignments.classList.toggle(
|
|
15570
|
+
"hidden",
|
|
15571
|
+
tab !== "assignments"
|
|
15572
|
+
);
|
|
15407
15573
|
}
|
|
15408
15574
|
if (elements2.controlsDashboard) {
|
|
15409
15575
|
elements2.controlsDashboard.classList.toggle("hidden", tab !== "dashboard");
|
|
@@ -15475,7 +15641,9 @@ ${logTarget.textContent}`;
|
|
|
15475
15641
|
});
|
|
15476
15642
|
return [...filtered].sort((a, b) => {
|
|
15477
15643
|
if (state.assignmentSort.column === "label") {
|
|
15478
|
-
const cmp = a.label.localeCompare(b.label, void 0, {
|
|
15644
|
+
const cmp = a.label.localeCompare(b.label, void 0, {
|
|
15645
|
+
sensitivity: "base"
|
|
15646
|
+
});
|
|
15479
15647
|
return state.assignmentSort.direction === "asc" ? cmp : -cmp;
|
|
15480
15648
|
}
|
|
15481
15649
|
const aRank = a.assigned ? 1 : 2;
|
|
@@ -15620,12 +15788,146 @@ ${logTarget.textContent}`;
|
|
|
15620
15788
|
for (const button of elements2.sortButtons) {
|
|
15621
15789
|
button.classList.remove("sort-asc", "sort-desc");
|
|
15622
15790
|
if (button.dataset.sort === state.sort.column) {
|
|
15623
|
-
button.classList.add(
|
|
15791
|
+
button.classList.add(
|
|
15792
|
+
state.sort.direction === "asc" ? "sort-asc" : "sort-desc"
|
|
15793
|
+
);
|
|
15624
15794
|
}
|
|
15625
15795
|
}
|
|
15626
15796
|
}
|
|
15627
15797
|
function isPrivilegeAvailable(row, privilege) {
|
|
15628
|
-
return Boolean(
|
|
15798
|
+
return Boolean(
|
|
15799
|
+
state.privilegeIdByKey.get(`${row.entityLogicalName}:${privilege}`)
|
|
15800
|
+
);
|
|
15801
|
+
}
|
|
15802
|
+
function getAllowedLevelsForPrivilege(row, privilege) {
|
|
15803
|
+
const privilegeId = state.privilegeIdByKey.get(
|
|
15804
|
+
`${row.entityLogicalName}:${privilege}`
|
|
15805
|
+
);
|
|
15806
|
+
if (!privilegeId) {
|
|
15807
|
+
return [];
|
|
15808
|
+
}
|
|
15809
|
+
const info = state.privilegeInfoById.get(privilegeId);
|
|
15810
|
+
const allowedLevels = ["none"];
|
|
15811
|
+
if (info?.canBeBasic) {
|
|
15812
|
+
allowedLevels.push("user");
|
|
15813
|
+
}
|
|
15814
|
+
if (info?.canBeLocal) {
|
|
15815
|
+
allowedLevels.push("businessUnit");
|
|
15816
|
+
}
|
|
15817
|
+
if (info?.canBeDeep) {
|
|
15818
|
+
allowedLevels.push("parentChild");
|
|
15819
|
+
}
|
|
15820
|
+
if (info?.canBeGlobal) {
|
|
15821
|
+
allowedLevels.push("organization");
|
|
15822
|
+
}
|
|
15823
|
+
return allowedLevels;
|
|
15824
|
+
}
|
|
15825
|
+
function getRoleIdForVisibleRow(row, isRoleMode) {
|
|
15826
|
+
if (isRoleMode) {
|
|
15827
|
+
return elements2.roleSelect.value || void 0;
|
|
15828
|
+
}
|
|
15829
|
+
return row.roleId;
|
|
15830
|
+
}
|
|
15831
|
+
function renderBulkControls(rows, isRoleMode) {
|
|
15832
|
+
const selectByPrivilege = /* @__PURE__ */ new Map();
|
|
15833
|
+
for (const select of elements2.bulkSelects) {
|
|
15834
|
+
const privilege = select.dataset.bulkSelect;
|
|
15835
|
+
if (!privilege) {
|
|
15836
|
+
continue;
|
|
15837
|
+
}
|
|
15838
|
+
selectByPrivilege.set(privilege, select);
|
|
15839
|
+
}
|
|
15840
|
+
const buttonByPrivilege = /* @__PURE__ */ new Map();
|
|
15841
|
+
for (const button of elements2.bulkApplyButtons) {
|
|
15842
|
+
const privilege = button.dataset.bulkApply;
|
|
15843
|
+
if (!privilege) {
|
|
15844
|
+
continue;
|
|
15845
|
+
}
|
|
15846
|
+
buttonByPrivilege.set(privilege, button);
|
|
15847
|
+
}
|
|
15848
|
+
for (const privilege of accessRights) {
|
|
15849
|
+
const select = selectByPrivilege.get(privilege);
|
|
15850
|
+
const button = buttonByPrivilege.get(privilege);
|
|
15851
|
+
if (!select || !button) {
|
|
15852
|
+
continue;
|
|
15853
|
+
}
|
|
15854
|
+
const allowedLevels = /* @__PURE__ */ new Set();
|
|
15855
|
+
let hasEditableVisibleRows = false;
|
|
15856
|
+
for (const row of rows) {
|
|
15857
|
+
const roleId = getRoleIdForVisibleRow(row, isRoleMode);
|
|
15858
|
+
if (!roleId) {
|
|
15859
|
+
continue;
|
|
15860
|
+
}
|
|
15861
|
+
const rowAllowedLevels = getAllowedLevelsForPrivilege(row, privilege);
|
|
15862
|
+
if (rowAllowedLevels.length === 0) {
|
|
15863
|
+
continue;
|
|
15864
|
+
}
|
|
15865
|
+
hasEditableVisibleRows = true;
|
|
15866
|
+
for (const level of rowAllowedLevels) {
|
|
15867
|
+
allowedLevels.add(level);
|
|
15868
|
+
}
|
|
15869
|
+
}
|
|
15870
|
+
select.innerHTML = "";
|
|
15871
|
+
const placeholder = document.createElement("option");
|
|
15872
|
+
placeholder.value = "";
|
|
15873
|
+
placeholder.textContent = UI_TEXT.bulkUpdateSelect;
|
|
15874
|
+
select.appendChild(placeholder);
|
|
15875
|
+
for (const optionMeta of levelOptions) {
|
|
15876
|
+
if (!allowedLevels.has(optionMeta.level)) {
|
|
15877
|
+
continue;
|
|
15878
|
+
}
|
|
15879
|
+
const option = document.createElement("option");
|
|
15880
|
+
option.value = optionMeta.level;
|
|
15881
|
+
option.textContent = `${optionMeta.icon} ${optionMeta.label}`;
|
|
15882
|
+
select.appendChild(option);
|
|
15883
|
+
}
|
|
15884
|
+
select.disabled = !hasEditableVisibleRows;
|
|
15885
|
+
button.disabled = !hasEditableVisibleRows;
|
|
15886
|
+
button.textContent = UI_TEXT.bulkUpdateApply;
|
|
15887
|
+
button.title = hasEditableVisibleRows ? UI_TEXT.bulkUpdateApply : UI_TEXT.bulkUpdateNoRights;
|
|
15888
|
+
}
|
|
15889
|
+
}
|
|
15890
|
+
function applyBulkUpdate(privilege, level) {
|
|
15891
|
+
const isRoleMode = state.tableMode === "role";
|
|
15892
|
+
const visibleRows = applySortAndFilters(state.privilegeRows);
|
|
15893
|
+
let updatedCount = 0;
|
|
15894
|
+
let skippedCount = 0;
|
|
15895
|
+
for (const row of visibleRows) {
|
|
15896
|
+
const roleId = getRoleIdForVisibleRow(row, isRoleMode);
|
|
15897
|
+
if (!roleId) {
|
|
15898
|
+
skippedCount++;
|
|
15899
|
+
continue;
|
|
15900
|
+
}
|
|
15901
|
+
const allowedLevels = getAllowedLevelsForPrivilege(row, privilege);
|
|
15902
|
+
if (allowedLevels.length === 0 || !allowedLevels.includes(level)) {
|
|
15903
|
+
skippedCount++;
|
|
15904
|
+
continue;
|
|
15905
|
+
}
|
|
15906
|
+
const changed = updatePendingChange(
|
|
15907
|
+
roleId,
|
|
15908
|
+
row.entityLogicalName,
|
|
15909
|
+
privilege,
|
|
15910
|
+
level
|
|
15911
|
+
);
|
|
15912
|
+
if (changed) {
|
|
15913
|
+
updatedCount++;
|
|
15914
|
+
}
|
|
15915
|
+
}
|
|
15916
|
+
const privilegeLabel = privilegeLabels[privilege] ?? privilege;
|
|
15917
|
+
const levelLabel = levelOptions.find((option) => option.level === level)?.label ?? level;
|
|
15918
|
+
if (updatedCount > 0) {
|
|
15919
|
+
logMessage(
|
|
15920
|
+
formatBulkUpdatedVisible(
|
|
15921
|
+
privilegeLabel,
|
|
15922
|
+
levelLabel,
|
|
15923
|
+
updatedCount,
|
|
15924
|
+
skippedCount
|
|
15925
|
+
)
|
|
15926
|
+
);
|
|
15927
|
+
} else {
|
|
15928
|
+
logMessage(formatBulkUpdateNoRows(privilegeLabel));
|
|
15929
|
+
}
|
|
15930
|
+
renderPrivilegeTable();
|
|
15629
15931
|
}
|
|
15630
15932
|
function hasAnyRights(row) {
|
|
15631
15933
|
return accessRights.some((privilege) => {
|
|
@@ -15646,11 +15948,17 @@ ${logTarget.textContent}`;
|
|
|
15646
15948
|
);
|
|
15647
15949
|
}
|
|
15648
15950
|
function updatePendingChange(roleId, entityLogicalName, privilege, level) {
|
|
15649
|
-
const currentLevel = getCurrentPrivilegeLevel(
|
|
15951
|
+
const currentLevel = getCurrentPrivilegeLevel(
|
|
15952
|
+
roleId,
|
|
15953
|
+
entityLogicalName,
|
|
15954
|
+
privilege
|
|
15955
|
+
);
|
|
15650
15956
|
const existing = findPendingChange(roleId, entityLogicalName, privilege);
|
|
15651
15957
|
if (level === currentLevel) {
|
|
15652
15958
|
if (existing) {
|
|
15653
|
-
state.pendingChanges = state.pendingChanges.filter(
|
|
15959
|
+
state.pendingChanges = state.pendingChanges.filter(
|
|
15960
|
+
(change) => change !== existing
|
|
15961
|
+
);
|
|
15654
15962
|
}
|
|
15655
15963
|
updatePendingUi();
|
|
15656
15964
|
return false;
|
|
@@ -15722,18 +16030,30 @@ ${logTarget.textContent}`;
|
|
|
15722
16030
|
});
|
|
15723
16031
|
const sorted = [...filtered].sort((a, b) => {
|
|
15724
16032
|
if (state.sort.column === "label") {
|
|
15725
|
-
const cmp = a.entityLabel.localeCompare(b.entityLabel, void 0, {
|
|
16033
|
+
const cmp = a.entityLabel.localeCompare(b.entityLabel, void 0, {
|
|
16034
|
+
sensitivity: "base"
|
|
16035
|
+
});
|
|
15726
16036
|
return state.sort.direction === "asc" ? cmp : -cmp;
|
|
15727
16037
|
}
|
|
15728
16038
|
const privilege = state.sort.column;
|
|
15729
16039
|
const aAvailable = isPrivilegeAvailable(a, privilege);
|
|
15730
16040
|
const bAvailable = isPrivilegeAvailable(b, privilege);
|
|
15731
|
-
const aRank = getPrivilegeSortRank(
|
|
15732
|
-
|
|
16041
|
+
const aRank = getPrivilegeSortRank(
|
|
16042
|
+
a[privilege],
|
|
16043
|
+
aAvailable,
|
|
16044
|
+
state.sort.direction
|
|
16045
|
+
);
|
|
16046
|
+
const bRank = getPrivilegeSortRank(
|
|
16047
|
+
b[privilege],
|
|
16048
|
+
bAvailable,
|
|
16049
|
+
state.sort.direction
|
|
16050
|
+
);
|
|
15733
16051
|
if (aRank !== bRank) {
|
|
15734
16052
|
return aRank - bRank;
|
|
15735
16053
|
}
|
|
15736
|
-
return a.entityLabel.localeCompare(b.entityLabel, void 0, {
|
|
16054
|
+
return a.entityLabel.localeCompare(b.entityLabel, void 0, {
|
|
16055
|
+
sensitivity: "base"
|
|
16056
|
+
});
|
|
15737
16057
|
});
|
|
15738
16058
|
return sorted;
|
|
15739
16059
|
}
|
|
@@ -15741,6 +16061,7 @@ ${logTarget.textContent}`;
|
|
|
15741
16061
|
elements2.privilegesTable.innerHTML = "";
|
|
15742
16062
|
const isRoleMode = state.tableMode === "role";
|
|
15743
16063
|
const rows = applySortAndFilters(state.privilegeRows);
|
|
16064
|
+
renderBulkControls(rows, isRoleMode);
|
|
15744
16065
|
if (elements2.tableEmpty) {
|
|
15745
16066
|
elements2.tableEmpty.classList.toggle("hidden", state.cacheLoaded);
|
|
15746
16067
|
}
|
|
@@ -15764,26 +16085,15 @@ ${logTarget.textContent}`;
|
|
|
15764
16085
|
tr.appendChild(ownershipCell);
|
|
15765
16086
|
for (const privilege of accessRights) {
|
|
15766
16087
|
const td = document.createElement("td");
|
|
15767
|
-
const privilegeId = state.privilegeIdByKey.get(
|
|
16088
|
+
const privilegeId = state.privilegeIdByKey.get(
|
|
16089
|
+
`${row.entityLogicalName}:${privilege}`
|
|
16090
|
+
);
|
|
15768
16091
|
if (!privilegeId) {
|
|
15769
16092
|
td.textContent = UI_TEXT.tableCellEmpty;
|
|
15770
16093
|
tr.appendChild(td);
|
|
15771
16094
|
continue;
|
|
15772
16095
|
}
|
|
15773
|
-
const
|
|
15774
|
-
const allowedLevels = ["none"];
|
|
15775
|
-
if (info?.canBeBasic) {
|
|
15776
|
-
allowedLevels.push("user");
|
|
15777
|
-
}
|
|
15778
|
-
if (info?.canBeLocal) {
|
|
15779
|
-
allowedLevels.push("businessUnit");
|
|
15780
|
-
}
|
|
15781
|
-
if (info?.canBeDeep) {
|
|
15782
|
-
allowedLevels.push("parentChild");
|
|
15783
|
-
}
|
|
15784
|
-
if (info?.canBeGlobal) {
|
|
15785
|
-
allowedLevels.push("organization");
|
|
15786
|
-
}
|
|
16096
|
+
const allowedLevels = getAllowedLevelsForPrivilege(row, privilege);
|
|
15787
16097
|
const select = document.createElement("select");
|
|
15788
16098
|
select.className = "level-select";
|
|
15789
16099
|
select.dataset.entityLogicalName = row.entityLogicalName;
|
|
@@ -15813,7 +16123,12 @@ ${logTarget.textContent}`;
|
|
|
15813
16123
|
return;
|
|
15814
16124
|
}
|
|
15815
16125
|
const level = select.value;
|
|
15816
|
-
const isPending = updatePendingChange(
|
|
16126
|
+
const isPending = updatePendingChange(
|
|
16127
|
+
roleId,
|
|
16128
|
+
row.entityLogicalName,
|
|
16129
|
+
privilege,
|
|
16130
|
+
level
|
|
16131
|
+
);
|
|
15817
16132
|
setPendingClass(select, isPending);
|
|
15818
16133
|
});
|
|
15819
16134
|
select.disabled = !isRoleMode && !row.roleId;
|
|
@@ -15823,7 +16138,11 @@ ${logTarget.textContent}`;
|
|
|
15823
16138
|
});
|
|
15824
16139
|
if (select.dataset.roleId) {
|
|
15825
16140
|
const pending = Boolean(
|
|
15826
|
-
findPendingChange(
|
|
16141
|
+
findPendingChange(
|
|
16142
|
+
select.dataset.roleId,
|
|
16143
|
+
row.entityLogicalName,
|
|
16144
|
+
privilege
|
|
16145
|
+
)
|
|
15827
16146
|
);
|
|
15828
16147
|
setPendingClass(select, pending);
|
|
15829
16148
|
}
|
|
@@ -16041,7 +16360,8 @@ ${logTarget.textContent}`;
|
|
|
16041
16360
|
{ prefix: "prvDelete", access: "delete" },
|
|
16042
16361
|
{ prefix: "prvAppendTo", access: "appendto" },
|
|
16043
16362
|
{ prefix: "prvAppend", access: "append" },
|
|
16044
|
-
{ prefix: "prvAssign", access: "assign" }
|
|
16363
|
+
{ prefix: "prvAssign", access: "assign" },
|
|
16364
|
+
{ prefix: "prvShare", access: "share" }
|
|
16045
16365
|
];
|
|
16046
16366
|
for (const { prefix, access } of prefixes) {
|
|
16047
16367
|
if (name.startsWith(prefix)) {
|
|
@@ -16066,7 +16386,8 @@ ${logTarget.textContent}`;
|
|
|
16066
16386
|
delete: "none",
|
|
16067
16387
|
append: "none",
|
|
16068
16388
|
appendto: "none",
|
|
16069
|
-
assign: "none"
|
|
16389
|
+
assign: "none",
|
|
16390
|
+
share: "none"
|
|
16070
16391
|
});
|
|
16071
16392
|
}
|
|
16072
16393
|
return roleMap.get(entityLogicalName);
|
|
@@ -16125,7 +16446,11 @@ ${logTarget.textContent}`;
|
|
|
16125
16446
|
elements2.assignmentRoleSelect,
|
|
16126
16447
|
state.roles,
|
|
16127
16448
|
(item) => item.id,
|
|
16128
|
-
(item) => formatAssignmentSelectLabel(
|
|
16449
|
+
(item) => formatAssignmentSelectLabel(
|
|
16450
|
+
item.name,
|
|
16451
|
+
counts.get(item.id) ?? 0,
|
|
16452
|
+
unitLabel
|
|
16453
|
+
)
|
|
16129
16454
|
);
|
|
16130
16455
|
}
|
|
16131
16456
|
function renderAssignmentUserOptionsWithCounts(unitLabel, counts) {
|
|
@@ -16133,7 +16458,11 @@ ${logTarget.textContent}`;
|
|
|
16133
16458
|
elements2.assignmentUserSelect,
|
|
16134
16459
|
state.users,
|
|
16135
16460
|
(item) => item.id,
|
|
16136
|
-
(item) => formatAssignmentSelectLabel(
|
|
16461
|
+
(item) => formatAssignmentSelectLabel(
|
|
16462
|
+
item.name,
|
|
16463
|
+
counts.get(item.id) ?? 0,
|
|
16464
|
+
unitLabel
|
|
16465
|
+
)
|
|
16137
16466
|
);
|
|
16138
16467
|
}
|
|
16139
16468
|
function renderAssignmentTeamOptionsWithCounts(unitLabel, counts) {
|
|
@@ -16141,7 +16470,11 @@ ${logTarget.textContent}`;
|
|
|
16141
16470
|
elements2.assignmentTeamSelect,
|
|
16142
16471
|
state.teams,
|
|
16143
16472
|
(item) => item.id,
|
|
16144
|
-
(item) => formatAssignmentSelectLabel(
|
|
16473
|
+
(item) => formatAssignmentSelectLabel(
|
|
16474
|
+
item.name,
|
|
16475
|
+
counts.get(item.id) ?? 0,
|
|
16476
|
+
unitLabel
|
|
16477
|
+
)
|
|
16145
16478
|
);
|
|
16146
16479
|
}
|
|
16147
16480
|
async function getAssignedUsersForRoleCached(roleId) {
|
|
@@ -16182,7 +16515,11 @@ ${logTarget.textContent}`;
|
|
|
16182
16515
|
state.roles.length ? Promise.resolve() : loadRoles2(),
|
|
16183
16516
|
state.teamsLoaded ? Promise.resolve() : loadTeams2()
|
|
16184
16517
|
]);
|
|
16185
|
-
setDashboardLoadingProgress(
|
|
16518
|
+
setDashboardLoadingProgress(
|
|
16519
|
+
++currentStep,
|
|
16520
|
+
totalSteps,
|
|
16521
|
+
UI_TEXT.loadingDashboardPeople
|
|
16522
|
+
);
|
|
16186
16523
|
const [users, businessUnits, teamMemberships] = await Promise.all([
|
|
16187
16524
|
loadUsersForDashboard(),
|
|
16188
16525
|
loadBusinessUnits(),
|
|
@@ -16407,9 +16744,15 @@ ${logTarget.textContent}`;
|
|
|
16407
16744
|
continue;
|
|
16408
16745
|
}
|
|
16409
16746
|
if (isApplicationUser(user)) {
|
|
16410
|
-
appCounts.set(
|
|
16747
|
+
appCounts.set(
|
|
16748
|
+
user.businessUnitId,
|
|
16749
|
+
(appCounts.get(user.businessUnitId) ?? 0) + 1
|
|
16750
|
+
);
|
|
16411
16751
|
} else {
|
|
16412
|
-
humanCounts.set(
|
|
16752
|
+
humanCounts.set(
|
|
16753
|
+
user.businessUnitId,
|
|
16754
|
+
(humanCounts.get(user.businessUnitId) ?? 0) + 1
|
|
16755
|
+
);
|
|
16413
16756
|
}
|
|
16414
16757
|
}
|
|
16415
16758
|
const units = state.dashboardBusinessUnits.map((unit) => ({
|
|
@@ -16437,11 +16780,17 @@ ${logTarget.textContent}`;
|
|
|
16437
16780
|
const appCounts = /* @__PURE__ */ new Map();
|
|
16438
16781
|
for (const membership of state.dashboardTeamMemberships) {
|
|
16439
16782
|
if (humanIds.has(membership.userId)) {
|
|
16440
|
-
humanCounts.set(
|
|
16783
|
+
humanCounts.set(
|
|
16784
|
+
membership.teamId,
|
|
16785
|
+
(humanCounts.get(membership.teamId) ?? 0) + 1
|
|
16786
|
+
);
|
|
16441
16787
|
continue;
|
|
16442
16788
|
}
|
|
16443
16789
|
if (appIds.has(membership.userId)) {
|
|
16444
|
-
appCounts.set(
|
|
16790
|
+
appCounts.set(
|
|
16791
|
+
membership.teamId,
|
|
16792
|
+
(appCounts.get(membership.teamId) ?? 0) + 1
|
|
16793
|
+
);
|
|
16445
16794
|
}
|
|
16446
16795
|
}
|
|
16447
16796
|
const teamFilterId = elements2.dashboardTeamSelect?.value ?? "";
|
|
@@ -16564,7 +16913,9 @@ ${logTarget.textContent}`;
|
|
|
16564
16913
|
if (!elements2.chartModalBody || !elements2.chartModalCanvas) {
|
|
16565
16914
|
return;
|
|
16566
16915
|
}
|
|
16567
|
-
let empty = elements2.chartModalBody.querySelector(
|
|
16916
|
+
let empty = elements2.chartModalBody.querySelector(
|
|
16917
|
+
".chart-empty"
|
|
16918
|
+
);
|
|
16568
16919
|
if (!empty) {
|
|
16569
16920
|
empty = document.createElement("div");
|
|
16570
16921
|
empty.className = "chart-empty";
|
|
@@ -16592,13 +16943,27 @@ ${logTarget.textContent}`;
|
|
|
16592
16943
|
elements2.chartUsersByRole,
|
|
16593
16944
|
usersByRoleData.labels,
|
|
16594
16945
|
[
|
|
16595
|
-
{
|
|
16596
|
-
|
|
16946
|
+
{
|
|
16947
|
+
label: "Human users",
|
|
16948
|
+
data: usersByRoleData.human,
|
|
16949
|
+
backgroundColor: "#d35400"
|
|
16950
|
+
},
|
|
16951
|
+
{
|
|
16952
|
+
label: "Application users",
|
|
16953
|
+
data: usersByRoleData.app,
|
|
16954
|
+
backgroundColor: "#f39c4a"
|
|
16955
|
+
}
|
|
16597
16956
|
],
|
|
16598
16957
|
true
|
|
16599
16958
|
);
|
|
16600
|
-
setChartEmptyState(
|
|
16601
|
-
|
|
16959
|
+
setChartEmptyState(
|
|
16960
|
+
elements2.chartUsersByRole,
|
|
16961
|
+
usersByRoleData.labels.length === 0
|
|
16962
|
+
);
|
|
16963
|
+
const teamsByRoleCounts = buildTeamsByRoleCounts(
|
|
16964
|
+
businessUnitId,
|
|
16965
|
+
teamFilterId
|
|
16966
|
+
);
|
|
16602
16967
|
const teamsByRoleData = buildRoleTotalChartData(
|
|
16603
16968
|
teamsByRoleCounts,
|
|
16604
16969
|
roleFilterId || null,
|
|
@@ -16610,34 +16975,63 @@ ${logTarget.textContent}`;
|
|
|
16610
16975
|
elements2.chartTeamsByRole,
|
|
16611
16976
|
teamsByRoleData.labels,
|
|
16612
16977
|
[
|
|
16613
|
-
{
|
|
16978
|
+
{
|
|
16979
|
+
label: "Teams",
|
|
16980
|
+
data: teamsByRoleData.values,
|
|
16981
|
+
backgroundColor: "#1f7a8c"
|
|
16982
|
+
}
|
|
16614
16983
|
]
|
|
16615
16984
|
);
|
|
16616
|
-
setChartEmptyState(
|
|
16985
|
+
setChartEmptyState(
|
|
16986
|
+
elements2.chartTeamsByRole,
|
|
16987
|
+
teamsByRoleData.labels.length === 0
|
|
16988
|
+
);
|
|
16617
16989
|
const usersByBuData = buildUsersByBusinessUnitData(filteredUsers, maxRoles);
|
|
16618
16990
|
state.dashboardCharts.usersByBusinessUnit = renderOrUpdateBarChart(
|
|
16619
16991
|
state.dashboardCharts.usersByBusinessUnit,
|
|
16620
16992
|
elements2.chartUsersByBusinessUnit,
|
|
16621
16993
|
usersByBuData.labels,
|
|
16622
16994
|
[
|
|
16623
|
-
{
|
|
16624
|
-
|
|
16995
|
+
{
|
|
16996
|
+
label: "Human users",
|
|
16997
|
+
data: usersByBuData.human,
|
|
16998
|
+
backgroundColor: "#d35400"
|
|
16999
|
+
},
|
|
17000
|
+
{
|
|
17001
|
+
label: "Application users",
|
|
17002
|
+
data: usersByBuData.app,
|
|
17003
|
+
backgroundColor: "#f39c4a"
|
|
17004
|
+
}
|
|
16625
17005
|
],
|
|
16626
17006
|
true
|
|
16627
17007
|
);
|
|
16628
|
-
setChartEmptyState(
|
|
17008
|
+
setChartEmptyState(
|
|
17009
|
+
elements2.chartUsersByBusinessUnit,
|
|
17010
|
+
usersByBuData.labels.length === 0
|
|
17011
|
+
);
|
|
16629
17012
|
const usersByTeamData = buildUsersByTeamData(filteredUsers, maxRoles);
|
|
16630
17013
|
state.dashboardCharts.usersByTeam = renderOrUpdateBarChart(
|
|
16631
17014
|
state.dashboardCharts.usersByTeam,
|
|
16632
17015
|
elements2.chartUsersByTeam,
|
|
16633
17016
|
usersByTeamData.labels,
|
|
16634
17017
|
[
|
|
16635
|
-
{
|
|
16636
|
-
|
|
17018
|
+
{
|
|
17019
|
+
label: "Human users",
|
|
17020
|
+
data: usersByTeamData.human,
|
|
17021
|
+
backgroundColor: "#d35400"
|
|
17022
|
+
},
|
|
17023
|
+
{
|
|
17024
|
+
label: "Application users",
|
|
17025
|
+
data: usersByTeamData.app,
|
|
17026
|
+
backgroundColor: "#f39c4a"
|
|
17027
|
+
}
|
|
16637
17028
|
],
|
|
16638
17029
|
true
|
|
16639
17030
|
);
|
|
16640
|
-
setChartEmptyState(
|
|
17031
|
+
setChartEmptyState(
|
|
17032
|
+
elements2.chartUsersByTeam,
|
|
17033
|
+
usersByTeamData.labels.length === 0
|
|
17034
|
+
);
|
|
16641
17035
|
}
|
|
16642
17036
|
function getDashboardChartData(kind, maxRoles) {
|
|
16643
17037
|
const roleFilterId = elements2.dashboardRoleSelect?.value ?? "";
|
|
@@ -16658,13 +17052,24 @@ ${logTarget.textContent}`;
|
|
|
16658
17052
|
labels: data.labels,
|
|
16659
17053
|
stacked: true,
|
|
16660
17054
|
datasets: [
|
|
16661
|
-
{
|
|
16662
|
-
|
|
17055
|
+
{
|
|
17056
|
+
label: "Human users",
|
|
17057
|
+
data: data.human,
|
|
17058
|
+
backgroundColor: "#d35400"
|
|
17059
|
+
},
|
|
17060
|
+
{
|
|
17061
|
+
label: "Application users",
|
|
17062
|
+
data: data.app,
|
|
17063
|
+
backgroundColor: "#f39c4a"
|
|
17064
|
+
}
|
|
16663
17065
|
]
|
|
16664
17066
|
};
|
|
16665
17067
|
}
|
|
16666
17068
|
case "teamsByRole": {
|
|
16667
|
-
const teamsByRoleCounts = buildTeamsByRoleCounts(
|
|
17069
|
+
const teamsByRoleCounts = buildTeamsByRoleCounts(
|
|
17070
|
+
businessUnitId,
|
|
17071
|
+
teamFilterId
|
|
17072
|
+
);
|
|
16668
17073
|
const data = buildRoleTotalChartData(
|
|
16669
17074
|
teamsByRoleCounts,
|
|
16670
17075
|
roleFilterId || null,
|
|
@@ -16675,7 +17080,9 @@ ${logTarget.textContent}`;
|
|
|
16675
17080
|
title: "Teams per role",
|
|
16676
17081
|
labels: data.labels,
|
|
16677
17082
|
stacked: false,
|
|
16678
|
-
datasets: [
|
|
17083
|
+
datasets: [
|
|
17084
|
+
{ label: "Teams", data: data.values, backgroundColor: "#1f7a8c" }
|
|
17085
|
+
]
|
|
16679
17086
|
};
|
|
16680
17087
|
}
|
|
16681
17088
|
case "usersByBusinessUnit": {
|
|
@@ -16685,8 +17092,16 @@ ${logTarget.textContent}`;
|
|
|
16685
17092
|
labels: data.labels,
|
|
16686
17093
|
stacked: true,
|
|
16687
17094
|
datasets: [
|
|
16688
|
-
{
|
|
16689
|
-
|
|
17095
|
+
{
|
|
17096
|
+
label: "Human users",
|
|
17097
|
+
data: data.human,
|
|
17098
|
+
backgroundColor: "#d35400"
|
|
17099
|
+
},
|
|
17100
|
+
{
|
|
17101
|
+
label: "Application users",
|
|
17102
|
+
data: data.app,
|
|
17103
|
+
backgroundColor: "#f39c4a"
|
|
17104
|
+
}
|
|
16690
17105
|
]
|
|
16691
17106
|
};
|
|
16692
17107
|
}
|
|
@@ -16697,8 +17112,16 @@ ${logTarget.textContent}`;
|
|
|
16697
17112
|
labels: data.labels,
|
|
16698
17113
|
stacked: true,
|
|
16699
17114
|
datasets: [
|
|
16700
|
-
{
|
|
16701
|
-
|
|
17115
|
+
{
|
|
17116
|
+
label: "Human users",
|
|
17117
|
+
data: data.human,
|
|
17118
|
+
backgroundColor: "#d35400"
|
|
17119
|
+
},
|
|
17120
|
+
{
|
|
17121
|
+
label: "Application users",
|
|
17122
|
+
data: data.app,
|
|
17123
|
+
backgroundColor: "#f39c4a"
|
|
17124
|
+
}
|
|
16702
17125
|
]
|
|
16703
17126
|
};
|
|
16704
17127
|
}
|
|
@@ -16764,11 +17187,15 @@ ${logTarget.textContent}`;
|
|
|
16764
17187
|
return isActiveUser(user) ? "Active" : "Inactive";
|
|
16765
17188
|
}
|
|
16766
17189
|
function buildUserRoleExportRows() {
|
|
16767
|
-
const roleNameById = new Map(
|
|
17190
|
+
const roleNameById = new Map(
|
|
17191
|
+
state.allRoles.map((role) => [role.id, role.name])
|
|
17192
|
+
);
|
|
16768
17193
|
const businessUnitById = new Map(
|
|
16769
17194
|
state.dashboardBusinessUnits.map((unit) => [unit.id, unit.name])
|
|
16770
17195
|
);
|
|
16771
|
-
const usersById = new Map(
|
|
17196
|
+
const usersById = new Map(
|
|
17197
|
+
state.dashboardUsers.map((user) => [user.id, user])
|
|
17198
|
+
);
|
|
16772
17199
|
const rows = [
|
|
16773
17200
|
["User", "Email", "Status", "Business Unit", "Security Role"]
|
|
16774
17201
|
];
|
|
@@ -16791,7 +17218,9 @@ ${logTarget.textContent}`;
|
|
|
16791
17218
|
}
|
|
16792
17219
|
function buildUserTeamExportRows() {
|
|
16793
17220
|
const teamNameById = new Map(state.teams.map((team) => [team.id, team.name]));
|
|
16794
|
-
const usersById = new Map(
|
|
17221
|
+
const usersById = new Map(
|
|
17222
|
+
state.dashboardUsers.map((user) => [user.id, user])
|
|
17223
|
+
);
|
|
16795
17224
|
const rows = [["User", "Email", "Status", "Team"]];
|
|
16796
17225
|
for (const membership of state.dashboardTeamMemberships) {
|
|
16797
17226
|
const user = usersById.get(membership.userId);
|
|
@@ -16828,8 +17257,14 @@ ${logTarget.textContent}`;
|
|
|
16828
17257
|
toolboxAPI2.fileSystem,
|
|
16829
17258
|
toolboxAPI2.utils,
|
|
16830
17259
|
[
|
|
16831
|
-
{
|
|
16832
|
-
|
|
17260
|
+
{
|
|
17261
|
+
filename: `security-roles-users-${timestamp}.csv`,
|
|
17262
|
+
content: userRolesCsv
|
|
17263
|
+
},
|
|
17264
|
+
{
|
|
17265
|
+
filename: `security-roles-teams-${timestamp}.csv`,
|
|
17266
|
+
content: userTeamsCsv
|
|
17267
|
+
}
|
|
16833
17268
|
],
|
|
16834
17269
|
`security-roles-users-${timestamp}.csv`
|
|
16835
17270
|
);
|
|
@@ -16872,7 +17307,10 @@ ${logTarget.textContent}`;
|
|
|
16872
17307
|
canBeGlobal: Boolean(privilege.canbeglobal)
|
|
16873
17308
|
});
|
|
16874
17309
|
privilegeMeta.set(privilege.privilegeid, parsed);
|
|
16875
|
-
privilegeIdByKey.set(
|
|
17310
|
+
privilegeIdByKey.set(
|
|
17311
|
+
`${parsed.entityLogicalName}:${parsed.access}`,
|
|
17312
|
+
privilege.privilegeid
|
|
17313
|
+
);
|
|
16876
17314
|
}
|
|
16877
17315
|
const rolePrivilegesCache = /* @__PURE__ */ new Map();
|
|
16878
17316
|
const rolesToCache = state.allRoles.length > 0 ? state.allRoles : state.roles;
|
|
@@ -16896,7 +17334,11 @@ ${logTarget.textContent}`;
|
|
|
16896
17334
|
rolePrivilegeCount += roleEntries.length;
|
|
16897
17335
|
loadedRoles += 1;
|
|
16898
17336
|
if (state.loading.active) {
|
|
16899
|
-
updateLoadingProgress(
|
|
17337
|
+
updateLoadingProgress(
|
|
17338
|
+
loadedRoles,
|
|
17339
|
+
rolesToCache.length,
|
|
17340
|
+
UI_TEXT.loadingRolePrivileges
|
|
17341
|
+
);
|
|
16900
17342
|
}
|
|
16901
17343
|
for (const entry of roleEntries) {
|
|
16902
17344
|
const privilegeId = entry.PrivilegeId ?? entry.privilegeid ?? entry._privilegeid_value;
|
|
@@ -16909,7 +17351,10 @@ ${logTarget.textContent}`;
|
|
|
16909
17351
|
continue;
|
|
16910
17352
|
}
|
|
16911
17353
|
const roleMap = rolePrivilegesCache.get(role.id);
|
|
16912
|
-
const record = ensureRolePrivilegeRecord(
|
|
17354
|
+
const record = ensureRolePrivilegeRecord(
|
|
17355
|
+
roleMap,
|
|
17356
|
+
meta.entityLogicalName
|
|
17357
|
+
);
|
|
16913
17358
|
record[meta.access] = mapPrivilegeLevelFromDepth(depth);
|
|
16914
17359
|
}
|
|
16915
17360
|
}
|
|
@@ -16919,7 +17364,11 @@ ${logTarget.textContent}`;
|
|
|
16919
17364
|
state.rolePrivileges = rolePrivilegesCache;
|
|
16920
17365
|
state.cacheLoaded = true;
|
|
16921
17366
|
logMessage(
|
|
16922
|
-
formatCachedPrivileges(
|
|
17367
|
+
formatCachedPrivileges(
|
|
17368
|
+
privileges.length,
|
|
17369
|
+
rolePrivilegeCount,
|
|
17370
|
+
rolesToCache.length
|
|
17371
|
+
)
|
|
16923
17372
|
);
|
|
16924
17373
|
return true;
|
|
16925
17374
|
}
|
|
@@ -16969,7 +17418,8 @@ ${logTarget.textContent}`;
|
|
|
16969
17418
|
delete: "none",
|
|
16970
17419
|
append: "none",
|
|
16971
17420
|
appendto: "none",
|
|
16972
|
-
assign: "none"
|
|
17421
|
+
assign: "none",
|
|
17422
|
+
share: "none"
|
|
16973
17423
|
};
|
|
16974
17424
|
return {
|
|
16975
17425
|
entityLabel: entity.displayName,
|
|
@@ -16981,7 +17431,8 @@ ${logTarget.textContent}`;
|
|
|
16981
17431
|
delete: record.delete,
|
|
16982
17432
|
append: record.append,
|
|
16983
17433
|
appendto: record.appendto,
|
|
16984
|
-
assign: record.assign
|
|
17434
|
+
assign: record.assign,
|
|
17435
|
+
share: record.share
|
|
16985
17436
|
};
|
|
16986
17437
|
});
|
|
16987
17438
|
renderPrivilegeTable();
|
|
@@ -16994,8 +17445,12 @@ ${logTarget.textContent}`;
|
|
|
16994
17445
|
return;
|
|
16995
17446
|
}
|
|
16996
17447
|
state.tableMode = "entity";
|
|
16997
|
-
const entityLabel = state.entities.find(
|
|
16998
|
-
|
|
17448
|
+
const entityLabel = state.entities.find(
|
|
17449
|
+
(entity) => entity.logicalName === entityLogicalName
|
|
17450
|
+
)?.displayName;
|
|
17451
|
+
const visibleRoles = state.roles.filter(
|
|
17452
|
+
(role) => state.selectedRoleIds.has(role.id)
|
|
17453
|
+
);
|
|
16999
17454
|
state.privilegeRows = visibleRoles.map((role) => {
|
|
17000
17455
|
const record = state.rolePrivileges.get(role.id)?.get(entityLogicalName) ?? {
|
|
17001
17456
|
create: "none",
|
|
@@ -17004,7 +17459,8 @@ ${logTarget.textContent}`;
|
|
|
17004
17459
|
delete: "none",
|
|
17005
17460
|
append: "none",
|
|
17006
17461
|
appendto: "none",
|
|
17007
|
-
assign: "none"
|
|
17462
|
+
assign: "none",
|
|
17463
|
+
share: "none"
|
|
17008
17464
|
};
|
|
17009
17465
|
return {
|
|
17010
17466
|
roleId: role.id,
|
|
@@ -17017,11 +17473,14 @@ ${logTarget.textContent}`;
|
|
|
17017
17473
|
delete: record.delete,
|
|
17018
17474
|
append: record.append,
|
|
17019
17475
|
appendto: record.appendto,
|
|
17020
|
-
assign: record.assign
|
|
17476
|
+
assign: record.assign,
|
|
17477
|
+
share: record.share
|
|
17021
17478
|
};
|
|
17022
17479
|
});
|
|
17023
17480
|
renderPrivilegeTable();
|
|
17024
|
-
setTableTitle(
|
|
17481
|
+
setTableTitle(
|
|
17482
|
+
formatPrivilegesForTableTitle(entityLabel ?? entityLogicalName)
|
|
17483
|
+
);
|
|
17025
17484
|
}
|
|
17026
17485
|
async function loadAssignmentView() {
|
|
17027
17486
|
if (!state.allRoles.length) {
|
|
@@ -17039,7 +17498,10 @@ ${logTarget.textContent}`;
|
|
|
17039
17498
|
activeUserIds
|
|
17040
17499
|
);
|
|
17041
17500
|
}
|
|
17042
|
-
renderAssignmentRoleOptionsWithCounts(
|
|
17501
|
+
renderAssignmentRoleOptionsWithCounts(
|
|
17502
|
+
UI_TEXT.unitUsers,
|
|
17503
|
+
state.assignmentRoleUserCounts
|
|
17504
|
+
);
|
|
17043
17505
|
const roleId = elements2.assignmentRoleSelect.value;
|
|
17044
17506
|
if (!roleId) {
|
|
17045
17507
|
setAssignmentStatus(UI_TEXT.assignmentSelectRoleUsers);
|
|
@@ -17071,7 +17533,10 @@ ${logTarget.textContent}`;
|
|
|
17071
17533
|
if (state.assignmentUserRoleCounts.size !== state.users.length) {
|
|
17072
17534
|
state.assignmentUserRoleCounts = await loadUserAssignmentCounts();
|
|
17073
17535
|
}
|
|
17074
|
-
renderAssignmentUserOptionsWithCounts(
|
|
17536
|
+
renderAssignmentUserOptionsWithCounts(
|
|
17537
|
+
UI_TEXT.unitRoles,
|
|
17538
|
+
state.assignmentUserRoleCounts
|
|
17539
|
+
);
|
|
17075
17540
|
const userId = elements2.assignmentUserSelect.value;
|
|
17076
17541
|
if (!userId) {
|
|
17077
17542
|
setAssignmentStatus(UI_TEXT.assignmentSelectUserRoles);
|
|
@@ -17106,7 +17571,10 @@ ${logTarget.textContent}`;
|
|
|
17106
17571
|
state.allRoles
|
|
17107
17572
|
);
|
|
17108
17573
|
}
|
|
17109
|
-
renderAssignmentRoleOptionsWithCounts(
|
|
17574
|
+
renderAssignmentRoleOptionsWithCounts(
|
|
17575
|
+
UI_TEXT.unitTeams,
|
|
17576
|
+
state.assignmentRoleTeamCounts
|
|
17577
|
+
);
|
|
17110
17578
|
const roleId = elements2.assignmentRoleSelect.value;
|
|
17111
17579
|
if (!roleId) {
|
|
17112
17580
|
setAssignmentStatus(UI_TEXT.assignmentSelectRoleTeams);
|
|
@@ -17138,7 +17606,10 @@ ${logTarget.textContent}`;
|
|
|
17138
17606
|
if (state.assignmentTeamRoleCounts.size !== state.teams.length) {
|
|
17139
17607
|
state.assignmentTeamRoleCounts = await loadTeamAssignmentCounts();
|
|
17140
17608
|
}
|
|
17141
|
-
renderAssignmentTeamOptionsWithCounts(
|
|
17609
|
+
renderAssignmentTeamOptionsWithCounts(
|
|
17610
|
+
UI_TEXT.unitRoles,
|
|
17611
|
+
state.assignmentTeamRoleCounts
|
|
17612
|
+
);
|
|
17142
17613
|
const teamId = elements2.assignmentTeamSelect.value;
|
|
17143
17614
|
if (!teamId) {
|
|
17144
17615
|
setAssignmentStatus(UI_TEXT.assignmentSelectTeamRoles);
|
|
@@ -17191,7 +17662,9 @@ ${logTarget.textContent}`;
|
|
|
17191
17662
|
processedUsers.push(user.name);
|
|
17192
17663
|
}
|
|
17193
17664
|
if (processedUsers.length > 0) {
|
|
17194
|
-
logMessage(
|
|
17665
|
+
logMessage(
|
|
17666
|
+
formatRoleAssignmentLogUsers(action, roleName, processedUsers)
|
|
17667
|
+
);
|
|
17195
17668
|
}
|
|
17196
17669
|
} else if (state.assignmentMode === "user") {
|
|
17197
17670
|
const userId = elements2.assignmentUserSelect.value;
|
|
@@ -17218,7 +17691,9 @@ ${logTarget.textContent}`;
|
|
|
17218
17691
|
processedRoles.push(roleName);
|
|
17219
17692
|
}
|
|
17220
17693
|
if (processedRoles.length > 0) {
|
|
17221
|
-
logMessage(
|
|
17694
|
+
logMessage(
|
|
17695
|
+
formatRoleAssignmentLogRolesForUser(action, user.name, processedRoles)
|
|
17696
|
+
);
|
|
17222
17697
|
}
|
|
17223
17698
|
} else if (state.assignmentMode === "role-team") {
|
|
17224
17699
|
const roleRootId = elements2.assignmentRoleSelect.value;
|
|
@@ -17245,7 +17720,9 @@ ${logTarget.textContent}`;
|
|
|
17245
17720
|
processedTeams.push(team.name);
|
|
17246
17721
|
}
|
|
17247
17722
|
if (processedTeams.length > 0) {
|
|
17248
|
-
logMessage(
|
|
17723
|
+
logMessage(
|
|
17724
|
+
formatRoleAssignmentLogTeams(action, roleName, processedTeams)
|
|
17725
|
+
);
|
|
17249
17726
|
}
|
|
17250
17727
|
} else {
|
|
17251
17728
|
const teamId = elements2.assignmentTeamSelect.value;
|
|
@@ -17272,7 +17749,9 @@ ${logTarget.textContent}`;
|
|
|
17272
17749
|
processedRoles.push(roleName);
|
|
17273
17750
|
}
|
|
17274
17751
|
if (processedRoles.length > 0) {
|
|
17275
|
-
logMessage(
|
|
17752
|
+
logMessage(
|
|
17753
|
+
formatRoleAssignmentLogRolesForTeam(action, team.name, processedRoles)
|
|
17754
|
+
);
|
|
17276
17755
|
}
|
|
17277
17756
|
}
|
|
17278
17757
|
resetAssignmentCaches();
|
|
@@ -17296,17 +17775,25 @@ ${logTarget.textContent}`;
|
|
|
17296
17775
|
const removesByRole = /* @__PURE__ */ new Map();
|
|
17297
17776
|
const addsByRole = /* @__PURE__ */ new Map();
|
|
17298
17777
|
for (const change of state.pendingChanges) {
|
|
17299
|
-
const privilegeId = state.privilegeIdByKey.get(
|
|
17778
|
+
const privilegeId = state.privilegeIdByKey.get(
|
|
17779
|
+
`${change.entityLogicalName}:${change.privilege}`
|
|
17780
|
+
);
|
|
17300
17781
|
if (!privilegeId) {
|
|
17301
|
-
logMessage(
|
|
17782
|
+
logMessage(
|
|
17783
|
+
formatMissingPrivilegeId(change.entityLogicalName, change.privilege)
|
|
17784
|
+
);
|
|
17302
17785
|
continue;
|
|
17303
17786
|
}
|
|
17304
17787
|
const roleMap = state.rolePrivileges.get(change.roleId) ?? /* @__PURE__ */ new Map();
|
|
17305
17788
|
const record = roleMap.get(change.entityLogicalName) ?? {
|
|
17789
|
+
create: "none",
|
|
17306
17790
|
read: "none",
|
|
17307
17791
|
write: "none",
|
|
17792
|
+
delete: "none",
|
|
17308
17793
|
append: "none",
|
|
17309
|
-
appendto: "none"
|
|
17794
|
+
appendto: "none",
|
|
17795
|
+
assign: "none",
|
|
17796
|
+
share: "none"
|
|
17310
17797
|
};
|
|
17311
17798
|
const currentLevel = record[change.privilege];
|
|
17312
17799
|
if (currentLevel === change.level) {
|
|
@@ -17343,20 +17830,31 @@ ${logTarget.textContent}`;
|
|
|
17343
17830
|
for (const privilegeId of privilegeIds) {
|
|
17344
17831
|
await removePrivilegesFromRole(roleId, privilegeId);
|
|
17345
17832
|
completedCalls += 1;
|
|
17346
|
-
updateLoadingProgress(
|
|
17833
|
+
updateLoadingProgress(
|
|
17834
|
+
completedCalls,
|
|
17835
|
+
totalCalls,
|
|
17836
|
+
UI_TEXT.loadingApplyingChanges
|
|
17837
|
+
);
|
|
17347
17838
|
}
|
|
17348
17839
|
}
|
|
17349
17840
|
for (const [roleId, privileges] of addsByRole) {
|
|
17350
17841
|
await addPrivilegesToRole(roleId, privileges);
|
|
17351
17842
|
completedCalls += 1;
|
|
17352
|
-
updateLoadingProgress(
|
|
17843
|
+
updateLoadingProgress(
|
|
17844
|
+
completedCalls,
|
|
17845
|
+
totalCalls,
|
|
17846
|
+
UI_TEXT.loadingApplyingChanges
|
|
17847
|
+
);
|
|
17353
17848
|
}
|
|
17354
17849
|
for (const change of state.pendingChanges) {
|
|
17355
17850
|
if (!state.rolePrivileges.has(change.roleId)) {
|
|
17356
17851
|
state.rolePrivileges.set(change.roleId, /* @__PURE__ */ new Map());
|
|
17357
17852
|
}
|
|
17358
17853
|
const roleMap = state.rolePrivileges.get(change.roleId);
|
|
17359
|
-
const record = ensureRolePrivilegeRecord(
|
|
17854
|
+
const record = ensureRolePrivilegeRecord(
|
|
17855
|
+
roleMap,
|
|
17856
|
+
change.entityLogicalName
|
|
17857
|
+
);
|
|
17360
17858
|
record[change.privilege] = change.level;
|
|
17361
17859
|
}
|
|
17362
17860
|
} catch (error) {
|
|
@@ -17631,10 +18129,18 @@ ${logTarget.textContent}`;
|
|
|
17631
18129
|
loadAssignmentView();
|
|
17632
18130
|
}
|
|
17633
18131
|
});
|
|
17634
|
-
elements2.assignmentAdd.addEventListener(
|
|
17635
|
-
|
|
18132
|
+
elements2.assignmentAdd.addEventListener(
|
|
18133
|
+
"click",
|
|
18134
|
+
() => applyAssignmentChange("add")
|
|
18135
|
+
);
|
|
18136
|
+
elements2.assignmentRemove.addEventListener(
|
|
18137
|
+
"click",
|
|
18138
|
+
() => applyAssignmentChange("remove")
|
|
18139
|
+
);
|
|
17636
18140
|
elements2.assignmentSelectAll.addEventListener("click", () => {
|
|
17637
|
-
state.selectedAssignmentIds = new Set(
|
|
18141
|
+
state.selectedAssignmentIds = new Set(
|
|
18142
|
+
state.assignmentItems.map((item) => item.id)
|
|
18143
|
+
);
|
|
17638
18144
|
renderAssignmentTable(state.assignmentItems);
|
|
17639
18145
|
updateAssignmentSelectionUi();
|
|
17640
18146
|
});
|
|
@@ -17681,6 +18187,22 @@ ${logTarget.textContent}`;
|
|
|
17681
18187
|
renderPrivilegeTable();
|
|
17682
18188
|
});
|
|
17683
18189
|
}
|
|
18190
|
+
for (const button of elements2.bulkApplyButtons) {
|
|
18191
|
+
button.addEventListener("click", () => {
|
|
18192
|
+
const privilege = button.dataset.bulkApply;
|
|
18193
|
+
if (!privilege) {
|
|
18194
|
+
return;
|
|
18195
|
+
}
|
|
18196
|
+
const select = elements2.bulkSelects.find(
|
|
18197
|
+
(item) => item.dataset.bulkSelect === privilege
|
|
18198
|
+
);
|
|
18199
|
+
if (!select || !select.value) {
|
|
18200
|
+
logMessage(UI_TEXT.bulkUpdateNoSelection);
|
|
18201
|
+
return;
|
|
18202
|
+
}
|
|
18203
|
+
applyBulkUpdate(privilege, select.value);
|
|
18204
|
+
});
|
|
18205
|
+
}
|
|
17684
18206
|
for (const select of elements2.filterSelects) {
|
|
17685
18207
|
select.addEventListener("change", async () => {
|
|
17686
18208
|
const privilege = select.dataset.filter;
|