@gooddata/sdk-ui-ext 11.52.0-alpha.6 → 11.52.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.
Files changed (125) hide show
  1. package/esm/dataLoaders/InsightDataLoader.d.ts +6 -0
  2. package/esm/dataLoaders/InsightDataLoader.d.ts.map +1 -1
  3. package/esm/dataLoaders/InsightDataLoader.js +4 -1
  4. package/esm/dataLoaders/index.d.ts +13 -0
  5. package/esm/dataLoaders/index.d.ts.map +1 -1
  6. package/esm/dataLoaders/index.js +14 -0
  7. package/esm/index.d.ts +1 -1
  8. package/esm/index.d.ts.map +1 -1
  9. package/esm/index.js +1 -1
  10. package/esm/insightView/InsightRenderer.d.ts +2 -5
  11. package/esm/insightView/InsightRenderer.d.ts.map +1 -1
  12. package/esm/insightView/InsightRenderer.js +1 -2
  13. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.d.ts +6 -1
  14. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.d.ts.map +1 -1
  15. package/esm/internal/components/pluggableVisualizations/mekko/PluggableMekko.js +25 -4
  16. package/esm/internal/components/pluggableVisualizations/pivotTable/PluggablePivotTable.d.ts.map +1 -1
  17. package/esm/internal/components/pluggableVisualizations/pivotTable/PluggablePivotTable.js +0 -1
  18. package/esm/internal/translations/de-DE.localization-bundle.d.ts +2 -0
  19. package/esm/internal/translations/de-DE.localization-bundle.d.ts.map +1 -1
  20. package/esm/internal/translations/de-DE.localization-bundle.js +2 -0
  21. package/esm/internal/translations/en-AU.localization-bundle.d.ts +2 -0
  22. package/esm/internal/translations/en-AU.localization-bundle.d.ts.map +1 -1
  23. package/esm/internal/translations/en-AU.localization-bundle.js +2 -0
  24. package/esm/internal/translations/en-GB.localization-bundle.d.ts +2 -0
  25. package/esm/internal/translations/en-GB.localization-bundle.d.ts.map +1 -1
  26. package/esm/internal/translations/en-GB.localization-bundle.js +2 -0
  27. package/esm/internal/translations/en-US.localization-bundle.d.ts +4 -0
  28. package/esm/internal/translations/en-US.localization-bundle.d.ts.map +1 -1
  29. package/esm/internal/translations/en-US.localization-bundle.js +4 -0
  30. package/esm/internal/translations/es-419.localization-bundle.d.ts +2 -0
  31. package/esm/internal/translations/es-419.localization-bundle.d.ts.map +1 -1
  32. package/esm/internal/translations/es-419.localization-bundle.js +2 -0
  33. package/esm/internal/translations/es-ES.localization-bundle.d.ts +2 -0
  34. package/esm/internal/translations/es-ES.localization-bundle.d.ts.map +1 -1
  35. package/esm/internal/translations/es-ES.localization-bundle.js +2 -0
  36. package/esm/internal/translations/fi-FI.localization-bundle.d.ts +2 -0
  37. package/esm/internal/translations/fi-FI.localization-bundle.d.ts.map +1 -1
  38. package/esm/internal/translations/fi-FI.localization-bundle.js +2 -0
  39. package/esm/internal/translations/fr-CA.localization-bundle.d.ts +2 -0
  40. package/esm/internal/translations/fr-CA.localization-bundle.d.ts.map +1 -1
  41. package/esm/internal/translations/fr-CA.localization-bundle.js +2 -0
  42. package/esm/internal/translations/fr-FR.localization-bundle.d.ts +2 -0
  43. package/esm/internal/translations/fr-FR.localization-bundle.d.ts.map +1 -1
  44. package/esm/internal/translations/fr-FR.localization-bundle.js +2 -0
  45. package/esm/internal/translations/id-ID.localization-bundle.d.ts +2 -0
  46. package/esm/internal/translations/id-ID.localization-bundle.d.ts.map +1 -1
  47. package/esm/internal/translations/id-ID.localization-bundle.js +2 -0
  48. package/esm/internal/translations/it-IT.localization-bundle.d.ts +2 -0
  49. package/esm/internal/translations/it-IT.localization-bundle.d.ts.map +1 -1
  50. package/esm/internal/translations/it-IT.localization-bundle.js +2 -0
  51. package/esm/internal/translations/ja-JP.localization-bundle.d.ts +2 -0
  52. package/esm/internal/translations/ja-JP.localization-bundle.d.ts.map +1 -1
  53. package/esm/internal/translations/ja-JP.localization-bundle.js +2 -0
  54. package/esm/internal/translations/ko-KR.localization-bundle.d.ts +2 -0
  55. package/esm/internal/translations/ko-KR.localization-bundle.d.ts.map +1 -1
  56. package/esm/internal/translations/ko-KR.localization-bundle.js +2 -0
  57. package/esm/internal/translations/nl-NL.localization-bundle.d.ts +2 -0
  58. package/esm/internal/translations/nl-NL.localization-bundle.d.ts.map +1 -1
  59. package/esm/internal/translations/nl-NL.localization-bundle.js +2 -0
  60. package/esm/internal/translations/pl-PL.localization-bundle.d.ts +2 -0
  61. package/esm/internal/translations/pl-PL.localization-bundle.d.ts.map +1 -1
  62. package/esm/internal/translations/pl-PL.localization-bundle.js +2 -0
  63. package/esm/internal/translations/pt-BR.localization-bundle.d.ts +2 -0
  64. package/esm/internal/translations/pt-BR.localization-bundle.d.ts.map +1 -1
  65. package/esm/internal/translations/pt-BR.localization-bundle.js +2 -0
  66. package/esm/internal/translations/pt-PT.localization-bundle.d.ts +2 -0
  67. package/esm/internal/translations/pt-PT.localization-bundle.d.ts.map +1 -1
  68. package/esm/internal/translations/pt-PT.localization-bundle.js +2 -0
  69. package/esm/internal/translations/ru-RU.localization-bundle.d.ts +2 -0
  70. package/esm/internal/translations/ru-RU.localization-bundle.d.ts.map +1 -1
  71. package/esm/internal/translations/ru-RU.localization-bundle.js +2 -0
  72. package/esm/internal/translations/sl-SI.localization-bundle.d.ts +2 -0
  73. package/esm/internal/translations/sl-SI.localization-bundle.d.ts.map +1 -1
  74. package/esm/internal/translations/sl-SI.localization-bundle.js +2 -0
  75. package/esm/internal/translations/th-TH.localization-bundle.d.ts +2 -0
  76. package/esm/internal/translations/th-TH.localization-bundle.d.ts.map +1 -1
  77. package/esm/internal/translations/th-TH.localization-bundle.js +2 -0
  78. package/esm/internal/translations/tr-TR.localization-bundle.d.ts +2 -0
  79. package/esm/internal/translations/tr-TR.localization-bundle.d.ts.map +1 -1
  80. package/esm/internal/translations/tr-TR.localization-bundle.js +2 -0
  81. package/esm/internal/translations/uk-UA.localization-bundle.d.ts +2 -0
  82. package/esm/internal/translations/uk-UA.localization-bundle.d.ts.map +1 -1
  83. package/esm/internal/translations/uk-UA.localization-bundle.js +2 -0
  84. package/esm/internal/translations/vi-VN.localization-bundle.d.ts +2 -0
  85. package/esm/internal/translations/vi-VN.localization-bundle.d.ts.map +1 -1
  86. package/esm/internal/translations/vi-VN.localization-bundle.js +2 -0
  87. package/esm/internal/translations/zh-HK.localization-bundle.d.ts +2 -0
  88. package/esm/internal/translations/zh-HK.localization-bundle.d.ts.map +1 -1
  89. package/esm/internal/translations/zh-HK.localization-bundle.js +2 -0
  90. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts +2 -0
  91. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts.map +1 -1
  92. package/esm/internal/translations/zh-Hans.localization-bundle.js +2 -0
  93. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts +2 -0
  94. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts.map +1 -1
  95. package/esm/internal/translations/zh-Hant.localization-bundle.js +2 -0
  96. package/esm/notificationsPanel/Notification/Notification.d.ts.map +1 -1
  97. package/esm/notificationsPanel/Notification/Notification.js +6 -3
  98. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.d.ts +3 -3
  99. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.d.ts.map +1 -1
  100. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetail.js +4 -4
  101. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.d.ts +9 -3
  102. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.d.ts.map +1 -1
  103. package/esm/notificationsPanel/NotificationFiltersDetail/NotificationFiltersDetailDialog.js +4 -4
  104. package/esm/sdk-ui-ext.d.ts +13 -0
  105. package/esm/share/ObjectShareDialog.js +22 -6
  106. package/esm/share/messages.d.ts +7 -0
  107. package/esm/share/messages.d.ts.map +1 -1
  108. package/esm/share/messages.js +5 -0
  109. package/esm/share/objectShareController.helpers.d.ts +117 -17
  110. package/esm/share/objectShareController.helpers.d.ts.map +1 -1
  111. package/esm/share/objectShareController.helpers.js +181 -44
  112. package/esm/share/objectShareController.types.d.ts +34 -10
  113. package/esm/share/objectShareController.types.d.ts.map +1 -1
  114. package/esm/share/useAccessList.d.ts +6 -0
  115. package/esm/share/useAccessList.d.ts.map +1 -1
  116. package/esm/share/useAccessList.js +26 -6
  117. package/esm/share/useLabelScope.d.ts +46 -1
  118. package/esm/share/useLabelScope.d.ts.map +1 -1
  119. package/esm/share/useLabelScope.js +98 -6
  120. package/esm/share/useObjectShareController.d.ts.map +1 -1
  121. package/esm/share/useObjectShareController.js +213 -45
  122. package/esm/share/useObjectShareDialog.d.ts +7 -0
  123. package/esm/share/useObjectShareDialog.d.ts.map +1 -1
  124. package/esm/share/useObjectShareDialog.js +22 -2
  125. package/package.json +21 -21
@@ -2,8 +2,13 @@
2
2
  import { useCallback, useMemo, useState } from "react";
3
3
  import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
4
4
  import { isPermissionsNotAvailable } from "./accessErrors.js";
5
- import { buildLabelMutationsForPrincipals, isGranteeGrantedIn, } from "./objectShareController.helpers.js";
6
- /** Pure: each grantee's in-scope label ids — primary always counts, others only where the grantee is granted. */
5
+ import { buildLabelMutationsForScopes, buildLabelRegrades, granteeGrantIn, } from "./objectShareController.helpers.js";
6
+ /**
7
+ * Pure: each grantee's in-scope label ids — primary always counts, others wherever
8
+ * the grantee holds the label, whether granted here or inherited. An inherited label
9
+ * is genuinely in scope: the grantee can read it, so the checklist must show it
10
+ * checked, exactly as the parent workspace shows it.
11
+ */
7
12
  function resolveScopes(results, committedGranteeIds) {
8
13
  const resolved = {};
9
14
  for (const id of committedGranteeIds) {
@@ -14,13 +19,52 @@ function resolveScopes(results, committedGranteeIds) {
14
19
  continue;
15
20
  }
16
21
  for (const id of committedGranteeIds) {
17
- if (result.label.isPrimary || isGranteeGrantedIn(result.list, id)) {
22
+ if (result.label.isPrimary || granteeGrantIn(result.list, id)) {
18
23
  resolved[id].push(result.label.id);
19
24
  }
20
25
  }
21
26
  }
22
27
  return resolved;
23
28
  }
29
+ /**
30
+ * Pure: per-grantee label provenance, split by which question it answers. A label that is
31
+ * both granted here and inherited appears in BOTH maps, and that is the point — the two
32
+ * facts drive different decisions.
33
+ *
34
+ * - `inherited` — access survives revoking whatever this workspace granted, so the
35
+ * checkbox stays checked and locked. Immutable for the session: no write from this
36
+ * workspace can change a group's or a parent's grant, so deriving it from the probe
37
+ * cannot go stale.
38
+ * - `direct` — granted HERE, so it is the only thing a write may target. This one DOES
39
+ * change under our own writes, so the hook keeps it as an optimistic overlay seeded from
40
+ * here rather than re-deriving it from a probe that runs once per session.
41
+ *
42
+ * The primary label is excluded from both: it is locked for every grantee regardless, and
43
+ * never written.
44
+ */
45
+ function resolveLabelProvenance(results, committedGranteeIds) {
46
+ const inherited = {};
47
+ const direct = {};
48
+ for (const id of committedGranteeIds) {
49
+ inherited[id] = [];
50
+ direct[id] = [];
51
+ }
52
+ for (const result of results) {
53
+ if ("transient" in result || result.label.isPrimary) {
54
+ continue;
55
+ }
56
+ for (const id of committedGranteeIds) {
57
+ const grant = granteeGrantIn(result.list, id);
58
+ if (grant?.inherited) {
59
+ inherited[id].push(result.label.id);
60
+ }
61
+ if (grant?.direct) {
62
+ direct[id].push(result.label.id);
63
+ }
64
+ }
65
+ }
66
+ return { inherited, direct };
67
+ }
24
68
  /**
25
69
  * Owns label-scope resolution + writes for {@link useObjectShareController}.
26
70
  * Resolves each grantee's scope by fetching every label's access list, tracks
@@ -41,6 +85,10 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
41
85
  // a fresh add / labels edit must survive the backend's lagging re-read, so the
42
86
  // probe below only seeds grantees it doesn't already know.
43
87
  const [selectedLabelIdsByGrantee, setSelectedLabelIdsByGrantee] = useState({});
88
+ // Which labels THIS workspace grants each grantee. Optimistic for the same reason the
89
+ // scope is, and for a sharper one: our own revokes and grants change it, and the probe
90
+ // will not run again to notice.
91
+ const [directLabelIdsByGrantee, setDirectLabelIdsByGrantee] = useState({});
44
92
  // Whether the session's first probe has settled (see `labelsInitializing`) —
45
93
  // a fact about session history, so it is state, flipped once in onSuccess.
46
94
  const [everResolved, setEverResolved] = useState(false);
@@ -52,6 +100,7 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
52
100
  if (seenLabelsKey !== labelsKey) {
53
101
  setSeenLabelsKey(labelsKey);
54
102
  setSelectedLabelIdsByGrantee({});
103
+ setDirectLabelIdsByGrantee({});
55
104
  }
56
105
  // Probe each label's access list to learn which are permissionable (some 404) and
57
106
  // which each grantee holds. `hasList` gates it: a list with no named grantees keeps
@@ -73,6 +122,7 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
73
122
  onSuccess: (results) => {
74
123
  setEverResolved(true);
75
124
  const resolved = resolveScopes(results, committedGranteeIds);
125
+ const { direct } = resolveLabelProvenance(results, committedGranteeIds);
76
126
  // Seed only grantees we don't already have a scope for — an optimistic
77
127
  // scope is authoritative and must survive this re-resolution. Fired once
78
128
  // per resolution (onSuccess), so reading `prev` is safe.
@@ -83,6 +133,14 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
83
133
  }
84
134
  return next;
85
135
  });
136
+ // Same rule for the direct set: what we wrote outranks what the probe read.
137
+ setDirectLabelIdsByGrantee((prev) => {
138
+ const next = {};
139
+ for (const id of committedGranteeIds) {
140
+ next[id] = prev[id] ?? direct[id];
141
+ }
142
+ return next;
143
+ });
86
144
  },
87
145
  },
88
146
  // Keyed on the label set's stable string hash, not the array (rebuilt every
@@ -112,6 +170,30 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
112
170
  }
113
171
  return permissionable;
114
172
  }, [labelLists]);
173
+ // Inheritance is the one fact no write from here can change, so it stays a pure
174
+ // derivation of the probe — there is no optimistic version of "someone else granted
175
+ // this", and nothing we do can make it stale.
176
+ const inheritedLabelIdsByGrantee = useMemo(() => (labelLists ? resolveLabelProvenance(labelLists, committedGranteeIds).inherited : {}), [labelLists, committedGranteeIds]);
177
+ const recordDirectLabelWrites = useCallback((granteeId, granted, revoked) => {
178
+ if (granted.length === 0 && revoked.length === 0) {
179
+ return;
180
+ }
181
+ setDirectLabelIdsByGrantee((prev) => {
182
+ const dropped = new Set(revoked);
183
+ const kept = (prev[granteeId] ?? []).filter((id) => !dropped.has(id));
184
+ return { ...prev, [granteeId]: Array.from(new Set([...kept, ...granted])) };
185
+ });
186
+ }, []);
187
+ const forgetGranteeLabels = useCallback((granteeId) => {
188
+ setSelectedLabelIdsByGrantee((prev) => {
189
+ const { [granteeId]: _scope, ...rest } = prev;
190
+ return rest;
191
+ });
192
+ setDirectLabelIdsByGrantee((prev) => {
193
+ const { [granteeId]: _direct, ...rest } = prev;
194
+ return rest;
195
+ });
196
+ }, []);
115
197
  // Only permissionable labels are scope-controllable; assume all until resolved.
116
198
  const effectiveLabels = useMemo(() => hasList && permissionableLabelIds
117
199
  ? labels.filter((l) => permissionableLabelIds.has(l.id))
@@ -137,8 +219,9 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
137
219
  // drift. Writes settle independently (allSettled), and the failed labels are
138
220
  // reported by id — never collapsed into one boolean, or a partial failure would
139
221
  // roll callers back past writes that actually landed.
140
- const reconcileLabelScope = useCallback(async (principals, desiredLabelIds, currentLabelIds) => {
141
- const writes = buildLabelMutationsForPrincipals(principals, desiredLabelIds, currentLabelIds, effectiveLabels);
222
+ // Issues one manageObjectPermissions per label and reports the failures by id.
223
+ // Shared by the scope diff and the level re-grade so both settle identically.
224
+ const writeLabels = useCallback(async (writes) => {
142
225
  if (writes.length === 0) {
143
226
  return { ok: true, failedLabelIds: [] };
144
227
  }
@@ -148,13 +231,22 @@ export function useLabelScope(target, labels, hasList, committedGranteeIds, labe
148
231
  .filter((_, i) => results[i].status === "rejected")
149
232
  .map((w) => w.id);
150
233
  return { ok: failedLabelIds.length === 0, failedLabelIds };
151
- }, [effectiveLabels, backend, workspace]);
234
+ }, [backend, workspace]);
235
+ const reconcileLabelScopes = useCallback((changes) => writeLabels(buildLabelMutationsForScopes(changes, effectiveLabels)), [effectiveLabels, writeLabels]);
236
+ const reconcileLabelScope = useCallback((principals, desiredLabelIds, currentLabelIds) => reconcileLabelScopes(principals.map((principal) => ({ principal, desiredLabelIds, currentLabelIds }))), [reconcileLabelScopes]);
237
+ const regradeLabelScope = useCallback((principals, scopeLabelIds) => writeLabels(buildLabelRegrades(principals, scopeLabelIds, effectiveLabels)), [effectiveLabels, writeLabels]);
152
238
  return {
153
239
  effectiveLabels,
154
240
  labelsResolved,
155
241
  labelsInitializing,
156
242
  selectedLabelIdsByGrantee,
157
243
  setSelectedLabelIdsByGrantee,
244
+ inheritedLabelIdsByGrantee,
245
+ directLabelIdsByGrantee,
246
+ recordDirectLabelWrites,
247
+ forgetGranteeLabels,
158
248
  reconcileLabelScope,
249
+ reconcileLabelScopes,
250
+ regradeLabelScope,
159
251
  };
160
252
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useObjectShareController.d.ts","sourceRoot":"","sources":["../../src/share/useObjectShareController.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAiB1E,OAAO,EACH,KAAK,sBAAsB,EAI3B,KAAK,sBAAsB,EAE9B,MAAM,kCAAkC,CAAC;AAI1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,wBAAwB,GAAG,SAAS,EAC5C,OAAO,CAAC,EAAE,sBAAsB,GACjC,sBAAsB,CA+kBxB"}
1
+ {"version":3,"file":"useObjectShareController.d.ts","sourceRoot":"","sources":["../../src/share/useObjectShareController.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAkB1E,OAAO,EACH,KAAK,sBAAsB,EAI3B,KAAK,sBAAsB,EAE9B,MAAM,kCAAkC,CAAC;AAI1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,wBAAwB,GAAG,SAAS,EAC5C,OAAO,CAAC,EAAE,sBAAsB,GACjC,sBAAsB,CAkxBxB"}
@@ -3,7 +3,7 @@ import { useCallback, useMemo, useState } from "react";
3
3
  import { useToastMessage } from "@gooddata/sdk-ui-kit";
4
4
  import { composeEffectiveWorkspaceAccess } from "./accessSummary.js";
5
5
  import { objectShareMessages } from "./messages.js";
6
- import { EMPTY_IDS, NO_LABELS, granularGranteeFor, levelsAbove, levelsBelow, sortGrantees, toGranularGrantee, userDisplayPair, } from "./objectShareController.helpers.js";
6
+ import { EMPTY_IDS, NO_LABELS, changesEffectiveLevel, granularGranteeFor, levelsAbove, levelsBelow, sortGrantees, toGranularGrantee, userDisplayPair, } from "./objectShareController.helpers.js";
7
7
  import { useAccessList } from "./useAccessList.js";
8
8
  import { useLabelScope } from "./useLabelScope.js";
9
9
  /**
@@ -35,7 +35,7 @@ export function useObjectShareController(target, options) {
35
35
  const [subview, setSubview] = useState("main");
36
36
  const [pendingGrantees, setPendingGrantees] = useState([]);
37
37
  const [pendingGeneralAccess, setPendingGeneralAccess] = useState(undefined);
38
- const { hasList, grantees, seededWithoutSelfGrant, selfIdentity, selfIdentityResolved, generalAccess, workspaceLevel, workspaceInheritedLevel, workspaceLevelSaving, summary, status, loadError, commit, loadOptions, applyGranteeAdd, applyGranteeLevel, applyGranteeRemove, settleGranteeEdit, failGranteeEdit, applyRuleEdit, settleRuleEdit, failRuleEdit, } = useAccessList(target);
38
+ const { hasList, grantees, seededWithoutSelfGrant, selfIdentity, selfIdentityResolved, generalAccess, workspaceLevel, workspaceInheritedLevel, workspaceLevelSaving, summary, status, loadError, commit, loadOptions, applyGranteeAdd, applyGranteeLevel, applyGranteeLock, applyGranteeRemove, settleGranteeEdit, failGranteeEdit, applyRuleEdit, settleRuleEdit, failRuleEdit, } = useAccessList(target);
39
39
  // Grantee ids the label-scope probe resolves against — a removing row is excluded
40
40
  // so its scope is dropped, not re-seeded.
41
41
  const committedGranteeIds = useMemo(() => {
@@ -48,7 +48,16 @@ export function useObjectShareController(target, options) {
48
48
  return ids;
49
49
  }, [grantees]);
50
50
  // Per-label scope resolution + the single label-write path live in their own hook.
51
- const { effectiveLabels, labelsResolved, labelsInitializing, selectedLabelIdsByGrantee, setSelectedLabelIdsByGrantee, reconcileLabelScope, } = useLabelScope(target, labels, hasList, committedGranteeIds, labelsError, labelsLoading);
51
+ const { effectiveLabels, labelsResolved, labelsInitializing, selectedLabelIdsByGrantee, setSelectedLabelIdsByGrantee, inheritedLabelIdsByGrantee, directLabelIdsByGrantee, recordDirectLabelWrites, forgetGranteeLabels, reconcileLabelScope, reconcileLabelScopes, regradeLabelScope, } = useLabelScope(target, labels, hasList, committedGranteeIds, labelsError, labelsLoading);
52
+ // The labels THIS workspace granted — the only ones a write may touch. Read straight
53
+ // from the tracked direct set rather than subtracting "inherited" from the scope: the
54
+ // subtraction relied on the probe still describing our own grants, and after a revoke it
55
+ // did not, so a later re-grade re-created access that had just been removed. A label
56
+ // held by inheritance ALONE is absent here, so no write can reach it: revoking one is a
57
+ // no-op whose compensation could mint a real grant, and re-grading one would invent one.
58
+ // A dual-granted label IS here — its local grant is ours to revoke and re-grade, or it
59
+ // would outlive the inherited grant hiding it.
60
+ const directLabelScopeOf = useCallback((granteeId) => new Set(directLabelIdsByGrantee[granteeId] ?? effectiveLabels.map((l) => l.id)), [directLabelIdsByGrantee, effectiveLabels]);
52
61
  // Effective access: the direct state composed with inherited rule access.
53
62
  // Also pins the level to VIEW while restricted, so the (hidden) dropdown
54
63
  // never shows a stale SHARE left over from a prior grant.
@@ -74,12 +83,12 @@ export function useObjectShareController(target, options) {
74
83
  // overlay, the revert and any toast beyond `commit`'s own.
75
84
  const applyAccessChange = useCallback(async (params) => {
76
85
  const { principal, objectMutation, successMessage, labelDesired, labelCurrent } = params;
77
- const { ok: labelsOk } = await reconcileLabelScope([principal], labelDesired, labelCurrent);
86
+ const { ok: labelsOk, failedLabelIds } = await reconcileLabelScope([principal], labelDesired, labelCurrent);
78
87
  if (!labelsOk && params.abortIfLabelsFail) {
79
88
  // Don't write the object on a half-applied label scope: undo whatever
80
89
  // mirrored and surface the failure to the caller.
81
90
  await reconcileLabelScope([principal], labelCurrent, labelDesired);
82
- return { ok: false, labelsOk: false };
91
+ return { ok: false, labelsOk: false, failedLabelIds };
83
92
  }
84
93
  const ok = await commit([objectMutation], successMessage);
85
94
  if (!ok) {
@@ -87,7 +96,10 @@ export function useObjectShareController(target, options) {
87
96
  // don't drift.
88
97
  await reconcileLabelScope([principal], labelCurrent, labelDesired);
89
98
  }
90
- return { ok, labelsOk };
99
+ // The failed ids are reported, not just counted: a caller that keeps the row
100
+ // must keep those labels in its scope, or the local state would claim access
101
+ // the backend still grants and a later edit would diff against a lie.
102
+ return { ok, labelsOk, failedLabelIds };
91
103
  }, [commit, reconcileLabelScope]);
92
104
  // ── Grantee mutations (add / level / remove / labels) ────────────────────────
93
105
  const confirmAddGrantees = useCallback(async () => {
@@ -105,18 +117,30 @@ export function useObjectShareController(target, options) {
105
117
  name: g.name,
106
118
  email: g.email,
107
119
  level: g.permissionLevel,
120
+ // The add writes a grant in THIS workspace, so the new row holds a
121
+ // direct grant at the picked level — without it the row would read as
122
+ // inherited-only and its Remove would be (correctly) refused.
123
+ directLevel: g.permissionLevel,
108
124
  }));
109
125
  const mutations = pendingGrantees.map((g) => toGranularGrantee(g.kind, g.ref, g.permissionLevel));
110
- // Default each new grantee to ALL labels (the picker's Add is gated until
111
- // labels have loaded, so the set is known here). Reflect the full scope
112
- // before the writes so the row shows it immediately.
126
+ // Each grantee is granted the label scope picked in the add dialog; an
127
+ // untouched picker leaves it undefined, which means ALL labels (the picker's
128
+ // Add is gated until labels have loaded, so the set is known here). The
129
+ // primary label is always in scope, exactly as `changeGranteeLabels` keeps it.
130
+ // Reflect each scope before the writes so the rows show them immediately.
113
131
  const allLabelIds = effectiveLabels.map((l) => l.id);
114
- const allLabelIdSet = new Set(allLabelIds);
132
+ const primaryLabelIds = effectiveLabels.filter((l) => l.isPrimary).map((l) => l.id);
133
+ const scopeById = new Map(pendingGrantees.map((g) => [
134
+ g.id,
135
+ g.labelIds === undefined
136
+ ? allLabelIds
137
+ : Array.from(new Set([...g.labelIds, ...primaryLabelIds])),
138
+ ]));
115
139
  addedRows.forEach(applyGranteeAdd);
116
140
  setSelectedLabelIdsByGrantee((prev) => {
117
141
  const next = { ...prev };
118
142
  for (const id of addedIds) {
119
- next[id] = allLabelIds;
143
+ next[id] = scopeById.get(id);
120
144
  }
121
145
  return next;
122
146
  });
@@ -134,19 +158,30 @@ export function useObjectShareController(target, options) {
134
158
  });
135
159
  return;
136
160
  }
137
- // One label write per label carrying all added grantees, not one per grantee.
138
- const principals = pendingGrantees.map((g) => ({ kind: g.kind, granteeRef: g.ref }));
139
- const { ok: labelsOk, failedLabelIds } = await reconcileLabelScope(principals, allLabelIdSet, EMPTY_IDS);
161
+ // One label write per label carrying all added grantees, not one per grantee
162
+ // even when their scopes differ, so a shared label stays a single call. Each
163
+ // label grant carries that grantee's picked level, so the label mirrors the
164
+ // object grant instead of landing on VIEW.
165
+ const { ok: labelsOk, failedLabelIds } = await reconcileLabelScopes(pendingGrantees.map((g) => ({
166
+ principal: { kind: g.kind, granteeRef: g.ref, level: g.permissionLevel },
167
+ desiredLabelIds: new Set(scopeById.get(g.id)),
168
+ currentLabelIds: EMPTY_IDS,
169
+ })));
170
+ const failed = new Set(failedLabelIds);
171
+ // Every label grant that landed is now a grant of OURS — record it, or a later
172
+ // removal would not know to revoke it.
173
+ for (const id of addedIds) {
174
+ recordDirectLabelWrites(id, scopeById.get(id).filter((labelId) => !failed.has(labelId)), []);
175
+ }
140
176
  if (!labelsOk) {
141
177
  toast.addWarning(objectShareMessages.toastLabelScopePartial);
142
- // Drop only the failed labels, keeping those that landed otherwise local
143
- // scope under-reports and changeGranteeLabels later skips their revokes.
144
- const failed = new Set(failedLabelIds);
145
- const survived = allLabelIds.filter((id) => !failed.has(id));
178
+ // Drop only the failed labels from each grantee's own scope, keeping those
179
+ // that landed — otherwise local scope under-reports and changeGranteeLabels
180
+ // later skips their revokes.
146
181
  setSelectedLabelIdsByGrantee((prev) => {
147
182
  const next = { ...prev };
148
183
  for (const id of addedIds) {
149
- next[id] = survived;
184
+ next[id] = scopeById.get(id).filter((labelId) => !failed.has(labelId));
150
185
  }
151
186
  return next;
152
187
  });
@@ -161,7 +196,8 @@ export function useObjectShareController(target, options) {
161
196
  commit,
162
197
  closeAddGrantee,
163
198
  effectiveLabels,
164
- reconcileLabelScope,
199
+ reconcileLabelScopes,
200
+ recordDirectLabelWrites,
165
201
  toast,
166
202
  applyGranteeAdd,
167
203
  settleGranteeEdit,
@@ -170,23 +206,83 @@ export function useObjectShareController(target, options) {
170
206
  ]);
171
207
  const changePermissionLevel = useCallback(async (granteeId, level) => {
172
208
  const grantee = grantees.find((g) => g.id === granteeId);
173
- if (!grantee || grantee.level === level || grantee.pending) {
209
+ // A pick that cannot move the effective level is refused rather than quietly
210
+ // strengthening the grant made here — the rule lives in `changesEffectiveLevel`
211
+ // so every reaction to a pick agrees, and no confirm is staged for a no-op.
212
+ // Also refused before the label scope resolves: the re-grade below would run
213
+ // over the assumed-all fallback and mint grants the grantee never held. The
214
+ // UI gates on the same fact (isMutable); the controller stays authoritative.
215
+ if (!grantee || grantee.pending || !labelsResolved || !changesEffectiveLevel(grantee, level)) {
174
216
  return;
175
217
  }
176
218
  applyGranteeLevel(granteeId, level);
219
+ // A label grant is an independent access-list entry carrying its own
220
+ // level, so re-grading the object alone would leave the grantee's labels
221
+ // at the level they were granted at.
222
+ //
223
+ // Order so a label grant is never left above the object grant: lower the
224
+ // labels BEFORE lowering the object, and raise the object BEFORE raising
225
+ // the labels. Either way a failure leaves labels no broader than the
226
+ // object, and a failed object write puts the labels back.
227
+ const previousLevel = grantee.directLevel ?? grantee.level;
228
+ const lowering = levelsBelow(previousLevel).includes(level);
229
+ const scope = directLabelScopeOf(granteeId);
230
+ const regradeLabels = (to) => regradeLabelScope([{ kind: grantee.kind, granteeRef: grantee.granteeRef, level: to }], scope);
231
+ let labelsOk = true;
232
+ if (lowering) {
233
+ labelsOk = (await regradeLabels(level)).ok;
234
+ if (!labelsOk) {
235
+ // A label that kept the old, HIGHER level while the object dropped
236
+ // would leave label access above object access — the one state this
237
+ // ordering exists to prevent. So abort: put every in-scope label back
238
+ // and leave the object alone. Same all-or-nothing policy the
239
+ // general-access change applies to its label mirror.
240
+ await regradeLabels(previousLevel);
241
+ failGranteeEdit(granteeId);
242
+ toast.addError(objectShareMessages.toastError);
243
+ return;
244
+ }
245
+ }
177
246
  const ok = await commit([toGranularGrantee(grantee.kind, grantee.granteeRef, level)], objectShareMessages.toastAccessUpdated);
178
247
  // The settled entry persists on success (base still holds the old level);
179
248
  // failure restores the last committed entry, or the fetched row.
180
- if (ok) {
181
- settleGranteeEdit(granteeId);
182
- }
183
- else {
249
+ if (!ok) {
250
+ if (lowering) {
251
+ await regradeLabels(previousLevel);
252
+ }
184
253
  failGranteeEdit(granteeId);
254
+ return;
255
+ }
256
+ if (!lowering) {
257
+ labelsOk = (await regradeLabels(level)).ok;
258
+ }
259
+ settleGranteeEdit(granteeId);
260
+ if (!labelsOk) {
261
+ // The object level changed but some labels kept the old one — warn so
262
+ // the partial state isn't mistaken for success.
263
+ toast.addWarning(objectShareMessages.toastLabelScopePartial);
185
264
  }
186
- }, [grantees, commit, applyGranteeLevel, settleGranteeEdit, failGranteeEdit]);
265
+ }, [
266
+ grantees,
267
+ labelsResolved,
268
+ commit,
269
+ directLabelScopeOf,
270
+ regradeLabelScope,
271
+ toast,
272
+ applyGranteeLevel,
273
+ settleGranteeEdit,
274
+ failGranteeEdit,
275
+ ]);
187
276
  const removeGrantee = useCallback(async (granteeId) => {
188
277
  const grantee = grantees.find((g) => g.id === granteeId);
189
- if (!grantee || grantee.pending) {
278
+ // Only a grant made in THIS workspace can be revoked here. With access
279
+ // inherited-only (a group, or a parent workspace) there is nothing local
280
+ // to revoke: the write would be an empty-permissions no-op that the row
281
+ // then reported as removed. The menu also disables Remove in that case;
282
+ // this keeps the controller — not the UI — authoritative. Same for an
283
+ // unresolved label scope: the revoke below would run over the assumed-all
284
+ // fallback and revoke (then compensate with) grants that never existed.
285
+ if (!grantee || grantee.pending || !labelsResolved || grantee.directLevel === undefined) {
190
286
  return;
191
287
  }
192
288
  // Mark the row removed but keep it visible (muted) until the write lands.
@@ -198,12 +294,20 @@ export function useObjectShareController(target, options) {
198
294
  // the grantee didn't hold. The object revoke is what matters; a label
199
295
  // revoke that fails is non-fatal (surfaced as a warning), so don't abort
200
296
  // on it.
201
- const { ok, labelsOk } = await applyAccessChange({
202
- principal: { kind: grantee.kind, granteeRef: grantee.granteeRef },
297
+ const { ok, labelsOk, failedLabelIds } = await applyAccessChange({
298
+ // The level matters only for the compensating re-grant if the object
299
+ // revoke fails: without it the labels would come back at the default
300
+ // VIEW, quietly downgrading an EDIT/SHARE grantee we just failed to
301
+ // remove.
302
+ principal: {
303
+ kind: grantee.kind,
304
+ granteeRef: grantee.granteeRef,
305
+ level: grantee.directLevel,
306
+ },
203
307
  objectMutation: toGranularGrantee(grantee.kind, grantee.granteeRef, "none"),
204
308
  successMessage: objectShareMessages.toastAccessUpdated,
205
309
  labelDesired: EMPTY_IDS,
206
- labelCurrent: new Set(selectedLabelIdsByGrantee[granteeId] ?? effectiveLabels.map((l) => l.id)),
310
+ labelCurrent: directLabelScopeOf(granteeId),
207
311
  abortIfLabelsFail: false,
208
312
  });
209
313
  if (!ok) {
@@ -215,10 +319,37 @@ export function useObjectShareController(target, options) {
215
319
  // Object revoke landed. For a fetched row the settled `removed` entry
216
320
  // persists to keep it hidden; a revoked overlay-born row drops entirely.
217
321
  settleGranteeEdit(granteeId);
218
- setSelectedLabelIdsByGrantee((prev) => {
219
- const { [granteeId]: _omit, ...rest } = prev;
220
- return rest;
221
- });
322
+ // Every local label grant is gone except the ones whose revoke failed — record
323
+ // that, so a later write on a surviving row cannot act on grants we removed.
324
+ const revokedIds = [...directLabelScopeOf(granteeId)].filter((id) => !failedLabelIds.includes(id));
325
+ recordDirectLabelWrites(granteeId, [], revokedIds);
326
+ if (grantee.inheritedLevel === undefined) {
327
+ // Row is gone for good; drop its bookkeeping — unless a label revoke
328
+ // failed. The direct set is then the ONLY record that the label is still
329
+ // granted (the probe never re-runs), and forgetting it would let the
330
+ // grant outlive a same-session re-add: reseeded from the new writes
331
+ // alone, no later diff would ever revoke it.
332
+ if (failedLabelIds.length === 0) {
333
+ forgetGranteeLabels(granteeId);
334
+ }
335
+ }
336
+ else {
337
+ // A grantee who also inherits survives as an inherited-only row, so its
338
+ // scope must survive too — narrowed to what the removal could not take away.
339
+ // Dropping the entry would fall back to "all labels" (the probe does not
340
+ // re-run for grantee changes) and overstate what they can reach. Any label
341
+ // whose revoke FAILED stays in: the backend still grants it.
342
+ setSelectedLabelIdsByGrantee((prev) => {
343
+ const keep = new Set([
344
+ ...(inheritedLabelIdsByGrantee[granteeId] ?? []),
345
+ ...failedLabelIds,
346
+ ]);
347
+ const survivingIds = effectiveLabels
348
+ .filter((l) => l.isPrimary || keep.has(l.id))
349
+ .map((l) => l.id);
350
+ return { ...prev, [granteeId]: survivingIds };
351
+ });
352
+ }
222
353
  if (!labelsOk) {
223
354
  // Object access is gone but some per-label grants couldn't be
224
355
  // revoked — warn so the leftover scope isn't mistaken for success.
@@ -226,9 +357,13 @@ export function useObjectShareController(target, options) {
226
357
  }
227
358
  }, [
228
359
  grantees,
360
+ labelsResolved,
229
361
  applyAccessChange,
362
+ directLabelScopeOf,
363
+ recordDirectLabelWrites,
364
+ forgetGranteeLabels,
230
365
  effectiveLabels,
231
- selectedLabelIdsByGrantee,
366
+ inheritedLabelIdsByGrantee,
232
367
  toast,
233
368
  applyGranteeRemove,
234
369
  settleGranteeEdit,
@@ -237,27 +372,54 @@ export function useObjectShareController(target, options) {
237
372
  ]);
238
373
  const changeGranteeLabels = useCallback(async (granteeId, requested) => {
239
374
  const grantee = grantees.find((g) => g.id === granteeId);
240
- if (!grantee || grantee.pending || !target) {
375
+ // Refused before the label scope resolves — the diff below would otherwise
376
+ // run against the assumed-all fallback (the UI gates on the same fact via
377
+ // `isMutable`; the controller stays authoritative).
378
+ if (!grantee || grantee.pending || !labelsResolved || !target) {
241
379
  return;
242
380
  }
243
- // Primary label is always in scope; never let it be dropped.
381
+ // The primary label is always in scope, and so is a label the grantee only
382
+ // inherits: there is no local grant to revoke, so dropping it would report
383
+ // access removed that this workspace cannot reach. The checklist locks both;
384
+ // this keeps the controller — not the UI — authoritative.
244
385
  const primaryIds = effectiveLabels.filter((l) => l.isPrimary).map((l) => l.id);
245
- const nextScope = Array.from(new Set([...requested, ...primaryIds]));
386
+ const inheritedIds = inheritedLabelIdsByGrantee[granteeId] ?? [];
387
+ const nextScope = Array.from(new Set([...requested, ...primaryIds, ...inheritedIds]));
246
388
  const currentScope = selectedLabelIdsByGrantee[granteeId] ?? effectiveLabels.map((l) => l.id);
247
389
  const desired = new Set(nextScope);
248
- const current = new Set(currentScope);
390
+ // Inherited labels join the CURRENT side too: an add-path scope is seeded
391
+ // before inheritance is known for the new row, so without this an untouched
392
+ // Apply would diff an inherited label as newly checked and grant it locally.
393
+ const current = new Set([...currentScope, ...inheritedIds]);
249
394
  // Applying the checklist unchanged is a no-op — don't lock the row or
250
395
  // toast success over zero writes.
251
396
  if (desired.size === current.size && nextScope.every((id) => current.has(id))) {
252
397
  return;
253
398
  }
254
399
  // Reflect the new scope immediately and lock the row until the writes
255
- // settle — an overlapping label edit or removal would race these writes
256
- // on the same labels. The lock reuses the level overlay at the unchanged
257
- // level; pending is the only fact it adds.
258
- applyGranteeLevel(granteeId, grantee.level);
400
+ // settle — an overlapping label edit or removal would race these writes on
401
+ // the same labels. A lock-only overlay, because this changes no object
402
+ // access: re-applying the displayed level would persist the EFFECTIVE level
403
+ // as this row's direct grant, so an inherited EDIT over a direct VIEW would
404
+ // become a local EDIT after any label edit.
405
+ applyGranteeLock(granteeId);
259
406
  setSelectedLabelIdsByGrantee((prev) => ({ ...prev, [granteeId]: nextScope }));
260
- const { ok, failedLabelIds } = await reconcileLabelScope([{ kind: grantee.kind, granteeRef: grantee.granteeRef }], desired, current);
407
+ // Labels newly brought into scope are granted at the level the grantee
408
+ // holds on the object — with no grant of their own here (inherited-only
409
+ // access) there is no level to mirror, so VIEW stands.
410
+ const { ok, failedLabelIds } = await reconcileLabelScope([
411
+ {
412
+ kind: grantee.kind,
413
+ granteeRef: grantee.granteeRef,
414
+ level: grantee.directLevel ?? "VIEW",
415
+ },
416
+ ], desired, current);
417
+ // Record what the writes actually did to OUR grants: a label brought into scope
418
+ // gains one, a label dropped loses one. Only over the labels this workspace could
419
+ // write — an inherited-only label is absent from the diff either way.
420
+ const failedIds = new Set(failedLabelIds);
421
+ const writable = directLabelScopeOf(granteeId);
422
+ recordDirectLabelWrites(granteeId, nextScope.filter((id) => !current.has(id) && !failedIds.has(id)), currentScope.filter((id) => writable.has(id) && !desired.has(id) && !failedIds.has(id)));
261
423
  if (ok) {
262
424
  settleGranteeEdit(granteeId);
263
425
  toast.addSuccess(objectShareMessages.toastAccessUpdated);
@@ -281,11 +443,15 @@ export function useObjectShareController(target, options) {
281
443
  }, [
282
444
  grantees,
283
445
  target,
446
+ labelsResolved,
284
447
  effectiveLabels,
285
448
  selectedLabelIdsByGrantee,
449
+ inheritedLabelIdsByGrantee,
450
+ directLabelScopeOf,
451
+ recordDirectLabelWrites,
286
452
  reconcileLabelScope,
287
453
  toast,
288
- applyGranteeLevel,
454
+ applyGranteeLock,
289
455
  settleGranteeEdit,
290
456
  failGranteeEdit,
291
457
  setSelectedLabelIdsByGrantee,
@@ -479,6 +645,7 @@ export function useObjectShareController(target, options) {
479
645
  labelsResolved,
480
646
  labelsInitializing,
481
647
  selectedLabelIdsByGrantee,
648
+ inheritedLabelIdsByGrantee,
482
649
  pendingGeneralAccess,
483
650
  pendingGrantees,
484
651
  };
@@ -500,6 +667,7 @@ export function useObjectShareController(target, options) {
500
667
  labelsResolved,
501
668
  labelsInitializing,
502
669
  selectedLabelIdsByGrantee,
670
+ inheritedLabelIdsByGrantee,
503
671
  pendingGeneralAccess,
504
672
  pendingGrantees,
505
673
  ]);
@@ -44,6 +44,13 @@ export interface IObjectShareDialogViewModel {
44
44
  * for the signed-in user's own sole grant, undefined for every other row.
45
45
  */
46
46
  rowDisabledLevels: (grantee: IObjectShareGrantee) => ObjectSharePermissionLevel[] | undefined;
47
+ /**
48
+ * Whether Remove access must render disabled: the grantee holds no grant in this
49
+ * workspace, so there is nothing here to revoke (their access is inherited).
50
+ */
51
+ isRowRemoveDisabled: (grantee: IObjectShareGrantee) => boolean;
52
+ /** Tooltip explaining why Remove access is disabled on this row. */
53
+ rowRemoveDisabledTooltip: string;
47
54
  /** Close the whole dialog, discarding any staged self-restriction. */
48
55
  onClose: () => void;
49
56
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"useObjectShareDialog.d.ts","sourceRoot":"","sources":["../../src/share/useObjectShareDialog.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EACH,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAClC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAY1E;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IACxC,yFAAyF;IACzF,KAAK,EAAE,2BAA2B,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,6BAA6B,CAAC;IAEvC,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;IACzB,qDAAqD;IACrD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA0E;IAC1E,0BAA0B,EAAE,OAAO,CAAC;IACpC,+EAA+E;IAC/E,yBAAyB,EAAE,OAAO,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB,kGAAkG;IAClG,uBAAuB,EAAE,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAClE;;;OAGG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAE9F,sEAAsE;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,qBAAqB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IACjG,qGAAqG;IACrG,WAAW,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,+FAA6F;IAC7F,qBAAqB,EAAE,MAAM,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,UAAU,2BAA2B;IACjC,wFAAsF;IACtF,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,oGAAoG;IACpG,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D,2FAA2F;IAC3F,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,oGAAoG;IACpG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iGAAiG;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,MAAM,EACN,OAAO,EACP,eAAe,EACf,MAAM,EACN,aAAa,EACb,WAAW,EACd,EAAE,2BAA2B,GAAG,2BAA2B,CAwF3D"}
1
+ {"version":3,"file":"useObjectShareDialog.d.ts","sourceRoot":"","sources":["../../src/share/useObjectShareDialog.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAI1E,OAAO,EACH,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAClC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAY1E;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IACxC,yFAAyF;IACzF,KAAK,EAAE,2BAA2B,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,6BAA6B,CAAC;IAEvC,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;IACzB,qDAAqD;IACrD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA0E;IAC1E,0BAA0B,EAAE,OAAO,CAAC;IACpC,+EAA+E;IAC/E,yBAAyB,EAAE,OAAO,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB,kGAAkG;IAClG,uBAAuB,EAAE,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAClE;;;OAGG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAC9F;;;OAGG;IACH,mBAAmB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC;IAC/D,oEAAoE;IACpE,wBAAwB,EAAE,MAAM,CAAC;IAEjC,sEAAsE;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,qBAAqB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IACjG,qGAAqG;IACrG,WAAW,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,+FAA6F;IAC7F,qBAAqB,EAAE,MAAM,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,UAAU,2BAA2B;IACjC,wFAAsF;IACtF,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,oGAAoG;IACpG,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D,2FAA2F;IAC3F,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,oGAAoG;IACpG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iGAAiG;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,MAAM,EACN,OAAO,EACP,eAAe,EACf,MAAM,EACN,aAAa,EACb,WAAW,EACd,EAAE,2BAA2B,GAAG,2BAA2B,CA6G3D"}