@gooddata/sdk-ui-catalog 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/esm/catalogDetail/share/CatalogDetailAccessRow.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogDetailAccessRow.js +9 -5
- package/esm/catalogDetail/share/CatalogDetailLabels.d.ts +2 -2
- package/esm/catalogDetail/share/CatalogDetailLabels.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogDetailLabels.js +6 -2
- package/esm/catalogDetail/share/CatalogItemAccessRow.d.ts +5 -3
- package/esm/catalogDetail/share/CatalogItemAccessRow.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogItemAccessRow.js +12 -10
- package/esm/catalogDetail/share/CatalogItemShareDialog.d.ts +4 -4
- package/esm/catalogDetail/share/CatalogItemShareDialog.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogItemShareDialog.js +6 -12
- package/esm/catalogDetail/share/CatalogItemShareDialogInner.d.ts +4 -3
- package/esm/catalogDetail/share/CatalogItemShareDialogInner.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogItemShareDialogInner.js +6 -8
- package/esm/catalogDetail/share/CatalogItemShareProvider.d.ts +36 -21
- package/esm/catalogDetail/share/CatalogItemShareProvider.d.ts.map +1 -1
- package/esm/catalogDetail/share/CatalogItemShareProvider.js +80 -47
- package/esm/catalogDetail/share/messages.d.ts +6 -0
- package/esm/catalogDetail/share/messages.d.ts.map +1 -1
- package/esm/catalogDetail/share/messages.js +2 -0
- package/esm/catalogDetail/share/useShareableLabels.d.ts +1 -1
- package/esm/catalogDetail/share/useShareableLabels.d.ts.map +1 -1
- package/esm/catalogDetail/share/useShareableLabels.js +7 -2
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +8 -0
- package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +9 -1
- package/package.json +15 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogDetailAccessRow.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailAccessRow.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CatalogDetailAccessRow.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailAccessRow.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAYjE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IACzC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AASD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,4BAA4B,2CA8CvF"}
|
|
@@ -5,6 +5,12 @@ import { UiIcon } from "@gooddata/sdk-ui-kit";
|
|
|
5
5
|
import { catalogDetailAccessRow, catalogDetailAccessRowSharedLink, catalogDetailAccessRowState, } from "../../automation/testIds.js";
|
|
6
6
|
import { CatalogDetailContentRow } from "../CatalogDetailContentRow.js";
|
|
7
7
|
import { shareMessages } from "./messages.js";
|
|
8
|
+
// Chip copy for each workspace-wide access level.
|
|
9
|
+
const WORKSPACE_ACCESS_ROW_MESSAGE = {
|
|
10
|
+
EDIT: shareMessages.accessRowWorkspaceEdit,
|
|
11
|
+
SHARE: shareMessages.accessRowWorkspaceShare,
|
|
12
|
+
VIEW: shareMessages.accessRowWorkspaceView,
|
|
13
|
+
};
|
|
8
14
|
/**
|
|
9
15
|
* Inline metadata row showing the current access state. Composed of two chips:
|
|
10
16
|
*
|
|
@@ -17,11 +23,9 @@ import { shareMessages } from "./messages.js";
|
|
|
17
23
|
export function CatalogDetailAccessRow({ summary, onOpen }) {
|
|
18
24
|
const intl = useIntl();
|
|
19
25
|
const { generalAccess, workspaceLevel, granteeCount } = summary;
|
|
20
|
-
const stateText = generalAccess === "RESTRICTED"
|
|
21
|
-
?
|
|
22
|
-
: workspaceLevel
|
|
23
|
-
? intl.formatMessage(shareMessages.accessRowWorkspaceShare)
|
|
24
|
-
: intl.formatMessage(shareMessages.accessRowWorkspaceView);
|
|
26
|
+
const stateText = intl.formatMessage(generalAccess === "RESTRICTED"
|
|
27
|
+
? shareMessages.accessRowRestricted
|
|
28
|
+
: WORKSPACE_ACCESS_ROW_MESSAGE[workspaceLevel]);
|
|
25
29
|
const stateIcon = generalAccess === "RESTRICTED" ? "lock" : "building";
|
|
26
30
|
return (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { ...shareMessages.accessRowLabel }), content: _jsxs("div", { className: "gd-analytics-catalog-detail__access-row", "data-testid": catalogDetailAccessRow, children: [
|
|
27
31
|
_jsxs("span", { className: "gd-analytics-catalog-detail__access-row__chip", "data-testid": catalogDetailAccessRowState, children: [
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type IObjectShareLabel } from "@gooddata/sdk-ui-ext";
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
5
|
export interface ICatalogDetailLabelsProps {
|
|
6
|
-
/** Labels of the attribute,
|
|
6
|
+
/** Labels of the attribute, already in display order (primary first, then alphabetical). */
|
|
7
7
|
labels: IObjectShareLabel[];
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogDetailLabels.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailLabels.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"CatalogDetailLabels.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailLabels.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,sBAAsB,CAAC;AAWnF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC,4FAA4F;IAC5F,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,EAAE,yBAAyB,kDA6DxE"}
|
|
@@ -2,6 +2,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { useIntl } from "react-intl";
|
|
5
|
+
import { sortShareableLabels } from "@gooddata/sdk-ui-ext";
|
|
5
6
|
import { UiLabelsList, UiPopover } from "@gooddata/sdk-ui-kit";
|
|
6
7
|
import { catalogDetailLabels, catalogDetailLabelsList, catalogDetailLabelsTrigger, } from "../../automation/testIds.js";
|
|
7
8
|
import { labelsMessages } from "./messages.js";
|
|
@@ -14,8 +15,11 @@ import { labelsMessages } from "./messages.js";
|
|
|
14
15
|
*/
|
|
15
16
|
export function CatalogDetailLabels({ labels }) {
|
|
16
17
|
const intl = useIntl();
|
|
17
|
-
//
|
|
18
|
-
|
|
18
|
+
// Deterministic display order (primary first, then alphabetical) via the
|
|
19
|
+
// shared helper — the same order the share dialog's label-access checklist
|
|
20
|
+
// uses, so the two lists never disagree. Sorting here as well keeps the
|
|
21
|
+
// component robust to an unsorted input.
|
|
22
|
+
const ordered = useMemo(() => sortShareableLabels(labels), [labels]);
|
|
19
23
|
const items = useMemo(() => ordered.map((label) => ({
|
|
20
24
|
id: label.id,
|
|
21
25
|
label: label.title,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inline access row for the metadata tab, wired to the share context. Renders the
|
|
3
|
-
* current access summary,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* current access summary, a placeholder while it loads, or an error note when the
|
|
4
|
+
* summary fetch failed (the row stays in both cases because Share is still
|
|
5
|
+
* reachable for the object — opening the dialog fetches again and fills the
|
|
6
|
+
* summary in). Renders nothing when sharing is unavailable. Self-subscribing so
|
|
7
|
+
* it re-renders on access edits without re-rendering the tab.
|
|
6
8
|
*
|
|
7
9
|
* @internal
|
|
8
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogItemAccessRow.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemAccessRow.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CatalogItemAccessRow.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemAccessRow.tsx"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,mDA2BnC"}
|
|
@@ -5,26 +5,28 @@ import { UiSkeleton } from "@gooddata/sdk-ui-kit";
|
|
|
5
5
|
import { CatalogDetailContentRow } from "../CatalogDetailContentRow.js";
|
|
6
6
|
import { CatalogDetailAccessRow } from "./CatalogDetailAccessRow.js";
|
|
7
7
|
import { useCatalogItemShareActions, useCatalogItemShareState } from "./CatalogItemShareProvider.js";
|
|
8
|
+
import { shareMessages } from "./messages.js";
|
|
8
9
|
/**
|
|
9
10
|
* Inline access row for the metadata tab, wired to the share context. Renders the
|
|
10
|
-
* current access summary,
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* current access summary, a placeholder while it loads, or an error note when the
|
|
12
|
+
* summary fetch failed (the row stays in both cases because Share is still
|
|
13
|
+
* reachable for the object — opening the dialog fetches again and fills the
|
|
14
|
+
* summary in). Renders nothing when sharing is unavailable. Self-subscribing so
|
|
15
|
+
* it re-renders on access edits without re-rendering the tab.
|
|
13
16
|
*
|
|
14
17
|
* @internal
|
|
15
18
|
*/
|
|
16
19
|
export function CatalogItemAccessRow() {
|
|
17
|
-
const { active,
|
|
20
|
+
const { active, summary, summaryError } = useCatalogItemShareState();
|
|
18
21
|
const { open } = useCatalogItemShareActions();
|
|
19
|
-
if (!active
|
|
22
|
+
if (!active) {
|
|
20
23
|
return null;
|
|
21
24
|
}
|
|
22
|
-
const summary = controller.state.summary;
|
|
23
25
|
if (summary) {
|
|
24
26
|
return _jsx(CatalogDetailAccessRow, { summary: summary, onOpen: open });
|
|
25
27
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
return (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { ...shareMessages.accessRowLabel }), content: summaryError ? (
|
|
29
|
+
// role="alert": the error replaces the skeleton after an async
|
|
30
|
+
// failure — it must be announced, not just inserted.
|
|
31
|
+
_jsx("span", { role: "alert", children: _jsx(FormattedMessage, { ...shareMessages.accessRowError }) })) : (_jsx(UiSkeleton, { itemWidth: 200, itemHeight: 20 })) }));
|
|
30
32
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lazy boundary for the catalog item's share dialog.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Lazy boundary for the catalog item's share dialog. Mounted only while the dialog
|
|
3
|
+
* is open — one mount is one dialog session, and unmounting (close or navigation)
|
|
4
|
+
* discards the session's transient state. Reopening remounts the component; the
|
|
5
|
+
* chunk itself stays cached by the browser after the first open.
|
|
6
6
|
*
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogItemShareDialog.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareDialog.tsx"],"names":[],"mappings":"AAaA;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CatalogItemShareDialog.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareDialog.tsx"],"names":[],"mappings":"AAaA;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,mDAYrC"}
|
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
|
-
import { Suspense, lazy
|
|
3
|
+
import { Suspense, lazy } from "react";
|
|
4
4
|
import { useCatalogItemShareState } from "./CatalogItemShareProvider.js";
|
|
5
5
|
// Code-split the dialog (and the heavy kit dialog chrome it pulls from
|
|
6
6
|
// @gooddata/sdk-ui-ext) into its own chunk, loaded on first open rather than with
|
|
7
7
|
// the catalog bundle. The always-visible inline access row stays in the main chunk.
|
|
8
8
|
const CatalogItemShareDialogInner = lazy(() => import("./CatalogItemShareDialogInner.js").then((m) => ({ default: m.CatalogItemShareDialogInner })));
|
|
9
9
|
/**
|
|
10
|
-
* Lazy boundary for the catalog item's share dialog.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Lazy boundary for the catalog item's share dialog. Mounted only while the dialog
|
|
11
|
+
* is open — one mount is one dialog session, and unmounting (close or navigation)
|
|
12
|
+
* discards the session's transient state. Reopening remounts the component; the
|
|
13
|
+
* chunk itself stays cached by the browser after the first open.
|
|
14
14
|
*
|
|
15
15
|
* @internal
|
|
16
16
|
*/
|
|
17
17
|
export function CatalogItemShareDialog() {
|
|
18
18
|
const { active, isOpen } = useCatalogItemShareState();
|
|
19
|
-
|
|
20
|
-
// the chunk or lose the dialog's transient state.
|
|
21
|
-
const [everOpened, setEverOpened] = useState(false);
|
|
22
|
-
if (isOpen && !everOpened) {
|
|
23
|
-
setEverOpened(true);
|
|
24
|
-
}
|
|
25
|
-
if (!active || !everOpened) {
|
|
19
|
+
if (!active || !isOpen) {
|
|
26
20
|
return null;
|
|
27
21
|
}
|
|
28
22
|
return (_jsx(Suspense, { fallback: null, children: _jsx(CatalogItemShareDialogInner, {}) }));
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The connected share dialog, split into its own module so it (and the heavy kit
|
|
3
3
|
* dialog chrome it pulls from `@gooddata/sdk-ui-ext`) is code-split out of the main
|
|
4
|
-
* catalog chunk and loaded only when the dialog is first opened.
|
|
5
|
-
*
|
|
4
|
+
* catalog chunk and loaded only when the dialog is first opened. Mounted per dialog
|
|
5
|
+
* session (see {@link CatalogItemShareDialog}); it reports summary changes back to
|
|
6
|
+
* the provider so the inline access row stays in sync without a refetch.
|
|
6
7
|
*
|
|
7
8
|
* @internal
|
|
8
9
|
*/
|
|
9
|
-
export declare function CatalogItemShareDialogInner(): import("react/jsx-runtime").JSX.Element
|
|
10
|
+
export declare function CatalogItemShareDialogInner(): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
//# sourceMappingURL=CatalogItemShareDialogInner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogItemShareDialogInner.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareDialogInner.tsx"],"names":[],"mappings":"AAMA
|
|
1
|
+
{"version":3,"file":"CatalogItemShareDialogInner.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareDialogInner.tsx"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,4CAgB1C"}
|
|
@@ -5,16 +5,14 @@ import { useCatalogItemShareActions, useCatalogItemShareState } from "./CatalogI
|
|
|
5
5
|
/**
|
|
6
6
|
* The connected share dialog, split into its own module so it (and the heavy kit
|
|
7
7
|
* dialog chrome it pulls from `@gooddata/sdk-ui-ext`) is code-split out of the main
|
|
8
|
-
* catalog chunk and loaded only when the dialog is first opened.
|
|
9
|
-
*
|
|
8
|
+
* catalog chunk and loaded only when the dialog is first opened. Mounted per dialog
|
|
9
|
+
* session (see {@link CatalogItemShareDialog}); it reports summary changes back to
|
|
10
|
+
* the provider so the inline access row stays in sync without a refetch.
|
|
10
11
|
*
|
|
11
12
|
* @internal
|
|
12
13
|
*/
|
|
13
14
|
export function CatalogItemShareDialogInner() {
|
|
14
|
-
const {
|
|
15
|
-
const { close } = useCatalogItemShareActions();
|
|
16
|
-
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
return (_jsx(ObjectShareDialog, { target: target, objectTitle: objectTitle, isOpen: isOpen, onClose: close, labelsLoading: labelsLoading, controller: controller }));
|
|
15
|
+
const { target, objectTitle, labels } = useCatalogItemShareState();
|
|
16
|
+
const { close, onSummaryChange } = useCatalogItemShareActions();
|
|
17
|
+
return (_jsx(ObjectShareDialog, { target: target, objectTitle: objectTitle, isOpen: true, onClose: close, labels: labels.labels, labelsError: labels.error, labelsLoading: labels.loading, onSummaryChange: onSummaryChange }));
|
|
20
18
|
}
|
|
@@ -1,32 +1,45 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type { IObjectPermissionsObject } from "@gooddata/sdk-backend-spi";
|
|
3
|
-
import { type
|
|
3
|
+
import { type IObjectAccessSummary } from "@gooddata/sdk-ui-ext";
|
|
4
4
|
import type { ShareableCatalogItem } from "./types.js";
|
|
5
5
|
import type { IShareableLabels } from "./useShareableLabels.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Page-level share state for the catalog item: the latest known access summary and
|
|
8
|
+
* the dialog-open flag. `active` is false when the item can't be shared (flag off /
|
|
9
|
+
* not a shareable kind / permissions unavailable), so consumers can render nothing
|
|
10
|
+
* without conditional hooks.
|
|
11
11
|
*/
|
|
12
12
|
interface ICatalogItemShareState {
|
|
13
13
|
active: boolean;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Latest known access summary — seeded by the page-level fetch, then kept in
|
|
16
|
+
* sync by the open dialog's `onSummaryChange`. Undefined while loading.
|
|
17
|
+
*/
|
|
18
|
+
summary: IObjectAccessSummary | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the page-level summary fetch failed transiently (a definitive
|
|
21
|
+
* not-permissionable failure turns the whole feature inactive instead).
|
|
22
|
+
* Sharing stays offered — opening the dialog runs its own fetch, whose
|
|
23
|
+
* `onSummaryChange` report then fills the summary in.
|
|
24
|
+
*/
|
|
25
|
+
summaryError: boolean;
|
|
15
26
|
target: IObjectPermissionsObject | undefined;
|
|
16
27
|
objectTitle: string;
|
|
17
|
-
/** Whether the share dialog is open. */
|
|
28
|
+
/** Whether the share dialog is open (and should be mounted). */
|
|
18
29
|
isOpen: boolean;
|
|
19
|
-
/**
|
|
20
|
-
|
|
30
|
+
/** The item's labels bundle, forwarded to the dialog. */
|
|
31
|
+
labels: IShareableLabels;
|
|
21
32
|
}
|
|
22
33
|
/**
|
|
23
|
-
* Stable
|
|
24
|
-
*
|
|
34
|
+
* Stable share actions. Split from the state so an actions-only consumer (the
|
|
35
|
+
* Share button) never re-renders on a state tick.
|
|
25
36
|
*/
|
|
26
37
|
interface ICatalogItemShareActions {
|
|
27
38
|
active: boolean;
|
|
28
39
|
open: () => void;
|
|
29
40
|
close: () => void;
|
|
41
|
+
/** The dialog reports summary changes here, keeping the inline row in sync without refetching. */
|
|
42
|
+
onSummaryChange: (summary: IObjectAccessSummary) => void;
|
|
30
43
|
}
|
|
31
44
|
/**
|
|
32
45
|
* @internal
|
|
@@ -41,28 +54,30 @@ export interface ICatalogItemShareProviderProps {
|
|
|
41
54
|
children: ReactNode;
|
|
42
55
|
}
|
|
43
56
|
/**
|
|
44
|
-
* Owns the
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
57
|
+
* Owns the PAGE state of sharing for one catalog item: the initial access-summary
|
|
58
|
+
* fetch (the inline access row is visible before the dialog ever opens, so the page
|
|
59
|
+
* fetches its own summary) and the dialog-open flag. The dialog itself is a separate,
|
|
60
|
+
* session-scoped component — mounted only while open, owning its own controller and
|
|
61
|
+
* fetch — that reports summary changes back through `onSummaryChange`, so the row
|
|
62
|
+
* stays in sync with edits without a refetch.
|
|
49
63
|
*
|
|
50
|
-
* No-ops cleanly when the item can't be shared: the contexts then carry an
|
|
51
|
-
*
|
|
64
|
+
* No-ops cleanly when the item can't be shared: the contexts then carry an inactive
|
|
65
|
+
* value and the hooks below report `active: false`.
|
|
52
66
|
*
|
|
53
67
|
* @internal
|
|
54
68
|
*/
|
|
55
69
|
export declare function CatalogItemShareProvider({ shareableItem, target, labels, children }: ICatalogItemShareProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
56
70
|
/**
|
|
57
|
-
*
|
|
71
|
+
* Page share state (summary, open flag, dialog inputs) for the current catalog item.
|
|
58
72
|
* Reports `active: false` when sharing is unavailable.
|
|
59
73
|
*
|
|
60
74
|
* @internal
|
|
61
75
|
*/
|
|
62
76
|
export declare function useCatalogItemShareState(): ICatalogItemShareState;
|
|
63
77
|
/**
|
|
64
|
-
* Stable share actions (open/close the dialog) for the
|
|
65
|
-
* Reading this instead of the state keeps a consumer from
|
|
78
|
+
* Stable share actions (open/close the dialog, receive summary updates) for the
|
|
79
|
+
* current catalog item. Reading this instead of the state keeps a consumer from
|
|
80
|
+
* re-rendering on state ticks.
|
|
66
81
|
*
|
|
67
82
|
* @internal
|
|
68
83
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogItemShareProvider.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA6D,MAAM,OAAO,CAAC;AAElG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"CatalogItemShareProvider.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogItemShareProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA6D,MAAM,OAAO,CAAC;AAElG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAG1E,OAAO,EACH,KAAK,oBAAoB,EAG5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;GAKG;AACH,UAAU,sBAAsB;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,MAAM,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;GAGG;AACH,UAAU,wBAAwB;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,kGAAkG;IAClG,eAAe,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC5D;AAyBD;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC3C,+FAA+F;IAC/F,aAAa,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAChD,sDAAsD;IACtD,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7C,mFAAmF;IACnF,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,EACrC,aAAa,EACb,MAAM,EACN,MAAM,EACN,QAAQ,EACX,EAAE,8BAA8B,2CA2FhC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,sBAAsB,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,wBAAwB,CAErE"}
|
|
@@ -1,79 +1,111 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
3
|
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
5
|
+
import { accessListToSummary, isPermissionsNotAvailable, } from "@gooddata/sdk-ui-ext";
|
|
6
|
+
const NO_LABELS = { labels: [], loading: false, error: false };
|
|
5
7
|
const INACTIVE_STATE = {
|
|
6
8
|
active: false,
|
|
7
|
-
|
|
9
|
+
summary: undefined,
|
|
10
|
+
summaryError: false,
|
|
8
11
|
target: undefined,
|
|
9
12
|
objectTitle: "",
|
|
10
13
|
isOpen: false,
|
|
11
|
-
|
|
14
|
+
labels: NO_LABELS,
|
|
12
15
|
};
|
|
13
16
|
const noop = () => { };
|
|
14
|
-
const INACTIVE_ACTIONS = {
|
|
17
|
+
const INACTIVE_ACTIONS = {
|
|
18
|
+
active: false,
|
|
19
|
+
open: noop,
|
|
20
|
+
close: noop,
|
|
21
|
+
onSummaryChange: noop,
|
|
22
|
+
};
|
|
15
23
|
const ShareStateContext = createContext(INACTIVE_STATE);
|
|
16
24
|
const ShareActionsContext = createContext(INACTIVE_ACTIONS);
|
|
17
25
|
/**
|
|
18
|
-
* Owns the
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
26
|
+
* Owns the PAGE state of sharing for one catalog item: the initial access-summary
|
|
27
|
+
* fetch (the inline access row is visible before the dialog ever opens, so the page
|
|
28
|
+
* fetches its own summary) and the dialog-open flag. The dialog itself is a separate,
|
|
29
|
+
* session-scoped component — mounted only while open, owning its own controller and
|
|
30
|
+
* fetch — that reports summary changes back through `onSummaryChange`, so the row
|
|
31
|
+
* stays in sync with edits without a refetch.
|
|
23
32
|
*
|
|
24
|
-
* No-ops cleanly when the item can't be shared: the contexts then carry an
|
|
25
|
-
*
|
|
33
|
+
* No-ops cleanly when the item can't be shared: the contexts then carry an inactive
|
|
34
|
+
* value and the hooks below report `active: false`.
|
|
26
35
|
*
|
|
27
36
|
* @internal
|
|
28
37
|
*/
|
|
29
38
|
export function CatalogItemShareProvider({ shareableItem, target, labels, children, }) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
const backend = useBackendStrict();
|
|
40
|
+
const workspace = useWorkspaceStrict();
|
|
41
|
+
// The page-session boundary: everything below (summary, open flag, the fetch) is
|
|
42
|
+
// scoped to this key. Workspace and kind are part of it — the same identifier can
|
|
43
|
+
// reappear under another workspace (or as another object kind), and the previous
|
|
44
|
+
// summary/dialog must not survive into it.
|
|
45
|
+
const itemKey = shareableItem
|
|
46
|
+
? `${workspace}:${shareableItem.type}:${shareableItem.identifier}`
|
|
47
|
+
: undefined;
|
|
48
|
+
const [summary, setSummary] = useState(undefined);
|
|
49
|
+
// Which item's dialog is open. Navigating to another item changes `itemKey`, so
|
|
50
|
+
// `isOpen` turns false and the dialog unmounts.
|
|
51
|
+
const [dialogFor, setDialogFor] = useState(undefined);
|
|
52
|
+
// Both the summary and the open flag belong to one item under one backend —
|
|
53
|
+
// drop them when either changes. Item change: the new item shows its loading
|
|
54
|
+
// skeleton instead of the previous item's access, and navigating BACK to an
|
|
55
|
+
// item whose dialog was open must not reopen it (a lingering `dialogFor`
|
|
56
|
+
// would match the returning key). Backend change (compared by reference —
|
|
57
|
+
// an instance has no string identity to fold into `itemKey`): the previous
|
|
58
|
+
// backend's summary must not survive into the new one, and clearing
|
|
59
|
+
// `dialogFor` unmounts the dialog session, discarding its edit overlay and
|
|
60
|
+
// staged state with it.
|
|
61
|
+
const [seenScope, setSeenScope] = useState({ backend, itemKey });
|
|
62
|
+
if (seenScope.backend !== backend || seenScope.itemKey !== itemKey) {
|
|
63
|
+
setSeenScope({ backend, itemKey });
|
|
64
|
+
setSummary(undefined);
|
|
65
|
+
setDialogFor(undefined);
|
|
48
66
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
// The page-level summary fetch runs only while the summary is UNKNOWN: once
|
|
68
|
+
// anything seeds it — this fetch, or the dialog's `onSummaryChange` report (the
|
|
69
|
+
// dialog session fetches on its own) — the promise clears, so an open dialog
|
|
70
|
+
// never runs alongside a page fetch and a close never refetches. The item-change
|
|
71
|
+
// reset above clears the summary, which re-arms the fetch. The `prev ??` seed
|
|
72
|
+
// guard covers the resolve-vs-cancel race.
|
|
73
|
+
const summaryUnknown = summary === undefined;
|
|
74
|
+
const { status, error } = useCancelablePromise({
|
|
75
|
+
promise: target && summaryUnknown
|
|
76
|
+
? () => backend.workspace(workspace).objectPermissions().getAccessList(target)
|
|
77
|
+
: undefined,
|
|
78
|
+
onSuccess: (list) => setSummary((prev) => prev ?? accessListToSummary(list)),
|
|
79
|
+
onError: () => { },
|
|
80
|
+
}, [backend, workspace, itemKey, summaryUnknown]);
|
|
54
81
|
// Sharing is offered only while the access list is reachable. The permissions
|
|
55
82
|
// endpoint is manage-gated, so a user who can only view/analyze the object gets
|
|
56
|
-
// a 404
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
const active = Boolean(shareableItem) && !
|
|
83
|
+
// a 404; we then hide both the Share button and the inline access row — there is
|
|
84
|
+
// nothing they can act on. A transient load error does not set the flag, so a
|
|
85
|
+
// flaky fetch doesn't strip the UI — it is reported as `summaryError` instead,
|
|
86
|
+
// so the access row can show an error rather than load forever.
|
|
87
|
+
const accessUnavailable = status === "error" && isPermissionsNotAvailable(error);
|
|
88
|
+
const active = Boolean(shareableItem) && !accessUnavailable;
|
|
89
|
+
const summaryError = status === "error" && !accessUnavailable;
|
|
90
|
+
const isOpen = dialogFor !== undefined && dialogFor === itemKey;
|
|
91
|
+
const open = useCallback(() => setDialogFor(itemKey), [itemKey]);
|
|
92
|
+
const close = useCallback(() => setDialogFor(undefined), []);
|
|
62
93
|
const state = useMemo(() => active && shareableItem
|
|
63
94
|
? {
|
|
64
95
|
active: true,
|
|
65
|
-
|
|
96
|
+
summary,
|
|
97
|
+
summaryError,
|
|
66
98
|
target,
|
|
67
99
|
objectTitle: shareableItem.title,
|
|
68
100
|
isOpen,
|
|
69
|
-
|
|
101
|
+
labels,
|
|
70
102
|
}
|
|
71
|
-
: INACTIVE_STATE, [active, shareableItem,
|
|
72
|
-
const actions = useMemo(() => (active ? { active: true, open, close } : INACTIVE_ACTIONS), [active, open, close]);
|
|
103
|
+
: INACTIVE_STATE, [active, shareableItem, summary, summaryError, target, isOpen, labels]);
|
|
104
|
+
const actions = useMemo(() => (active ? { active: true, open, close, onSummaryChange: setSummary } : INACTIVE_ACTIONS), [active, open, close]);
|
|
73
105
|
return (_jsx(ShareActionsContext.Provider, { value: actions, children: _jsx(ShareStateContext.Provider, { value: state, children: children }) }));
|
|
74
106
|
}
|
|
75
107
|
/**
|
|
76
|
-
*
|
|
108
|
+
* Page share state (summary, open flag, dialog inputs) for the current catalog item.
|
|
77
109
|
* Reports `active: false` when sharing is unavailable.
|
|
78
110
|
*
|
|
79
111
|
* @internal
|
|
@@ -82,8 +114,9 @@ export function useCatalogItemShareState() {
|
|
|
82
114
|
return useContext(ShareStateContext);
|
|
83
115
|
}
|
|
84
116
|
/**
|
|
85
|
-
* Stable share actions (open/close the dialog) for the
|
|
86
|
-
* Reading this instead of the state keeps a consumer from
|
|
117
|
+
* Stable share actions (open/close the dialog, receive summary updates) for the
|
|
118
|
+
* current catalog item. Reading this instead of the state keeps a consumer from
|
|
119
|
+
* re-rendering on state ticks.
|
|
87
120
|
*
|
|
88
121
|
* @internal
|
|
89
122
|
*/
|
|
@@ -10,6 +10,9 @@ export declare const shareMessages: {
|
|
|
10
10
|
accessRowLabel: {
|
|
11
11
|
id: string;
|
|
12
12
|
};
|
|
13
|
+
accessRowError: {
|
|
14
|
+
id: string;
|
|
15
|
+
};
|
|
13
16
|
accessRowRestricted: {
|
|
14
17
|
id: string;
|
|
15
18
|
};
|
|
@@ -19,6 +22,9 @@ export declare const shareMessages: {
|
|
|
19
22
|
accessRowWorkspaceShare: {
|
|
20
23
|
id: string;
|
|
21
24
|
};
|
|
25
|
+
accessRowWorkspaceEdit: {
|
|
26
|
+
id: string;
|
|
27
|
+
};
|
|
22
28
|
accessRowSharedWith: {
|
|
23
29
|
id: string;
|
|
24
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/messages.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/messages.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;CASxB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;CAKzB,CAAC"}
|
|
@@ -8,9 +8,11 @@ import { defineMessages } from "react-intl";
|
|
|
8
8
|
export const shareMessages = defineMessages({
|
|
9
9
|
shareButton: { id: "analyticsCatalog.share.button" },
|
|
10
10
|
accessRowLabel: { id: "analyticsCatalog.share.access.row.label" },
|
|
11
|
+
accessRowError: { id: "analyticsCatalog.share.access.row.error" },
|
|
11
12
|
accessRowRestricted: { id: "analyticsCatalog.share.access.row.restricted" },
|
|
12
13
|
accessRowWorkspaceView: { id: "analyticsCatalog.share.access.row.workspace.view" },
|
|
13
14
|
accessRowWorkspaceShare: { id: "analyticsCatalog.share.access.row.workspace.share" },
|
|
15
|
+
accessRowWorkspaceEdit: { id: "analyticsCatalog.share.access.row.workspace.edit" },
|
|
14
16
|
accessRowSharedWith: { id: "analyticsCatalog.share.access.row.sharedWith" },
|
|
15
17
|
});
|
|
16
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useShareableLabels.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/useShareableLabels.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useShareableLabels.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/useShareableLabels.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,sBAAsB,CAAC;AAEnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,8EAA8E;IAC9E,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,KAAK,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,SAAS,GAAG,gBAAgB,CA2C3F"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { objRefToString } from "@gooddata/sdk-model";
|
|
4
4
|
import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
5
|
+
import { sortShareableLabels } from "@gooddata/sdk-ui-ext";
|
|
5
6
|
/**
|
|
6
7
|
* Loads the labels (display forms) of a shareable attribute so the share dialog
|
|
7
8
|
* can scope a grantee's access per label. Facts and measures have no labels —
|
|
@@ -23,13 +24,17 @@ export function useShareableLabels(item) {
|
|
|
23
24
|
.getAttribute({ identifier: attributeRef, type: "attribute" })
|
|
24
25
|
: undefined,
|
|
25
26
|
}, [backend, workspace, attributeRef]);
|
|
26
|
-
const labels = useMemo(() =>
|
|
27
|
+
const labels = useMemo(() =>
|
|
28
|
+
// Sort once at the source so the detail-page labels popup and the share
|
|
29
|
+
// dialog's label-access checklist — both fed from here — share one
|
|
30
|
+
// deterministic order (primary first, then alphabetical).
|
|
31
|
+
sortShareableLabels((result?.displayForms ?? []).map((df) => ({
|
|
27
32
|
ref: df.ref,
|
|
28
33
|
id: objRefToString(df.ref),
|
|
29
34
|
title: df.title,
|
|
30
35
|
isPrimary: df.isPrimary === true,
|
|
31
36
|
isDefault: df.isDefault === true,
|
|
32
|
-
})), [result]);
|
|
37
|
+
}))), [result]);
|
|
33
38
|
// Facts and measures have no fetch, so they never "load". An attribute loads
|
|
34
39
|
// until its fetch settles (success or error).
|
|
35
40
|
const loading = attributeRef !== undefined && status !== "success" && status !== "error";
|
|
@@ -943,6 +943,10 @@ export declare const en_US: {
|
|
|
943
943
|
text: string;
|
|
944
944
|
crowdinContext: string;
|
|
945
945
|
};
|
|
946
|
+
"analyticsCatalog.share.access.row.error": {
|
|
947
|
+
text: string;
|
|
948
|
+
crowdinContext: string;
|
|
949
|
+
};
|
|
946
950
|
"analyticsCatalog.share.access.row.restricted": {
|
|
947
951
|
text: string;
|
|
948
952
|
crowdinContext: string;
|
|
@@ -955,6 +959,10 @@ export declare const en_US: {
|
|
|
955
959
|
text: string;
|
|
956
960
|
crowdinContext: string;
|
|
957
961
|
};
|
|
962
|
+
"analyticsCatalog.share.access.row.workspace.edit": {
|
|
963
|
+
text: string;
|
|
964
|
+
crowdinContext: string;
|
|
965
|
+
};
|
|
958
966
|
"analyticsCatalog.share.access.row.sharedWith": {
|
|
959
967
|
text: string;
|
|
960
968
|
crowdinContext: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en-US.localization-bundle.d.ts","sourceRoot":"","sources":["../../../src/localization/bundles/en-US.localization-bundle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"en-US.localization-bundle.d.ts","sourceRoot":"","sources":["../../../src/localization/bundles/en-US.localization-bundle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAy9BjB,CAAC"}
|
|
@@ -945,6 +945,10 @@ export const en_US = {
|
|
|
945
945
|
"text": "Access",
|
|
946
946
|
"crowdinContext": "Label for the row in the catalog detail metadata grid that shows the current sharing state of the object."
|
|
947
947
|
},
|
|
948
|
+
"analyticsCatalog.share.access.row.error": {
|
|
949
|
+
"text": "Couldn't load access.",
|
|
950
|
+
"crowdinContext": "Shown in the catalog detail Access row when loading the access summary failed; opening the Share dialog retries the load."
|
|
951
|
+
},
|
|
948
952
|
"analyticsCatalog.share.access.row.restricted": {
|
|
949
953
|
"text": "Restricted",
|
|
950
954
|
"crowdinContext": "State chip text shown when the object's access is restricted to explicitly listed grantees only."
|
|
@@ -957,8 +961,12 @@ export const en_US = {
|
|
|
957
961
|
"text": "All workspace users can share",
|
|
958
962
|
"crowdinContext": "State chip text shown when every workspace user has view+share access to the object."
|
|
959
963
|
},
|
|
964
|
+
"analyticsCatalog.share.access.row.workspace.edit": {
|
|
965
|
+
"text": "All workspace users can edit",
|
|
966
|
+
"crowdinContext": "State chip text shown when every workspace user has edit access to the object."
|
|
967
|
+
},
|
|
960
968
|
"analyticsCatalog.share.access.row.sharedWith": {
|
|
961
|
-
"text": "Shared with {count, plural, one {# user
|
|
969
|
+
"text": "Shared with {count, plural, one {# user/group} other {# users/groups}}",
|
|
962
970
|
"crowdinContext": "Clickable summary in the catalog detail Access row. Opens the share dialog. Placeholder is the count of named grantees (users and groups)."
|
|
963
971
|
},
|
|
964
972
|
"analyticsCatalog.labels.more": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-ui-catalog",
|
|
3
|
-
"version": "11.51.0-alpha.
|
|
3
|
+
"version": "11.51.0-alpha.2",
|
|
4
4
|
"description": "GoodData SDK - Analytics Catalog",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "GoodData Corporation",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
"tslib": "2.8.1",
|
|
42
42
|
"yaml": "2.8.3",
|
|
43
43
|
"zod": "4.3.6",
|
|
44
|
-
"@gooddata/sdk-backend-spi": "11.51.0-alpha.
|
|
45
|
-
"@gooddata/sdk-code-schemas": "11.51.0-alpha.
|
|
46
|
-
"@gooddata/sdk-model": "11.51.0-alpha.
|
|
47
|
-
"@gooddata/sdk-ui": "11.51.0-alpha.
|
|
48
|
-
"@gooddata/sdk-ui
|
|
49
|
-
"@gooddata/sdk-ui-kit": "11.51.0-alpha.
|
|
50
|
-
"@gooddata/sdk-ui-semantic-search": "11.51.0-alpha.
|
|
51
|
-
"@gooddata/
|
|
52
|
-
"@gooddata/
|
|
44
|
+
"@gooddata/sdk-backend-spi": "11.51.0-alpha.2",
|
|
45
|
+
"@gooddata/sdk-code-schemas": "11.51.0-alpha.2",
|
|
46
|
+
"@gooddata/sdk-model": "11.51.0-alpha.2",
|
|
47
|
+
"@gooddata/sdk-ui-ext": "11.51.0-alpha.2",
|
|
48
|
+
"@gooddata/sdk-ui": "11.51.0-alpha.2",
|
|
49
|
+
"@gooddata/sdk-ui-kit": "11.51.0-alpha.2",
|
|
50
|
+
"@gooddata/sdk-ui-semantic-search": "11.51.0-alpha.2",
|
|
51
|
+
"@gooddata/util": "11.51.0-alpha.2",
|
|
52
|
+
"@gooddata/sdk-ui-theme-provider": "11.51.0-alpha.2"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@microsoft/api-documenter": "^7.17.0",
|
|
@@ -89,11 +89,11 @@
|
|
|
89
89
|
"typescript": "5.9.3",
|
|
90
90
|
"vitest": "4.1.8",
|
|
91
91
|
"vitest-dom": "0.1.1",
|
|
92
|
-
"@gooddata/eslint-config": "11.51.0-alpha.
|
|
93
|
-
"@gooddata/i18n-toolkit": "11.51.0-alpha.
|
|
94
|
-
"@gooddata/oxlint-config": "11.51.0-alpha.
|
|
95
|
-
"@gooddata/sdk-backend-mockingbird": "11.51.0-alpha.
|
|
96
|
-
"@gooddata/stylelint-config": "11.51.0-alpha.
|
|
92
|
+
"@gooddata/eslint-config": "11.51.0-alpha.2",
|
|
93
|
+
"@gooddata/i18n-toolkit": "11.51.0-alpha.2",
|
|
94
|
+
"@gooddata/oxlint-config": "11.51.0-alpha.2",
|
|
95
|
+
"@gooddata/sdk-backend-mockingbird": "11.51.0-alpha.2",
|
|
96
|
+
"@gooddata/stylelint-config": "11.51.0-alpha.2"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
99
|
"react": "^18.0.0 || ^19.0.0",
|