@robertraaijmakers/pptb-securityplugin 0.1.1 → 0.1.2-beta.1

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 CHANGED
@@ -14545,6 +14545,14 @@ ${logTarget.textContent}`;
14545
14545
 
14546
14546
  // src/services/dataverseService.ts
14547
14547
  var dataverseAPI = window.dataverseAPI;
14548
+ function buildPrivilegeReference(privilegeId) {
14549
+ const apiEndpoint = dataverseAPI?.apiEndpoint;
14550
+ if (!apiEndpoint) {
14551
+ return `privileges(${privilegeId})`;
14552
+ }
14553
+ const separator = apiEndpoint.endsWith("/") ? "" : "/";
14554
+ return `${apiEndpoint}${separator}privileges(${privilegeId})`;
14555
+ }
14548
14556
  async function queryAll(odataQuery) {
14549
14557
  const all = [];
14550
14558
  let response = await dataverseAPI.queryData(odataQuery);
@@ -14675,6 +14683,35 @@ ${logTarget.textContent}`;
14675
14683
  const response = await dataverseAPI.queryData(query);
14676
14684
  return response?.RolePrivileges ?? response?.rolePrivileges ?? response?.value ?? [];
14677
14685
  }
14686
+ async function addPrivilegesToRole(roleId, privileges) {
14687
+ if (privileges.length === 0) {
14688
+ return;
14689
+ }
14690
+ await dataverseAPI.execute({
14691
+ entityName: "role",
14692
+ entityId: roleId,
14693
+ operationName: "AddPrivilegesRole",
14694
+ operationType: "action",
14695
+ parameters: {
14696
+ Privileges: privileges
14697
+ }
14698
+ });
14699
+ }
14700
+ async function removePrivilegesFromRole(roleId, privilegeId) {
14701
+ if (!privilegeId) {
14702
+ return;
14703
+ }
14704
+ const privilegeReference = buildPrivilegeReference(privilegeId);
14705
+ await dataverseAPI.execute({
14706
+ entityName: "role",
14707
+ entityId: roleId,
14708
+ operationName: "RemovePrivilegeRole",
14709
+ operationType: "action",
14710
+ parameters: {
14711
+ Privilege: privilegeReference
14712
+ }
14713
+ });
14714
+ }
14678
14715
  async function associateRoleToUser(userId, roleId) {
14679
14716
  await dataverseAPI.associate(
14680
14717
  "systemuser",
@@ -14741,6 +14778,7 @@ ${logTarget.textContent}`;
14741
14778
  loadingRolesMetadata: "Loading roles and metadata",
14742
14779
  loadingRolePrivileges: "Loading role privileges",
14743
14780
  loadingRefreshingPrivileges: "Refreshing role privileges",
14781
+ loadingApplyingChanges: "Applying privilege changes",
14744
14782
  loadingDashboardData: "Loading dashboard data",
14745
14783
  loadingDashboardRolesTeams: "Loading roles and teams",
14746
14784
  loadingDashboardPeople: "Loading users, business units, and team memberships",
@@ -14791,10 +14829,6 @@ ${logTarget.textContent}`;
14791
14829
  title: "Update failed",
14792
14830
  body: "Failed to apply privilege updates. See console for details."
14793
14831
  },
14794
- updated: {
14795
- title: "Privileges updated",
14796
- body: "Your changes have been queued for update."
14797
- },
14798
14832
  cacheFailed: {
14799
14833
  title: "Cache failed",
14800
14834
  body: "Could not cache role privileges. See console for details."
@@ -14846,9 +14880,6 @@ ${logTarget.textContent}`;
14846
14880
  function formatMissingPrivilegeId(entityLogicalName, privilege) {
14847
14881
  return `Missing privilege ID for ${entityLogicalName}:${privilege}`;
14848
14882
  }
14849
- function formatQueuedPrivilegeChange(privilege, entityLogicalName, level) {
14850
- return `Queued ${privilege} change for ${entityLogicalName}: ${level}`;
14851
- }
14852
14883
  function formatNoPrivilegesForRole(roleName) {
14853
14884
  return `No privileges returned for role ${roleName}.`;
14854
14885
  }
@@ -14944,6 +14975,7 @@ ${logTarget.textContent}`;
14944
14975
  direction: "asc"
14945
14976
  },
14946
14977
  assignmentFilter: "",
14978
+ assignmentSearch: "",
14947
14979
  sort: {
14948
14980
  column: "label",
14949
14981
  direction: "asc"
@@ -15004,6 +15036,7 @@ ${logTarget.textContent}`;
15004
15036
  document.querySelectorAll("[data-assign-sort]")
15005
15037
  ),
15006
15038
  assignmentFilterAssigned: document.getElementById("assignment-filter-assigned"),
15039
+ assignmentSearch: document.getElementById("assignment-search"),
15007
15040
  controlsPrivileges: document.getElementById("controls-privileges"),
15008
15041
  controlsAssignments: document.getElementById("controls-assignments"),
15009
15042
  controlsDashboard: document.getElementById("controls-dashboard"),
@@ -15424,6 +15457,17 @@ ${logTarget.textContent}`;
15424
15457
  if (state.assignmentFilter === "not-assigned") {
15425
15458
  return !item.assigned;
15426
15459
  }
15460
+ if (state.assignmentSearch) {
15461
+ const rawTerm = state.assignmentSearch.toLowerCase();
15462
+ const term = rawTerm.replace(/\*/g, "").trim();
15463
+ if (term) {
15464
+ const labelMatch = item.label.toLowerCase().includes(term);
15465
+ const subLabelMatch = item.subLabel ? item.subLabel.toLowerCase().includes(term) : false;
15466
+ if (!labelMatch && !subLabelMatch) {
15467
+ return false;
15468
+ }
15469
+ }
15470
+ }
15427
15471
  return true;
15428
15472
  });
15429
15473
  return [...filtered].sort((a, b) => {
@@ -15768,7 +15812,6 @@ ${logTarget.textContent}`;
15768
15812
  const level = select.value;
15769
15813
  const isPending = updatePendingChange(roleId, row.entityLogicalName, privilege, level);
15770
15814
  setPendingClass(select, isPending);
15771
- logMessage(formatQueuedPrivilegeChange(privilege, row.entityLogicalName, level));
15772
15815
  });
15773
15816
  select.disabled = !isRoleMode && !row.roleId;
15774
15817
  applyLevelClass(select, select.value);
@@ -15929,18 +15972,18 @@ ${logTarget.textContent}`;
15929
15972
  }
15930
15973
  return "none";
15931
15974
  }
15932
- function mapPrivilegeDepth(level) {
15975
+ function mapPrivilegeDepthLabel(level) {
15933
15976
  switch (level) {
15934
15977
  case "user":
15935
- return 1;
15978
+ return "Basic";
15936
15979
  case "businessUnit":
15937
- return 2;
15980
+ return "Local";
15938
15981
  case "parentChild":
15939
- return 4;
15982
+ return "Deep";
15940
15983
  case "organization":
15941
- return 8;
15984
+ return "Global";
15942
15985
  default:
15943
- return 0;
15986
+ return "None";
15944
15987
  }
15945
15988
  }
15946
15989
  function mapOwnershipLabel(raw) {
@@ -17266,42 +17309,44 @@ ${logTarget.textContent}`;
17266
17309
  if (currentLevel === change.level) {
17267
17310
  continue;
17268
17311
  }
17269
- if (currentLevel !== "none") {
17312
+ if (change.level === "none") {
17270
17313
  if (!removesByRole.has(change.roleId)) {
17271
17314
  removesByRole.set(change.roleId, []);
17272
17315
  }
17273
17316
  removesByRole.get(change.roleId).push(privilegeId);
17274
- }
17275
- if (change.level !== "none") {
17317
+ } else {
17276
17318
  if (!addsByRole.has(change.roleId)) {
17277
17319
  addsByRole.set(change.roleId, []);
17278
17320
  }
17321
+ const privilegeInfo = state.privilegeInfoById.get(privilegeId);
17279
17322
  addsByRole.get(change.roleId).push({
17280
17323
  PrivilegeId: privilegeId,
17281
- Depth: mapPrivilegeDepth(change.level)
17324
+ Depth: mapPrivilegeDepthLabel(change.level),
17325
+ PrivilegeName: privilegeInfo?.name
17282
17326
  });
17283
17327
  }
17284
17328
  }
17329
+ const totalRemoveCalls = Array.from(removesByRole.values()).reduce(
17330
+ (total, privilegeIds) => total + privilegeIds.length,
17331
+ 0
17332
+ );
17333
+ const totalAddCalls = addsByRole.size;
17334
+ const totalCalls = totalRemoveCalls + totalAddCalls;
17335
+ let completedCalls = 0;
17336
+ setLoading(true, UI_TEXT.loadingApplyingChanges);
17337
+ updateLoadingProgress(0, totalCalls, UI_TEXT.loadingApplyingChanges);
17285
17338
  try {
17286
17339
  for (const [roleId, privilegeIds] of removesByRole) {
17287
- await dataverseAPI.execute({
17288
- operationName: "RemovePrivilegesRole",
17289
- operationType: "action",
17290
- parameters: {
17291
- RoleId: roleId,
17292
- PrivilegeIds: privilegeIds
17293
- }
17294
- });
17340
+ for (const privilegeId of privilegeIds) {
17341
+ await removePrivilegesFromRole(roleId, privilegeId);
17342
+ completedCalls += 1;
17343
+ updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
17344
+ }
17295
17345
  }
17296
17346
  for (const [roleId, privileges] of addsByRole) {
17297
- await dataverseAPI.execute({
17298
- operationName: "AddPrivilegesRole",
17299
- operationType: "action",
17300
- parameters: {
17301
- RoleId: roleId,
17302
- Privileges: privileges
17303
- }
17304
- });
17347
+ await addPrivilegesToRole(roleId, privileges);
17348
+ completedCalls += 1;
17349
+ updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
17305
17350
  }
17306
17351
  for (const change of state.pendingChanges) {
17307
17352
  if (!state.rolePrivileges.has(change.roleId)) {
@@ -17320,16 +17365,12 @@ ${logTarget.textContent}`;
17320
17365
  duration: 3500
17321
17366
  });
17322
17367
  return;
17368
+ } finally {
17369
+ setLoading(false);
17323
17370
  }
17324
17371
  state.pendingChanges = [];
17325
- await toolboxAPI2.utils.showNotification({
17326
- title: NOTIFICATIONS.updated.title,
17327
- body: NOTIFICATIONS.updated.body,
17328
- type: "success",
17329
- duration: 2500
17330
- });
17331
17372
  updatePendingUi();
17332
- renderPrivilegeTable();
17373
+ await refreshPrivilegeView();
17333
17374
  }
17334
17375
  async function refreshData() {
17335
17376
  if (state.refreshInProgress) {
@@ -17618,6 +17659,12 @@ ${logTarget.textContent}`;
17618
17659
  renderAssignmentTable(state.assignmentItems);
17619
17660
  });
17620
17661
  }
17662
+ if (elements2.assignmentSearch) {
17663
+ elements2.assignmentSearch.addEventListener("input", () => {
17664
+ state.assignmentSearch = elements2.assignmentSearch.value.trim();
17665
+ renderAssignmentTable(state.assignmentItems);
17666
+ });
17667
+ }
17621
17668
  for (const button of elements2.sortButtons) {
17622
17669
  button.addEventListener("click", () => {
17623
17670
  const column = button.dataset.sort || "label";