@gooddata/sdk-ui-ext 11.49.0-alpha.0 → 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.
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/internal/components/dialogs/userManagementDialogs/Workspace/WorkspaceItem/GranularPermissionsWorkspaceItem.d.ts.map +1 -1
- package/esm/internal/components/dialogs/userManagementDialogs/Workspace/WorkspaceItem/GranularPermissionsWorkspaceItem.js +1 -0
- package/esm/internal/translations/de-DE.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/de-DE.localization-bundle.js +1 -0
- package/esm/internal/translations/en-AU.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/en-AU.localization-bundle.js +1 -0
- package/esm/internal/translations/en-GB.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/en-GB.localization-bundle.js +1 -0
- package/esm/internal/translations/en-US.localization-bundle.d.ts +5 -9
- package/esm/internal/translations/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/en-US.localization-bundle.js +15 -19
- package/esm/internal/translations/es-419.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/es-419.localization-bundle.js +1 -0
- package/esm/internal/translations/es-ES.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/es-ES.localization-bundle.js +1 -0
- package/esm/internal/translations/fi-FI.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/fi-FI.localization-bundle.js +1 -0
- package/esm/internal/translations/fr-CA.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/fr-CA.localization-bundle.js +1 -0
- package/esm/internal/translations/fr-FR.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/fr-FR.localization-bundle.js +1 -0
- package/esm/internal/translations/id-ID.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/id-ID.localization-bundle.js +1 -0
- package/esm/internal/translations/it-IT.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/it-IT.localization-bundle.js +1 -0
- package/esm/internal/translations/ja-JP.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/ja-JP.localization-bundle.js +1 -0
- package/esm/internal/translations/ko-KR.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/ko-KR.localization-bundle.js +1 -0
- package/esm/internal/translations/nl-NL.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/nl-NL.localization-bundle.js +1 -0
- package/esm/internal/translations/pl-PL.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/pl-PL.localization-bundle.js +1 -0
- package/esm/internal/translations/pt-BR.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/pt-BR.localization-bundle.js +1 -0
- package/esm/internal/translations/pt-PT.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/pt-PT.localization-bundle.js +1 -0
- package/esm/internal/translations/ru-RU.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/ru-RU.localization-bundle.js +1 -0
- package/esm/internal/translations/sl-SI.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/sl-SI.localization-bundle.js +1 -0
- package/esm/internal/translations/th-TH.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/th-TH.localization-bundle.js +1 -0
- package/esm/internal/translations/tr-TR.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/tr-TR.localization-bundle.js +2 -1
- package/esm/internal/translations/uk-UA.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/uk-UA.localization-bundle.js +1 -0
- package/esm/internal/translations/vi-VN.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/vi-VN.localization-bundle.js +1 -0
- package/esm/internal/translations/zh-HK.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/zh-HK.localization-bundle.js +1 -0
- package/esm/internal/translations/zh-Hans.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/zh-Hans.localization-bundle.js +1 -0
- package/esm/internal/translations/zh-Hant.localization-bundle.d.ts +1 -0
- package/esm/internal/translations/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/zh-Hant.localization-bundle.js +1 -0
- package/esm/sdk-ui-ext.d.ts +45 -53
- package/esm/share/ObjectShareDialog.d.ts.map +1 -1
- package/esm/share/ObjectShareDialog.js +118 -58
- package/esm/share/messages.d.ts +10 -8
- package/esm/share/messages.d.ts.map +1 -1
- package/esm/share/messages.js +10 -6
- package/esm/share/objectShareController.types.d.ts +45 -53
- package/esm/share/objectShareController.types.d.ts.map +1 -1
- package/esm/share/useAccessList.d.ts +20 -24
- package/esm/share/useAccessList.d.ts.map +1 -1
- package/esm/share/useAccessList.js +39 -30
- package/esm/share/useObjectShareController.d.ts.map +1 -1
- package/esm/share/useObjectShareController.js +10 -201
- package/package.json +21 -21
- package/styles/css/main.css +5 -0
- package/styles/css/main.css.map +1 -1
- package/styles/internal/css/user_management_dialogs.css +5 -0
- package/styles/internal/css/user_management_dialogs.css.map +1 -1
- package/styles/internal/scss/user_management_dialogs.scss +10 -0
|
@@ -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,
|
|
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
|
|
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:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
}
|
package/esm/share/messages.d.ts
CHANGED
|
@@ -22,19 +22,24 @@ export declare const objectShareMessages: {
|
|
|
22
22
|
confirmButton: {
|
|
23
23
|
id: string;
|
|
24
24
|
};
|
|
25
|
-
|
|
25
|
+
selfRestrictTitle: {
|
|
26
26
|
id: string;
|
|
27
27
|
};
|
|
28
|
-
|
|
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
|
-
|
|
36
|
+
granteeYou: {
|
|
32
37
|
id: string;
|
|
33
38
|
};
|
|
34
|
-
|
|
39
|
+
adminTagLabel: {
|
|
35
40
|
id: string;
|
|
36
41
|
};
|
|
37
|
-
|
|
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
|
|
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"}
|
package/esm/share/messages.js
CHANGED
|
@@ -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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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,
|
|
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"
|
|
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
|
|
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.
|
|
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
|
|
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":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,
|
|
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
|
|
53
|
-
* already-granted grantees (add-grantee picker)
|
|
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
|
-
|
|
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,
|
|
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"}
|