@gooddata/sdk-ui-ext 11.51.0-alpha.0 → 11.51.0-alpha.2
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/NOTICE +4 -4
- package/esm/index.d.ts +3 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -1
- package/esm/internal/translations/en-US.localization-bundle.d.ts +4 -0
- package/esm/internal/translations/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/internal/translations/en-US.localization-bundle.js +4 -0
- package/esm/sdk-ui-ext.d.ts +56 -305
- package/esm/share/ObjectShareDialog.d.ts +19 -23
- package/esm/share/ObjectShareDialog.d.ts.map +1 -1
- package/esm/share/ObjectShareDialog.js +85 -171
- package/esm/share/accessSummary.d.ts +18 -8
- package/esm/share/accessSummary.d.ts.map +1 -1
- package/esm/share/accessSummary.js +25 -13
- package/esm/share/messages.d.ts +7 -0
- package/esm/share/messages.d.ts.map +1 -1
- package/esm/share/messages.js +5 -0
- package/esm/share/objectShareController.helpers.d.ts +83 -5
- package/esm/share/objectShareController.helpers.d.ts.map +1 -1
- package/esm/share/objectShareController.helpers.js +144 -10
- package/esm/share/objectShareController.types.d.ts +63 -64
- package/esm/share/objectShareController.types.d.ts.map +1 -1
- package/esm/share/types.d.ts +4 -5
- package/esm/share/types.d.ts.map +1 -1
- package/esm/share/useAccessList.d.ts +64 -63
- package/esm/share/useAccessList.d.ts.map +1 -1
- package/esm/share/useAccessList.js +174 -221
- package/esm/share/useLabelScope.d.ts +18 -13
- package/esm/share/useLabelScope.d.ts.map +1 -1
- package/esm/share/useLabelScope.js +112 -123
- package/esm/share/useObjectShareController.d.ts +14 -17
- package/esm/share/useObjectShareController.d.ts.map +1 -1
- package/esm/share/useObjectShareController.js +211 -224
- package/esm/share/useObjectShareDialog.d.ts +90 -0
- package/esm/share/useObjectShareDialog.d.ts.map +1 -0
- package/esm/share/useObjectShareDialog.js +82 -0
- package/package.json +21 -21
- package/src/notificationsPanel/NotificationsPanel/DefaultNotificationsPanelButton.scss +4 -1
- package/styles/css/main.css +1 -1
- package/styles/css/main.css.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectShareDialog.d.ts","sourceRoot":"","sources":["../../src/share/ObjectShareDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ObjectShareDialog.d.ts","sourceRoot":"","sources":["../../src/share/ObjectShareDialog.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAc1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA8B1E;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,gDAAgD;IAChD,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,sFAAsF;IACtF,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,uBAAuB,kDAK/D"}
|
|
@@ -1,15 +1,21 @@
|
|
|
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, useState } from "react";
|
|
4
3
|
import { useIntl } from "react-intl";
|
|
5
4
|
import { UiAddGranteeDialog, UiConfirmDialog, UiGranteeRowControls, UiObjectShareDialog, UiTag, UiTooltip, } from "@gooddata/sdk-ui-kit";
|
|
6
5
|
import { objectShareMessages } from "./messages.js";
|
|
7
|
-
import { granteeDisplayPair
|
|
8
|
-
import {
|
|
6
|
+
import { granteeDisplayPair } from "./objectShareController.helpers.js";
|
|
7
|
+
import { useObjectShareDialog } from "./useObjectShareDialog.js";
|
|
9
8
|
// The workspace row has no labels menu (see workspaceControls below), so its
|
|
10
9
|
// required onLabelsChange never fires; a stable no-op satisfies the prop type
|
|
11
10
|
// without churning the controls' identity each render.
|
|
12
11
|
const noop = () => { };
|
|
12
|
+
// Static Admin badge on the synthesized administrator self row — the tooltip
|
|
13
|
+
// explains the grant-independent access; the focusable span keeps it
|
|
14
|
+
// keyboard-reachable (UiTag itself is not interactive).
|
|
15
|
+
function AdminSelfTag() {
|
|
16
|
+
const intl = useIntl();
|
|
17
|
+
return (_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" }) }) }));
|
|
18
|
+
}
|
|
13
19
|
/**
|
|
14
20
|
* Connected share dialog. Renders the main share modal, the add-grantee
|
|
15
21
|
* sub-dialog and the general-access confirm dialog, all driven by one
|
|
@@ -17,178 +23,98 @@ const noop = () => { };
|
|
|
17
23
|
* be safely co-mounted; focus, backdrop and portal lifecycles are owned by
|
|
18
24
|
* `UiModalDialog` inside the kit.
|
|
19
25
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* <ObjectShareDialog target={ref} objectTitle={title} isOpen={open} onClose={close} />
|
|
26
|
-
* ```
|
|
26
|
+
* One open = one dialog session over one fixed `target`: the session (the
|
|
27
|
+
* controller, its fetches, every transient — pending rows, staged confirms,
|
|
28
|
+
* optimistic edits) exists only while `isOpen`, enforced here, so the component
|
|
29
|
+
* may safely stay mounted across open/close cycles. Do not swap the target —
|
|
30
|
+
* or the backend/workspace context — while open; close and reopen instead.
|
|
27
31
|
*
|
|
28
32
|
* @internal
|
|
29
33
|
*/
|
|
30
|
-
export function ObjectShareDialog(
|
|
34
|
+
export function ObjectShareDialog(props) {
|
|
35
|
+
if (!props.isOpen) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return _jsx(ObjectShareDialogSession, { ...props });
|
|
39
|
+
}
|
|
40
|
+
/** The dialog session — mounted only while open, so its state cannot outlive a close. */
|
|
41
|
+
function ObjectShareDialogSession({ target, objectTitle, onClose, onSummaryChange, labels, labelsLoading, labelsError, }) {
|
|
31
42
|
const intl = useIntl();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const ownController = useObjectShareController(controller ? undefined : target, {
|
|
37
|
-
onSaved,
|
|
43
|
+
const { state, actions, isShareViewOpen, isAddGranteeOpen, isGeneralAccessConfirmOpen, isSelfRestrictConfirmOpen, isMutable, isLoading, workspaceDisabledLevels, rowDisabledLevels, onClose: closeDialog, onRowPermissionChange, onRowRemove, onSelfRestrictCancel, onSelfRestrictConfirm, } = useObjectShareDialog({
|
|
44
|
+
target,
|
|
45
|
+
onClose,
|
|
46
|
+
onSummaryChange,
|
|
38
47
|
labels,
|
|
39
|
-
labelsError,
|
|
40
48
|
labelsLoading,
|
|
41
|
-
|
|
49
|
+
labelsError,
|
|
42
50
|
});
|
|
43
|
-
|
|
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
|
-
}
|
|
60
|
-
const handleClose = useCallback(() => {
|
|
61
|
-
setPendingSelfChange(undefined);
|
|
62
|
-
actions.reset();
|
|
63
|
-
onClose();
|
|
64
|
-
}, [actions, onClose]);
|
|
65
|
-
const isAddGranteeOpen = isOpen && state.subview === "addGrantee";
|
|
66
|
-
const isShareOpen = isOpen && state.subview === "main";
|
|
67
|
-
const isConfirmOpen = isOpen && !!state.pendingGeneralAccess;
|
|
68
|
-
// Don't allow mutations until the access list has loaded: before then the
|
|
69
|
-
// controller reports empty grantees + RESTRICTED, which is a placeholder, not
|
|
70
|
-
// the real state. Acting on it would write from a false assumption. Mutations
|
|
71
|
-
// are also gated until per-label scope resolves (`labelsResolved`): a new
|
|
72
|
-
// grantee defaults to all labels, and any access change before resolution
|
|
73
|
-
// would diff against an assumed-full scope (skipping grants / revoking the
|
|
74
|
-
// wrong labels). `labelsResolved` is false while labels are still loading and
|
|
75
|
-
// when their fetch failed, so a pending/failed label set blocks every
|
|
76
|
-
// access-changing control here — Add, row controls and general access alike.
|
|
77
|
-
const isLoaded = state.status === "success";
|
|
78
|
-
const isMutable = isLoaded && state.labelsResolved;
|
|
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;
|
|
105
|
-
// Map the controller's labels to the picker's item shape; the primary label
|
|
106
|
-
// is rendered locked (always selected, can't be unchecked).
|
|
51
|
+
// Primary label is locked — always selected, can't be unchecked.
|
|
107
52
|
const labelItems = state.labels.map((l) => ({
|
|
108
53
|
id: l.id,
|
|
109
54
|
label: l.title,
|
|
110
55
|
kind: l.isPrimary ? "primary" : undefined,
|
|
111
56
|
locked: l.isPrimary,
|
|
112
57
|
}));
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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,
|
|
173
|
-
// Inherited workspace access can't be revoked here — the kit disables
|
|
174
|
-
// the Restricted option and explains why.
|
|
175
|
-
workspaceAccessInherited: state.workspaceAccessInherited,
|
|
176
|
-
// Permission dropdown on the "All workspace members" row — only while
|
|
177
|
-
// workspace access is on (the rule must exist to be re-graded). No
|
|
178
|
-
// labels (⋯) menu and no remove: per the Figma spec the workspace row
|
|
179
|
-
// carries the permission picker alone; the workspace rule's label
|
|
180
|
-
// scope is managed implicitly with the RESTRICTED↔WORKSPACE toggle.
|
|
58
|
+
const toGranteeRow = (g) => {
|
|
59
|
+
const display = granteeDisplayPair(g);
|
|
60
|
+
// Levels come back only for the signed-in user's own sole grant (you can't
|
|
61
|
+
// raise yourself); the confirm-vs-direct routing lives in the hook too.
|
|
62
|
+
const disabledLevels = rowDisabledLevels(g);
|
|
63
|
+
return {
|
|
64
|
+
id: g.id,
|
|
65
|
+
kind: g.kind,
|
|
66
|
+
name: g.isSelf
|
|
67
|
+
? intl.formatMessage(objectShareMessages.granteeYou, { name: display.name })
|
|
68
|
+
: display.name,
|
|
69
|
+
email: display.email,
|
|
70
|
+
isPending: g.pending !== undefined,
|
|
71
|
+
controls: (_jsx(UiGranteeRowControls, { labels: labelItems, selectedLabelIds: state.selectedLabelIdsByGrantee[g.id] ?? state.labels.map((l) => l.id), permissionLevel: g.level, effectivePermission: g.effectivePermission, disabledLevels: disabledLevels, disabledTooltip: disabledLevels
|
|
72
|
+
? intl.formatMessage(objectShareMessages.selfRestrictWarning)
|
|
73
|
+
: undefined,
|
|
74
|
+
// Disabled while the row's own write is saving, while mutations are
|
|
75
|
+
// gated (unresolved label scope would orphan real per-label grants),
|
|
76
|
+
// and while a sole row's self identity is unknown.
|
|
77
|
+
isDisabled: g.pending !== undefined || !isMutable || state.granteeControlsLocked, onLabelsChange: (selectedIds) => {
|
|
78
|
+
void actions.changeGranteeLabels(g.id, selectedIds);
|
|
79
|
+
}, onPermissionChange: (level) => onRowPermissionChange(g, level), onRemoveAccess: () => onRowRemove(g) })),
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
// Synthesized empty-state row: the controller reports it only while the list
|
|
83
|
+
// holds no grantees (adding one replaces it, removing the last one restores
|
|
84
|
+
// it — see `adminSelfRow`). The controller decides; this only renders it.
|
|
85
|
+
const rows = [
|
|
86
|
+
...(state.adminSelfRow
|
|
87
|
+
? [
|
|
88
|
+
{
|
|
89
|
+
id: "self-admin",
|
|
90
|
+
kind: "user",
|
|
91
|
+
name: intl.formatMessage(objectShareMessages.granteeYou, {
|
|
92
|
+
name: state.adminSelfRow.name,
|
|
93
|
+
}),
|
|
94
|
+
email: state.adminSelfRow.email,
|
|
95
|
+
controls: _jsx(AdminSelfTag, {}),
|
|
96
|
+
},
|
|
97
|
+
]
|
|
98
|
+
: []),
|
|
99
|
+
...state.grantees.map(toGranteeRow),
|
|
100
|
+
];
|
|
101
|
+
return (_jsxs(_Fragment, { children: [_jsx(UiObjectShareDialog, { isOpen: isShareViewOpen, objectTitle: objectTitle, onClose: closeDialog, grantees: rows, isLoading: isLoading, onAddClick: actions.openAddGrantee, isAddDisabled: !isMutable, generalAccess: state.generalAccess, onGeneralAccessChange: actions.requestGeneralAccessChange,
|
|
102
|
+
// Inherited workspace access can't be revoked here.
|
|
103
|
+
workspaceAccessInherited: state.workspaceInheritedLevel !== undefined,
|
|
104
|
+
// Only while workspace access is on (the rule must exist to re-grade).
|
|
105
|
+
// The workspace row has the permission picker alone — no labels/remove;
|
|
106
|
+
// its label scope follows the RESTRICTED↔WORKSPACE toggle implicitly.
|
|
181
107
|
workspaceControls: state.generalAccess === "WORKSPACE" ? (_jsx(UiGranteeRowControls, { labels: [], selectedLabelIds: [], permissionLevel: state.workspaceLevel,
|
|
108
|
+
// Levels below an inherited workspace-wide level can't take
|
|
109
|
+
// effect (the inherited grant already exceeds them).
|
|
110
|
+
disabledLevels: workspaceDisabledLevels, disabledTooltip: intl.formatMessage(objectShareMessages.workspaceLevelInherited),
|
|
182
111
|
// Also disabled while its own re-grade is committing, so
|
|
183
112
|
// rapid toggles can't queue overlapping writes — and when
|
|
184
113
|
// the level is locked (inherited-only access has no direct
|
|
185
|
-
// rule to re-grade; an inherited
|
|
114
|
+
// rule to re-grade; an inherited EDIT pins the level).
|
|
186
115
|
isDisabled: !isMutable || state.workspaceLevelSaving || state.workspaceLevelLocked, onLabelsChange: noop, onPermissionChange: (level) => {
|
|
187
116
|
void actions.changeWorkspaceLevel(level);
|
|
188
|
-
} })) : undefined,
|
|
189
|
-
// Keep the "All workspace members" description in sync with the picked
|
|
190
|
-
// level ("can view" vs "can view and share").
|
|
191
|
-
workspaceLevel: state.workspaceLevel,
|
|
117
|
+
} })) : undefined, workspaceLevel: state.workspaceLevel,
|
|
192
118
|
// Gated on the same condition as Add: changing general access also
|
|
193
119
|
// mirrors the label scope, so it must wait for resolution and stay
|
|
194
120
|
// disabled when label metadata failed to load. Also gated while a
|
|
@@ -199,26 +125,14 @@ export function ObjectShareDialog({ target, objectTitle, isOpen, onClose, onSave
|
|
|
199
125
|
// On a failed load the empty grantee list + RESTRICTED radio are a
|
|
200
126
|
// placeholder, not the real policy — show why instead of letting it
|
|
201
127
|
// read as "no one has access".
|
|
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:
|
|
128
|
+
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: closeDialog, onCancel: actions.closeAddGrantee, onShare: () => {
|
|
203
129
|
void actions.confirmAddGrantees();
|
|
204
|
-
} }), _jsx(UiConfirmDialog, { isOpen:
|
|
130
|
+
} }), _jsx(UiConfirmDialog, { isOpen: isGeneralAccessConfirmOpen, title: intl.formatMessage(state.pendingGeneralAccess === "RESTRICTED"
|
|
205
131
|
? objectShareMessages.confirmRestrictTitle
|
|
206
132
|
: objectShareMessages.confirmGrantWorkspaceTitle), description: intl.formatMessage(state.pendingGeneralAccess === "RESTRICTED"
|
|
207
133
|
? objectShareMessages.confirmRestrictDescription
|
|
208
134
|
: objectShareMessages.confirmGrantWorkspaceDescription, { title: objectTitle }), confirmLabel: intl.formatMessage(objectShareMessages.confirmButton), confirmVariant: "primary", onCancel: actions.cancelGeneralAccessChange, onClose: actions.cancelGeneralAccessChange, onConfirm: () => {
|
|
209
135
|
void actions.confirmGeneralAccessChange();
|
|
210
|
-
} }), _jsx(UiConfirmDialog, { isOpen:
|
|
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
|
-
}
|
|
222
|
-
} })
|
|
136
|
+
} }), _jsx(UiConfirmDialog, { isOpen: isSelfRestrictConfirmOpen, title: intl.formatMessage(objectShareMessages.selfRestrictTitle), description: intl.formatMessage(objectShareMessages.selfRestrictWarning), confirmLabel: intl.formatMessage(objectShareMessages.confirmButton), confirmVariant: "primary", onCancel: onSelfRestrictCancel, onClose: onSelfRestrictCancel, onConfirm: onSelfRestrictConfirm })
|
|
223
137
|
] }));
|
|
224
138
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { AccessGranteeDetail, IGranularRulesAccess } from "@gooddata/sdk-model";
|
|
1
|
+
import type { AccessGranteeDetail, IGranularRulesAccess, IObjectAccessList } from "@gooddata/sdk-model";
|
|
2
2
|
import type { GeneralAccessValue } from "@gooddata/sdk-ui-kit";
|
|
3
|
+
import type { ObjectSharePermissionLevel } from "./objectShareController.types.js";
|
|
4
|
+
import type { IObjectAccessSummary } from "./types.js";
|
|
3
5
|
/**
|
|
4
6
|
* All `allWorkspaceUsers` rule grants. With workspace hierarchy the backend
|
|
5
7
|
* returns one entry per granting workspace — this workspace's own grant carries
|
|
@@ -16,11 +18,10 @@ export declare function findAllWorkspaceUsersGrants(grants: AccessGranteeDetail[
|
|
|
16
18
|
*/
|
|
17
19
|
export declare function deriveGeneralAccess(grants: AccessGranteeDetail[]): GeneralAccessValue;
|
|
18
20
|
/**
|
|
19
|
-
* Workspace-wide permission level of this workspace's own rule grant
|
|
20
|
-
*
|
|
21
|
-
* EDIT is intentionally not surfaced — the UI caps at VIEW/SHARE.
|
|
21
|
+
* Workspace-wide permission level of this workspace's own rule grant — the
|
|
22
|
+
* strongest level any rule entry directly permits, defaulting to VIEW.
|
|
22
23
|
*/
|
|
23
|
-
export declare function deriveWorkspacePermissionLevel(grants: AccessGranteeDetail[]):
|
|
24
|
+
export declare function deriveWorkspacePermissionLevel(grants: AccessGranteeDetail[]): ObjectSharePermissionLevel;
|
|
24
25
|
/**
|
|
25
26
|
* Strongest workspace-wide level inherited from parent workspaces, or undefined
|
|
26
27
|
* when none is inherited. Inherited rule access grants every user of this
|
|
@@ -28,15 +29,24 @@ export declare function deriveWorkspacePermissionLevel(grants: AccessGranteeDeta
|
|
|
28
29
|
* cannot be revoked from here — consumers must surface it as workspace access
|
|
29
30
|
* and disable the Restricted option.
|
|
30
31
|
*/
|
|
31
|
-
export declare function deriveInheritedWorkspaceLevel(grants: AccessGranteeDetail[]):
|
|
32
|
+
export declare function deriveInheritedWorkspaceLevel(grants: AccessGranteeDetail[]): ObjectSharePermissionLevel | undefined;
|
|
32
33
|
/**
|
|
33
34
|
* The effective (displayed) workspace access: the direct state composed with
|
|
34
35
|
* inherited rule access. Inherited access makes general access WORKSPACE even
|
|
35
36
|
* when this workspace holds no rule of its own, and the level is the strongest
|
|
36
37
|
* of the two.
|
|
37
38
|
*/
|
|
38
|
-
export declare function composeEffectiveWorkspaceAccess(direct: GeneralAccessValue,
|
|
39
|
+
export declare function composeEffectiveWorkspaceAccess(direct: GeneralAccessValue, directLevelValue: ObjectSharePermissionLevel, inheritedLevel: ObjectSharePermissionLevel | undefined): {
|
|
39
40
|
generalAccess: GeneralAccessValue;
|
|
40
|
-
workspaceLevel:
|
|
41
|
+
workspaceLevel: ObjectSharePermissionLevel;
|
|
41
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* The access summary of a fetched access list — effective workspace access plus the
|
|
45
|
+
* explicit grantee count. The single derivation shared by an inline access row (a
|
|
46
|
+
* consumer's own page-level fetch) and {@link ObjectShareDialog}'s `onSummaryChange`,
|
|
47
|
+
* so the two can never disagree on what a list means.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export declare function accessListToSummary(list: IObjectAccessList): IObjectAccessSummary;
|
|
42
52
|
//# sourceMappingURL=accessSummary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessSummary.d.ts","sourceRoot":"","sources":["../../src/share/accessSummary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"accessSummary.d.ts","sourceRoot":"","sources":["../../src/share/accessSummary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,oBAAoB,EAAE,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,kBAAkB,CAIrF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,0BAA0B,CAExG;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,mBAAmB,EAAE,GAC9B,0BAA0B,GAAG,SAAS,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC3C,MAAM,EAAE,kBAAkB,EAC1B,gBAAgB,EAAE,0BAA0B,EAC5C,cAAc,EAAE,0BAA0B,GAAG,SAAS,GACvD;IAAE,aAAa,EAAE,kBAAkB,CAAC;IAAC,cAAc,EAAE,0BAA0B,CAAA;CAAE,CAOnF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,oBAAoB,CAUjF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { directLevel, granteesFromAccessList, strongestLevel } from "./objectShareController.helpers.js";
|
|
2
3
|
/**
|
|
3
4
|
* All `allWorkspaceUsers` rule grants. With workspace hierarchy the backend
|
|
4
5
|
* returns one entry per granting workspace — this workspace's own grant carries
|
|
@@ -21,14 +22,11 @@ export function deriveGeneralAccess(grants) {
|
|
|
21
22
|
: "RESTRICTED";
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
* Workspace-wide permission level of this workspace's own rule grant
|
|
25
|
-
*
|
|
26
|
-
* EDIT is intentionally not surfaced — the UI caps at VIEW/SHARE.
|
|
25
|
+
* Workspace-wide permission level of this workspace's own rule grant — the
|
|
26
|
+
* strongest level any rule entry directly permits, defaulting to VIEW.
|
|
27
27
|
*/
|
|
28
28
|
export function deriveWorkspacePermissionLevel(grants) {
|
|
29
|
-
return findAllWorkspaceUsersGrants(grants).
|
|
30
|
-
? "SHARE"
|
|
31
|
-
: "VIEW";
|
|
29
|
+
return directLevel(findAllWorkspaceUsersGrants(grants).flatMap((rule) => rule.permissions));
|
|
32
30
|
}
|
|
33
31
|
/**
|
|
34
32
|
* Strongest workspace-wide level inherited from parent workspaces, or undefined
|
|
@@ -38,11 +36,7 @@ export function deriveWorkspacePermissionLevel(grants) {
|
|
|
38
36
|
* and disable the Restricted option.
|
|
39
37
|
*/
|
|
40
38
|
export function deriveInheritedWorkspaceLevel(grants) {
|
|
41
|
-
|
|
42
|
-
if (inherited.includes("SHARE")) {
|
|
43
|
-
return "SHARE";
|
|
44
|
-
}
|
|
45
|
-
return inherited.length > 0 ? "VIEW" : undefined;
|
|
39
|
+
return strongestLevel(findAllWorkspaceUsersGrants(grants).flatMap((rule) => rule.inheritedPermissions));
|
|
46
40
|
}
|
|
47
41
|
/**
|
|
48
42
|
* The effective (displayed) workspace access: the direct state composed with
|
|
@@ -50,8 +44,26 @@ export function deriveInheritedWorkspaceLevel(grants) {
|
|
|
50
44
|
* when this workspace holds no rule of its own, and the level is the strongest
|
|
51
45
|
* of the two.
|
|
52
46
|
*/
|
|
53
|
-
export function composeEffectiveWorkspaceAccess(direct,
|
|
47
|
+
export function composeEffectiveWorkspaceAccess(direct, directLevelValue, inheritedLevel) {
|
|
54
48
|
const generalAccess = direct === "WORKSPACE" || inheritedLevel ? "WORKSPACE" : "RESTRICTED";
|
|
55
|
-
const workspaceLevel =
|
|
49
|
+
const workspaceLevel = directLevel([
|
|
50
|
+
...(direct === "WORKSPACE" ? [directLevelValue] : []),
|
|
51
|
+
...(inheritedLevel ? [inheritedLevel] : []),
|
|
52
|
+
]);
|
|
56
53
|
return { generalAccess, workspaceLevel };
|
|
57
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* The access summary of a fetched access list — effective workspace access plus the
|
|
57
|
+
* explicit grantee count. The single derivation shared by an inline access row (a
|
|
58
|
+
* consumer's own page-level fetch) and {@link ObjectShareDialog}'s `onSummaryChange`,
|
|
59
|
+
* so the two can never disagree on what a list means.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export function accessListToSummary(list) {
|
|
64
|
+
const inheritedLevel = deriveInheritedWorkspaceLevel(list.grants);
|
|
65
|
+
return {
|
|
66
|
+
...composeEffectiveWorkspaceAccess(deriveGeneralAccess(list.grants), deriveWorkspacePermissionLevel(list.grants), inheritedLevel),
|
|
67
|
+
granteeCount: granteesFromAccessList(list).length,
|
|
68
|
+
};
|
|
69
|
+
}
|
package/esm/share/messages.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare const objectShareMessages: {
|
|
|
33
33
|
selfRestrictWarning: {
|
|
34
34
|
id: string;
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Disabled-option tooltip on the workspace rule's permission menu for levels
|
|
38
|
+
* below an inherited workspace-wide grant, which they could never lower.
|
|
39
|
+
*/
|
|
40
|
+
workspaceLevelInherited: {
|
|
41
|
+
id: string;
|
|
42
|
+
};
|
|
36
43
|
granteeYou: {
|
|
37
44
|
id: string;
|
|
38
45
|
};
|
|
@@ -1 +1 @@
|
|
|
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"}
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/share/messages.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;IAO5B;;;;OAIG;;;;IAEH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWL,CAAC"}
|
package/esm/share/messages.js
CHANGED
|
@@ -21,6 +21,11 @@ export const objectShareMessages = defineMessages({
|
|
|
21
21
|
* the copy must stay identical in both places by design.
|
|
22
22
|
*/
|
|
23
23
|
selfRestrictWarning: { id: "objectShare.selfRestrict.warning" },
|
|
24
|
+
/**
|
|
25
|
+
* Disabled-option tooltip on the workspace rule's permission menu for levels
|
|
26
|
+
* below an inherited workspace-wide grant, which they could never lower.
|
|
27
|
+
*/
|
|
28
|
+
workspaceLevelInherited: { id: "objectShare.workspaceLevel.inherited" },
|
|
24
29
|
granteeYou: { id: "objectShare.grantee.you" },
|
|
25
30
|
adminTagLabel: { id: "objectShare.adminTag.label" },
|
|
26
31
|
adminTagTooltip: { id: "objectShare.adminTag.tooltip" },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type IAvailableAccessGrantee, type IGranularAccessGrantee, type IObjectAccessList, type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
-
import type {
|
|
2
|
+
import type { GeneralAccessValue } from "@gooddata/sdk-ui-kit";
|
|
3
|
+
import type { IGranteeIdentityFacts, IObjectShareGrantee, ISelfIdentity, ObjectSharePermissionLevel } from "./objectShareController.types.js";
|
|
3
4
|
import type { IObjectShareLabel } from "./types.js";
|
|
4
5
|
/** Stable row id shared by grantee rows and picker options: `user:<ref>` / `group:<ref>`. */
|
|
5
6
|
export declare function granteeId(kind: "user" | "group", ref: ObjRef): string;
|
|
@@ -14,7 +15,7 @@ export declare function userIdentityFacts(ref: ObjRef, name: string | undefined,
|
|
|
14
15
|
export declare function groupNameFact(ref: ObjRef, name: string | undefined): string | undefined;
|
|
15
16
|
/** Identity facts for a listing/picker assignee — {@link userIdentityFacts} for users, a name fact for groups. */
|
|
16
17
|
export declare function assigneeIdentityFacts(assignee: IAvailableAccessGrantee): IGranteeIdentityFacts;
|
|
17
|
-
/** Display pair
|
|
18
|
+
/** Display pair, falling back: name + email → name + userID → email + userID → userID. */
|
|
18
19
|
export declare function userDisplayPair(facts: IGranteeIdentityFacts, userId: string): {
|
|
19
20
|
name: string;
|
|
20
21
|
email?: string;
|
|
@@ -24,18 +25,95 @@ export declare function granteeDisplayPair(grantee: IObjectShareGrantee): {
|
|
|
24
25
|
name: string;
|
|
25
26
|
email?: string;
|
|
26
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Deterministic display order for grantee rows — the backend returns them
|
|
30
|
+
* unsorted (and in an order that shuffles across reloads). Own row first, then
|
|
31
|
+
* groups, then users; within each, case-insensitive by display name with the
|
|
32
|
+
* grantee id as a stable tiebreaker so equal names don't reshuffle. Returns a
|
|
33
|
+
* new array; the input is not mutated.
|
|
34
|
+
*/
|
|
35
|
+
export declare function sortGrantees(grantees: readonly IObjectShareGrantee[]): IObjectShareGrantee[];
|
|
36
|
+
/**
|
|
37
|
+
* Deterministic display order for an attribute's labels — the backend returns
|
|
38
|
+
* display forms in an order that isn't guaranteed stable. Primary (key) label
|
|
39
|
+
* first, then the rest case-insensitive by title with the label id as a stable
|
|
40
|
+
* tiebreaker. Shared by the detail-page labels popup and the share dialog's
|
|
41
|
+
* label-access checklist so the two never disagree. Returns a new array; the
|
|
42
|
+
* input is not mutated.
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function sortShareableLabels(labels: readonly IObjectShareLabel[]): IObjectShareLabel[];
|
|
27
47
|
/** Case-insensitive match of an assignee against the picker query (name, or email for users). */
|
|
28
48
|
export declare function assigneeMatchesQuery(assignee: IAvailableAccessGrantee, query: string): boolean;
|
|
49
|
+
/** The strongest permission level present, or undefined when none. */
|
|
50
|
+
export declare function strongestLevel(permissions: readonly string[]): ObjectSharePermissionLevel | undefined;
|
|
29
51
|
/** The row's directly-granted level — the strongest permission present, defaulting to VIEW. */
|
|
30
52
|
export declare function directLevel(permissions: readonly string[]): ObjectSharePermissionLevel;
|
|
53
|
+
/**
|
|
54
|
+
* Levels strictly above the given one, e.g. for disabling levels the caller can't
|
|
55
|
+
* grant. An undefined bound means "unknown" — nothing is above it, so no level is
|
|
56
|
+
* disabled.
|
|
57
|
+
*/
|
|
58
|
+
export declare function levelsAbove(level: ObjectSharePermissionLevel | undefined): ObjectSharePermissionLevel[];
|
|
59
|
+
/** Levels strictly below the given one, e.g. for disabling levels an inherited grant already exceeds. */
|
|
60
|
+
export declare function levelsBelow(level: ObjectSharePermissionLevel): ObjectSharePermissionLevel[];
|
|
31
61
|
/**
|
|
32
62
|
* The effective permission to surface as a warning, or undefined when the direct
|
|
33
|
-
* grant already covers it. Set only when the grantee *inherits*
|
|
34
|
-
* group)
|
|
63
|
+
* grant already covers it. Set only when the grantee *inherits* a level (e.g. via
|
|
64
|
+
* a group) above the directly-granted one — i.e. the effective access is higher
|
|
35
65
|
* than what the row's permission control shows.
|
|
36
66
|
*/
|
|
37
|
-
export declare function effectivePermissionAbove(direct: ObjectSharePermissionLevel,
|
|
67
|
+
export declare function effectivePermissionAbove(direct: ObjectSharePermissionLevel, inheritedLevel: ObjectSharePermissionLevel | undefined): ObjectSharePermissionLevel | undefined;
|
|
38
68
|
export declare function granteesFromAccessList(list: IObjectAccessList | undefined): IObjectShareGrantee[];
|
|
69
|
+
/**
|
|
70
|
+
* A transient edit overlaid on a fetched grantee row (keyed by grantee id in
|
|
71
|
+
* {@link mergeGrantees}). The pending-guard keeps at most one edit in flight per id.
|
|
72
|
+
* A pending edit that superseded an already-COMMITTED entry (an added row, an
|
|
73
|
+
* earlier level change) carries it as `settled`, because the fetched base no longer
|
|
74
|
+
* holds that row's last-settled state: failure restores `settled`, success drops it.
|
|
75
|
+
* With no `settled`, failure deletes the entry, reverting to the fetched row.
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
export type GranteeEdit = {
|
|
80
|
+
kind: "level";
|
|
81
|
+
level: ObjectSharePermissionLevel;
|
|
82
|
+
pending: boolean;
|
|
83
|
+
settled?: GranteeEdit;
|
|
84
|
+
} | {
|
|
85
|
+
kind: "added";
|
|
86
|
+
grantee: IObjectShareGrantee;
|
|
87
|
+
pending: boolean;
|
|
88
|
+
settled?: GranteeEdit;
|
|
89
|
+
} | {
|
|
90
|
+
kind: "removed";
|
|
91
|
+
pending: boolean;
|
|
92
|
+
settled?: GranteeEdit;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Transient edit of the all-workspace-users rule (general access + its level),
|
|
96
|
+
* overlaid on the fetched rule state in the hook. Same lifecycle and `settled`
|
|
97
|
+
* semantics as {@link GranteeEdit}, one edit in flight at a time.
|
|
98
|
+
*
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
export interface IRuleEdit {
|
|
102
|
+
generalAccess: GeneralAccessValue;
|
|
103
|
+
level: ObjectSharePermissionLevel;
|
|
104
|
+
pending: boolean;
|
|
105
|
+
/** The committed rule edit this pending one superseded; restored on failure. */
|
|
106
|
+
settled?: IRuleEdit;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Pure composition of the fetched base with the transient overlay — the hook's
|
|
110
|
+
* `grantees` derive from this with no effect and no mirrored state. Marks the
|
|
111
|
+
* caller's own row via `selfId`, backfilling its facts from `selfIdentity` (the
|
|
112
|
+
* self row is absent from the grant list by design). Input arrays are not mutated.
|
|
113
|
+
*
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
export declare function mergeGrantees(base: readonly IObjectShareGrantee[], edits: Readonly<Record<string, GranteeEdit>>, selfId: string | undefined, selfIdentity: ISelfIdentity | undefined): IObjectShareGrantee[];
|
|
39
117
|
export declare function toGranularGrantee(kind: "user" | "group", granteeRef: ObjRef, level: ObjectSharePermissionLevel | "none"): IGranularAccessGrantee;
|
|
40
118
|
/**
|
|
41
119
|
* The principal a label-scope reconcile applies to: a named user/group, or the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectShareController.helpers.d.ts","sourceRoot":"","sources":["../../src/share/objectShareController.helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,MAAM,EAId,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"objectShareController.helpers.d.ts","sourceRoot":"","sources":["../../src/share/objectShareController.helpers.ts"],"names":[],"mappings":"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"}
|