@robertraaijmakers/pptb-securityplugin 0.1.1 → 0.1.2

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
@@ -1050,14 +1050,14 @@ ${logTarget.textContent}`;
1050
1050
  }
1051
1051
  return Array.from(set2);
1052
1052
  }
1053
- var requestAnimFrame = function() {
1053
+ var requestAnimFrame = (function() {
1054
1054
  if (typeof window === "undefined") {
1055
1055
  return function(callback2) {
1056
1056
  return callback2();
1057
1057
  };
1058
1058
  }
1059
1059
  return window.requestAnimationFrame;
1060
- }();
1060
+ })();
1061
1061
  function throttled(fn, thisArg) {
1062
1062
  let argsToUse = [];
1063
1063
  let ticking = false;
@@ -1671,6 +1671,7 @@ ${logTarget.textContent}`;
1671
1671
  }
1672
1672
  ctx.beginPath();
1673
1673
  switch (style) {
1674
+ // Default includes circle
1674
1675
  default:
1675
1676
  if (w) {
1676
1677
  ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU);
@@ -1709,6 +1710,7 @@ ${logTarget.textContent}`;
1709
1710
  break;
1710
1711
  }
1711
1712
  rad += QUARTER_PI;
1713
+ /* falls through */
1712
1714
  case "rectRot":
1713
1715
  xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1714
1716
  xOffset = Math.cos(rad) * radius;
@@ -1722,6 +1724,7 @@ ${logTarget.textContent}`;
1722
1724
  break;
1723
1725
  case "crossRot":
1724
1726
  rad += QUARTER_PI;
1727
+ /* falls through */
1725
1728
  case "cross":
1726
1729
  xOffsetW = Math.cos(rad) * (w ? w / 2 : radius);
1727
1730
  xOffset = Math.cos(rad) * radius;
@@ -2611,7 +2614,7 @@ ${logTarget.textContent}`;
2611
2614
  }
2612
2615
  return false;
2613
2616
  }
2614
- var supportsEventListenerOptions = function() {
2617
+ var supportsEventListenerOptions = (function() {
2615
2618
  let passiveSupported = false;
2616
2619
  try {
2617
2620
  const options = {
@@ -2627,7 +2630,7 @@ ${logTarget.textContent}`;
2627
2630
  } catch (e) {
2628
2631
  }
2629
2632
  return passiveSupported;
2630
- }();
2633
+ })();
2631
2634
  function readUsedSize(element, property) {
2632
2635
  const value = getStyle(element, property);
2633
2636
  const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
@@ -14545,6 +14548,14 @@ ${logTarget.textContent}`;
14545
14548
 
14546
14549
  // src/services/dataverseService.ts
14547
14550
  var dataverseAPI = window.dataverseAPI;
14551
+ function buildPrivilegeReference(privilegeId) {
14552
+ const apiEndpoint = dataverseAPI?.apiEndpoint;
14553
+ if (!apiEndpoint) {
14554
+ return `privileges(${privilegeId})`;
14555
+ }
14556
+ const separator = apiEndpoint.endsWith("/") ? "" : "/";
14557
+ return `${apiEndpoint}${separator}privileges(${privilegeId})`;
14558
+ }
14548
14559
  async function queryAll(odataQuery) {
14549
14560
  const all = [];
14550
14561
  let response = await dataverseAPI.queryData(odataQuery);
@@ -14675,6 +14686,35 @@ ${logTarget.textContent}`;
14675
14686
  const response = await dataverseAPI.queryData(query);
14676
14687
  return response?.RolePrivileges ?? response?.rolePrivileges ?? response?.value ?? [];
14677
14688
  }
14689
+ async function addPrivilegesToRole(roleId, privileges) {
14690
+ if (privileges.length === 0) {
14691
+ return;
14692
+ }
14693
+ await dataverseAPI.execute({
14694
+ entityName: "role",
14695
+ entityId: roleId,
14696
+ operationName: "AddPrivilegesRole",
14697
+ operationType: "action",
14698
+ parameters: {
14699
+ Privileges: privileges
14700
+ }
14701
+ });
14702
+ }
14703
+ async function removePrivilegesFromRole(roleId, privilegeId) {
14704
+ if (!privilegeId) {
14705
+ return;
14706
+ }
14707
+ const privilegeReference = buildPrivilegeReference(privilegeId);
14708
+ await dataverseAPI.execute({
14709
+ entityName: "role",
14710
+ entityId: roleId,
14711
+ operationName: "RemovePrivilegeRole",
14712
+ operationType: "action",
14713
+ parameters: {
14714
+ Privilege: privilegeReference
14715
+ }
14716
+ });
14717
+ }
14678
14718
  async function associateRoleToUser(userId, roleId) {
14679
14719
  await dataverseAPI.associate(
14680
14720
  "systemuser",
@@ -14741,6 +14781,7 @@ ${logTarget.textContent}`;
14741
14781
  loadingRolesMetadata: "Loading roles and metadata",
14742
14782
  loadingRolePrivileges: "Loading role privileges",
14743
14783
  loadingRefreshingPrivileges: "Refreshing role privileges",
14784
+ loadingApplyingChanges: "Applying privilege changes",
14744
14785
  loadingDashboardData: "Loading dashboard data",
14745
14786
  loadingDashboardRolesTeams: "Loading roles and teams",
14746
14787
  loadingDashboardPeople: "Loading users, business units, and team memberships",
@@ -14791,10 +14832,6 @@ ${logTarget.textContent}`;
14791
14832
  title: "Update failed",
14792
14833
  body: "Failed to apply privilege updates. See console for details."
14793
14834
  },
14794
- updated: {
14795
- title: "Privileges updated",
14796
- body: "Your changes have been queued for update."
14797
- },
14798
14835
  cacheFailed: {
14799
14836
  title: "Cache failed",
14800
14837
  body: "Could not cache role privileges. See console for details."
@@ -14846,9 +14883,6 @@ ${logTarget.textContent}`;
14846
14883
  function formatMissingPrivilegeId(entityLogicalName, privilege) {
14847
14884
  return `Missing privilege ID for ${entityLogicalName}:${privilege}`;
14848
14885
  }
14849
- function formatQueuedPrivilegeChange(privilege, entityLogicalName, level) {
14850
- return `Queued ${privilege} change for ${entityLogicalName}: ${level}`;
14851
- }
14852
14886
  function formatNoPrivilegesForRole(roleName) {
14853
14887
  return `No privileges returned for role ${roleName}.`;
14854
14888
  }
@@ -14944,6 +14978,7 @@ ${logTarget.textContent}`;
14944
14978
  direction: "asc"
14945
14979
  },
14946
14980
  assignmentFilter: "",
14981
+ assignmentSearch: "",
14947
14982
  sort: {
14948
14983
  column: "label",
14949
14984
  direction: "asc"
@@ -15004,6 +15039,7 @@ ${logTarget.textContent}`;
15004
15039
  document.querySelectorAll("[data-assign-sort]")
15005
15040
  ),
15006
15041
  assignmentFilterAssigned: document.getElementById("assignment-filter-assigned"),
15042
+ assignmentSearch: document.getElementById("assignment-search"),
15007
15043
  controlsPrivileges: document.getElementById("controls-privileges"),
15008
15044
  controlsAssignments: document.getElementById("controls-assignments"),
15009
15045
  controlsDashboard: document.getElementById("controls-dashboard"),
@@ -15424,6 +15460,17 @@ ${logTarget.textContent}`;
15424
15460
  if (state.assignmentFilter === "not-assigned") {
15425
15461
  return !item.assigned;
15426
15462
  }
15463
+ if (state.assignmentSearch) {
15464
+ const rawTerm = state.assignmentSearch.toLowerCase();
15465
+ const term = rawTerm.replace(/\*/g, "").trim();
15466
+ if (term) {
15467
+ const labelMatch = item.label.toLowerCase().includes(term);
15468
+ const subLabelMatch = item.subLabel ? item.subLabel.toLowerCase().includes(term) : false;
15469
+ if (!labelMatch && !subLabelMatch) {
15470
+ return false;
15471
+ }
15472
+ }
15473
+ }
15427
15474
  return true;
15428
15475
  });
15429
15476
  return [...filtered].sort((a, b) => {
@@ -15768,7 +15815,6 @@ ${logTarget.textContent}`;
15768
15815
  const level = select.value;
15769
15816
  const isPending = updatePendingChange(roleId, row.entityLogicalName, privilege, level);
15770
15817
  setPendingClass(select, isPending);
15771
- logMessage(formatQueuedPrivilegeChange(privilege, row.entityLogicalName, level));
15772
15818
  });
15773
15819
  select.disabled = !isRoleMode && !row.roleId;
15774
15820
  applyLevelClass(select, select.value);
@@ -15929,18 +15975,18 @@ ${logTarget.textContent}`;
15929
15975
  }
15930
15976
  return "none";
15931
15977
  }
15932
- function mapPrivilegeDepth(level) {
15978
+ function mapPrivilegeDepthLabel(level) {
15933
15979
  switch (level) {
15934
15980
  case "user":
15935
- return 1;
15981
+ return "Basic";
15936
15982
  case "businessUnit":
15937
- return 2;
15983
+ return "Local";
15938
15984
  case "parentChild":
15939
- return 4;
15985
+ return "Deep";
15940
15986
  case "organization":
15941
- return 8;
15987
+ return "Global";
15942
15988
  default:
15943
- return 0;
15989
+ return "None";
15944
15990
  }
15945
15991
  }
15946
15992
  function mapOwnershipLabel(raw) {
@@ -17266,42 +17312,44 @@ ${logTarget.textContent}`;
17266
17312
  if (currentLevel === change.level) {
17267
17313
  continue;
17268
17314
  }
17269
- if (currentLevel !== "none") {
17315
+ if (change.level === "none") {
17270
17316
  if (!removesByRole.has(change.roleId)) {
17271
17317
  removesByRole.set(change.roleId, []);
17272
17318
  }
17273
17319
  removesByRole.get(change.roleId).push(privilegeId);
17274
- }
17275
- if (change.level !== "none") {
17320
+ } else {
17276
17321
  if (!addsByRole.has(change.roleId)) {
17277
17322
  addsByRole.set(change.roleId, []);
17278
17323
  }
17324
+ const privilegeInfo = state.privilegeInfoById.get(privilegeId);
17279
17325
  addsByRole.get(change.roleId).push({
17280
17326
  PrivilegeId: privilegeId,
17281
- Depth: mapPrivilegeDepth(change.level)
17327
+ Depth: mapPrivilegeDepthLabel(change.level),
17328
+ PrivilegeName: privilegeInfo?.name
17282
17329
  });
17283
17330
  }
17284
17331
  }
17332
+ const totalRemoveCalls = Array.from(removesByRole.values()).reduce(
17333
+ (total, privilegeIds) => total + privilegeIds.length,
17334
+ 0
17335
+ );
17336
+ const totalAddCalls = addsByRole.size;
17337
+ const totalCalls = totalRemoveCalls + totalAddCalls;
17338
+ let completedCalls = 0;
17339
+ setLoading(true, UI_TEXT.loadingApplyingChanges);
17340
+ updateLoadingProgress(0, totalCalls, UI_TEXT.loadingApplyingChanges);
17285
17341
  try {
17286
17342
  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
- });
17343
+ for (const privilegeId of privilegeIds) {
17344
+ await removePrivilegesFromRole(roleId, privilegeId);
17345
+ completedCalls += 1;
17346
+ updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
17347
+ }
17295
17348
  }
17296
17349
  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
- });
17350
+ await addPrivilegesToRole(roleId, privileges);
17351
+ completedCalls += 1;
17352
+ updateLoadingProgress(completedCalls, totalCalls, UI_TEXT.loadingApplyingChanges);
17305
17353
  }
17306
17354
  for (const change of state.pendingChanges) {
17307
17355
  if (!state.rolePrivileges.has(change.roleId)) {
@@ -17320,16 +17368,12 @@ ${logTarget.textContent}`;
17320
17368
  duration: 3500
17321
17369
  });
17322
17370
  return;
17371
+ } finally {
17372
+ setLoading(false);
17323
17373
  }
17324
17374
  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
17375
  updatePendingUi();
17332
- renderPrivilegeTable();
17376
+ await refreshPrivilegeView();
17333
17377
  }
17334
17378
  async function refreshData() {
17335
17379
  if (state.refreshInProgress) {
@@ -17618,6 +17662,12 @@ ${logTarget.textContent}`;
17618
17662
  renderAssignmentTable(state.assignmentItems);
17619
17663
  });
17620
17664
  }
17665
+ if (elements2.assignmentSearch) {
17666
+ elements2.assignmentSearch.addEventListener("input", () => {
17667
+ state.assignmentSearch = elements2.assignmentSearch.value.trim();
17668
+ renderAssignmentTable(state.assignmentItems);
17669
+ });
17670
+ }
17621
17671
  for (const button of elements2.sortButtons) {
17622
17672
  button.addEventListener("click", () => {
17623
17673
  const column = button.dataset.sort || "label";
@@ -17681,13 +17731,6 @@ ${logTarget.textContent}`;
17681
17731
  *)
17682
17732
 
17683
17733
  chart.js/dist/chunks/helpers.dataset.js:
17684
- (*!
17685
- * Chart.js v4.5.1
17686
- * https://www.chartjs.org
17687
- * (c) 2025 Chart.js Contributors
17688
- * Released under the MIT License
17689
- *)
17690
-
17691
17734
  chart.js/dist/chart.js:
17692
17735
  (*!
17693
17736
  * Chart.js v4.5.1