@gooddata/sdk-ui-catalog 11.43.0-alpha.0 → 11.43.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.
Files changed (48) hide show
  1. package/esm/automation/testIds.d.ts +7 -0
  2. package/esm/automation/testIds.d.ts.map +1 -1
  3. package/esm/automation/testIds.js +7 -0
  4. package/esm/catalogDetail/CatalogDetailActions.d.ts +3 -1
  5. package/esm/catalogDetail/CatalogDetailActions.d.ts.map +1 -1
  6. package/esm/catalogDetail/CatalogDetailActions.js +11 -9
  7. package/esm/catalogDetail/CatalogDetailContent.d.ts.map +1 -1
  8. package/esm/catalogDetail/CatalogDetailContent.js +62 -23
  9. package/esm/catalogDetail/CatalogDetailHeader.d.ts +13 -1
  10. package/esm/catalogDetail/CatalogDetailHeader.d.ts.map +1 -1
  11. package/esm/catalogDetail/CatalogDetailHeader.js +44 -28
  12. package/esm/catalogDetail/CatalogDetailTabMetadata.d.ts +17 -1
  13. package/esm/catalogDetail/CatalogDetailTabMetadata.d.ts.map +1 -1
  14. package/esm/catalogDetail/CatalogDetailTabMetadata.js +8 -3
  15. package/esm/catalogDetail/share/CatalogDetailAccessRow.d.ts +19 -0
  16. package/esm/catalogDetail/share/CatalogDetailAccessRow.d.ts.map +1 -0
  17. package/esm/catalogDetail/share/CatalogDetailAccessRow.js +33 -0
  18. package/esm/catalogDetail/share/CatalogDetailLabels.d.ts +17 -0
  19. package/esm/catalogDetail/share/CatalogDetailLabels.d.ts.map +1 -0
  20. package/esm/catalogDetail/share/CatalogDetailLabels.js +36 -0
  21. package/esm/catalogDetail/share/ShareButton.d.ts +15 -0
  22. package/esm/catalogDetail/share/ShareButton.d.ts.map +1 -0
  23. package/esm/catalogDetail/share/ShareButton.js +16 -0
  24. package/esm/catalogDetail/share/guards.d.ts +15 -0
  25. package/esm/catalogDetail/share/guards.d.ts.map +1 -0
  26. package/esm/catalogDetail/share/guards.js +21 -0
  27. package/esm/catalogDetail/share/messages.d.ts +43 -0
  28. package/esm/catalogDetail/share/messages.d.ts.map +1 -0
  29. package/esm/catalogDetail/share/messages.js +24 -0
  30. package/esm/catalogDetail/share/types.d.ts +7 -0
  31. package/esm/catalogDetail/share/types.d.ts.map +1 -0
  32. package/esm/catalogDetail/share/types.js +2 -0
  33. package/esm/catalogDetail/share/useShareableLabels.d.ts +31 -0
  34. package/esm/catalogDetail/share/useShareableLabels.d.ts.map +1 -0
  35. package/esm/catalogDetail/share/useShareableLabels.js +37 -0
  36. package/esm/localization/bundles/en-US.localization-bundle.d.ts +44 -0
  37. package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  38. package/esm/localization/bundles/en-US.localization-bundle.js +44 -0
  39. package/esm/localization/translations.d.ts +1 -1
  40. package/esm/localization/translations.d.ts.map +1 -1
  41. package/esm/localization/translations.js +7 -5
  42. package/esm/tsdoc-metadata.json +1 -1
  43. package/package.json +14 -13
  44. package/styles/css/detail.css +67 -3
  45. package/styles/css/detail.css.map +1 -1
  46. package/styles/css/main.css +67 -3
  47. package/styles/css/main.css.map +1 -1
  48. package/styles/scss/detail.scss +86 -8
@@ -12,4 +12,11 @@ export declare const catalogDetail = "analytics-catalog-detail";
12
12
  export declare const catalogDetailActionsTrigger = "analytics-catalog-detail-actions/trigger";
13
13
  export declare const catalogDetailActionDuplicate = "analytics-catalog-detail-actions/duplicate";
14
14
  export declare const catalogDetailActionDelete = "analytics-catalog-detail-actions/delete";
15
+ export declare const catalogDetailActionShare = "analytics-catalog-detail-actions/share";
16
+ export declare const catalogDetailAccessRow = "analytics-catalog-detail-access-row";
17
+ export declare const catalogDetailAccessRowState = "analytics-catalog-detail-access-row/state";
18
+ export declare const catalogDetailAccessRowSharedLink = "analytics-catalog-detail-access-row/shared-link";
19
+ export declare const catalogDetailLabels = "analytics-catalog-detail-labels";
20
+ export declare const catalogDetailLabelsTrigger = "analytics-catalog-detail-labels/trigger";
21
+ export declare const catalogDetailLabelsList = "analytics-catalog-detail-labels/list";
15
22
  //# sourceMappingURL=testIds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testIds.d.ts","sourceRoot":"","sources":["../../src/automation/testIds.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,sBAAsB,CAAC;AAC3C,eAAO,MAAM,UAAU,kCAA2B,CAAC;AACnD,eAAO,MAAM,MAAM,6BAAsB,CAAC;AAC1C,eAAO,MAAM,eAAe,wCAAyB,CAAC;AACtD,eAAO,MAAM,YAAY,oCAAqB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,wCAAyB,CAAC;AACvD,eAAO,MAAM,mBAAmB,2CAA4B,CAAC;AAC7D,eAAO,MAAM,aAAa,qCAAsB,CAAC;AACjD,eAAO,MAAM,UAAU,kCAAmB,CAAC;AAC3C,eAAO,MAAM,WAAW,mCAAoB,CAAC;AAC7C,eAAO,MAAM,aAAa,6BAAsB,CAAC;AACjD,eAAO,MAAM,2BAA2B,6CAAqC,CAAC;AAC9E,eAAO,MAAM,4BAA4B,+CAAuC,CAAC;AACjF,eAAO,MAAM,yBAAyB,4CAAoC,CAAC"}
1
+ {"version":3,"file":"testIds.d.ts","sourceRoot":"","sources":["../../src/automation/testIds.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,sBAAsB,CAAC;AAC3C,eAAO,MAAM,UAAU,kCAA2B,CAAC;AACnD,eAAO,MAAM,MAAM,6BAAsB,CAAC;AAC1C,eAAO,MAAM,eAAe,wCAAyB,CAAC;AACtD,eAAO,MAAM,YAAY,oCAAqB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,wCAAyB,CAAC;AACvD,eAAO,MAAM,mBAAmB,2CAA4B,CAAC;AAC7D,eAAO,MAAM,aAAa,qCAAsB,CAAC;AACjD,eAAO,MAAM,UAAU,kCAAmB,CAAC;AAC3C,eAAO,MAAM,WAAW,mCAAoB,CAAC;AAC7C,eAAO,MAAM,aAAa,6BAAsB,CAAC;AACjD,eAAO,MAAM,2BAA2B,6CAAqC,CAAC;AAC9E,eAAO,MAAM,4BAA4B,+CAAuC,CAAC;AACjF,eAAO,MAAM,yBAAyB,4CAAoC,CAAC;AAC3E,eAAO,MAAM,wBAAwB,2CAAmC,CAAC;AACzE,eAAO,MAAM,sBAAsB,wCAAgC,CAAC;AACpE,eAAO,MAAM,2BAA2B,8CAAsC,CAAC;AAC/E,eAAO,MAAM,gCAAgC,oDAA4C,CAAC;AAC1F,eAAO,MAAM,mBAAmB,oCAA4B,CAAC;AAC7D,eAAO,MAAM,0BAA0B,4CAAoC,CAAC;AAC5E,eAAO,MAAM,uBAAuB,yCAAiC,CAAC"}
@@ -16,3 +16,10 @@ export const catalogDetail = `${catalog}-detail`;
16
16
  export const catalogDetailActionsTrigger = `${catalogDetail}-actions/trigger`;
17
17
  export const catalogDetailActionDuplicate = `${catalogDetail}-actions/duplicate`;
18
18
  export const catalogDetailActionDelete = `${catalogDetail}-actions/delete`;
19
+ export const catalogDetailActionShare = `${catalogDetail}-actions/share`;
20
+ export const catalogDetailAccessRow = `${catalogDetail}-access-row`;
21
+ export const catalogDetailAccessRowState = `${catalogDetail}-access-row/state`;
22
+ export const catalogDetailAccessRowSharedLink = `${catalogDetail}-access-row/shared-link`;
23
+ export const catalogDetailLabels = `${catalogDetail}-labels`;
24
+ export const catalogDetailLabelsTrigger = `${catalogDetail}-labels/trigger`;
25
+ export const catalogDetailLabelsList = `${catalogDetail}-labels/list`;
@@ -11,9 +11,11 @@ export interface ICatalogDetailActionsProps {
11
11
  onCatalogItemCreate?: (item: ICatalogItem) => void;
12
12
  onCatalogItemUpdate?: (item: ICatalogItem) => void;
13
13
  onCatalogItemDelete?: (ref: ICatalogItemRef) => void;
14
+ /** When set, a Share button is shown next to Open. Undefined hides it (not shareable / flag off). */
15
+ onShareClick?: () => void;
14
16
  }
15
17
  /**
16
18
  * @internal
17
19
  */
18
- export declare function CatalogDetailActions({ item, canEdit, onOpen, onCatalogItemCreate, onCatalogItemUpdate, onCatalogItemDelete }: ICatalogDetailActionsProps): import("react/jsx-runtime").JSX.Element | null;
20
+ export declare function CatalogDetailActions({ item, canEdit, onOpen, onCatalogItemCreate, onCatalogItemUpdate, onCatalogItemDelete, onShareClick }: ICatalogDetailActionsProps): import("react/jsx-runtime").JSX.Element | null;
19
21
  //# sourceMappingURL=CatalogDetailActions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogDetailActions.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailActions.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAkC,MAAM,OAAO,CAAC;AAUxE,OAAO,KAAK,EAAE,YAAY,EAAyB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAMpG,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAczE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClE,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;CACxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,MAAM,EACN,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACtB,EAAE,0BAA0B,kDAwI5B"}
1
+ {"version":3,"file":"CatalogDetailActions.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailActions.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAkC,MAAM,OAAO,CAAC;AAUxE,OAAO,KAAK,EAAE,YAAY,EAAyB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAOpG,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAczE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClE,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,qGAAqG;IACrG,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,MAAM,EACN,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACf,EAAE,0BAA0B,kDA2I5B"}
@@ -10,6 +10,7 @@ import { ParameterCreateDialog } from "../parameter/ParameterCreateDialog.js";
10
10
  import { ParameterDeleteDialog } from "../parameter/ParameterDeleteDialog.js";
11
11
  import { ParameterEditDialog } from "../parameter/ParameterEditDialog.js";
12
12
  import { CatalogDetailActionBar } from "./CatalogDetailActionBar.js";
13
+ import { ShareButton } from "./share/ShareButton.js";
13
14
  const messages = defineMessages({
14
15
  parameterDuplicate: { id: "analyticsCatalog.parameter.dialog.edit.duplicate" },
15
16
  parameterDelete: { id: "analyticsCatalog.parameter.dialog.delete.submit" },
@@ -17,7 +18,7 @@ const messages = defineMessages({
17
18
  /**
18
19
  * @internal
19
20
  */
20
- export function CatalogDetailActions({ item, canEdit, onOpen, onCatalogItemCreate, onCatalogItemUpdate, onCatalogItemDelete, }) {
21
+ export function CatalogDetailActions({ item, canEdit, onOpen, onCatalogItemCreate, onCatalogItemUpdate, onCatalogItemDelete, onShareClick, }) {
21
22
  const intl = useIntl();
22
23
  const workspaceId = useWorkspaceStrict();
23
24
  const [dialog, setDialog] = useState(undefined);
@@ -82,12 +83,13 @@ export function CatalogDetailActions({ item, canEdit, onOpen, onCatalogItemCreat
82
83
  return (_jsxs(_Fragment, { children: [
83
84
  _jsx(CatalogDetailActionBar, { item: item, workspaceId: workspaceId, actions: parameterActions, onEditClick: handleEditOpen, onActionsMenuSelect: handleActionsMenuSelect }), dialog?.kind === "edit" ? (_jsx(ParameterEditDialog, { item: dialog.item, onClose: closeDialog, onSaved: handleSaved, onDuplicate: handleEditDuplicate })) : null, dialog?.kind === "duplicate" ? (_jsx(ParameterCreateDialog, { sourceItem: dialog.item, onClose: closeDialog, onCreated: handleCreated })) : null, dialog?.kind === "delete" ? (_jsx(ParameterDeleteDialog, { item: dialog.item, onClose: closeDialog, onDeleted: handleDeleted })) : null] }));
84
85
  }
85
- return (_jsx(UiButton, { label: intl.formatMessage({ id: "analyticsCatalog.catalogItem.open" }), variant: "primary", accessibilityConfig: { role: "link" }, onClick: (event) => {
86
- onOpen?.(event, {
87
- item,
88
- workspaceId,
89
- newTab: event.metaKey || event.ctrlKey,
90
- preventDefault: event.preventDefault.bind(event),
91
- });
92
- } }));
86
+ return (_jsxs("div", { className: "gd-analytics-catalog-detail__header-actions", children: [onShareClick ? _jsx(ShareButton, { onClick: onShareClick }) : null, _jsx(UiButton, { label: intl.formatMessage({ id: "analyticsCatalog.catalogItem.open" }), variant: "primary", accessibilityConfig: { role: "link" }, onClick: (event) => {
87
+ onOpen?.(event, {
88
+ item,
89
+ workspaceId,
90
+ newTab: event.metaKey || event.ctrlKey,
91
+ preventDefault: event.preventDefault.bind(event),
92
+ });
93
+ } })
94
+ ] }));
93
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogDetailContent.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailContent.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAgC,MAAM,OAAO,CAAC;AAUtE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAazD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AASnD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAAC;IACzD;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5E;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5E;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD;;OAEG;IACH,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EAC1B,EAAE,0BAA0B,2CA6L5B"}
1
+ {"version":3,"file":"CatalogDetailContent.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailContent.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAA0C,MAAM,OAAO,CAAC;AAWhF,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAezD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AASnD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAAC;IACzD;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5E;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;OAEG;IACH,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5E;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD;;OAEG;IACH,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EAC1B,EAAE,0BAA0B,2CAwP5B"}
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2025-2026 GoodData Corporation
3
- import { useCallback, useMemo, useRef } from "react";
3
+ import { useCallback, useMemo, useRef, useState } from "react";
4
4
  import cx from "classnames";
5
5
  import { useIntl } from "react-intl";
6
6
  import {} from "@gooddata/sdk-model";
7
7
  import { useLocalStorage } from "@gooddata/sdk-ui";
8
+ import { ObjectShareDialog, useObjectShare } from "@gooddata/sdk-ui-ext";
8
9
  import { UiSkeleton, UiTabs } from "@gooddata/sdk-ui-kit";
9
10
  import { canEditCatalogItem } from "../catalogItem/permission.js";
10
11
  import {} from "../catalogItem/types.js";
@@ -22,6 +23,8 @@ import { CatalogDetailTabLineage } from "./CatalogDetailTabLineage.js";
22
23
  import { CatalogDetailTabMetadata } from "./CatalogDetailTabMetadata.js";
23
24
  import { CatalogDetailTabQuality } from "./CatalogDetailTabQuality.js";
24
25
  import { useCatalogItemUpdate } from "./hooks/useCatalogItemUpdate.js";
26
+ import { isShareableCatalogItem, toShareTarget } from "./share/guards.js";
27
+ import { useShareableLabels } from "./share/useShareableLabels.js";
25
28
  const Tabs = {
26
29
  METADATA: "metadata",
27
30
  QUALITY: "issues",
@@ -44,6 +47,38 @@ export function CatalogDetailContent({ objectId, objectType, objectDefinition, o
44
47
  onError: onCatalogItemUpdateError,
45
48
  });
46
49
  const canEdit = canEditCatalogItem(permissions, item);
50
+ // Sharing (object-level permissions) — gated by the column-level-permissions
51
+ // flag and limited to shareable item kinds (attributes, facts).
52
+ const enableColumnLevelPermissions = Boolean(settings?.enableColumnLevelPermissions);
53
+ const shareableItem = item && enableColumnLevelPermissions && isShareableCatalogItem(item) ? item : undefined;
54
+ const shareTarget = useMemo(() => (shareableItem ? toShareTarget(shareableItem) : undefined), [shareableItem]);
55
+ // Labels of the shared attribute drive the per-grantee label-scope picker.
56
+ const shareLabels = useShareableLabels(shareableItem);
57
+ // One controller drives both the dialog and the inline access row; the row
58
+ // reads `state.summary`, so a save inside the dialog refreshes it too.
59
+ // `labelsLoading`/`labelsError` keep the controller label-unresolved while labels
60
+ // are still pending, disabling every access-changing control (a write would
61
+ // otherwise diff against an empty label set and orphan real per-label grants).
62
+ const shareController = useObjectShare(shareTarget, {
63
+ labels: shareLabels.labels,
64
+ labelsError: shareLabels.error,
65
+ labelsLoading: shareLabels.loading,
66
+ });
67
+ const [isShareOpen, setIsShareOpen] = useState(false);
68
+ // The detail view is reused as the user navigates between objects, so reset the
69
+ // open dialog when the shareable target changes (or becomes non-shareable) —
70
+ // otherwise it would linger open on the next object. Reset during render (React's
71
+ // "adjust state on prop change" idiom) rather than in an effect.
72
+ const shareTargetKey = shareableItem?.identifier;
73
+ const [openForKey, setOpenForKey] = useState(undefined);
74
+ if (isShareOpen && openForKey !== shareTargetKey) {
75
+ setIsShareOpen(false);
76
+ }
77
+ const openShare = useCallback(() => {
78
+ setOpenForKey(shareTargetKey);
79
+ setIsShareOpen(true);
80
+ }, [shareTargetKey]);
81
+ const closeShare = useCallback(() => setIsShareOpen(false), []);
47
82
  const separators = settings?.separators;
48
83
  const enableMetricFormatOverrides = Boolean(settings?.["enableMetricFormatOverrides"]);
49
84
  const currencyFormatOverride = settings?.currencyFormatOverride ?? null;
@@ -97,28 +132,32 @@ export function CatalogDetailContent({ objectId, objectType, objectDefinition, o
97
132
  return tabs;
98
133
  }, [intl, isCertificationVisible, isQualityVisible, isLineageVisible, issueCount]);
99
134
  const [selectedTabId, setSelectedTabId] = useSelectedTabId(tabs);
100
- return (_jsx("div", { className: "gd-analytics-catalog-detail", children: _jsx(CatalogDetailStatus, { status: status, error: error, children: item ? (_jsxs("div", { className: cx("gd-analytics-catalog-detail__content", {
101
- lineage: selectedTabId === Tabs.LINEAGE,
102
- }), children: [
103
- _jsx(CatalogDetailHeader, { item: item, canEdit: canEdit, updateItemTitle: updateItemTitle, updateItemDescription: updateItemDescription, isDescriptionGenerationEnabled: isDescriptionGenerationEnabled, headerRef: headerRef, actions: _jsx(CatalogDetailActions, { item: item, canEdit: canEdit, onOpen: onOpenClick, onCatalogItemCreate: onCatalogItemCreate, onCatalogItemUpdate: applyItemUpdate, onCatalogItemDelete: applyItemDelete }) }), _jsx(UiTabs, { size: "large", tabs: tabs, onTabSelect: (tab) => setSelectedTabId(tab.id), selectedTabId: selectedTabId }), selectedTabId === Tabs.METADATA && (_jsx(CatalogDetailTabMetadata, { item: item, canEdit: canEdit, onTagClick: (tag) => {
104
- onTagClick?.(tag.label);
105
- }, onTagAdd: (tag) => {
106
- // Adding unique tags only
107
- updateItemTags([...new Set([...item.tags, tag.label])]);
108
- }, onTagRemove: (tag) => {
109
- updateItemTags(item.tags.filter((t) => t !== tag.label));
110
- }, onIsHiddenChange: (isHidden) => {
111
- updateItemIsHidden(isHidden);
112
- }, onIsHiddenFromKdaChange: (isHiddenFromKda) => {
113
- updateItemIsHiddenFromKda(isHiddenFromKda);
114
- }, onMetricTypeChange: (metricType) => {
115
- updateItemMetricType(metricType);
116
- }, onFormatChange: (format) => {
117
- updateItemFormat(format);
118
- }, separators: separators, currencyFormatOverride: enableMetricFormatOverrides ? currencyFormatOverride : undefined, enableMetricFormatOverrides: enableMetricFormatOverrides })), selectedTabId === Tabs.CERTIFICATION && isCertificationVisible ? (_jsx(CatalogDetailTabCertification, { item: item, canEdit: canEdit, onCertificationChange: (certification) => {
119
- updateItemCertification(certification);
120
- } })) : null, selectedTabId === Tabs.QUALITY &&
121
- (isQualityLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 65, itemsGap: 10 })) : (_jsx(CatalogDetailTabQuality, { item: item, issues: issues, canEdit: canEdit, onEditClick: handleEditClick, onCatalogItemNavigation: onCatalogItemNavigation }))), selectedTabId === Tabs.LINEAGE && _jsx(CatalogDetailTabLineage, { item: item })] })) : null }) }));
135
+ return (_jsxs("div", { className: "gd-analytics-catalog-detail", children: [
136
+ _jsx(CatalogDetailStatus, { status: status, error: error, children: item ? (_jsxs("div", { className: cx("gd-analytics-catalog-detail__content", {
137
+ lineage: selectedTabId === Tabs.LINEAGE,
138
+ }), children: [
139
+ _jsx(CatalogDetailHeader, { item: item, canEdit: canEdit, updateItemTitle: updateItemTitle, updateItemDescription: updateItemDescription, isDescriptionGenerationEnabled: isDescriptionGenerationEnabled, headerRef: headerRef, labels: shareableItem ? shareLabels.labels : undefined, labelsLoading: shareableItem ? shareLabels.loading : false, showInfoRow: enableColumnLevelPermissions, actions: _jsx(CatalogDetailActions, { item: item, canEdit: canEdit, onOpen: onOpenClick, onCatalogItemCreate: onCatalogItemCreate, onCatalogItemUpdate: applyItemUpdate, onCatalogItemDelete: applyItemDelete, onShareClick: shareableItem ? openShare : undefined }) }), _jsx(UiTabs, { size: "large", tabs: tabs, onTabSelect: (tab) => setSelectedTabId(tab.id), selectedTabId: selectedTabId }), selectedTabId === Tabs.METADATA && (_jsx(CatalogDetailTabMetadata, { item: item, canEdit: canEdit,
140
+ // With OLP off the dataset isn't relocated to the header,
141
+ // so keep the Dataset row in the metadata tab.
142
+ showDatasetRow: !enableColumnLevelPermissions, onTagClick: (tag) => {
143
+ onTagClick?.(tag.label);
144
+ }, onTagAdd: (tag) => {
145
+ // Adding unique tags only
146
+ updateItemTags([...new Set([...item.tags, tag.label])]);
147
+ }, onTagRemove: (tag) => {
148
+ updateItemTags(item.tags.filter((t) => t !== tag.label));
149
+ }, onIsHiddenChange: (isHidden) => {
150
+ updateItemIsHidden(isHidden);
151
+ }, onIsHiddenFromKdaChange: (isHiddenFromKda) => {
152
+ updateItemIsHiddenFromKda(isHiddenFromKda);
153
+ }, onMetricTypeChange: (metricType) => {
154
+ updateItemMetricType(metricType);
155
+ }, onFormatChange: (format) => {
156
+ updateItemFormat(format);
157
+ }, separators: separators, currencyFormatOverride: enableMetricFormatOverrides ? currencyFormatOverride : undefined, enableMetricFormatOverrides: enableMetricFormatOverrides, accessSummary: shareableItem ? shareController.state.summary : undefined, accessUnavailable: shareableItem ? shareController.state.status !== "success" : false, onAccessOpen: shareableItem ? openShare : undefined })), selectedTabId === Tabs.CERTIFICATION && isCertificationVisible ? (_jsx(CatalogDetailTabCertification, { item: item, canEdit: canEdit, onCertificationChange: (certification) => {
158
+ updateItemCertification(certification);
159
+ } })) : null, selectedTabId === Tabs.QUALITY &&
160
+ (isQualityLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 65, itemsGap: 10 })) : (_jsx(CatalogDetailTabQuality, { item: item, issues: issues, canEdit: canEdit, onEditClick: handleEditClick, onCatalogItemNavigation: onCatalogItemNavigation }))), selectedTabId === Tabs.LINEAGE && _jsx(CatalogDetailTabLineage, { item: item })] })) : null }), shareableItem ? (_jsx(ObjectShareDialog, { target: shareTarget, objectTitle: shareableItem.title, isOpen: isShareOpen, onClose: closeShare, labelsLoading: shareLabels.loading, controller: shareController })) : null] }));
122
161
  }
123
162
  /**
124
163
  * Hook for managing the currently selected tab ID with persistent storage.
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode, type RefObject } from "react";
2
+ import type { IObjectShareLabel } from "@gooddata/sdk-ui-ext";
2
3
  import { type ICatalogItem } from "../catalogItem/types.js";
3
4
  export interface ICatalogDetailHeaderRef {
4
5
  focusTitle: () => void;
@@ -12,7 +13,18 @@ interface IProps {
12
13
  updateItemDescription: (description: string) => void;
13
14
  isDescriptionGenerationEnabled: boolean;
14
15
  headerRef: RefObject<ICatalogDetailHeaderRef | null>;
16
+ /** Labels of the shared attribute, shown in the header LABELS column. Empty for non-attributes. */
17
+ labels?: IObjectShareLabel[];
18
+ /** While true, the LABELS column shows a skeleton instead of the (not-yet-loaded) value. */
19
+ labelsLoading?: boolean;
20
+ /**
21
+ * When true (object-level permissions on), the header shows the ID | Dataset |
22
+ * Labels info row and the Dataset row is relocated here from the metadata tab.
23
+ * When false, only the inline ID is shown and Dataset stays in the metadata tab
24
+ * — so turning the flag off leaves the original layout untouched.
25
+ */
26
+ showInfoRow?: boolean;
15
27
  }
16
- export declare function CatalogDetailHeader({ item, canEdit, actions, updateItemTitle, updateItemDescription, isDescriptionGenerationEnabled, headerRef }: IProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function CatalogDetailHeader({ item, canEdit, actions, updateItemTitle, updateItemDescription, isDescriptionGenerationEnabled, headerRef, labels, labelsLoading, showInfoRow }: IProps): import("react/jsx-runtime").JSX.Element;
17
29
  export {};
18
30
  //# sourceMappingURL=CatalogDetailHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogDetailHeader.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAQpF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAQ5D,MAAM,WAAW,uBAAuB;IACpC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,UAAU,MAAM;IACZ,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,SAAS,CAAC;IACnB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,qBAAqB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,8BAA8B,EAAE,OAAO,CAAC;IACxC,SAAS,EAAE,SAAS,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,8BAA8B,EAC9B,SAAS,EACZ,EAAE,MAAM,2CAkJR"}
1
+ {"version":3,"file":"CatalogDetailHeader.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAIpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK9D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAS5D,MAAM,WAAW,uBAAuB;IACpC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,UAAU,MAAM;IACZ,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,SAAS,CAAC;IACnB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,qBAAqB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,8BAA8B,EAAE,OAAO,CAAC;IACxC,SAAS,EAAE,SAAS,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IACrD,mGAAmG;IACnG,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,4FAA4F;IAC5F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,8BAA8B,EAC9B,SAAS,EACT,MAAM,EACN,aAAa,EACb,WAAW,EACd,EAAE,MAAM,2CAoMR"}
@@ -2,20 +2,28 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  // (C) 2025-2026 GoodData Corporation
3
3
  import { useImperativeHandle, useRef } from "react";
4
4
  import { FormattedMessage, useIntl } from "react-intl";
5
- import { EditableLabel, UiCard, UiCopyButton } from "@gooddata/sdk-ui-kit";
5
+ import { EditableLabel, UiCard, UiCopyButton, UiSkeleton } from "@gooddata/sdk-ui-kit";
6
6
  import { CatalogItemLockMemo } from "../catalogItem/CatalogItemLock.js";
7
- import { getVisualizationType } from "../catalogItem/guards.js";
7
+ import { getVisualizationType, isCatalogItemAttribute, isCatalogItemFact } from "../catalogItem/guards.js";
8
8
  import {} from "../catalogItem/types.js";
9
9
  import { CertificationIconMemo } from "../certification/CertificationIcon.js";
10
10
  import { ObjectTypeIconMemo } from "../objectType/ObjectTypeIcon.js";
11
11
  import { ObjectTypeTooltip } from "../objectType/ObjectTypeTooltip.js";
12
12
  import { CatalogDetailGenerateDescription } from "./CatalogDetailGenerateDescription.js";
13
13
  import { CatalogDetailGenerateTitle } from "./CatalogDetailGenerateTitle.js";
14
- export function CatalogDetailHeader({ item, canEdit, actions, updateItemTitle, updateItemDescription, isDescriptionGenerationEnabled, headerRef, }) {
14
+ import { CatalogDetailLabels } from "./share/CatalogDetailLabels.js";
15
+ export function CatalogDetailHeader({ item, canEdit, actions, updateItemTitle, updateItemDescription, isDescriptionGenerationEnabled, headerRef, labels, labelsLoading, showInfoRow, }) {
15
16
  const intl = useIntl();
16
17
  const type = item.type ?? "analyticalDashboard";
17
18
  const visualizationType = getVisualizationType(item);
18
19
  const canGenerateText = canEdit && item.type !== "dataSet" && isDescriptionGenerationEnabled;
20
+ // Header info columns: ID is always shown; Dataset only for attributes/facts
21
+ // that carry one; Labels for attributes — a skeleton while they load, then the
22
+ // value (or nothing if the attribute turns out to have no permissionable labels).
23
+ const datasetTitle = isCatalogItemAttribute(item) || isCatalogItemFact(item) ? item.dataSet?.title : undefined;
24
+ const isAttribute = isCatalogItemAttribute(item);
25
+ const hasLabels = isAttribute && (labels?.length ?? 0) > 0;
26
+ const showLabelsColumn = isAttribute && (labelsLoading === true || hasLabels);
19
27
  const titleRef = useRef(null);
20
28
  const descriptionRef = useRef(null);
21
29
  useImperativeHandle(headerRef, () => ({
@@ -27,33 +35,41 @@ export function CatalogDetailHeader({ item, canEdit, actions, updateItemTitle, u
27
35
  },
28
36
  }), []);
29
37
  return (_jsx(UiCard, { elevation: "1", children: _jsxs("div", { className: "gd-analytics-catalog-detail__card", children: [
30
- _jsxs("div", { className: "gd-analytics-catalog-detail__card__header", children: [
31
- _jsxs("div", { className: "gd-analytics-catalog-detail__card__header__title", children: [
32
- _jsx(ObjectTypeTooltip, { intl: intl, type: type, visualizationType: visualizationType, anchor: _jsx(ObjectTypeIconMemo, { intl: intl, type: type, visualizationType: visualizationType, backgroundSize: 32 }) }), item?.isLocked ? _jsx(CatalogItemLockMemo, { intl: intl }) : null, _jsx("div", { className: "gd-analytics-catalog-detail__card__header__title__name", children: canEdit ? (canGenerateText ? (_jsx(CatalogDetailGenerateTitle, { ref: titleRef, item: item, onApplyTitle: updateItemTitle }, item.identifier)) : (_jsxs(EditableLabel, { ref: titleRef, isEditableLabelWidthBasedOnText: true, ariaLabel: intl.formatMessage({
33
- id: "analyticsCatalog.column.title.label",
34
- }), placeholder: intl.formatMessage({
35
- id: "analyticsCatalog.catalogItem.title.add",
36
- }), onSubmit: updateItemTitle, value: item.title, maxRows: 9999, children: [item.title ||
37
- intl.formatMessage({
38
+ _jsxs("div", { className: "gd-analytics-catalog-detail__card__top", children: [
39
+ _jsxs("div", { className: "gd-analytics-catalog-detail__card__header", children: [
40
+ _jsxs("div", { className: "gd-analytics-catalog-detail__card__header__title", children: [
41
+ _jsx(ObjectTypeTooltip, { intl: intl, type: type, visualizationType: visualizationType, anchor: _jsx(ObjectTypeIconMemo, { intl: intl, type: type, visualizationType: visualizationType, backgroundSize: 32 }) }), item?.isLocked ? _jsx(CatalogItemLockMemo, { intl: intl }) : null, _jsx("div", { className: "gd-analytics-catalog-detail__card__header__title__name", children: canEdit ? (canGenerateText ? (_jsx(CatalogDetailGenerateTitle, { ref: titleRef, item: item, onApplyTitle: updateItemTitle }, item.identifier)) : (_jsxs(EditableLabel, { ref: titleRef, isEditableLabelWidthBasedOnText: true, ariaLabel: intl.formatMessage({
42
+ id: "analyticsCatalog.column.title.label",
43
+ }), placeholder: intl.formatMessage({
38
44
  id: "analyticsCatalog.catalogItem.title.add",
39
- }), _jsx("i", { className: "gd-icon-pencil" })
40
- ] }))) : (_jsx(_Fragment, { children: item.title })) }), _jsx(CertificationIconMemo, { className: "gd-analytics-catalog-detail__card__header__title__certified", intl: intl, certification: item.certification })
41
- ] }), canEdit ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row", children: [
42
- _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.description" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: canGenerateText ? (_jsx(CatalogDetailGenerateDescription, { ref: descriptionRef, item: item, onApplyDescription: updateItemDescription }, item.identifier)) : (_jsxs(EditableLabel, { ref: descriptionRef, maxRows: 9999, ariaLabel: intl.formatMessage({
43
- id: "analyticsCatalog.catalogItem.description",
44
- }), placeholder: intl.formatMessage({
45
- id: "analyticsCatalog.catalogItem.description.add",
46
- }), isEditableLabelWidthBasedOnText: true, onSubmit: updateItemDescription, value: item.description, children: [item.description ||
47
- intl.formatMessage({
45
+ }), onSubmit: updateItemTitle, value: item.title, maxRows: 9999, children: [item.title ||
46
+ intl.formatMessage({
47
+ id: "analyticsCatalog.catalogItem.title.add",
48
+ }), _jsx("i", { className: "gd-icon-pencil" })
49
+ ] }))) : (_jsx(_Fragment, { children: item.title })) }), _jsx(CertificationIconMemo, { className: "gd-analytics-catalog-detail__card__header__title__certified", intl: intl, certification: item.certification })
50
+ ] }), canEdit ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row", children: [
51
+ _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.description" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: canGenerateText ? (_jsx(CatalogDetailGenerateDescription, { ref: descriptionRef, item: item, onApplyDescription: updateItemDescription }, item.identifier)) : (_jsxs(EditableLabel, { ref: descriptionRef, maxRows: 9999, ariaLabel: intl.formatMessage({
52
+ id: "analyticsCatalog.catalogItem.description",
53
+ }), placeholder: intl.formatMessage({
48
54
  id: "analyticsCatalog.catalogItem.description.add",
49
- }), _jsx("i", { className: "gd-icon-pencil" })
50
- ] })) })
51
- ] })) : (_jsx(_Fragment, { children: item.description ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row", children: [
52
- _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.description" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: item.description })
53
- ] })) : null })), _jsxs("div", { children: [
55
+ }), isEditableLabelWidthBasedOnText: true, onSubmit: updateItemDescription, value: item.description, children: [item.description ||
56
+ intl.formatMessage({
57
+ id: "analyticsCatalog.catalogItem.description.add",
58
+ }), _jsx("i", { className: "gd-icon-pencil" })
59
+ ] })) })
60
+ ] })) : (_jsx(_Fragment, { children: item.description ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row", children: [
61
+ _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.description" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: item.description })
62
+ ] })) : null })), showInfoRow ? null : (_jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row", children: [
63
+ _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.id" }) }), _jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: [item.identifier, _jsx(UiCopyButton, { clipboardContent: item.identifier })
64
+ ] })
65
+ ] }))] }), _jsx("div", { className: "gd-analytics-catalog-detail__card__actions", children: actions })
66
+ ] }), showInfoRow ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__info", children: [
67
+ _jsxs("div", { className: "gd-analytics-catalog-detail__card__info__cell", children: [
54
68
  _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.catalogItem.id" }) }), _jsxs("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: [item.identifier, _jsx(UiCopyButton, { clipboardContent: item.identifier })
55
69
  ] })
56
- ] })
57
- ] }), _jsx("div", { className: "gd-analytics-catalog-detail__card__actions", children: actions })
58
- ] }) }));
70
+ ] }), datasetTitle ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__info__cell", children: [
71
+ _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.dataSet" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: datasetTitle })
72
+ ] })) : null, showLabelsColumn ? (_jsxs("div", { className: "gd-analytics-catalog-detail__card__info__cell", children: [
73
+ _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__subtitle", children: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.labels" }) }), _jsx("div", { className: "gd-analytics-catalog-detail__card__header__row__content", children: labelsLoading ? (_jsx(UiSkeleton, { itemWidth: 120, itemHeight: 20 })) : (_jsx(CatalogDetailLabels, { labels: labels ?? [] })) })
74
+ ] })) : null] })) : null] }) }));
59
75
  }
@@ -1,4 +1,5 @@
1
1
  import type { ISeparators, MetricType } from "@gooddata/sdk-model";
2
+ import type { IObjectAccessSummary } from "@gooddata/sdk-ui-ext";
2
3
  import { type IUiTagDef } from "@gooddata/sdk-ui-kit";
3
4
  import { type ICatalogItem } from "../catalogItem/types.js";
4
5
  type Props = {
@@ -14,7 +15,22 @@ type Props = {
14
15
  separators?: ISeparators;
15
16
  currencyFormatOverride?: string | null;
16
17
  enableMetricFormatOverrides?: boolean;
18
+ /** Access summary for the inline row. Undefined when sharing is unavailable for this item. */
19
+ accessSummary?: IObjectAccessSummary;
20
+ /**
21
+ * True while the access summary isn't available yet (loading or load error) for a
22
+ * shareable item. The Access row then shows a placeholder instead of vanishing —
23
+ * the row must stay because Share is still reachable for the object.
24
+ */
25
+ accessUnavailable?: boolean;
26
+ /** Opens the share dialog from the access row. Required for the row to render. */
27
+ onAccessOpen?: () => void;
28
+ /**
29
+ * Show the Dataset row here. True when object-level permissions are off — with
30
+ * the flag on the dataset is relocated to the header info row instead.
31
+ */
32
+ showDatasetRow?: boolean;
17
33
  };
18
- export declare function CatalogDetailTabMetadata({ item, canEdit, onTagClick, onTagAdd, onTagRemove, onIsHiddenChange, onIsHiddenFromKdaChange, onMetricTypeChange, onFormatChange, separators, currencyFormatOverride, enableMetricFormatOverrides }: Props): import("react/jsx-runtime").JSX.Element;
34
+ export declare function CatalogDetailTabMetadata({ item, canEdit, onTagClick, onTagAdd, onTagRemove, onIsHiddenChange, onIsHiddenFromKdaChange, onMetricTypeChange, onFormatChange, separators, currencyFormatOverride, enableMetricFormatOverrides, accessSummary, accessUnavailable, onAccessOpen, showDatasetRow }: Props): import("react/jsx-runtime").JSX.Element;
19
35
  export {};
20
36
  //# sourceMappingURL=CatalogDetailTabMetadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogDetailTabMetadata.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailTabMetadata.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,KAAK,SAAS,EAA6B,MAAM,sBAAsB,CAAC;AASjF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAO5D,KAAK,KAAK,GAAG;IACT,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,uBAAuB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5D,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,KAAK,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,EACrC,IAAI,EACJ,OAAO,EACP,UAAU,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,sBAAsB,EACtB,2BAA2B,EAC9B,EAAE,KAAK,2CA8IP"}
1
+ {"version":3,"file":"CatalogDetailTabMetadata.d.ts","sourceRoot":"","sources":["../../src/catalogDetail/CatalogDetailTabMetadata.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,KAAK,SAAS,EAAyC,MAAM,sBAAsB,CAAC;AAS7F,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAQ5D,KAAK,KAAK,GAAG;IACT,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,uBAAuB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5D,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,KAAK,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,8FAA8F;IAC9F,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,EACrC,IAAI,EACJ,OAAO,EACP,UAAU,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACjB,EAAE,KAAK,2CA0JP"}
@@ -2,19 +2,24 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  // (C) 2025-2026 GoodData Corporation
3
3
  import cx from "classnames";
4
4
  import { FormattedMessage, useIntl } from "react-intl";
5
- import { UiDate, UiIcon, UiTooltip } from "@gooddata/sdk-ui-kit";
5
+ import { UiDate, UiIcon, UiSkeleton, UiTooltip } from "@gooddata/sdk-ui-kit";
6
6
  import { isCatalogItemAttribute, isCatalogItemDataSet, isCatalogItemFact, isCatalogItemHidable, isCatalogItemMeasure, } from "../catalogItem/guards.js";
7
7
  import {} from "../catalogItem/types.js";
8
8
  import { CatalogDetailContentRow } from "./CatalogDetailContentRow.js";
9
9
  import { CatalogDetailGranularities } from "./CatalogDetailGranularities.js";
10
10
  import { CatalogDetailMetricSettings } from "./CatalogDetailMetricSettings.js";
11
11
  import { CatalogDetailTags } from "./CatalogDetailTags.js";
12
- export function CatalogDetailTabMetadata({ item, canEdit, onTagClick, onTagAdd, onTagRemove, onIsHiddenChange, onIsHiddenFromKdaChange, onMetricTypeChange, onFormatChange, separators, currencyFormatOverride, enableMetricFormatOverrides, }) {
12
+ import { CatalogDetailAccessRow } from "./share/CatalogDetailAccessRow.js";
13
+ export function CatalogDetailTabMetadata({ item, canEdit, onTagClick, onTagAdd, onTagRemove, onIsHiddenChange, onIsHiddenFromKdaChange, onMetricTypeChange, onFormatChange, separators, currencyFormatOverride, enableMetricFormatOverrides, accessSummary, accessUnavailable, onAccessOpen, showDatasetRow, }) {
13
14
  const intl = useIntl();
14
15
  const isMeasure = isCatalogItemMeasure(item);
15
16
  const isDataSet = isCatalogItemDataSet(item);
16
17
  const granularities = isDataSet ? (item.dataSet.attributes ?? []) : [];
17
- return (_jsxs("dl", { className: "gd-analytics-catalog-detail__tab-content", children: [(isCatalogItemAttribute(item) || isCatalogItemFact(item)) && item.dataSet ? (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.dataSet" }), content: item.dataSet.title })) : null, isDataSet && granularities.length > 0 ? (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.granularities" }), content: _jsx(CatalogDetailGranularities, { granularities: granularities }) })) : null, _jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.createdBy" }), content: item.createdBy ?? undefined }), _jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.createdAt" }), content: item.createdAt ? _jsx(UiDate, { date: item.createdAt, locale: intl.locale }) : undefined }), item.createdBy === item.updatedBy && !item.updatedBy ? null : (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.updatedBy" }), content: item.updatedBy ?? undefined })), item.createdAt?.getTime() === item.updatedAt?.getTime() ? null : (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.updatedAt" }), content: item.updatedAt ? _jsx(UiDate, { date: item.updatedAt, locale: intl.locale }) : undefined })), isCatalogItemHidable(item) ? (_jsx(CatalogDetailContentRow, { title: _jsxs(_Fragment, { children: [
18
+ const datasetTitle = isCatalogItemAttribute(item) || isCatalogItemFact(item) ? item.dataSet?.title : undefined;
19
+ return (_jsxs("dl", { className: "gd-analytics-catalog-detail__tab-content", children: [accessSummary && onAccessOpen ? (_jsx(CatalogDetailAccessRow, { summary: accessSummary, onOpen: onAccessOpen })) : accessUnavailable && onAccessOpen ? (
20
+ // Summary not available yet (loading or load error). Keep the row —
21
+ // Share is still reachable — with a placeholder rather than omitting it.
22
+ _jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.share.access.row.label" }), content: _jsx(UiSkeleton, { itemWidth: 200, itemHeight: 20 }) })) : null, showDatasetRow && datasetTitle ? (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.dataSet" }), content: datasetTitle })) : null, isDataSet && granularities.length > 0 ? (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.granularities" }), content: _jsx(CatalogDetailGranularities, { granularities: granularities }) })) : null, _jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.createdBy" }), content: item.createdBy ?? undefined }), _jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.createdAt" }), content: item.createdAt ? _jsx(UiDate, { date: item.createdAt, locale: intl.locale }) : undefined }), item.createdBy === item.updatedBy && !item.updatedBy ? null : (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.updatedBy" }), content: item.updatedBy ?? undefined })), item.createdAt?.getTime() === item.updatedAt?.getTime() ? null : (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.updatedAt" }), content: item.updatedAt ? _jsx(UiDate, { date: item.updatedAt, locale: intl.locale }) : undefined })), isCatalogItemHidable(item) ? (_jsx(CatalogDetailContentRow, { title: _jsxs(_Fragment, { children: [
18
23
  _jsx(FormattedMessage, { id: "analyticsCatalog.column.title.isHidden" }), _jsx(UiTooltip, { anchor: _jsx(UiIcon, { type: "question", size: 12, color: "complementary-6" }), content: _jsx(FormattedMessage, { id: "analyticsCatalog.column.isHidden.field.tooltip" }), arrowPlacement: "left", optimalPlacement: true, offset: 10, width: 280, triggerBy: ["hover", "click"] })
19
24
  ] }), content: _jsxs("label", { className: "input-checkbox-toggle", children: [
20
25
  _jsx("input", { type: "checkbox", checked: item.isHidden !== true, disabled: !canEdit, "aria-label": intl.formatMessage({
@@ -0,0 +1,19 @@
1
+ import type { IObjectAccessSummary } from "@gooddata/sdk-ui-ext";
2
+ /**
3
+ * @internal
4
+ */
5
+ export interface ICatalogDetailAccessRowProps {
6
+ summary: IObjectAccessSummary;
7
+ onOpen: () => void;
8
+ }
9
+ /**
10
+ * Inline metadata row showing the current access state. Composed of two chips:
11
+ *
12
+ * - State chip: lock (restricted) or earth (workspace-wide), with text describing
13
+ * the permission level.
14
+ * - Grantee count chip: users icon + "Shared with N" link that opens the dialog.
15
+ *
16
+ * @internal
17
+ */
18
+ export declare function CatalogDetailAccessRow({ summary, onOpen }: ICatalogDetailAccessRowProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=CatalogDetailAccessRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CatalogDetailAccessRow.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailAccessRow.tsx"],"names":[],"mappings":"AAIA,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;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,4BAA4B,2CA+CvF"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { FormattedMessage, useIntl } from "react-intl";
4
+ import { UiIcon } from "@gooddata/sdk-ui-kit";
5
+ import { catalogDetailAccessRow, catalogDetailAccessRowSharedLink, catalogDetailAccessRowState, } from "../../automation/testIds.js";
6
+ import { CatalogDetailContentRow } from "../CatalogDetailContentRow.js";
7
+ import { shareMessages } from "./messages.js";
8
+ /**
9
+ * Inline metadata row showing the current access state. Composed of two chips:
10
+ *
11
+ * - State chip: lock (restricted) or earth (workspace-wide), with text describing
12
+ * the permission level.
13
+ * - Grantee count chip: users icon + "Shared with N" link that opens the dialog.
14
+ *
15
+ * @internal
16
+ */
17
+ export function CatalogDetailAccessRow({ summary, onOpen }) {
18
+ const intl = useIntl();
19
+ const { generalAccess, workspaceLevel, granteeCount } = summary;
20
+ const stateText = generalAccess === "RESTRICTED"
21
+ ? intl.formatMessage(shareMessages.accessRowRestricted)
22
+ : workspaceLevel === "SHARE"
23
+ ? intl.formatMessage(shareMessages.accessRowWorkspaceShare)
24
+ : intl.formatMessage(shareMessages.accessRowWorkspaceView);
25
+ const stateIcon = generalAccess === "RESTRICTED" ? "lock" : "building";
26
+ return (_jsx(CatalogDetailContentRow, { title: _jsx(FormattedMessage, { ...shareMessages.accessRowLabel }), content: _jsxs("div", { className: "gd-analytics-catalog-detail__access-row", "data-testid": catalogDetailAccessRow, children: [
27
+ _jsxs("span", { className: "gd-analytics-catalog-detail__access-row__chip", "data-testid": catalogDetailAccessRowState, children: [
28
+ _jsx("span", { className: "gd-analytics-catalog-detail__access-row__chip-icon", children: _jsx(UiIcon, { type: stateIcon, size: 14, color: "complementary-7" }) }), _jsx("span", { children: stateText })
29
+ ] }), _jsxs("button", { type: "button", className: "gd-analytics-catalog-detail__access-row__chip gd-analytics-catalog-detail__access-row__shared-link", onClick: onOpen, "data-testid": catalogDetailAccessRowSharedLink, children: [
30
+ _jsx("span", { className: "gd-analytics-catalog-detail__access-row__chip-icon", children: _jsx(UiIcon, { type: "users", size: 14, color: "complementary-7" }) }), _jsx("span", { children: _jsx(FormattedMessage, { ...shareMessages.accessRowSharedWith, values: { count: granteeCount } }) })
31
+ ] })
32
+ ] }) }));
33
+ }
@@ -0,0 +1,17 @@
1
+ import type { IObjectShareLabel } from "@gooddata/sdk-ui-ext";
2
+ /**
3
+ * @internal
4
+ */
5
+ export interface ICatalogDetailLabelsProps {
6
+ /** Labels of the attribute, primary first is not required — sorted here. */
7
+ labels: IObjectShareLabel[];
8
+ }
9
+ /**
10
+ * LABELS column value in the detail header: shows the primary label title with a
11
+ * "(+N more)" suffix, and opens a read-only popup listing every label on click.
12
+ * Rendered only for attributes that have labels.
13
+ *
14
+ * @internal
15
+ */
16
+ export declare function CatalogDetailLabels({ labels }: ICatalogDetailLabelsProps): import("react/jsx-runtime").JSX.Element | null;
17
+ //# sourceMappingURL=CatalogDetailLabels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CatalogDetailLabels.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/CatalogDetailLabels.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAW9D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC,8EAA4E;IAC5E,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,EAAE,yBAAyB,kDA6DxE"}
@@ -0,0 +1,36 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { useMemo } from "react";
4
+ import { useIntl } from "react-intl";
5
+ import { UiLabelsList, UiPopover } from "@gooddata/sdk-ui-kit";
6
+ import { catalogDetailLabels, catalogDetailLabelsList, catalogDetailLabelsTrigger, } from "../../automation/testIds.js";
7
+ import { labelsMessages } from "./messages.js";
8
+ /**
9
+ * LABELS column value in the detail header: shows the primary label title with a
10
+ * "(+N more)" suffix, and opens a read-only popup listing every label on click.
11
+ * Rendered only for attributes that have labels.
12
+ *
13
+ * @internal
14
+ */
15
+ export function CatalogDetailLabels({ labels }) {
16
+ const intl = useIntl();
17
+ // Primary label leads the summary and the list; the rest follow in source order.
18
+ const ordered = useMemo(() => [...labels].sort((a, b) => Number(b.isPrimary) - Number(a.isPrimary)), [labels]);
19
+ const items = useMemo(() => ordered.map((label) => ({
20
+ id: label.id,
21
+ label: label.title,
22
+ // Only the primary (key) and the single default display label carry
23
+ // a qualifier; every other label shows just its name.
24
+ kind: label.isPrimary ? "primary" : label.isDefault ? "default" : undefined,
25
+ })), [ordered]);
26
+ if (ordered.length === 0) {
27
+ return null;
28
+ }
29
+ const remaining = ordered.length - 1;
30
+ return (_jsx(UiPopover, { title: intl.formatMessage(labelsMessages.popupTitle), closeVisible: true, closeText: intl.formatMessage(labelsMessages.popupClose),
31
+ // Always drop down from the link (left-aligned), like Figma — don't
32
+ // flip up over the cursor when the panel is near the viewport edge.
33
+ optimalPlacement: false,
34
+ // The labels list rows carry their own inset and sit flush.
35
+ contentPadding: "none", anchor: _jsxs("button", { type: "button", className: "gd-analytics-catalog-detail__labels", "data-testid": catalogDetailLabelsTrigger, "aria-label": intl.formatMessage(labelsMessages.triggerAriaLabel), children: [ordered[0].title, remaining > 0 ? (_jsxs(_Fragment, { children: [" (", _jsx("span", { className: "gd-analytics-catalog-detail__labels__more", children: intl.formatMessage(labelsMessages.more, { remaining }) }), ")"] })) : null] }), content: _jsx(UiLabelsList, { items: items, showHeading: false, dataTestId: catalogDetailLabelsList }), accessibilityConfig: { ariaLabel: intl.formatMessage(labelsMessages.popupTitle) }, "data-testid": catalogDetailLabels }));
36
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export interface IShareButtonProps {
5
+ onClick: () => void;
6
+ isDisabled?: boolean;
7
+ }
8
+ /**
9
+ * Catalog detail header trigger for the share dialog. Rendered in the
10
+ * `CatalogDetailActions` slot, immediately before the primary "Open" button.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function ShareButton({ onClick, isDisabled }: IShareButtonProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=ShareButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/catalogDetail/share/ShareButton.tsx"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,iBAAiB,2CAWrE"}