@gooddata/sdk-ui-ext 11.49.0-alpha.1 → 11.49.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 (94) hide show
  1. package/esm/index.d.ts +1 -1
  2. package/esm/index.d.ts.map +1 -1
  3. package/esm/internal/translations/de-DE.localization-bundle.d.ts +1 -0
  4. package/esm/internal/translations/de-DE.localization-bundle.d.ts.map +1 -1
  5. package/esm/internal/translations/de-DE.localization-bundle.js +1 -0
  6. package/esm/internal/translations/en-AU.localization-bundle.d.ts +1 -0
  7. package/esm/internal/translations/en-AU.localization-bundle.d.ts.map +1 -1
  8. package/esm/internal/translations/en-AU.localization-bundle.js +1 -0
  9. package/esm/internal/translations/en-GB.localization-bundle.d.ts +1 -0
  10. package/esm/internal/translations/en-GB.localization-bundle.d.ts.map +1 -1
  11. package/esm/internal/translations/en-GB.localization-bundle.js +1 -0
  12. package/esm/internal/translations/en-US.localization-bundle.d.ts +5 -9
  13. package/esm/internal/translations/en-US.localization-bundle.d.ts.map +1 -1
  14. package/esm/internal/translations/en-US.localization-bundle.js +15 -19
  15. package/esm/internal/translations/es-419.localization-bundle.d.ts +1 -0
  16. package/esm/internal/translations/es-419.localization-bundle.d.ts.map +1 -1
  17. package/esm/internal/translations/es-419.localization-bundle.js +1 -0
  18. package/esm/internal/translations/es-ES.localization-bundle.d.ts +1 -0
  19. package/esm/internal/translations/es-ES.localization-bundle.d.ts.map +1 -1
  20. package/esm/internal/translations/es-ES.localization-bundle.js +1 -0
  21. package/esm/internal/translations/fi-FI.localization-bundle.d.ts +1 -0
  22. package/esm/internal/translations/fi-FI.localization-bundle.d.ts.map +1 -1
  23. package/esm/internal/translations/fi-FI.localization-bundle.js +1 -0
  24. package/esm/internal/translations/fr-CA.localization-bundle.d.ts +1 -0
  25. package/esm/internal/translations/fr-CA.localization-bundle.d.ts.map +1 -1
  26. package/esm/internal/translations/fr-CA.localization-bundle.js +1 -0
  27. package/esm/internal/translations/fr-FR.localization-bundle.d.ts +1 -0
  28. package/esm/internal/translations/fr-FR.localization-bundle.d.ts.map +1 -1
  29. package/esm/internal/translations/fr-FR.localization-bundle.js +1 -0
  30. package/esm/internal/translations/id-ID.localization-bundle.d.ts +1 -0
  31. package/esm/internal/translations/id-ID.localization-bundle.d.ts.map +1 -1
  32. package/esm/internal/translations/id-ID.localization-bundle.js +1 -0
  33. package/esm/internal/translations/it-IT.localization-bundle.d.ts +1 -0
  34. package/esm/internal/translations/it-IT.localization-bundle.d.ts.map +1 -1
  35. package/esm/internal/translations/it-IT.localization-bundle.js +1 -0
  36. package/esm/internal/translations/ja-JP.localization-bundle.d.ts +1 -0
  37. package/esm/internal/translations/ja-JP.localization-bundle.d.ts.map +1 -1
  38. package/esm/internal/translations/ja-JP.localization-bundle.js +1 -0
  39. package/esm/internal/translations/ko-KR.localization-bundle.d.ts +1 -0
  40. package/esm/internal/translations/ko-KR.localization-bundle.d.ts.map +1 -1
  41. package/esm/internal/translations/ko-KR.localization-bundle.js +1 -0
  42. package/esm/internal/translations/nl-NL.localization-bundle.d.ts +1 -0
  43. package/esm/internal/translations/nl-NL.localization-bundle.d.ts.map +1 -1
  44. package/esm/internal/translations/nl-NL.localization-bundle.js +1 -0
  45. package/esm/internal/translations/pl-PL.localization-bundle.d.ts +1 -0
  46. package/esm/internal/translations/pl-PL.localization-bundle.d.ts.map +1 -1
  47. package/esm/internal/translations/pl-PL.localization-bundle.js +1 -0
  48. package/esm/internal/translations/pt-BR.localization-bundle.d.ts +1 -0
  49. package/esm/internal/translations/pt-BR.localization-bundle.d.ts.map +1 -1
  50. package/esm/internal/translations/pt-BR.localization-bundle.js +1 -0
  51. package/esm/internal/translations/pt-PT.localization-bundle.d.ts +1 -0
  52. package/esm/internal/translations/pt-PT.localization-bundle.d.ts.map +1 -1
  53. package/esm/internal/translations/pt-PT.localization-bundle.js +1 -0
  54. package/esm/internal/translations/ru-RU.localization-bundle.d.ts +1 -0
  55. package/esm/internal/translations/ru-RU.localization-bundle.d.ts.map +1 -1
  56. package/esm/internal/translations/ru-RU.localization-bundle.js +1 -0
  57. package/esm/internal/translations/sl-SI.localization-bundle.d.ts +1 -0
  58. package/esm/internal/translations/sl-SI.localization-bundle.d.ts.map +1 -1
  59. package/esm/internal/translations/sl-SI.localization-bundle.js +1 -0
  60. package/esm/internal/translations/th-TH.localization-bundle.d.ts +1 -0
  61. package/esm/internal/translations/th-TH.localization-bundle.d.ts.map +1 -1
  62. package/esm/internal/translations/th-TH.localization-bundle.js +1 -0
  63. package/esm/internal/translations/tr-TR.localization-bundle.d.ts +1 -0
  64. package/esm/internal/translations/tr-TR.localization-bundle.d.ts.map +1 -1
  65. package/esm/internal/translations/tr-TR.localization-bundle.js +2 -1
  66. package/esm/internal/translations/uk-UA.localization-bundle.d.ts +1 -0
  67. package/esm/internal/translations/uk-UA.localization-bundle.d.ts.map +1 -1
  68. package/esm/internal/translations/uk-UA.localization-bundle.js +1 -0
  69. package/esm/internal/translations/vi-VN.localization-bundle.d.ts +1 -0
  70. package/esm/internal/translations/vi-VN.localization-bundle.d.ts.map +1 -1
  71. package/esm/internal/translations/vi-VN.localization-bundle.js +1 -0
  72. package/esm/internal/translations/zh-HK.localization-bundle.d.ts +1 -0
  73. package/esm/internal/translations/zh-HK.localization-bundle.d.ts.map +1 -1
  74. package/esm/internal/translations/zh-HK.localization-bundle.js +1 -0
  75. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts +1 -0
  76. package/esm/internal/translations/zh-Hans.localization-bundle.d.ts.map +1 -1
  77. package/esm/internal/translations/zh-Hans.localization-bundle.js +1 -0
  78. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts +1 -0
  79. package/esm/internal/translations/zh-Hant.localization-bundle.d.ts.map +1 -1
  80. package/esm/internal/translations/zh-Hant.localization-bundle.js +1 -0
  81. package/esm/sdk-ui-ext.d.ts +45 -53
  82. package/esm/share/ObjectShareDialog.d.ts.map +1 -1
  83. package/esm/share/ObjectShareDialog.js +118 -58
  84. package/esm/share/messages.d.ts +10 -8
  85. package/esm/share/messages.d.ts.map +1 -1
  86. package/esm/share/messages.js +10 -6
  87. package/esm/share/objectShareController.types.d.ts +45 -53
  88. package/esm/share/objectShareController.types.d.ts.map +1 -1
  89. package/esm/share/useAccessList.d.ts +20 -24
  90. package/esm/share/useAccessList.d.ts.map +1 -1
  91. package/esm/share/useAccessList.js +39 -30
  92. package/esm/share/useObjectShareController.d.ts.map +1 -1
  93. package/esm/share/useObjectShareController.js +10 -201
  94. package/package.json +21 -21
@@ -1,10 +1,10 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2026 GoodData Corporation
3
- import { useCallback } from "react";
3
+ import { useCallback, useState } from "react";
4
4
  import { useIntl } from "react-intl";
5
- import { UiAddGranteeDialog, UiConfirmDialog, UiGranteeRowControls, UiObjectShareDialog, UiRadioRow, UiTransferOwnershipDialog, } from "@gooddata/sdk-ui-kit";
5
+ import { UiAddGranteeDialog, UiConfirmDialog, UiGranteeRowControls, UiObjectShareDialog, UiTag, UiTooltip, } from "@gooddata/sdk-ui-kit";
6
6
  import { objectShareMessages } from "./messages.js";
7
- import { granteeDisplayPair } from "./objectShareController.helpers.js";
7
+ import { granteeDisplayPair, userDisplayPair } from "./objectShareController.helpers.js";
8
8
  import { useObjectShareController } from "./useObjectShareController.js";
9
9
  // The workspace row has no labels menu (see workspaceControls below), so its
10
10
  // required onLabelsChange never fires; a stable no-op satisfies the prop type
@@ -41,30 +41,28 @@ export function ObjectShareDialog({ target, objectTitle, isOpen, onClose, onSave
41
41
  isOpen,
42
42
  });
43
43
  const { state, actions } = controller ?? ownController;
44
+ // Staged self-restriction — the level (or removal) the signed-in user picked
45
+ // for their own sole grant, held until the "Restrict your access?" confirm.
46
+ const [pendingSelfChange, setPendingSelfChange] = useState(undefined);
47
+ // Drop the staged self-restriction whenever `isOpen` flips OR the target
48
+ // changes — the detail view navigates between objects by toggling `isOpen`
49
+ // alone (no onClose), but a consumer may also swap the target while open, and
50
+ // the self row's id is target-independent: a stale confirm could otherwise
51
+ // apply the restriction to the NEXT object. Render-time adjust, matching the
52
+ // controller's own reset-on-target idiom.
53
+ const [lastOpen, setLastOpen] = useState(isOpen);
54
+ const [lastTargetKey, setLastTargetKey] = useState(state.targetKey);
55
+ if (lastOpen !== isOpen || lastTargetKey !== state.targetKey) {
56
+ setLastOpen(isOpen);
57
+ setLastTargetKey(state.targetKey);
58
+ setPendingSelfChange(undefined);
59
+ }
44
60
  const handleClose = useCallback(() => {
61
+ setPendingSelfChange(undefined);
45
62
  actions.reset();
46
63
  onClose();
47
64
  }, [actions, onClose]);
48
- // Owner is always an individual user, so the transfer picker drops any groups
49
- // the shared loader returns. `includeGranted` keeps already-granted users in
50
- // the list — promoting an existing viewer to owner is a primary case.
51
- //
52
- // Depend on the stable `loadOptions` alone, not the whole `actions` object:
53
- // `actions` changes identity as transfer state ticks (and as the picker's own
54
- // name-cache writes re-derive grantees), and the autocomplete refetches page 0
55
- // whenever its loader's identity changes — depending on `actions` here would
56
- // self-feed into an infinite assignee-fetch loop.
57
- const { loadOptions } = actions;
58
- const loadOwnerOptions = useCallback(async (search) => {
59
- const { users } = await loadOptions(search, true);
60
- return { groups: [], users };
61
- }, [loadOptions]);
62
65
  const isAddGranteeOpen = isOpen && state.subview === "addGrantee";
63
- // The transfer subview splits into two co-mounted dialogs: the transfer card
64
- // while picking a non-owner, and the "already an owner" confirm once the picked
65
- // user already owns the object.
66
- const isTransferOpen = isOpen && state.subview === "transferOwnership" && !state.transferTargetIsOwner;
67
- const isAlreadyOwnerOpen = isOpen && state.subview === "transferOwnership" && state.transferTargetIsOwner;
68
66
  const isShareOpen = isOpen && state.subview === "main";
69
67
  const isConfirmOpen = isOpen && !!state.pendingGeneralAccess;
70
68
  // Don't allow mutations until the access list has loaded: before then the
@@ -76,14 +74,34 @@ export function ObjectShareDialog({ target, objectTitle, isOpen, onClose, onSave
76
74
  // wrong labels). `labelsResolved` is false while labels are still loading and
77
75
  // when their fetch failed, so a pending/failed label set blocks every
78
76
  // access-changing control here — Add, row controls and general access alike.
79
- // Also locked while a transfer-ownership write is committing: the transfer
80
- // dialog can be dismissed (Back/Cancel/close) mid-save, so without this the
81
- // user could return here and mutate other grantees concurrently with the
82
- // in-flight ownership write — racing the same object's permissions with no
83
- // refetch to reconcile. `transferSaving` clears when the transfer settles.
84
77
  const isLoaded = state.status === "success";
85
- const isMutable = isLoaded && state.labelsResolved && !state.transferSaving;
78
+ const isMutable = isLoaded && state.labelsResolved;
86
79
  const isAddDisabled = !isMutable;
80
+ // Single-viewer empty states (design: the "restrict own access" board):
81
+ // (a) the sole explicit grant is the signed-in user's own → their row hosts a
82
+ // merged menu managing their own access, with lowering gated by a confirm.
83
+ const soleSelfGrantee = state.grantees.length === 1 && !!state.grantees[0].isSelf;
84
+ // Until the profile resolves (or when it silently failed), a sole USER row
85
+ // can't be told apart from the caller's own grant — mutating it then would
86
+ // bypass the self-restriction confirm, so it stays disabled, not merely
87
+ // unmerged. Group rows are never the caller's own, and multi-row lists are
88
+ // unaffected: their rows aren't self-managed.
89
+ const soleRowIdentityPending = state.grantees.length === 1 && state.grantees[0].kind === "user" && !state.selfIdentityResolved;
90
+ // (b) the manage-gated list LOADED with no explicit grants at all → the caller
91
+ // can only have passed the backend's gate through administrator/manager
92
+ // rights, so render a synthesized self row with a static Admin tag. Keyed
93
+ // to the load-time fact (`seededWithoutGrants`), not the live list — a
94
+ // grant-holder who removes their own sole grant empties the list without
95
+ // having grant-independent access. A workspace-wide SHARE rule is the one
96
+ // other way through the gate — the viewer may then be any workspace
97
+ // member, so no badge (list stays empty).
98
+ const workspaceShareCapable = state.generalAccess === "WORKSPACE" && state.workspaceLevel === "SHARE";
99
+ const adminSelfIdentity = isLoaded && state.grantees.length === 0 && state.seededWithoutGrants && !workspaceShareCapable
100
+ ? state.selfIdentity
101
+ : undefined;
102
+ const adminDisplay = adminSelfIdentity
103
+ ? userDisplayPair(adminSelfIdentity, adminSelfIdentity.id)
104
+ : undefined;
87
105
  // Map the controller's labels to the picker's item shape; the primary label
88
106
  // is rendered locked (always selected, can't be unchecked).
89
107
  const labelItems = state.labels.map((l) => ({
@@ -92,28 +110,66 @@ export function ObjectShareDialog({ target, objectTitle, isOpen, onClose, onSave
92
110
  kind: l.isPrimary ? "primary" : undefined,
93
111
  locked: l.isPrimary,
94
112
  }));
95
- return (_jsxs(_Fragment, { children: [_jsx(UiObjectShareDialog, { isOpen: isShareOpen, objectTitle: objectTitle, onClose: handleClose, grantees: state.grantees.map((g) => ({
96
- id: g.id,
97
- kind: g.kind,
98
- ...granteeDisplayPair(g),
99
- isPending: g.pending !== undefined,
100
- controls: (_jsx(UiGranteeRowControls, { labels: labelItems, selectedLabelIds: state.selectedLabelIdsByGrantee[g.id] ?? state.labels.map((l) => l.id), permissionLevel: g.level, effectivePermission: g.effectivePermission,
101
- // Disable row controls while saving, and until per-label
102
- // scope resolves (labels still loading, failed, or the
103
- // probe in flight) — removing or re-scoping before then
104
- // would diff against the "assume all"/empty placeholder
105
- // and silently orphan real per-label grants.
106
- isDisabled: g.pending !== undefined || !state.labelsResolved || state.transferSaving, onLabelsChange: (selectedIds) => {
107
- void actions.changeGranteeLabels(g.id, selectedIds);
108
- }, onPermissionChange: (level) => {
109
- void actions.changePermissionLevel(g.id, level);
110
- }, onRemoveAccess: () => {
111
- void actions.removeGrantee(g.id);
112
- },
113
- // Owner-only — omitting the handler hides the menu item for
114
- // users who can't transfer (e.g. View&Share).
115
- onTransferOwnership: state.canTransferOwnership ? actions.openTransferOwnership : undefined })),
116
- })), onAddClick: actions.openAddGrantee, isAddDisabled: isAddDisabled, generalAccess: state.generalAccess, onGeneralAccessChange: actions.requestGeneralAccessChange,
113
+ return (_jsxs(_Fragment, { children: [_jsx(UiObjectShareDialog, { isOpen: isShareOpen, objectTitle: objectTitle, onClose: handleClose, grantees: adminDisplay
114
+ ? [
115
+ {
116
+ id: "self-admin",
117
+ kind: "user",
118
+ name: intl.formatMessage(objectShareMessages.granteeYou, {
119
+ name: adminDisplay.name,
120
+ }),
121
+ email: adminDisplay.email,
122
+ controls: (_jsx(UiTooltip, { triggerBy: ["hover", "focus"], content: intl.formatMessage(objectShareMessages.adminTagTooltip), anchor: _jsx("span", { tabIndex: 0, children: _jsx(UiTag, { label: intl.formatMessage(objectShareMessages.adminTagLabel), size: "small", variant: "solid" }) }) })),
123
+ },
124
+ ]
125
+ : state.grantees.map((g) => {
126
+ const display = granteeDisplayPair(g);
127
+ const isManagedSelf = soleSelfGrantee && !!g.isSelf;
128
+ return {
129
+ id: g.id,
130
+ kind: g.kind,
131
+ name: g.isSelf
132
+ ? intl.formatMessage(objectShareMessages.granteeYou, {
133
+ name: display.name,
134
+ })
135
+ : display.name,
136
+ email: display.email,
137
+ isPending: g.pending !== undefined,
138
+ controls: (_jsx(UiGranteeRowControls, { labels: labelItems, selectedLabelIds: state.selectedLabelIdsByGrantee[g.id] ??
139
+ state.labels.map((l) => l.id), permissionLevel: g.level, effectivePermission: g.effectivePermission, mergedControls: isManagedSelf,
140
+ // Above the user's own level there is no way back
141
+ // (you can't raise yourself) — offered levels above
142
+ // it render disabled with the shared warning.
143
+ disabledLevels: isManagedSelf && g.level === "VIEW" ? ["SHARE"] : undefined, disabledTooltip: isManagedSelf
144
+ ? intl.formatMessage(objectShareMessages.selfRestrictWarning)
145
+ : undefined,
146
+ // Disable row controls while saving, until per-label
147
+ // scope resolves (labels still loading, failed, or the
148
+ // probe in flight) — removing or re-scoping before then
149
+ // would diff against the "assume all"/empty placeholder
150
+ // and silently orphan real per-label grants — and while
151
+ // a sole row's self identity is still unknown.
152
+ isDisabled: g.pending !== undefined ||
153
+ !state.labelsResolved ||
154
+ soleRowIdentityPending, onLabelsChange: (selectedIds) => {
155
+ void actions.changeGranteeLabels(g.id, selectedIds);
156
+ }, onPermissionChange: (level) => {
157
+ if (isManagedSelf) {
158
+ if (level !== g.level) {
159
+ setPendingSelfChange({ granteeId: g.id, level });
160
+ }
161
+ return;
162
+ }
163
+ void actions.changePermissionLevel(g.id, level);
164
+ }, onRemoveAccess: () => {
165
+ if (isManagedSelf) {
166
+ setPendingSelfChange({ granteeId: g.id, level: "none" });
167
+ return;
168
+ }
169
+ void actions.removeGrantee(g.id);
170
+ } })),
171
+ };
172
+ }), onAddClick: actions.openAddGrantee, isAddDisabled: isAddDisabled, generalAccess: state.generalAccess, onGeneralAccessChange: actions.requestGeneralAccessChange,
117
173
  // Inherited workspace access can't be revoked here — the kit disables
118
174
  // the Restricted option and explains why.
119
175
  workspaceAccessInherited: state.workspaceAccessInherited,
@@ -145,20 +201,24 @@ export function ObjectShareDialog({ target, objectTitle, isOpen, onClose, onSave
145
201
  // read as "no one has access".
146
202
  error: state.status === "error" ? intl.formatMessage(objectShareMessages.loadError) : undefined }), _jsx(UiAddGranteeDialog, { isOpen: isAddGranteeOpen, objectTitle: objectTitle, loadOptions: actions.loadOptions, selectedGrantees: state.pendingGrantees, onSelectedGranteesChange: actions.setPendingGrantees, onBack: actions.closeAddGrantee, onClose: handleClose, onCancel: actions.closeAddGrantee, onShare: () => {
147
203
  void actions.confirmAddGrantees();
148
- } }), _jsx(UiTransferOwnershipDialog, { isOpen: isTransferOpen, objectTitle: objectTitle, loadOptions: loadOwnerOptions, selectedOwner: state.transferTarget, onSelectedOwnerChange: actions.setTransferTarget, alsoRemoveMyAccess: state.transferAlsoRemoveSelf, onAlsoRemoveMyAccessChange: actions.setTransferAlsoRemoveSelf, onBack: actions.closeTransferOwnership, onClose: handleClose, onCancel: actions.closeTransferOwnership, onTransfer: () => {
149
- void actions.confirmTransferOwnership();
150
- }, isSaving: state.transferSaving }), _jsx(UiConfirmDialog, { isOpen: isAlreadyOwnerOpen, title: intl.formatMessage(objectShareMessages.transferAlreadyOwnerTitle, {
151
- name: state.transferTarget?.name ?? "",
152
- }), description: _jsxs(_Fragment, { children: [
153
- _jsx("p", { children: intl.formatMessage(objectShareMessages.transferAlreadyOwnerDescription) }), _jsx(UiRadioRow, { name: "transfer-already-owner", checked: !state.transferAlsoRemoveSelf, onChange: () => actions.setTransferAlsoRemoveSelf(false), title: intl.formatMessage(objectShareMessages.transferAlreadyOwnerKeepAccess) }), _jsx(UiRadioRow, { name: "transfer-already-owner", checked: state.transferAlsoRemoveSelf, onChange: () => actions.setTransferAlsoRemoveSelf(true), title: intl.formatMessage(objectShareMessages.transferAlreadyOwnerRemoveAccess) })
154
- ] }), confirmLabel: intl.formatMessage(objectShareMessages.transferConfirmButton), confirmVariant: "primary", onCancel: actions.closeTransferOwnership, onClose: actions.closeTransferOwnership, onConfirm: () => {
155
- void actions.confirmTransferOwnership();
156
204
  } }), _jsx(UiConfirmDialog, { isOpen: isConfirmOpen, title: intl.formatMessage(state.pendingGeneralAccess === "RESTRICTED"
157
205
  ? objectShareMessages.confirmRestrictTitle
158
206
  : objectShareMessages.confirmGrantWorkspaceTitle), description: intl.formatMessage(state.pendingGeneralAccess === "RESTRICTED"
159
207
  ? objectShareMessages.confirmRestrictDescription
160
208
  : objectShareMessages.confirmGrantWorkspaceDescription, { title: objectTitle }), confirmLabel: intl.formatMessage(objectShareMessages.confirmButton), confirmVariant: "primary", onCancel: actions.cancelGeneralAccessChange, onClose: actions.cancelGeneralAccessChange, onConfirm: () => {
161
209
  void actions.confirmGeneralAccessChange();
210
+ } }), _jsx(UiConfirmDialog, { isOpen: Boolean(isOpen && pendingSelfChange), title: intl.formatMessage(objectShareMessages.selfRestrictTitle), description: intl.formatMessage(objectShareMessages.selfRestrictWarning), confirmLabel: intl.formatMessage(objectShareMessages.confirmButton), confirmVariant: "primary", onCancel: () => setPendingSelfChange(undefined), onClose: () => setPendingSelfChange(undefined), onConfirm: () => {
211
+ if (!pendingSelfChange) {
212
+ return;
213
+ }
214
+ const { granteeId, level } = pendingSelfChange;
215
+ setPendingSelfChange(undefined);
216
+ if (level === "none") {
217
+ void actions.removeGrantee(granteeId);
218
+ }
219
+ else {
220
+ void actions.changePermissionLevel(granteeId, level);
221
+ }
162
222
  } })
163
223
  ] }));
164
224
  }
@@ -22,19 +22,24 @@ export declare const objectShareMessages: {
22
22
  confirmButton: {
23
23
  id: string;
24
24
  };
25
- transferAlreadyOwnerTitle: {
25
+ selfRestrictTitle: {
26
26
  id: string;
27
27
  };
28
- transferAlreadyOwnerDescription: {
28
+ /**
29
+ * Single source for the self-restriction warning: shown as the confirm dialog
30
+ * body AND as the disabled-option tooltip in the self row's permission menu —
31
+ * the copy must stay identical in both places by design.
32
+ */
33
+ selfRestrictWarning: {
29
34
  id: string;
30
35
  };
31
- transferAlreadyOwnerKeepAccess: {
36
+ granteeYou: {
32
37
  id: string;
33
38
  };
34
- transferAlreadyOwnerRemoveAccess: {
39
+ adminTagLabel: {
35
40
  id: string;
36
41
  };
37
- transferConfirmButton: {
42
+ adminTagTooltip: {
38
43
  id: string;
39
44
  };
40
45
  toastGranteeAdded: {
@@ -46,9 +51,6 @@ export declare const objectShareMessages: {
46
51
  toastGeneralAccessUpdated: {
47
52
  id: string;
48
53
  };
49
- toastOwnershipTransferred: {
50
- id: string;
51
- };
52
54
  toastError: {
53
55
  id: string;
54
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/share/messages.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkB9B,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/share/messages.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;IAO5B;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWL,CAAC"}
@@ -14,15 +14,19 @@ export const objectShareMessages = defineMessages({
14
14
  confirmGrantWorkspaceTitle: { id: "objectShare.confirm.grantWorkspace.title" },
15
15
  confirmGrantWorkspaceDescription: { id: "objectShare.confirm.grantWorkspace.description" },
16
16
  confirmButton: { id: "objectShare.confirm.button" },
17
- transferAlreadyOwnerTitle: { id: "objectShare.transfer.alreadyOwner.title" },
18
- transferAlreadyOwnerDescription: { id: "objectShare.transfer.alreadyOwner.description" },
19
- transferAlreadyOwnerKeepAccess: { id: "objectShare.transfer.alreadyOwner.keepAccess" },
20
- transferAlreadyOwnerRemoveAccess: { id: "objectShare.transfer.alreadyOwner.removeAccess" },
21
- transferConfirmButton: { id: "objectShare.transfer.confirmButton" },
17
+ selfRestrictTitle: { id: "objectShare.selfRestrict.title" },
18
+ /**
19
+ * Single source for the self-restriction warning: shown as the confirm dialog
20
+ * body AND as the disabled-option tooltip in the self row's permission menu —
21
+ * the copy must stay identical in both places by design.
22
+ */
23
+ selfRestrictWarning: { id: "objectShare.selfRestrict.warning" },
24
+ granteeYou: { id: "objectShare.grantee.you" },
25
+ adminTagLabel: { id: "objectShare.adminTag.label" },
26
+ adminTagTooltip: { id: "objectShare.adminTag.tooltip" },
22
27
  toastGranteeAdded: { id: "objectShare.toast.granteeAdded" },
23
28
  toastAccessUpdated: { id: "objectShare.toast.accessUpdated" },
24
29
  toastGeneralAccessUpdated: { id: "objectShare.toast.generalAccessUpdated" },
25
- toastOwnershipTransferred: { id: "objectShare.toast.ownershipTransferred" },
26
30
  toastError: { id: "objectShare.toast.error" },
27
31
  toastLabelScopePartial: { id: "objectShare.toast.labelScopePartial" },
28
32
  loadError: { id: "objectShare.loadError" },
@@ -1,5 +1,5 @@
1
1
  import type { AccessGranularPermission, ObjRef } from "@gooddata/sdk-model";
2
- import type { GeneralAccessValue, IUiGranteeAsyncOption, IUiGranteeAsyncOptions, IUiPickedGrantee } from "@gooddata/sdk-ui-kit";
2
+ import type { GeneralAccessValue, IUiGranteeAsyncOptions, IUiPickedGrantee } from "@gooddata/sdk-ui-kit";
3
3
  import type { IObjectAccessSummary, IObjectShareLabel } from "./types.js";
4
4
  /**
5
5
  * Permission level surfaced in the share dialog — the model's granular access
@@ -23,6 +23,15 @@ export interface IGranteeIdentityFacts {
23
23
  /** Real email, when known (users only). */
24
24
  email?: string;
25
25
  }
26
+ /**
27
+ * Signed-in user's identity: real facts plus the stable `id` (profile login)
28
+ * used as the display fallback, mirroring grantee rows.
29
+ *
30
+ * @internal
31
+ */
32
+ export interface ISelfIdentity extends IGranteeIdentityFacts {
33
+ id: string;
34
+ }
26
35
  /**
27
36
  * Dialog row derived from a backend grant. `name`/`email` are real facts only;
28
37
  * display fallbacks are `granteeDisplayPair`'s concern.
@@ -34,6 +43,11 @@ export interface IObjectShareGrantee extends IGranteeIdentityFacts {
34
43
  id: string;
35
44
  kind: "user" | "group";
36
45
  granteeRef: ObjRef;
46
+ /**
47
+ * Whether this row is the signed-in user's own grant. Derived from the
48
+ * profile, so it holds for rows of any origin (fetched or optimistic).
49
+ */
50
+ isSelf?: boolean;
37
51
  level: ObjectSharePermissionLevel;
38
52
  /**
39
53
  * Effective permission when it is *higher* than the directly-granted `level`
@@ -59,7 +73,7 @@ export interface IObjectShareGrantee extends IGranteeIdentityFacts {
59
73
  * @internal
60
74
  */
61
75
  export interface IObjectShareControllerState {
62
- subview: "main" | "addGrantee" | "transferOwnership";
76
+ subview: "main" | "addGrantee";
63
77
  status: "idle" | "loading" | "success" | "error" | "saving";
64
78
  error?: Error;
65
79
  /**
@@ -71,6 +85,32 @@ export interface IObjectShareControllerState {
71
85
  */
72
86
  accessUnavailable: boolean;
73
87
  summary: IObjectAccessSummary | undefined;
88
+ /**
89
+ * Stable serialized key of the current target's ref, or undefined when none.
90
+ * Consumers key target-scoped transient UI (e.g. a staged confirmation) on it,
91
+ * so nothing staged for one object can be applied to another.
92
+ */
93
+ targetKey: string | undefined;
94
+ /**
95
+ * Signed-in user's identity, once the profile resolves. Feeds their
96
+ * synthesized row when they can manage the object without holding any
97
+ * grant (administrator access) and the grantee list is empty.
98
+ */
99
+ selfIdentity: ISelfIdentity | undefined;
100
+ /**
101
+ * Whether the profile request resolved successfully. Until then — or after a
102
+ * silently-swallowed failure — `isSelf` on the rows is only its unresolved
103
+ * default, so a sole grantee row cannot be told apart from the caller's own
104
+ * grant and must not be offered destructive controls.
105
+ */
106
+ selfIdentityResolved: boolean;
107
+ /**
108
+ * Whether the manage-gated access list was LOADED with zero explicit grants —
109
+ * the caller reached it without holding a grant of their own. A load-time
110
+ * fact (never recomputed from the live list): removing your own sole grant
111
+ * empties the list but does not make this true.
112
+ */
113
+ seededWithoutGrants: boolean;
74
114
  grantees: IObjectShareGrantee[];
75
115
  generalAccess: GeneralAccessValue;
76
116
  /**
@@ -122,34 +162,6 @@ export interface IObjectShareControllerState {
122
162
  pendingGeneralAccess?: GeneralAccessValue;
123
163
  /** Grantees staged in the add-grantee dialog before confirmation. */
124
164
  pendingGrantees: IUiPickedGrantee[];
125
- /**
126
- * The user picked as the new owner in the transfer-ownership subview, or
127
- * undefined before one is chosen. Only users can own an object, so this is
128
- * never a group.
129
- */
130
- transferTarget: IUiGranteeAsyncOption | undefined;
131
- /**
132
- * Whether "Also remove my access" is checked in the transfer dialog. When
133
- * true the current user's grant is removed after the transfer; otherwise it
134
- * is downgraded to VIEW.
135
- */
136
- transferAlsoRemoveSelf: boolean;
137
- /**
138
- * Whether `transferTarget` already owns the object (already holds EDIT). When
139
- * true there is nothing to transfer — consumers show the "already an owner"
140
- * variant offering to remove the current user's own access instead.
141
- */
142
- transferTargetIsOwner: boolean;
143
- /** Whether the transfer write (or self-removal) is in flight. */
144
- transferSaving: boolean;
145
- /**
146
- * Whether the signed-in user may transfer ownership (owner-only). Consumers hide
147
- * the transfer affordance when false — e.g. for a View&Share (SHARE) user.
148
- * Detects a direct EDIT grant only (ownership inherited via a user group is not
149
- * recognized) and gates the affordance, not the actions — the transfer write
150
- * stays callable and the backend remains the authority.
151
- */
152
- canTransferOwnership: boolean;
153
165
  }
154
166
  /**
155
167
  * @internal
@@ -161,13 +173,11 @@ export interface IObjectShareControllerActions {
161
173
  closeAddGrantee: () => void;
162
174
  setPendingGrantees: (next: IUiPickedGrantee[]) => void;
163
175
  /**
164
- * Loader for the grantee pickers. Wraps `getAvailableAssignees` with
176
+ * Loader for the add-grantee picker. Wraps `getAvailableAssignees` with
165
177
  * client-side search + already-picked filtering, returning the picker's
166
- * `{ groups, users }` shape. By default excludes already-granted grantees
167
- * (add-grantee picker); pass `includeGranted` to keep them (transfer-ownership
168
- * picker, which may promote an existing viewer to owner).
178
+ * `{ groups, users }` shape. Excludes already-granted grantees.
169
179
  */
170
- loadOptions: (search: string, includeGranted?: boolean) => Promise<IUiGranteeAsyncOptions>;
180
+ loadOptions: (search: string) => Promise<IUiGranteeAsyncOptions>;
171
181
  /** Commit all pending grantees to the backend. */
172
182
  confirmAddGrantees: () => Promise<void>;
173
183
  /** Change the permission level for a single grantee. Auto-saves. */
@@ -191,24 +201,6 @@ export interface IObjectShareControllerActions {
191
201
  * already-granted rule.
192
202
  */
193
203
  changeWorkspaceLevel: (level: "VIEW" | "SHARE") => Promise<void>;
194
- /** Open the transfer-ownership subview with an empty picker. */
195
- openTransferOwnership: () => void;
196
- /** Close the transfer-ownership subview and clear its buffers; returns to main. */
197
- closeTransferOwnership: () => void;
198
- /**
199
- * Pick (or replace) the candidate new owner. Recomputes whether that user
200
- * already owns the object (`transferTargetIsOwner`).
201
- */
202
- setTransferTarget: (owner: IUiGranteeAsyncOption) => void;
203
- /** Toggle "Also remove my access" in the transfer dialog. */
204
- setTransferAlsoRemoveSelf: (next: boolean) => void;
205
- /**
206
- * Commit the ownership transfer: grant the picked user EDIT and downgrade the
207
- * current user to VIEW (or remove them if "Also remove my access" is set), in
208
- * one write. When the picked user already owns the object this transfers
209
- * nothing and only applies the self-access choice. Auto-saves.
210
- */
211
- confirmTransferOwnership: () => Promise<void>;
212
204
  }
213
205
  /**
214
206
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"objectShareController.types.d.ts","sourceRoot":"","sources":["../../src/share/objectShareController.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"objectShareController.types.d.ts","sourceRoot":"","sources":["../../src/share/objectShareController.types.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { IObjectPermissionsObject } from "@gooddata/sdk-backend-spi";
2
2
  import { type IGranularAccessGrantee, type ObjRef } from "@gooddata/sdk-model";
3
3
  import { type GeneralAccessValue, type IUiGranteeAsyncOptions } from "@gooddata/sdk-ui-kit";
4
- import type { IObjectShareControllerState, IObjectShareGrantee } from "./objectShareController.types.js";
4
+ import type { IObjectShareControllerState, IObjectShareGrantee, ISelfIdentity } from "./objectShareController.types.js";
5
5
  import type { IObjectAccessSummary } from "./types.js";
6
6
  /**
7
7
  * The owned access list for {@link useObjectShareController}.
@@ -15,6 +15,22 @@ export interface IAccessList {
15
15
  hasList: boolean;
16
16
  /** Local grantee rows — seeded from the fetch, then authoritative; mutations write through. */
17
17
  grantees: IObjectShareGrantee[];
18
+ /**
19
+ * Whether the manage-gated fetch seeded ZERO explicit grants for the current
20
+ * target — i.e. the caller reached the access list without holding a grant of
21
+ * their own (grant-independent access). A load-time fact: locally emptying the
22
+ * list later (e.g. removing your own sole grant) must not retroactively claim
23
+ * grant-independent access, so this is never recomputed from the live list.
24
+ */
25
+ seededWithoutGrants: boolean;
26
+ /** Signed-in user's identity facts + login id, once the profile resolves. */
27
+ selfIdentity: ISelfIdentity | undefined;
28
+ /**
29
+ * Whether the profile request resolved successfully — until then (or after a
30
+ * failure) rows' `isSelf` is only its unresolved default, so a sole grantee
31
+ * row cannot be told apart from the caller's own grant.
32
+ */
33
+ selfIdentityResolved: boolean;
18
34
  /**
19
35
  * Workspace vs restricted general access granted by THIS workspace's own rule —
20
36
  * local state; mutations write through. Excludes inherited (parent-workspace)
@@ -49,30 +65,10 @@ export interface IAccessList {
49
65
  id: string;
50
66
  }) => Promise<boolean>;
51
67
  /**
52
- * Picker loader — available assignees filtered by query. By default excludes
53
- * already-granted grantees (add-grantee picker); pass `includeGranted` to keep
54
- * them (transfer-ownership picker, which may promote an existing viewer).
55
- */
56
- loadOptions: (search: string, includeGranted?: boolean) => Promise<IUiGranteeAsyncOptions>;
57
- /**
58
- * The current user's ref, resolved on demand (and cached). Used by the
59
- * transfer-ownership flow to write the current user's own grant change. The
60
- * add-grantee *picker* excludes the current user, but `getAccessList` does
61
- * not, so a self grant can still appear as a row. Always an idRef in the
62
- * access list's id space, so it is comparable to grantee refs. Rejects if
63
- * the profile can't be read.
64
- */
65
- getCurrentUserRef: () => Promise<ObjRef>;
66
- /**
67
- * Whether the signed-in user owns the object (holds a direct EDIT grant) — the
68
- * gate for the owner-only transfer-ownership action. Resolved eagerly so the
69
- * affordance is correct at render time; false until the current user resolves.
70
- * Detects direct grants only: ownership held via a user group is not recognized
71
- * (the row model drops inherited EDIT, and whether the access list surfaces a
72
- * self row for group-only members is an open API question). Affordance-only by
73
- * design — the transfer actions are never blocked on it, the backend decides.
68
+ * Picker loader — available assignees filtered by query, excluding
69
+ * already-granted grantees (add-grantee picker).
74
70
  */
75
- canTransferOwnership: boolean;
71
+ loadOptions: (search: string) => Promise<IUiGranteeAsyncOptions>;
76
72
  /** Resolve a grantee id back to the picker's original ObjRef (preserves Uri vs Id ref). */
77
73
  refForId: (id: string) => ObjRef;
78
74
  /** Write through a local grantee-row change (insert / level / remove); rolled back by the caller. */
@@ -1 +1 @@
1
- {"version":3,"file":"useAccessList.d.ts","sourceRoot":"","sources":["../../src/share/useAccessList.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAEH,KAAK,sBAAsB,EAE3B,KAAK,MAAM,EAGd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAmB,MAAM,sBAAsB,CAAC;AAkB7G,OAAO,KAAK,EAER,2BAA2B,EAC3B,mBAAmB,EACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,iFAAiF;IACjF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,wFAAwF;IACxF,OAAO,EAAE,OAAO,CAAC;IACjB,iGAA+F;IAC/F,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC;;;;OAIG;IACH,aAAa,EAAE,kBAAkB,CAAC;IAClC,6FAA2F;IAC3F,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,uBAAuB,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACtD,iEAAiE;IACjE,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,+DAA+D;IAC/D,MAAM,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC9C,iDAAiD;IACjD,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAC7B;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B,mFAAmF;IACnF,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,EAAE,EAAE,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F;;;;OAIG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC3F;;;;;;;OAOG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC;;;;;;;;OAQG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B,2FAA2F;IAC3F,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAEjC,qGAAqG;IACrG,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACzE,8EAA8E;IAC9E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC3E;;;;OAIG;IACH,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,wBAAwB,GAAG,SAAS,EAC5C,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,GACpB,WAAW,CAwTb"}
1
+ {"version":3,"file":"useAccessList.d.ts","sourceRoot":"","sources":["../../src/share/useAccessList.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAEH,KAAK,sBAAsB,EAE3B,KAAK,MAAM,EAId,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAmB,MAAM,sBAAsB,CAAC;AAkB7G,OAAO,KAAK,EAER,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EAChB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,iFAAiF;IACjF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,wFAAwF;IACxF,OAAO,EAAE,OAAO,CAAC;IACjB,iGAA+F;IAC/F,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,aAAa,EAAE,kBAAkB,CAAC;IAClC,6FAA2F;IAC3F,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,uBAAuB,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACtD,iEAAiE;IACjE,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,+DAA+D;IAC/D,MAAM,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC9C,iDAAiD;IACjD,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IAC7B;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B,mFAAmF;IACnF,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,EAAE,EAAE,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F;;;OAGG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE,2FAA2F;IAC3F,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAEjC,qGAAqG;IACrG,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACzE,8EAA8E;IAC9E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC3E;;;;OAIG;IACH,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,wBAAwB,GAAG,SAAS,EAC5C,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,GACpB,WAAW,CAiUb"}