@masterteam/delegations 0.0.39 → 0.0.41

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.
@@ -122,12 +122,13 @@ let DelegationSessionState = class DelegationSessionState {
122
122
  constructor() {
123
123
  this.actions$
124
124
  .pipe(ofActionSuccessful(GatewayLoginSuccessShell))
125
- .subscribe(() => this.store.dispatch([
126
- // Reset the prompt flag for the new login, then (re)load candidates so
127
- // the "delegations available" prompt fires exactly once after login.
128
- new MarkDelegationPrompted(false),
129
- new LoadDelegationCandidates(),
130
- ]));
125
+ .subscribe(() =>
126
+ // Only (re)load candidates here. The prompt flag is NOT reset on login
127
+ // because the host re-dispatches "Login Success" on every bootstrap /
128
+ // refresh — resetting here would re-prompt on each refresh. The flag is
129
+ // reset on explicit logout / user / app switch (see EndDelegationSession),
130
+ // so the prompt fires once per real login.
131
+ this.store.dispatch(new LoadDelegationCandidates()));
131
132
  this.actions$
132
133
  .pipe(ofActionDispatched(GatewayLogoutShell))
133
134
  .subscribe(() => this.store.dispatch(new EndDelegationSession('Logout')));
@@ -2167,17 +2168,24 @@ class ScopePicker {
2167
2168
  }
2168
2169
  }
2169
2170
  });
2170
- // Default-expand Template nodes whenever options (re)load (levels collapse
2171
- // so large catalogs open compact; search auto-expands matches).
2171
+ // Expansion on options (re)load: Template nodes expand by default (levels
2172
+ // collapse so large catalogs open compact); additionally expand the path to
2173
+ // any already-selected grant so an edit's saved selection is visible.
2172
2174
  effect(() => {
2173
2175
  const model = this.treeModel();
2174
- const keys = new Set();
2175
- for (const node of model) {
2176
- if (node.kind === 'template') {
2177
- keys.add(node.key);
2178
- }
2176
+ untracked(() => this.expandedKeys.set(this.collectExpansion(model, this.selectedKeys(), new Set())));
2177
+ });
2178
+ // One-time: when an initial (edit) scope arrives AFTER options, expand the
2179
+ // path to its selected grants so the user sees what's re-selected.
2180
+ let prefillExpanded = false;
2181
+ effect(() => {
2182
+ const grants = this.scope().grants;
2183
+ const model = this.treeModel();
2184
+ if (prefillExpanded || !grants.length || !model.length) {
2185
+ return;
2179
2186
  }
2180
- untracked(() => this.expandedKeys.set(keys));
2187
+ prefillExpanded = true;
2188
+ untracked(() => this.expandedKeys.update((prev) => this.collectExpansion(model, this.selectedKeys(), prev)));
2181
2189
  });
2182
2190
  // Debounced scope preview.
2183
2191
  let timer = null;
@@ -2321,6 +2329,32 @@ class ScopePicker {
2321
2329
  trackVisible(_index, item) {
2322
2330
  return item.node.key;
2323
2331
  }
2332
+ /**
2333
+ * Template keys (open by default) plus the ancestor keys of every selected
2334
+ * operation, so an edit's saved selection is expanded into view. Only valid
2335
+ * grants (those matching an option node) contribute — invalid saved grants
2336
+ * have no node and are simply ignored.
2337
+ */
2338
+ collectExpansion(model, selected, base) {
2339
+ const keys = new Set(base);
2340
+ const walk = (nodes, ancestors) => {
2341
+ for (const node of nodes) {
2342
+ if (node.kind === 'template') {
2343
+ keys.add(node.key);
2344
+ }
2345
+ if (node.kind === 'operation' && selected.has(node.key)) {
2346
+ for (const ancestor of ancestors) {
2347
+ keys.add(ancestor);
2348
+ }
2349
+ }
2350
+ if (node.children?.length) {
2351
+ walk(node.children, [...ancestors, node.key]);
2352
+ }
2353
+ }
2354
+ };
2355
+ model.forEach((node) => walk([node], []));
2356
+ return keys;
2357
+ }
2324
2358
  // --- App accessibility ----------------------------------------------------
2325
2359
  toggleAccessibility(key) {
2326
2360
  if (this.readonly()) {