@robertraaijmakers/pptb-securityplugin 0.1.6-beta.0 → 0.1.6

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/README.md CHANGED
@@ -1,62 +1,17 @@
1
1
  # Security Roles Explorer
2
2
  Power Platform ToolBox tool for inspecting and managing Dataverse security roles, table privileges, and user assignments. Helps you quickly understand which roles grant access to which tables and lets you update privileges or user-role assignments in one place.
3
3
 
4
- ## Features
5
- - View role privileges by role or by table
6
- - Batch cache of role privilege data for faster loading
7
- - Sort and filter by privilege level
8
- - Rights filter (all / with rights / without rights)
9
- - Role multi-select filter (entity mode)
10
- - Apply or undo pending privilege changes
11
- - Assign or remove roles for users (role -> users or user -> roles)
12
- - Activity log with timestamps
13
- - Light/dark theme support with a manual toggle
14
-
15
- ## Requirements
16
- - Power Platform ToolBox (desktop app)
17
- - Node.js 18+ (recommended)
18
-
19
- ## Development
20
- Install dependencies:
21
-
22
- ```bash
23
- npm install
24
- ```
25
-
26
- Build once:
27
-
28
- ```bash
29
- npm run build
30
- ```
4
+ More information and user manual can be [found here](https://robertraaijmakers.github.io/pptb.securityplugin/).
31
5
 
32
- Watch mode:
33
-
34
- ```bash
35
- npm run build:watch
36
- ```
37
-
38
- ## Loading in ToolBox (for developers)
39
- 1. Enable Debug Menu in ToolBox settings.
40
- 2. Use Debug > Load Local Tool and select this folder.
41
- 3. Close and reopen the tool to refresh changes.
42
-
43
- ## Usage
44
- 1. Select a connection in ToolBox.
45
- 2. Use the filters and sort controls to narrow results.
46
- 3. Change privilege levels in the grid and click Apply changes.
47
- 4. Use the Assign security roles tab to add/remove roles for users.
48
-
49
- ## Contributing
50
- 1. Fork the repo.
51
- 2. Create a feature branch.
52
- 3. Make changes with small, focused commits.
53
- 4. Run `npm run build` and verify in ToolBox.
54
- 5. Open a pull request with a clear description and screenshots if UI changes.
6
+ ## Features
7
+ - View and (bulk) edit security privileges by Security Role or Table
8
+ - Quickly filter & sort the roles or tables and bulk update the privileges
9
+ - View and (bulk) edit Security Role assignement per user, team and/or role
10
+ - Overview Dashboard with security metrics
55
11
 
56
12
  ## Troubleshooting
57
13
  - If the tool shows "Not connected", select a connection in ToolBox and reload.
58
- - If role privileges fail to load, verify the connection user has the required security role permissions.
59
- - If UI changes do not appear, ensure `npm run build` completed and reopen the tool.
14
+ - If role privileges fail to load, verify the connection user has the required security role permissions and try to refresh the details.
60
15
 
61
16
  ## License
62
17
  MIT
package/dist/README.md CHANGED
@@ -1,62 +1,17 @@
1
1
  # Security Roles Explorer
2
2
  Power Platform ToolBox tool for inspecting and managing Dataverse security roles, table privileges, and user assignments. Helps you quickly understand which roles grant access to which tables and lets you update privileges or user-role assignments in one place.
3
3
 
4
- ## Features
5
- - View role privileges by role or by table
6
- - Batch cache of role privilege data for faster loading
7
- - Sort and filter by privilege level
8
- - Rights filter (all / with rights / without rights)
9
- - Role multi-select filter (entity mode)
10
- - Apply or undo pending privilege changes
11
- - Assign or remove roles for users (role -> users or user -> roles)
12
- - Activity log with timestamps
13
- - Light/dark theme support with a manual toggle
14
-
15
- ## Requirements
16
- - Power Platform ToolBox (desktop app)
17
- - Node.js 18+ (recommended)
18
-
19
- ## Development
20
- Install dependencies:
21
-
22
- ```bash
23
- npm install
24
- ```
25
-
26
- Build once:
27
-
28
- ```bash
29
- npm run build
30
- ```
4
+ More information and user manual can be [found here](https://robertraaijmakers.github.io/pptb.securityplugin/).
31
5
 
32
- Watch mode:
33
-
34
- ```bash
35
- npm run build:watch
36
- ```
37
-
38
- ## Loading in ToolBox (for developers)
39
- 1. Enable Debug Menu in ToolBox settings.
40
- 2. Use Debug > Load Local Tool and select this folder.
41
- 3. Close and reopen the tool to refresh changes.
42
-
43
- ## Usage
44
- 1. Select a connection in ToolBox.
45
- 2. Use the filters and sort controls to narrow results.
46
- 3. Change privilege levels in the grid and click Apply changes.
47
- 4. Use the Assign security roles tab to add/remove roles for users.
48
-
49
- ## Contributing
50
- 1. Fork the repo.
51
- 2. Create a feature branch.
52
- 3. Make changes with small, focused commits.
53
- 4. Run `npm run build` and verify in ToolBox.
54
- 5. Open a pull request with a clear description and screenshots if UI changes.
6
+ ## Features
7
+ - View and (bulk) edit security privileges by Security Role or Table
8
+ - Quickly filter & sort the roles or tables and bulk update the privileges
9
+ - View and (bulk) edit Security Role assignement per user, team and/or role
10
+ - Overview Dashboard with security metrics
55
11
 
56
12
  ## Troubleshooting
57
13
  - If the tool shows "Not connected", select a connection in ToolBox and reload.
58
- - If role privileges fail to load, verify the connection user has the required security role permissions.
59
- - If UI changes do not appear, ensure `npm run build` completed and reopen the tool.
14
+ - If role privileges fail to load, verify the connection user has the required security role permissions and try to refresh the details.
60
15
 
61
16
  ## License
62
17
  MIT
package/dist/app.js CHANGED
@@ -15018,6 +15018,7 @@ ${logTarget.textContent}`;
15018
15018
  },
15019
15019
  assignmentFilter: "",
15020
15020
  assignmentSearch: "",
15021
+ privilegeSearch: "",
15021
15022
  sort: {
15022
15023
  column: "label",
15023
15024
  direction: "asc"
@@ -15130,6 +15131,9 @@ ${logTarget.textContent}`;
15130
15131
  assignmentSearch: document.getElementById(
15131
15132
  "assignment-search"
15132
15133
  ),
15134
+ privilegeSearch: document.getElementById(
15135
+ "privilege-search"
15136
+ ),
15133
15137
  controlsPrivileges: document.getElementById(
15134
15138
  "controls-privileges"
15135
15139
  ),
@@ -15487,14 +15491,18 @@ ${logTarget.textContent}`;
15487
15491
  }
15488
15492
  function setLoading(active, message) {
15489
15493
  state.loading.active = active;
15494
+ const hasLoadedData = state.cacheLoaded;
15490
15495
  if (elements2.tableLoading) {
15491
15496
  elements2.tableLoading.classList.toggle("hidden", !active);
15492
15497
  }
15493
15498
  if (elements2.privilegesTableRoot) {
15494
- elements2.privilegesTableRoot.classList.toggle("hidden", active);
15499
+ elements2.privilegesTableRoot.classList.toggle(
15500
+ "hidden",
15501
+ active || !hasLoadedData
15502
+ );
15495
15503
  }
15496
15504
  if (elements2.tableEmpty) {
15497
- elements2.tableEmpty.classList.toggle("hidden", active || state.cacheLoaded);
15505
+ elements2.tableEmpty.classList.toggle("hidden", active || hasLoadedData);
15498
15506
  }
15499
15507
  if (message && elements2.loadingText) {
15500
15508
  elements2.loadingText.textContent = message;
@@ -16001,6 +16009,14 @@ ${logTarget.textContent}`;
16001
16009
  }
16002
16010
  function applySortAndFilters(rows) {
16003
16011
  const filtered = rows.filter((row) => {
16012
+ if (state.privilegeSearch) {
16013
+ const term = state.privilegeSearch.toLowerCase();
16014
+ const labelMatch = row.entityLabel.toLowerCase().includes(term);
16015
+ const logicalNameMatch = row.entityLogicalName.toLowerCase().includes(term);
16016
+ if (!labelMatch && !logicalNameMatch) {
16017
+ return false;
16018
+ }
16019
+ }
16004
16020
  if (state.rightsFilter === "with" && !hasAnyRights(row)) {
16005
16021
  return false;
16006
16022
  }
@@ -16103,6 +16119,12 @@ ${logTarget.textContent}`;
16103
16119
  } else if (row.roleId) {
16104
16120
  select.dataset.roleId = row.roleId;
16105
16121
  }
16122
+ const pending = select.dataset.roleId ? findPendingChange(
16123
+ select.dataset.roleId,
16124
+ row.entityLogicalName,
16125
+ privilege
16126
+ ) : void 0;
16127
+ const effectiveLevel = pending?.level ?? row[privilege];
16106
16128
  for (const optionMeta of levelOptions) {
16107
16129
  if (!allowedLevels.includes(optionMeta.level)) {
16108
16130
  continue;
@@ -16112,7 +16134,7 @@ ${logTarget.textContent}`;
16112
16134
  option.textContent = `${optionMeta.icon} ${optionMeta.label}`;
16113
16135
  option.className = optionMeta.className;
16114
16136
  option.style.color = getLevelColor(optionMeta.level);
16115
- if (row[privilege] === optionMeta.level) {
16137
+ if (effectiveLevel === optionMeta.level) {
16116
16138
  option.selected = true;
16117
16139
  }
16118
16140
  select.appendChild(option);
@@ -16136,16 +16158,7 @@ ${logTarget.textContent}`;
16136
16158
  select.addEventListener("change", () => {
16137
16159
  applyLevelClass(select, select.value);
16138
16160
  });
16139
- if (select.dataset.roleId) {
16140
- const pending = Boolean(
16141
- findPendingChange(
16142
- select.dataset.roleId,
16143
- row.entityLogicalName,
16144
- privilege
16145
- )
16146
- );
16147
- setPendingClass(select, pending);
16148
- }
16161
+ setPendingClass(select, Boolean(pending));
16149
16162
  td.appendChild(select);
16150
16163
  tr.appendChild(td);
16151
16164
  }
@@ -18174,6 +18187,19 @@ ${logTarget.textContent}`;
18174
18187
  renderAssignmentTable(state.assignmentItems);
18175
18188
  });
18176
18189
  }
18190
+ if (elements2.privilegeSearch) {
18191
+ elements2.privilegeSearch.addEventListener("input", async () => {
18192
+ state.privilegeSearch = elements2.privilegeSearch.value.trim().toLowerCase();
18193
+ if (!state.cacheLoaded) {
18194
+ const loaded = await ensureSecurityCacheLoaded();
18195
+ if (loaded) {
18196
+ await refreshPrivilegeView();
18197
+ }
18198
+ return;
18199
+ }
18200
+ renderPrivilegeTable();
18201
+ });
18202
+ }
18177
18203
  for (const button of elements2.sortButtons) {
18178
18204
  button.addEventListener("click", () => {
18179
18205
  const column = button.dataset.sort || "label";