@gooddata/sdk-ui-ext 11.51.0-alpha.1 → 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
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { IObjectPermissionsObject } from "@gooddata/sdk-backend-spi";
|
|
2
|
+
import { type IObjectShareControllerActions, type IObjectShareControllerState, type IObjectShareGrantee, type ObjectSharePermissionLevel } from "./objectShareController.types.js";
|
|
3
|
+
import type { IObjectAccessSummary, IObjectShareLabel } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* The presentational state {@link ObjectShareDialog} renders from. All logic —
|
|
6
|
+
* controller ownership, the self-restriction confirm flow, open/close and the
|
|
7
|
+
* mutation gating — lives here; the component maps this to JSX and holds no logic
|
|
8
|
+
* of its own.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export interface IObjectShareDialogViewModel {
|
|
13
|
+
/** The controller's current state, read by the component to build its rows and props. */
|
|
14
|
+
state: IObjectShareControllerState;
|
|
15
|
+
/** The controller's mutation actions, wired to the rendered controls. */
|
|
16
|
+
actions: IObjectShareControllerActions;
|
|
17
|
+
/** Whether the main share view (grantee list + general access) is visible. */
|
|
18
|
+
isShareViewOpen: boolean;
|
|
19
|
+
/** Whether the add-grantee sub-dialog is visible. */
|
|
20
|
+
isAddGranteeOpen: boolean;
|
|
21
|
+
/** Whether the general-access RESTRICTED↔WORKSPACE confirm is visible. */
|
|
22
|
+
isGeneralAccessConfirmOpen: boolean;
|
|
23
|
+
/** Whether the "Restrict your access?" self-restriction confirm is visible. */
|
|
24
|
+
isSelfRestrictConfirmOpen: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether access-changing controls may be used. False until the list has loaded
|
|
27
|
+
* AND per-label scope resolved: before then the controller reports a placeholder
|
|
28
|
+
* (empty grantees + RESTRICTED, scope assumed-all), so a write would diff against
|
|
29
|
+
* a false state — skipping grants or revoking the wrong labels.
|
|
30
|
+
*/
|
|
31
|
+
isMutable: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Whether the dialog is still in its initial load — the access list or the
|
|
34
|
+
* session's first label-scope resolution in flight. The component shows
|
|
35
|
+
* skeletons in place of the grantee list and general access, so the reveal
|
|
36
|
+
* happens once, with controls already actionable (or legitimately disabled
|
|
37
|
+
* after a failed resolution). Mid-session re-probes don't turn it back on.
|
|
38
|
+
*/
|
|
39
|
+
isLoading: boolean;
|
|
40
|
+
/** The controller's workspace-rule menu policy, forwarded (see `IObjectShareControllerState`). */
|
|
41
|
+
workspaceDisabledLevels: ObjectSharePermissionLevel[] | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* The controller's self-managed-row policy resolved per row: its disabled levels
|
|
44
|
+
* for the signed-in user's own sole grant, undefined for every other row.
|
|
45
|
+
*/
|
|
46
|
+
rowDisabledLevels: (grantee: IObjectShareGrantee) => ObjectSharePermissionLevel[] | undefined;
|
|
47
|
+
/** Close the whole dialog, discarding any staged self-restriction. */
|
|
48
|
+
onClose: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Handle a grantee row's permission change. The signed-in user's own sole grant is
|
|
51
|
+
* staged for the self-restriction confirm; every other row commits immediately.
|
|
52
|
+
*/
|
|
53
|
+
onRowPermissionChange: (grantee: IObjectShareGrantee, level: ObjectSharePermissionLevel) => void;
|
|
54
|
+
/** Handle a grantee row's remove. Same self-restriction routing as {@link onRowPermissionChange}. */
|
|
55
|
+
onRowRemove: (grantee: IObjectShareGrantee) => void;
|
|
56
|
+
/** Dismiss the self-restriction confirm, leaving the user's own access unchanged. */
|
|
57
|
+
onSelfRestrictCancel: () => void;
|
|
58
|
+
/** Apply the staged self-restriction — lower the user's own level, or remove their grant. */
|
|
59
|
+
onSelfRestrictConfirm: () => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Inputs to {@link useObjectShareDialog} — the subset of {@link ObjectShareDialog}'s
|
|
63
|
+
* props the presentation logic needs. The component owns the public prop interface
|
|
64
|
+
* and forwards these through.
|
|
65
|
+
*/
|
|
66
|
+
interface IUseObjectShareDialogParams {
|
|
67
|
+
/** Object whose access is managed. Fixed for the mount — remount for a new target. */
|
|
68
|
+
target: IObjectPermissionsObject | undefined;
|
|
69
|
+
/** Called when the dialog requests to close; closing unmounts the session, discarding its state. */
|
|
70
|
+
onClose: () => void;
|
|
71
|
+
/** Fires with the current access summary whenever the displayed access changes. */
|
|
72
|
+
onSummaryChange?: (summary: IObjectAccessSummary) => void;
|
|
73
|
+
/** Attribute labels enabling the per-grantee scope picker; forwarded to the controller. */
|
|
74
|
+
labels?: IObjectShareLabel[];
|
|
75
|
+
/** Whether the object's labels are still loading (gates mutations); forwarded to the controller. */
|
|
76
|
+
labelsLoading?: boolean;
|
|
77
|
+
/** Whether the object's labels failed to load (gates mutations); forwarded to the controller. */
|
|
78
|
+
labelsError?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Owns everything {@link ObjectShareDialog} needs to render for one dialog session:
|
|
82
|
+
* the controller, the self-restriction confirm flow, the mutation-gating flags, and
|
|
83
|
+
* the outward summary synchronization. Returns a flat view model the component
|
|
84
|
+
* renders — no JSX and no rendering logic here.
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export declare function useObjectShareDialog({ target, onClose, onSummaryChange, labels, labelsLoading, labelsError }: IUseObjectShareDialogParams): IObjectShareDialogViewModel;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=useObjectShareDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useObjectShareDialog.d.ts","sourceRoot":"","sources":["../../src/share/useObjectShareDialog.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EACH,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAClC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAY1E;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IACxC,yFAAyF;IACzF,KAAK,EAAE,2BAA2B,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,6BAA6B,CAAC;IAEvC,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;IACzB,qDAAqD;IACrD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA0E;IAC1E,0BAA0B,EAAE,OAAO,CAAC;IACpC,+EAA+E;IAC/E,yBAAyB,EAAE,OAAO,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB,kGAAkG;IAClG,uBAAuB,EAAE,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAClE;;;OAGG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,0BAA0B,EAAE,GAAG,SAAS,CAAC;IAE9F,sEAAsE;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,qBAAqB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IACjG,qGAAqG;IACrG,WAAW,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,+FAA6F;IAC7F,qBAAqB,EAAE,MAAM,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,UAAU,2BAA2B;IACjC,wFAAsF;IACtF,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,oGAAoG;IACpG,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D,2FAA2F;IAC3F,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,oGAAoG;IACpG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iGAAiG;IACjG,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,MAAM,EACN,OAAO,EACP,eAAe,EACf,MAAM,EACN,aAAa,EACb,WAAW,EACd,EAAE,2BAA2B,GAAG,2BAA2B,CAwF3D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useObjectShareController } from "./useObjectShareController.js";
|
|
4
|
+
/**
|
|
5
|
+
* Owns everything {@link ObjectShareDialog} needs to render for one dialog session:
|
|
6
|
+
* the controller, the self-restriction confirm flow, the mutation-gating flags, and
|
|
7
|
+
* the outward summary synchronization. Returns a flat view model the component
|
|
8
|
+
* renders — no JSX and no rendering logic here.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export function useObjectShareDialog({ target, onClose, onSummaryChange, labels, labelsLoading, labelsError, }) {
|
|
13
|
+
const { state, actions } = useObjectShareController(target, { labels, labelsError, labelsLoading });
|
|
14
|
+
const [pendingSelfChange, setPendingSelfChange] = useState(undefined);
|
|
15
|
+
// Synchronize the displayed access summary out to the consumer — the legitimate
|
|
16
|
+
// effect kind (notifying an external system of a change). `state.summary` is
|
|
17
|
+
// content-stable, so this fires exactly when the displayed access changes: on
|
|
18
|
+
// load, and after each summary-affecting mutation.
|
|
19
|
+
//
|
|
20
|
+
// Deliberately OPTIMISTIC: the summary is emitted as soon as an edit applies,
|
|
21
|
+
// not when it settles. A failure while the dialog is open self-corrects (the
|
|
22
|
+
// overlay reverts and the corrected summary re-emits); a failure landing after
|
|
23
|
+
// the dialog closed leaves the consumer with the optimistic value — an accepted
|
|
24
|
+
// edge case, decided over settled-only emission and refetch-on-close.
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (state.summary) {
|
|
27
|
+
onSummaryChange?.(state.summary);
|
|
28
|
+
}
|
|
29
|
+
}, [state.summary, onSummaryChange]);
|
|
30
|
+
// A row belongs to the signed-in user's own sole grant when the controller has
|
|
31
|
+
// classified it as self-managed — those changes route through the confirm.
|
|
32
|
+
const onRowPermissionChange = useCallback((grantee, level) => {
|
|
33
|
+
if (state.selfManagedGranteeId === grantee.id) {
|
|
34
|
+
if (level !== grantee.level) {
|
|
35
|
+
setPendingSelfChange({ granteeId: grantee.id, level });
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
void actions.changePermissionLevel(grantee.id, level);
|
|
40
|
+
}, [state.selfManagedGranteeId, actions]);
|
|
41
|
+
const onRowRemove = useCallback((grantee) => {
|
|
42
|
+
if (state.selfManagedGranteeId === grantee.id) {
|
|
43
|
+
setPendingSelfChange({ granteeId: grantee.id, level: "none" });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
void actions.removeGrantee(grantee.id);
|
|
47
|
+
}, [state.selfManagedGranteeId, actions]);
|
|
48
|
+
const onSelfRestrictConfirm = useCallback(() => {
|
|
49
|
+
if (!pendingSelfChange) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const { granteeId, level } = pendingSelfChange;
|
|
53
|
+
setPendingSelfChange(undefined);
|
|
54
|
+
if (level === "none") {
|
|
55
|
+
void actions.removeGrantee(granteeId);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
void actions.changePermissionLevel(granteeId, level);
|
|
59
|
+
}
|
|
60
|
+
}, [pendingSelfChange, actions]);
|
|
61
|
+
const onSelfRestrictCancel = useCallback(() => setPendingSelfChange(undefined), []);
|
|
62
|
+
const rowDisabledLevels = useCallback((grantee) => state.selfManagedGranteeId === grantee.id ? state.selfManagedDisabledLevels : undefined, [state.selfManagedGranteeId, state.selfManagedDisabledLevels]);
|
|
63
|
+
const isMutable = state.status === "success" && state.labelsResolved;
|
|
64
|
+
const isLoading = state.status === "loading" || state.labelsInitializing;
|
|
65
|
+
return {
|
|
66
|
+
state,
|
|
67
|
+
actions,
|
|
68
|
+
isShareViewOpen: state.subview === "main",
|
|
69
|
+
isAddGranteeOpen: state.subview === "addGrantee",
|
|
70
|
+
isGeneralAccessConfirmOpen: !!state.pendingGeneralAccess,
|
|
71
|
+
isSelfRestrictConfirmOpen: pendingSelfChange !== undefined,
|
|
72
|
+
isMutable,
|
|
73
|
+
isLoading,
|
|
74
|
+
workspaceDisabledLevels: state.workspaceDisabledLevels,
|
|
75
|
+
rowDisabledLevels,
|
|
76
|
+
onClose,
|
|
77
|
+
onRowPermissionChange,
|
|
78
|
+
onRowRemove,
|
|
79
|
+
onSelfRestrictCancel,
|
|
80
|
+
onSelfRestrictConfirm,
|
|
81
|
+
};
|
|
82
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-ui-ext",
|
|
3
|
-
"version": "11.51.0-alpha.
|
|
3
|
+
"version": "11.51.0-alpha.2",
|
|
4
4
|
"description": "GoodData.UI SDK - Extensions",
|
|
5
5
|
"license": "LicenseRef-LICENSE",
|
|
6
6
|
"author": "GoodData Corporation",
|
|
@@ -63,20 +63,20 @@
|
|
|
63
63
|
"ts-invariant": "0.10.3",
|
|
64
64
|
"tslib": "2.8.1",
|
|
65
65
|
"uuid": "11.1.1",
|
|
66
|
-
"@gooddata/sdk-backend-base": "11.51.0-alpha.
|
|
67
|
-
"@gooddata/sdk-backend-spi": "11.51.0-alpha.
|
|
68
|
-
"@gooddata/sdk-embedding": "11.51.0-alpha.
|
|
69
|
-
"@gooddata/sdk-model": "11.51.0-alpha.
|
|
70
|
-
"@gooddata/sdk-ui": "11.51.0-alpha.
|
|
71
|
-
"@gooddata/sdk-ui-charts": "11.51.0-alpha.
|
|
72
|
-
"@gooddata/sdk-ui-
|
|
73
|
-
"@gooddata/sdk-ui-
|
|
74
|
-
"@gooddata/sdk-ui-kit": "11.51.0-alpha.
|
|
75
|
-
"@gooddata/sdk-ui-pivot": "11.51.0-alpha.
|
|
76
|
-
"@gooddata/sdk-ui-
|
|
77
|
-
"@gooddata/sdk-ui-
|
|
78
|
-
"@gooddata/sdk-ui-vis-commons": "11.51.0-alpha.
|
|
79
|
-
"@gooddata/util": "11.51.0-alpha.
|
|
66
|
+
"@gooddata/sdk-backend-base": "11.51.0-alpha.2",
|
|
67
|
+
"@gooddata/sdk-backend-spi": "11.51.0-alpha.2",
|
|
68
|
+
"@gooddata/sdk-embedding": "11.51.0-alpha.2",
|
|
69
|
+
"@gooddata/sdk-model": "11.51.0-alpha.2",
|
|
70
|
+
"@gooddata/sdk-ui": "11.51.0-alpha.2",
|
|
71
|
+
"@gooddata/sdk-ui-charts": "11.51.0-alpha.2",
|
|
72
|
+
"@gooddata/sdk-ui-geo": "11.51.0-alpha.2",
|
|
73
|
+
"@gooddata/sdk-ui-filters": "11.51.0-alpha.2",
|
|
74
|
+
"@gooddata/sdk-ui-kit": "11.51.0-alpha.2",
|
|
75
|
+
"@gooddata/sdk-ui-pivot": "11.51.0-alpha.2",
|
|
76
|
+
"@gooddata/sdk-ui-theme-provider": "11.51.0-alpha.2",
|
|
77
|
+
"@gooddata/sdk-ui-semantic-search": "11.51.0-alpha.2",
|
|
78
|
+
"@gooddata/sdk-ui-vis-commons": "11.51.0-alpha.2",
|
|
79
|
+
"@gooddata/util": "11.51.0-alpha.2"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@microsoft/api-documenter": "^7.17.0",
|
|
@@ -124,12 +124,12 @@
|
|
|
124
124
|
"typescript": "5.9.3",
|
|
125
125
|
"vitest": "4.1.8",
|
|
126
126
|
"vitest-dom": "0.1.1",
|
|
127
|
-
"@gooddata/
|
|
128
|
-
"@gooddata/
|
|
129
|
-
"@gooddata/
|
|
130
|
-
"@gooddata/
|
|
131
|
-
"@gooddata/
|
|
132
|
-
"@gooddata/
|
|
127
|
+
"@gooddata/eslint-config": "11.51.0-alpha.2",
|
|
128
|
+
"@gooddata/i18n-toolkit": "11.51.0-alpha.2",
|
|
129
|
+
"@gooddata/oxlint-config": "11.51.0-alpha.2",
|
|
130
|
+
"@gooddata/reference-workspace": "11.51.0-alpha.2",
|
|
131
|
+
"@gooddata/stylelint-config": "11.51.0-alpha.2",
|
|
132
|
+
"@gooddata/sdk-backend-mockingbird": "11.51.0-alpha.2"
|
|
133
133
|
},
|
|
134
134
|
"peerDependencies": {
|
|
135
135
|
"react": "^18.0.0 || ^19.0.0",
|