@backstage/plugin-catalog 2.0.8 → 2.0.9-next.1

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 (30) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/alpha/components/CatalogEntityPage.esm.js +46 -0
  3. package/dist/alpha/components/CatalogEntityPage.esm.js.map +1 -0
  4. package/dist/alpha/components/CatalogOverviewPage.esm.js +22 -0
  5. package/dist/alpha/components/CatalogOverviewPage.esm.js.map +1 -0
  6. package/dist/alpha/entityContents.esm.js +13 -43
  7. package/dist/alpha/entityContents.esm.js.map +1 -1
  8. package/dist/alpha/entityIconLinks.esm.js +1 -1
  9. package/dist/alpha/entityIconLinks.esm.js.map +1 -1
  10. package/dist/alpha/pages.esm.js +14 -44
  11. package/dist/alpha/pages.esm.js.map +1 -1
  12. package/dist/components/AboutCard/AboutCard.esm.js +4 -19
  13. package/dist/components/AboutCard/AboutCard.esm.js.map +1 -1
  14. package/dist/components/AboutCard/useCatalogSourceIconLinkProps.esm.js +25 -0
  15. package/dist/components/AboutCard/useCatalogSourceIconLinkProps.esm.js.map +1 -0
  16. package/dist/components/CatalogExportButton/CatalogExportButton.esm.js +1 -5
  17. package/dist/components/CatalogExportButton/CatalogExportButton.esm.js.map +1 -1
  18. package/dist/components/CatalogExportButton/CatalogExportType.esm.js +8 -0
  19. package/dist/components/CatalogExportButton/CatalogExportType.esm.js.map +1 -0
  20. package/dist/components/CatalogExportButton/file-download/useStreamingExport.esm.js +1 -1
  21. package/dist/components/CatalogExportButton/file-download/useStreamingExport.esm.js.map +1 -1
  22. package/dist/components/CatalogPage/DefaultCatalogPage.esm.js +1 -1
  23. package/dist/components/CatalogPage/DefaultCatalogPage.esm.js.map +1 -1
  24. package/dist/components/CatalogTable/CatalogTable.esm.js +1 -1
  25. package/dist/components/CatalogTable/CatalogTable.esm.js.map +1 -1
  26. package/dist/components/EntitySwitch/EntitySwitch.esm.js +1 -1
  27. package/dist/plugins/catalog/package.json.esm.js +1 -1
  28. package/package.json +26 -26
  29. package/dist/alpha/components/EntityLayout/index.esm.js +0 -2
  30. package/dist/alpha/components/EntityLayout/index.esm.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @backstage/plugin-catalog
2
2
 
3
+ ## 2.0.9-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - e3781a3: Fixed circular dependency warnings when building the catalog plugin.
8
+ - d421187: Reduced the initial app bundle size by loading page and optional UI implementations only when their extensions render.
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.18.14-next.1
11
+ - @backstage/plugin-scaffolder-common@2.3.0-next.1
12
+ - @backstage/frontend-plugin-api@0.18.1-next.0
13
+ - @backstage/plugin-catalog-react@3.2.3-next.1
14
+ - @backstage/ui@0.18.0-next.1
15
+ - @backstage/integration-react@1.2.22-next.0
16
+ - @backstage/core-compat-api@0.5.15-next.1
17
+ - @backstage/core-plugin-api@1.12.10-next.0
18
+ - @backstage/plugin-search-react@1.11.8-next.1
19
+ - @backstage/plugin-techdocs-react@1.3.15-next.1
20
+ - @backstage/catalog-client@1.16.2-next.0
21
+ - @backstage/plugin-permission-react@0.5.5-next.0
22
+
23
+ ## 2.0.9-next.0
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies
28
+ - @backstage/plugin-scaffolder-common@2.3.0-next.0
29
+ - @backstage/ui@0.17.2-next.0
30
+ - @backstage/plugin-catalog-react@3.2.2-next.0
31
+ - @backstage/core-components@0.18.14-next.0
32
+ - @backstage/core-compat-api@0.5.15-next.0
33
+ - @backstage/plugin-search-react@1.11.8-next.0
34
+ - @backstage/plugin-techdocs-react@1.3.15-next.0
35
+
3
36
  ## 2.0.8
4
37
 
5
38
  ### Patch Changes
@@ -0,0 +1,46 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { stringifyEntityRef } from '@backstage/catalog-model';
3
+ import { useRouteRefParams } from '@backstage/core-plugin-api';
4
+ import { entityRouteRef, AsyncEntityProvider } from '@backstage/plugin-catalog-react';
5
+ import { useEntityFromUrl } from '../../components/CatalogEntityPage/useEntityFromUrl.esm.js';
6
+ import { EntityLayout } from './EntityLayout/EntityLayout.esm.js';
7
+ import { EntityLayoutBui } from './EntityLayout/EntityLayoutBui.esm.js';
8
+
9
+ function CatalogEntityPage(props) {
10
+ const routeParams = useRouteRefParams(entityRouteRef);
11
+ const entityFromUrl = useEntityFromUrl();
12
+ const matchesRoute = !!entityFromUrl.entity && stringifyEntityRef(entityFromUrl.entity) === stringifyEntityRef(routeParams);
13
+ const entity = matchesRoute ? entityFromUrl.entity : void 0;
14
+ const entityProviderProps = {
15
+ ...entityFromUrl,
16
+ entity,
17
+ loading: entityFromUrl.loading || !!entityFromUrl.entity && !matchesRoute
18
+ };
19
+ const filteredMenuItems = entity ? props.menuItems.filter((item) => item.filter(entity)).map(({ data, node }) => ({ data, node })) : [];
20
+ const HeaderComponent = entity ? props.headerLayouts.find((layout2) => layout2.filter(entity))?.Component : void 0;
21
+ const legacyHeader = entity ? props.headers.find((header) => header.filter(entity))?.element : void 0;
22
+ const layout = HeaderComponent || !legacyHeader ? /* @__PURE__ */ jsx(
23
+ EntityLayoutBui,
24
+ {
25
+ routes: props.routes,
26
+ HeaderComponent,
27
+ contextMenuItems: filteredMenuItems,
28
+ groupDefinitions: props.groupDefinitions,
29
+ defaultContentOrder: props.defaultContentOrder
30
+ }
31
+ ) : /* @__PURE__ */ jsx(
32
+ EntityLayout,
33
+ {
34
+ routes: props.routes,
35
+ header: legacyHeader,
36
+ contextMenuItems: filteredMenuItems,
37
+ groupDefinitions: props.groupDefinitions,
38
+ defaultContentOrder: props.defaultContentOrder,
39
+ showNavItemIcons: props.showNavItemIcons
40
+ }
41
+ );
42
+ return /* @__PURE__ */ jsx(AsyncEntityProvider, { ...entityProviderProps, children: layout });
43
+ }
44
+
45
+ export { CatalogEntityPage };
46
+ //# sourceMappingURL=CatalogEntityPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CatalogEntityPage.esm.js","sources":["../../../src/alpha/components/CatalogEntityPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentType, ReactElement } from 'react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useRouteRefParams } from '@backstage/core-plugin-api';\nimport {\n AsyncEntityProvider,\n entityRouteRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n type EntityContentGroupDefinitions,\n type EntityHeaderLayoutProps,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { useEntityFromUrl } from '../../components/CatalogEntityPage/useEntityFromUrl';\nimport { EntityLayout } from './EntityLayout';\nimport { EntityLayoutBui } from './EntityLayout/EntityLayoutBui';\nimport type { EntityLayoutRoute } from './EntityLayout/entityLayoutRoutes';\nimport type { EntityContextMenuItemDataWithNode } from './EntityContextMenu';\n\nexport interface CatalogEntityPageProps {\n menuItems: Array<\n EntityContextMenuItemDataWithNode & { filter: (entity: Entity) => boolean }\n >;\n headerLayouts: Array<{\n Component: ComponentType<EntityHeaderLayoutProps>;\n filter: (entity: Entity) => boolean;\n }>;\n headers: Array<{\n element?: ReactElement;\n filter: (entity: Entity) => boolean;\n }>;\n routes: EntityLayoutRoute[];\n groupDefinitions: EntityContentGroupDefinitions;\n defaultContentOrder: 'title' | 'natural';\n showNavItemIcons: boolean;\n}\n\nexport function CatalogEntityPage(props: CatalogEntityPageProps) {\n const routeParams = useRouteRefParams(entityRouteRef);\n const entityFromUrl = useEntityFromUrl();\n const matchesRoute =\n !!entityFromUrl.entity &&\n stringifyEntityRef(entityFromUrl.entity) ===\n stringifyEntityRef(routeParams);\n const entity = matchesRoute ? entityFromUrl.entity : undefined;\n const entityProviderProps = {\n ...entityFromUrl,\n entity,\n loading: entityFromUrl.loading || (!!entityFromUrl.entity && !matchesRoute),\n };\n const filteredMenuItems = entity\n ? props.menuItems\n .filter(item => item.filter(entity))\n .map(({ data, node }) => ({ data, node }))\n : [];\n\n const HeaderComponent = entity\n ? props.headerLayouts.find(layout => layout.filter(entity))?.Component\n : undefined;\n const legacyHeader = entity\n ? props.headers.find(header => header.filter(entity))?.element\n : undefined;\n\n const layout =\n HeaderComponent || !legacyHeader ? (\n <EntityLayoutBui\n routes={props.routes}\n HeaderComponent={HeaderComponent}\n contextMenuItems={filteredMenuItems}\n groupDefinitions={props.groupDefinitions}\n defaultContentOrder={props.defaultContentOrder}\n />\n ) : (\n <EntityLayout\n routes={props.routes}\n header={legacyHeader}\n contextMenuItems={filteredMenuItems}\n groupDefinitions={props.groupDefinitions}\n defaultContentOrder={props.defaultContentOrder}\n showNavItemIcons={props.showNavItemIcons}\n />\n );\n\n return (\n <AsyncEntityProvider {...entityProviderProps}>{layout}</AsyncEntityProvider>\n );\n}\n"],"names":["layout"],"mappings":";;;;;;;;AAmDO,SAAS,kBAAkB,KAAA,EAA+B;AAC/D,EAAA,MAAM,WAAA,GAAc,kBAAkB,cAAc,CAAA;AACpD,EAAA,MAAM,gBAAgB,gBAAA,EAAiB;AACvC,EAAA,MAAM,YAAA,GACJ,CAAC,CAAC,aAAA,CAAc,MAAA,IAChB,mBAAmB,aAAA,CAAc,MAAM,CAAA,KACrC,kBAAA,CAAmB,WAAW,CAAA;AAClC,EAAA,MAAM,MAAA,GAAS,YAAA,GAAe,aAAA,CAAc,MAAA,GAAS,MAAA;AACrD,EAAA,MAAM,mBAAA,GAAsB;AAAA,IAC1B,GAAG,aAAA;AAAA,IACH,MAAA;AAAA,IACA,SAAS,aAAA,CAAc,OAAA,IAAY,CAAC,CAAC,aAAA,CAAc,UAAU,CAAC;AAAA,GAChE;AACA,EAAA,MAAM,iBAAA,GAAoB,SACtB,KAAA,CAAM,SAAA,CACH,OAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA,CAClC,IAAI,CAAC,EAAE,MAAM,IAAA,EAAK,MAAO,EAAE,IAAA,EAAM,IAAA,EAAK,CAAE,CAAA,GAC3C,EAAC;AAEL,EAAA,MAAM,eAAA,GAAkB,MAAA,GACpB,KAAA,CAAM,aAAA,CAAc,IAAA,CAAK,CAAAA,OAAAA,KAAUA,OAAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA,EAAG,SAAA,GAC3D,MAAA;AACJ,EAAA,MAAM,YAAA,GAAe,MAAA,GACjB,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,CAAA,MAAA,KAAU,MAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA,EAAG,OAAA,GACrD,MAAA;AAEJ,EAAA,MAAM,MAAA,GACJ,eAAA,IAAmB,CAAC,YAAA,mBAClB,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,eAAA;AAAA,MACA,gBAAA,EAAkB,iBAAA;AAAA,MAClB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,qBAAqB,KAAA,CAAM;AAAA;AAAA,GAC7B,mBAEA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,MAAA,EAAQ,YAAA;AAAA,MACR,gBAAA,EAAkB,iBAAA;AAAA,MAClB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,qBAAqB,KAAA,CAAM,mBAAA;AAAA,MAC3B,kBAAkB,KAAA,CAAM;AAAA;AAAA,GAC1B;AAGJ,EAAA,uBACE,GAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,mBAAA,EAAsB,QAAA,EAAA,MAAA,EAAO,CAAA;AAE1D;;;;"}
@@ -0,0 +1,22 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { lazy } from 'react';
3
+ import { ExtensionBoundary } from '@backstage/frontend-plugin-api';
4
+ import { useEntity } from '@backstage/plugin-catalog-react';
5
+
6
+ const LazyDefaultLayoutComponent = lazy(
7
+ () => import('../DefaultEntityContentLayout.esm.js').then((m) => ({
8
+ default: m.DefaultEntityContentLayout
9
+ }))
10
+ );
11
+ function CatalogOverviewPage(props) {
12
+ const { entity } = useEntity();
13
+ const layout = props.layouts.find((item) => item.filter(entity));
14
+ const cards = props.cards.filter((card) => card.filter(entity));
15
+ if (layout) {
16
+ return /* @__PURE__ */ jsx(layout.Component, { cards });
17
+ }
18
+ return /* @__PURE__ */ jsx(ExtensionBoundary, { node: props.node, children: /* @__PURE__ */ jsx(LazyDefaultLayoutComponent, { cards }) });
19
+ }
20
+
21
+ export { CatalogOverviewPage };
22
+ //# sourceMappingURL=CatalogOverviewPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CatalogOverviewPage.esm.js","sources":["../../../src/alpha/components/CatalogOverviewPage.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentType, lazy as reactLazy, ReactElement } from 'react';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n type AppNode,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport {\n type EntityCardType,\n type EntityContentLayoutProps,\n} from '@backstage/plugin-catalog-react/alpha';\n\nconst LazyDefaultLayoutComponent = reactLazy(() =>\n import('../DefaultEntityContentLayout').then(m => ({\n default: m.DefaultEntityContentLayout,\n })),\n);\n\nexport interface CatalogOverviewPageProps {\n node: AppNode;\n layouts: Array<{\n filter: (entity: Entity) => boolean;\n Component: ComponentType<EntityContentLayoutProps>;\n }>;\n cards: Array<{\n element: ReactElement;\n type?: EntityCardType;\n filter: (entity: Entity) => boolean;\n }>;\n}\n\nexport function CatalogOverviewPage(props: CatalogOverviewPageProps) {\n const { entity } = useEntity();\n const layout = props.layouts.find(item => item.filter(entity));\n const cards = props.cards.filter(card => card.filter(entity));\n\n if (layout) {\n return <layout.Component cards={cards} />;\n }\n\n return (\n <ExtensionBoundary node={props.node}>\n <LazyDefaultLayoutComponent cards={cards} />\n </ExtensionBoundary>\n );\n}\n"],"names":["reactLazy"],"mappings":";;;;;AA4BA,MAAM,0BAAA,GAA6BA,IAAA;AAAA,EAAU,MAC3C,OAAO,sCAA+B,CAAA,CAAE,KAAK,CAAA,CAAA,MAAM;AAAA,IACjD,SAAS,CAAA,CAAE;AAAA,GACb,CAAE;AACJ,CAAA;AAeO,SAAS,oBAAoB,KAAA,EAAiC;AACnE,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,UAAQ,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAC7D,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,MAAA,CAAO,UAAQ,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAE5D,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,uBAAO,GAAA,CAAC,MAAA,CAAO,SAAA,EAAP,EAAiB,KAAA,EAAc,CAAA;AAAA,EACzC;AAEA,EAAA,uBACE,GAAA,CAAC,qBAAkB,IAAA,EAAM,KAAA,CAAM,MAC7B,QAAA,kBAAA,GAAA,CAAC,0BAAA,EAAA,EAA2B,OAAc,CAAA,EAC5C,CAAA;AAEJ;;;;"}
@@ -1,9 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { lazy } from 'react';
3
- import { coreExtensionData, createExtensionInput, ExtensionBoundary } from '@backstage/frontend-plugin-api';
2
+ import { coreExtensionData, createExtensionInput } from '@backstage/frontend-plugin-api';
4
3
  import { EntityContentBlueprint, EntityContentLayoutBlueprint, EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha';
5
4
  import { buildFilterFn } from './filter/FilterWrapper.esm.js';
6
- import { useEntity } from '@backstage/plugin-catalog-react';
7
5
 
8
6
  const catalogOverviewEntityContent = EntityContentBlueprint.makeWithOverrides({
9
7
  name: "overview",
@@ -26,33 +24,18 @@ const catalogOverviewEntityContent = EntityContentBlueprint.makeWithOverrides({
26
24
  title: "Overview",
27
25
  group: "overview",
28
26
  loader: async () => {
29
- const LazyDefaultLayoutComponent = lazy(
30
- () => import('./DefaultEntityContentLayout.esm.js').then((m) => ({
31
- default: m.DefaultEntityContentLayout
32
- }))
33
- );
34
- const DefaultLayoutComponent = (props) => {
35
- return /* @__PURE__ */ jsx(ExtensionBoundary, { node, children: /* @__PURE__ */ jsx(LazyDefaultLayoutComponent, { ...props }) });
36
- };
37
- const layouts = [
38
- ...inputs.layouts.map((layout) => ({
39
- filter: buildFilterFn(
40
- layout.get(
41
- EntityContentLayoutBlueprint.dataRefs.filterFunction
42
- ),
43
- layout.get(
44
- EntityContentLayoutBlueprint.dataRefs.filterExpression
45
- )
46
- ),
47
- Component: layout.get(
48
- EntityContentLayoutBlueprint.dataRefs.component
27
+ const { CatalogOverviewPage } = await import('./components/CatalogOverviewPage.esm.js');
28
+ const layouts = inputs.layouts.map((layout) => ({
29
+ filter: buildFilterFn(
30
+ layout.get(EntityContentLayoutBlueprint.dataRefs.filterFunction),
31
+ layout.get(
32
+ EntityContentLayoutBlueprint.dataRefs.filterExpression
49
33
  )
50
- })),
51
- {
52
- filter: buildFilterFn(),
53
- Component: DefaultLayoutComponent
54
- }
55
- ];
34
+ ),
35
+ Component: layout.get(
36
+ EntityContentLayoutBlueprint.dataRefs.component
37
+ )
38
+ }));
56
39
  const cards = inputs.cards.map((card) => ({
57
40
  element: card.get(coreExtensionData.reactElement),
58
41
  type: card.get(EntityCardBlueprint.dataRefs.type),
@@ -61,20 +44,7 @@ const catalogOverviewEntityContent = EntityContentBlueprint.makeWithOverrides({
61
44
  card.get(EntityContentBlueprint.dataRefs.filterExpression)
62
45
  )
63
46
  }));
64
- const Component = () => {
65
- const { entity } = useEntity();
66
- const layout = layouts.find((l) => l.filter(entity));
67
- if (!layout) {
68
- throw new Error("No layout found for entity");
69
- }
70
- return /* @__PURE__ */ jsx(
71
- layout.Component,
72
- {
73
- cards: cards.filter((card) => card.filter(entity))
74
- }
75
- );
76
- };
77
- return /* @__PURE__ */ jsx(Component, {});
47
+ return /* @__PURE__ */ jsx(CatalogOverviewPage, { node, layouts, cards });
78
48
  }
79
49
  });
80
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"entityContents.esm.js","sources":["../../src/alpha/entityContents.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lazy as reactLazy } from 'react';\nimport {\n coreExtensionData,\n createExtensionInput,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport {\n EntityCardBlueprint,\n EntityContentBlueprint,\n EntityContentLayoutBlueprint,\n EntityContentLayoutProps,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { buildFilterFn } from './filter/FilterWrapper';\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nexport const catalogOverviewEntityContent =\n EntityContentBlueprint.makeWithOverrides({\n name: 'overview',\n inputs: {\n layouts: createExtensionInput([\n EntityContentLayoutBlueprint.dataRefs.filterFunction.optional(),\n EntityContentLayoutBlueprint.dataRefs.filterExpression.optional(),\n EntityContentLayoutBlueprint.dataRefs.component,\n ]),\n cards: createExtensionInput([\n coreExtensionData.reactElement,\n EntityContentBlueprint.dataRefs.filterFunction.optional(),\n EntityContentBlueprint.dataRefs.filterExpression.optional(),\n EntityCardBlueprint.dataRefs.type.optional(),\n ]),\n },\n factory: (originalFactory, { node, inputs }) => {\n return originalFactory({\n path: '/',\n title: 'Overview',\n group: 'overview',\n loader: async () => {\n const LazyDefaultLayoutComponent = reactLazy(() =>\n import('./DefaultEntityContentLayout').then(m => ({\n default: m.DefaultEntityContentLayout,\n })),\n );\n\n const DefaultLayoutComponent = (props: EntityContentLayoutProps) => {\n return (\n <ExtensionBoundary node={node}>\n <LazyDefaultLayoutComponent {...props} />\n </ExtensionBoundary>\n );\n };\n\n const layouts = [\n ...inputs.layouts.map(layout => ({\n filter: buildFilterFn(\n layout.get(\n EntityContentLayoutBlueprint.dataRefs.filterFunction,\n ),\n layout.get(\n EntityContentLayoutBlueprint.dataRefs.filterExpression,\n ),\n ),\n Component: layout.get(\n EntityContentLayoutBlueprint.dataRefs.component,\n ),\n })),\n {\n filter: buildFilterFn(),\n Component: DefaultLayoutComponent,\n },\n ];\n\n const cards = inputs.cards.map(card => ({\n element: card.get(coreExtensionData.reactElement),\n type: card.get(EntityCardBlueprint.dataRefs.type),\n filter: buildFilterFn(\n card.get(EntityContentBlueprint.dataRefs.filterFunction),\n card.get(EntityContentBlueprint.dataRefs.filterExpression),\n ),\n }));\n\n const Component = () => {\n const { entity } = useEntity();\n\n // Use the first layout that matches the entity filter\n const layout = layouts.find(l => l.filter(entity));\n if (!layout) {\n throw new Error('No layout found for entity'); // Shouldn't be able to happen\n }\n\n return (\n <layout.Component\n cards={cards.filter(card => card.filter(entity))}\n />\n );\n };\n\n return <Component />;\n },\n });\n },\n });\n\nexport default [catalogOverviewEntityContent];\n"],"names":["reactLazy"],"mappings":"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"}
1
+ {"version":3,"file":"entityContents.esm.js","sources":["../../src/alpha/entityContents.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreExtensionData,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport {\n EntityCardBlueprint,\n EntityContentBlueprint,\n EntityContentLayoutBlueprint,\n} from '@backstage/plugin-catalog-react/alpha';\nimport { buildFilterFn } from './filter/FilterWrapper';\n\nexport const catalogOverviewEntityContent =\n EntityContentBlueprint.makeWithOverrides({\n name: 'overview',\n inputs: {\n layouts: createExtensionInput([\n EntityContentLayoutBlueprint.dataRefs.filterFunction.optional(),\n EntityContentLayoutBlueprint.dataRefs.filterExpression.optional(),\n EntityContentLayoutBlueprint.dataRefs.component,\n ]),\n cards: createExtensionInput([\n coreExtensionData.reactElement,\n EntityContentBlueprint.dataRefs.filterFunction.optional(),\n EntityContentBlueprint.dataRefs.filterExpression.optional(),\n EntityCardBlueprint.dataRefs.type.optional(),\n ]),\n },\n factory: (originalFactory, { node, inputs }) => {\n return originalFactory({\n path: '/',\n title: 'Overview',\n group: 'overview',\n loader: async () => {\n const { CatalogOverviewPage } = await import(\n './components/CatalogOverviewPage'\n );\n const layouts = inputs.layouts.map(layout => ({\n filter: buildFilterFn(\n layout.get(EntityContentLayoutBlueprint.dataRefs.filterFunction),\n layout.get(\n EntityContentLayoutBlueprint.dataRefs.filterExpression,\n ),\n ),\n Component: layout.get(\n EntityContentLayoutBlueprint.dataRefs.component,\n ),\n }));\n\n const cards = inputs.cards.map(card => ({\n element: card.get(coreExtensionData.reactElement),\n type: card.get(EntityCardBlueprint.dataRefs.type),\n filter: buildFilterFn(\n card.get(EntityContentBlueprint.dataRefs.filterFunction),\n card.get(EntityContentBlueprint.dataRefs.filterExpression),\n ),\n }));\n\n return (\n <CatalogOverviewPage node={node} layouts={layouts} cards={cards} />\n );\n },\n });\n },\n });\n\nexport default [catalogOverviewEntityContent];\n"],"names":[],"mappings":";;;;;AA2BO,MAAM,4BAAA,GACX,uBAAuB,iBAAA,CAAkB;AAAA,EACvC,IAAA,EAAM,UAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,SAAS,oBAAA,CAAqB;AAAA,MAC5B,4BAAA,CAA6B,QAAA,CAAS,cAAA,CAAe,QAAA,EAAS;AAAA,MAC9D,4BAAA,CAA6B,QAAA,CAAS,gBAAA,CAAiB,QAAA,EAAS;AAAA,MAChE,6BAA6B,QAAA,CAAS;AAAA,KACvC,CAAA;AAAA,IACD,OAAO,oBAAA,CAAqB;AAAA,MAC1B,iBAAA,CAAkB,YAAA;AAAA,MAClB,sBAAA,CAAuB,QAAA,CAAS,cAAA,CAAe,QAAA,EAAS;AAAA,MACxD,sBAAA,CAAuB,QAAA,CAAS,gBAAA,CAAiB,QAAA,EAAS;AAAA,MAC1D,mBAAA,CAAoB,QAAA,CAAS,IAAA,CAAK,QAAA;AAAS,KAC5C;AAAA,GACH;AAAA,EACA,SAAS,CAAC,eAAA,EAAiB,EAAE,IAAA,EAAM,QAAO,KAAM;AAC9C,IAAA,OAAO,eAAA,CAAgB;AAAA,MACrB,IAAA,EAAM,GAAA;AAAA,MACN,KAAA,EAAO,UAAA;AAAA,MACP,KAAA,EAAO,UAAA;AAAA,MACP,QAAQ,YAAY;AAClB,QAAA,MAAM,EAAE,mBAAA,EAAoB,GAAI,MAAM,OACpC,yCACF,CAAA;AACA,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,MAAW;AAAA,UAC5C,MAAA,EAAQ,aAAA;AAAA,YACN,MAAA,CAAO,GAAA,CAAI,4BAAA,CAA6B,QAAA,CAAS,cAAc,CAAA;AAAA,YAC/D,MAAA,CAAO,GAAA;AAAA,cACL,6BAA6B,QAAA,CAAS;AAAA;AACxC,WACF;AAAA,UACA,WAAW,MAAA,CAAO,GAAA;AAAA,YAChB,6BAA6B,QAAA,CAAS;AAAA;AACxC,SACF,CAAE,CAAA;AAEF,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,UACtC,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,iBAAA,CAAkB,YAAY,CAAA;AAAA,UAChD,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,mBAAA,CAAoB,SAAS,IAAI,CAAA;AAAA,UAChD,MAAA,EAAQ,aAAA;AAAA,YACN,IAAA,CAAK,GAAA,CAAI,sBAAA,CAAuB,QAAA,CAAS,cAAc,CAAA;AAAA,YACvD,IAAA,CAAK,GAAA,CAAI,sBAAA,CAAuB,QAAA,CAAS,gBAAgB;AAAA;AAC3D,SACF,CAAE,CAAA;AAEF,QAAA,uBACE,GAAA,CAAC,mBAAA,EAAA,EAAoB,IAAA,EAAY,OAAA,EAAkB,KAAA,EAAc,CAAA;AAAA,MAErE;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;AAEH,qBAAe,CAAC,4BAA4B,CAAA;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha';
2
- import { useCatalogSourceIconLinkProps } from '../components/AboutCard/AboutCard.esm.js';
2
+ import { useCatalogSourceIconLinkProps } from '../components/AboutCard/useCatalogSourceIconLinkProps.esm.js';
3
3
 
4
4
  const catalogViewSourceEntityIconLink = EntityIconLinkBlueprint.make({
5
5
  name: "view-source",
@@ -1 +1 @@
1
- {"version":3,"file":"entityIconLinks.esm.js","sources":["../../src/alpha/entityIconLinks.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha';\nimport { useCatalogSourceIconLinkProps } from '../components/AboutCard/AboutCard';\n\nconst catalogViewSourceEntityIconLink = EntityIconLinkBlueprint.make({\n name: 'view-source',\n params: {\n useProps: useCatalogSourceIconLinkProps,\n },\n});\n\nexport default [catalogViewSourceEntityIconLink];\n"],"names":[],"mappings":";;;AAmBA,MAAM,+BAAA,GAAkC,wBAAwB,IAAA,CAAK;AAAA,EACnE,IAAA,EAAM,aAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAC,CAAA;AAED,sBAAe,CAAC,+BAA+B,CAAA;;;;"}
1
+ {"version":3,"file":"entityIconLinks.esm.js","sources":["../../src/alpha/entityIconLinks.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha';\nimport { useCatalogSourceIconLinkProps } from '../components/AboutCard/useCatalogSourceIconLinkProps';\n\nconst catalogViewSourceEntityIconLink = EntityIconLinkBlueprint.make({\n name: 'view-source',\n params: {\n useProps: useCatalogSourceIconLinkProps,\n },\n});\n\nexport default [catalogViewSourceEntityIconLink];\n"],"names":[],"mappings":";;;AAmBA,MAAM,+BAAA,GAAkC,wBAAwB,IAAA,CAAK;AAAA,EACnE,IAAA,EAAM,aAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAC,CAAA;AAED,sBAAe,CAAC,+BAA+B,CAAA;;;;"}
@@ -1,14 +1,11 @@
1
1
  import { jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { convertLegacyRouteRef } from '@backstage/core-compat-api';
3
- import { stringifyEntityRef } from '@backstage/catalog-model';
4
- import { useRouteRefParams } from '@backstage/core-plugin-api';
5
3
  import { createExtensionDataRef, createExtensionBlueprint, PageBlueprint, coreExtensionData, createExtensionInput } from '@backstage/frontend-plugin-api';
6
4
  import { z } from 'zod/v4';
7
- import { entityRouteRef, AsyncEntityProvider } from '@backstage/plugin-catalog-react';
5
+ import { entityRouteRef } from '@backstage/plugin-catalog-react';
8
6
  import { EntityContextMenuItemBlueprint, EntityHeaderLayoutBlueprint, EntityHeaderBlueprint, defaultEntityContentGroupDefinitions, EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
9
7
  import CategoryIcon from '@material-ui/icons/Category';
10
8
  import { rootRouteRef } from '../routes.esm.js';
11
- import { useEntityFromUrl } from '../components/CatalogEntityPage/useEntityFromUrl.esm.js';
12
9
  import { buildFilterFn } from './filter/FilterWrapper.esm.js';
13
10
 
14
11
  const catalogExportConfigDataRef = createExtensionDataRef().with({
@@ -145,10 +142,7 @@ const catalogEntityPage = PageBlueprint.makeWithOverrides({
145
142
  routeRef: convertLegacyRouteRef(entityRouteRef),
146
143
  // READ THE ABOVE
147
144
  loader: async () => {
148
- const [{ EntityLayout }, { EntityLayoutBui }] = await Promise.all([
149
- import('./components/EntityLayout/index.esm.js'),
150
- import('./components/EntityLayout/EntityLayoutBui.esm.js')
151
- ]);
145
+ const { CatalogEntityPage } = await import('./components/CatalogEntityPage.esm.js');
152
146
  const menuItems = inputs.contextMenuItems.map((item) => ({
153
147
  data: item.get(EntityContextMenuItemBlueprint.dataRefs.data),
154
148
  node: item.node,
@@ -191,42 +185,18 @@ const catalogEntityPage = PageBlueprint.makeWithOverrides({
191
185
  ),
192
186
  children: output.get(coreExtensionData.reactElement)
193
187
  }));
194
- const Component = () => {
195
- const routeParams = useRouteRefParams(entityRouteRef);
196
- const entityFromUrl = useEntityFromUrl();
197
- const matchesRoute = !!entityFromUrl.entity && stringifyEntityRef(entityFromUrl.entity) === stringifyEntityRef(routeParams);
198
- const entity = matchesRoute ? entityFromUrl.entity : void 0;
199
- const entityProviderProps = {
200
- ...entityFromUrl,
201
- entity,
202
- loading: entityFromUrl.loading || !!entityFromUrl.entity && !matchesRoute
203
- };
204
- const filteredMenuItems = entity ? menuItems.filter((i) => i.filter(entity)).map(({ data, node }) => ({ data, node })) : [];
205
- const HeaderComponent = entity ? headerLayouts.find((layout2) => layout2.filter(entity))?.Component : void 0;
206
- const legacyHeader = entity ? headers.find((header) => header.filter(entity))?.element : void 0;
207
- const layout = HeaderComponent || !legacyHeader ? /* @__PURE__ */ jsx(
208
- EntityLayoutBui,
209
- {
210
- routes,
211
- HeaderComponent,
212
- contextMenuItems: filteredMenuItems,
213
- groupDefinitions,
214
- defaultContentOrder: config.defaultContentOrder
215
- }
216
- ) : /* @__PURE__ */ jsx(
217
- EntityLayout,
218
- {
219
- routes,
220
- header: legacyHeader,
221
- contextMenuItems: filteredMenuItems,
222
- groupDefinitions,
223
- defaultContentOrder: config.defaultContentOrder,
224
- showNavItemIcons: config.showNavItemIcons
225
- }
226
- );
227
- return /* @__PURE__ */ jsx(AsyncEntityProvider, { ...entityProviderProps, children: layout });
228
- };
229
- return /* @__PURE__ */ jsx(Component, {});
188
+ return /* @__PURE__ */ jsx(
189
+ CatalogEntityPage,
190
+ {
191
+ menuItems,
192
+ headerLayouts,
193
+ headers,
194
+ routes,
195
+ groupDefinitions,
196
+ defaultContentOrder: config.defaultContentOrder,
197
+ showNavItemIcons: config.showNavItemIcons
198
+ }
199
+ );
230
200
  }
231
201
  });
232
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pages.esm.js","sources":["../../src/alpha/pages.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { convertLegacyRouteRef } from '@backstage/core-compat-api';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { useRouteRefParams } from '@backstage/core-plugin-api';\nimport {\n coreExtensionData,\n createExtensionInput,\n createExtensionDataRef,\n createExtensionBlueprint,\n PageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { z } from 'zod/v4';\nimport {\n AsyncEntityProvider,\n entityRouteRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n defaultEntityContentGroupDefinitions,\n EntityContentBlueprint,\n EntityContextMenuItemBlueprint,\n EntityHeaderBlueprint,\n EntityHeaderLayoutBlueprint,\n EntityContentGroupDefinitions,\n} from '@backstage/plugin-catalog-react/alpha';\nimport CategoryIcon from '@material-ui/icons/Category';\nimport { rootRouteRef } from '../routes';\nimport { useEntityFromUrl } from '../components/CatalogEntityPage/useEntityFromUrl';\nimport { buildFilterFn } from './filter/FilterWrapper';\nimport type { CatalogExportSettings } from '../components/CatalogExportButton';\n\nconst catalogExportConfigDataRef = createExtensionDataRef<{\n exporters?: CatalogExportSettings['exporters'];\n columns?: CatalogExportSettings['columns'];\n onSuccess?: CatalogExportSettings['onSuccess'];\n onError?: CatalogExportSettings['onError'];\n}>().with({\n id: 'catalog.export-customization',\n});\n\n/**\n * Blueprint for creating catalog export configuration extensions.\n * @public\n */\nexport const CatalogExportConfigBlueprint = createExtensionBlueprint({\n kind: 'catalog-export-config',\n attachTo: { id: 'page:catalog', input: 'exportConfig' },\n output: [catalogExportConfigDataRef],\n factory(params: {\n exporters?: CatalogExportSettings['exporters'];\n columns?: CatalogExportSettings['columns'];\n onSuccess?: CatalogExportSettings['onSuccess'];\n onError?: CatalogExportSettings['onError'];\n }) {\n return [catalogExportConfigDataRef(params)];\n },\n});\n\nexport const catalogPage = PageBlueprint.makeWithOverrides({\n inputs: {\n filters: createExtensionInput([coreExtensionData.reactElement]),\n exportConfig: createExtensionInput([catalogExportConfigDataRef.optional()]),\n },\n configSchema: {\n pagination: z\n .union([\n z.boolean(),\n z.object({\n mode: z.enum(['cursor', 'offset']),\n limit: z.number().optional(),\n offset: z.number().optional(),\n }),\n ])\n .default(true),\n exportSettings: z\n .object({\n /** When true, displays the export button in the catalog interface. */\n enabled: z.boolean().optional(),\n /**\n * When true, hides the built-in CSV and JSON export options.\n * Useful when only custom exporters (provided via extensions) should be available.\n */\n disableBuiltinExporters: z.boolean().optional(),\n })\n .optional(),\n },\n factory(originalFactory, { inputs, config }) {\n return originalFactory({\n path: '/catalog',\n routeRef: rootRouteRef,\n icon: <CategoryIcon fontSize=\"inherit\" />,\n title: 'Catalog',\n loader: async () => {\n const { NfsDefaultCatalogPage } = await import(\n '../components/CatalogPage/DefaultCatalogPage'\n );\n const filters = inputs.filters.map(filter =>\n filter.get(coreExtensionData.reactElement),\n );\n\n // Merge export customizers from all attached extensions\n const mergedExportSettings: CatalogExportSettings = {\n ...config.exportSettings,\n };\n\n for (const exportConfigInput of inputs.exportConfig) {\n const data = exportConfigInput.get(catalogExportConfigDataRef);\n if (data) {\n if (data.exporters) {\n mergedExportSettings.exporters = {\n ...mergedExportSettings.exporters,\n ...data.exporters,\n };\n }\n if (data.columns && !mergedExportSettings.columns) {\n mergedExportSettings.columns = data.columns;\n }\n if (data.onSuccess && !mergedExportSettings.onSuccess) {\n mergedExportSettings.onSuccess = data.onSuccess;\n }\n if (data.onError && !mergedExportSettings.onError) {\n mergedExportSettings.onError = data.onError;\n }\n }\n }\n\n return (\n <NfsDefaultCatalogPage\n filters={<>{filters}</>}\n pagination={config.pagination}\n exportSettings={\n mergedExportSettings.enabled ? mergedExportSettings : undefined\n }\n />\n );\n },\n });\n },\n});\n\nexport const catalogEntityPage = PageBlueprint.makeWithOverrides({\n name: 'entity',\n inputs: {\n headerLayouts: createExtensionInput([\n EntityHeaderLayoutBlueprint.dataRefs.component,\n EntityHeaderLayoutBlueprint.dataRefs.filterFunction.optional(),\n ]),\n headers: createExtensionInput([\n EntityHeaderBlueprint.dataRefs.element.optional(),\n EntityHeaderBlueprint.dataRefs.filterFunction.optional(),\n ]),\n contents: createExtensionInput([\n coreExtensionData.reactElement,\n coreExtensionData.routePath,\n coreExtensionData.routeRef.optional(),\n EntityContentBlueprint.dataRefs.title,\n EntityContentBlueprint.dataRefs.filterFunction.optional(),\n EntityContentBlueprint.dataRefs.filterExpression.optional(),\n EntityContentBlueprint.dataRefs.group.optional(),\n EntityContentBlueprint.dataRefs.icon.optional(),\n ]),\n contextMenuItems: createExtensionInput([\n EntityContextMenuItemBlueprint.dataRefs.data,\n EntityContextMenuItemBlueprint.dataRefs.filterFunction.optional(),\n ]),\n },\n configSchema: {\n groups: z\n .array(\n z.record(\n z.string(),\n z.object({\n title: z.string(),\n icon: z.string().optional(),\n aliases: z.array(z.string()).optional(),\n contentOrder: z.enum(['title', 'natural']).optional(),\n }),\n ),\n )\n .optional(),\n defaultContentOrder: z\n .enum(['title', 'natural'])\n .optional()\n .default('title'),\n showNavItemIcons: z.boolean().optional().default(false),\n },\n factory(originalFactory, { config, inputs }) {\n return originalFactory({\n path: '/catalog/:namespace/:kind/:name',\n // NOTE: The `convertLegacyRouteRef` call here ensures that this route ref\n // is mutated to support the new frontend system. Removing this conversion\n // is a potentially breaking change since this is a singleton and the\n // route refs from `core-plugin-api` used to not support the new format.\n // This shouldn't be removed until we completely deprecate the\n // `core-compat-api` package.\n routeRef: convertLegacyRouteRef(entityRouteRef), // READ THE ABOVE\n loader: async () => {\n const [{ EntityLayout }, { EntityLayoutBui }] = await Promise.all([\n import('./components/EntityLayout'),\n import('./components/EntityLayout/EntityLayoutBui'),\n ]);\n\n const menuItems = inputs.contextMenuItems.map(item => ({\n data: item.get(EntityContextMenuItemBlueprint.dataRefs.data),\n node: item.node,\n filter:\n item.get(EntityContextMenuItemBlueprint.dataRefs.filterFunction) ??\n (() => true),\n }));\n\n // Get available headers, sorted by if they have a filter function or not.\n // TODO(blam): we should really have priority or some specificity here which can be used to sort the headers.\n // That can be done with embedding the priority in the dataRef alongside the filter function.\n const headerLayouts = inputs.headerLayouts\n .map(layout => {\n const filterFunction = layout.get(\n EntityHeaderLayoutBlueprint.dataRefs.filterFunction,\n );\n return {\n Component: layout.get(\n EntityHeaderLayoutBlueprint.dataRefs.component,\n ),\n filter: filterFunction ?? (() => true),\n hasFilter: Boolean(filterFunction),\n };\n })\n .sort((a, b) => Number(b.hasFilter) - Number(a.hasFilter));\n\n const headers = inputs.headers\n .map(header => {\n const filterFunction = header.get(\n EntityHeaderBlueprint.dataRefs.filterFunction,\n );\n return {\n element: header.get(EntityHeaderBlueprint.dataRefs.element),\n filter: filterFunction ?? (() => true),\n hasFilter: Boolean(filterFunction),\n };\n })\n .sort((a, b) => Number(b.hasFilter) - Number(a.hasFilter));\n\n const groupDefinitions =\n config.groups?.reduce(\n (rest, group) => ({ ...rest, ...group }),\n {} as EntityContentGroupDefinitions,\n ) ?? defaultEntityContentGroupDefinitions;\n\n const routes = inputs.contents.map(output => ({\n group: output.get(EntityContentBlueprint.dataRefs.group),\n path: output.get(coreExtensionData.routePath),\n title: output.get(EntityContentBlueprint.dataRefs.title),\n icon: output.get(EntityContentBlueprint.dataRefs.icon),\n if: buildFilterFn(\n output.get(EntityContentBlueprint.dataRefs.filterFunction),\n output.get(EntityContentBlueprint.dataRefs.filterExpression),\n ),\n children: output.get(coreExtensionData.reactElement),\n }));\n\n const Component = () => {\n const routeParams = useRouteRefParams(entityRouteRef);\n const entityFromUrl = useEntityFromUrl();\n const matchesRoute =\n !!entityFromUrl.entity &&\n stringifyEntityRef(entityFromUrl.entity) ===\n stringifyEntityRef(routeParams);\n const entity = matchesRoute ? entityFromUrl.entity : undefined;\n const entityProviderProps = {\n ...entityFromUrl,\n entity,\n loading:\n entityFromUrl.loading ||\n (!!entityFromUrl.entity && !matchesRoute),\n };\n const filteredMenuItems = entity\n ? menuItems\n .filter(i => i.filter(entity))\n .map(({ data, node }) => ({ data, node }))\n : [];\n\n const HeaderComponent = entity\n ? headerLayouts.find(layout => layout.filter(entity))?.Component\n : undefined;\n const legacyHeader = entity\n ? headers.find(header => header.filter(entity))?.element\n : undefined;\n\n const layout =\n HeaderComponent || !legacyHeader ? (\n <EntityLayoutBui\n routes={routes}\n HeaderComponent={HeaderComponent}\n contextMenuItems={filteredMenuItems}\n groupDefinitions={groupDefinitions}\n defaultContentOrder={config.defaultContentOrder}\n />\n ) : (\n <EntityLayout\n routes={routes}\n header={legacyHeader}\n contextMenuItems={filteredMenuItems}\n groupDefinitions={groupDefinitions}\n defaultContentOrder={config.defaultContentOrder}\n showNavItemIcons={config.showNavItemIcons}\n />\n );\n\n return (\n <AsyncEntityProvider {...entityProviderProps}>\n {layout}\n </AsyncEntityProvider>\n );\n };\n\n return <Component />;\n },\n });\n },\n});\n\nexport default [catalogPage, catalogEntityPage];\n"],"names":["layout"],"mappings":"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"}
1
+ {"version":3,"file":"pages.esm.js","sources":["../../src/alpha/pages.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { convertLegacyRouteRef } from '@backstage/core-compat-api';\nimport {\n coreExtensionData,\n createExtensionInput,\n createExtensionDataRef,\n createExtensionBlueprint,\n PageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { z } from 'zod/v4';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport {\n defaultEntityContentGroupDefinitions,\n EntityContentBlueprint,\n EntityContextMenuItemBlueprint,\n EntityHeaderBlueprint,\n EntityHeaderLayoutBlueprint,\n EntityContentGroupDefinitions,\n} from '@backstage/plugin-catalog-react/alpha';\nimport CategoryIcon from '@material-ui/icons/Category';\nimport { rootRouteRef } from '../routes';\nimport { buildFilterFn } from './filter/FilterWrapper';\nimport type { CatalogExportSettings } from '../components/CatalogExportButton';\n\nconst catalogExportConfigDataRef = createExtensionDataRef<{\n exporters?: CatalogExportSettings['exporters'];\n columns?: CatalogExportSettings['columns'];\n onSuccess?: CatalogExportSettings['onSuccess'];\n onError?: CatalogExportSettings['onError'];\n}>().with({\n id: 'catalog.export-customization',\n});\n\n/**\n * Blueprint for creating catalog export configuration extensions.\n * @public\n */\nexport const CatalogExportConfigBlueprint = createExtensionBlueprint({\n kind: 'catalog-export-config',\n attachTo: { id: 'page:catalog', input: 'exportConfig' },\n output: [catalogExportConfigDataRef],\n factory(params: {\n exporters?: CatalogExportSettings['exporters'];\n columns?: CatalogExportSettings['columns'];\n onSuccess?: CatalogExportSettings['onSuccess'];\n onError?: CatalogExportSettings['onError'];\n }) {\n return [catalogExportConfigDataRef(params)];\n },\n});\n\nexport const catalogPage = PageBlueprint.makeWithOverrides({\n inputs: {\n filters: createExtensionInput([coreExtensionData.reactElement]),\n exportConfig: createExtensionInput([catalogExportConfigDataRef.optional()]),\n },\n configSchema: {\n pagination: z\n .union([\n z.boolean(),\n z.object({\n mode: z.enum(['cursor', 'offset']),\n limit: z.number().optional(),\n offset: z.number().optional(),\n }),\n ])\n .default(true),\n exportSettings: z\n .object({\n /** When true, displays the export button in the catalog interface. */\n enabled: z.boolean().optional(),\n /**\n * When true, hides the built-in CSV and JSON export options.\n * Useful when only custom exporters (provided via extensions) should be available.\n */\n disableBuiltinExporters: z.boolean().optional(),\n })\n .optional(),\n },\n factory(originalFactory, { inputs, config }) {\n return originalFactory({\n path: '/catalog',\n routeRef: rootRouteRef,\n icon: <CategoryIcon fontSize=\"inherit\" />,\n title: 'Catalog',\n loader: async () => {\n const { NfsDefaultCatalogPage } = await import(\n '../components/CatalogPage/DefaultCatalogPage'\n );\n const filters = inputs.filters.map(filter =>\n filter.get(coreExtensionData.reactElement),\n );\n\n // Merge export customizers from all attached extensions\n const mergedExportSettings: CatalogExportSettings = {\n ...config.exportSettings,\n };\n\n for (const exportConfigInput of inputs.exportConfig) {\n const data = exportConfigInput.get(catalogExportConfigDataRef);\n if (data) {\n if (data.exporters) {\n mergedExportSettings.exporters = {\n ...mergedExportSettings.exporters,\n ...data.exporters,\n };\n }\n if (data.columns && !mergedExportSettings.columns) {\n mergedExportSettings.columns = data.columns;\n }\n if (data.onSuccess && !mergedExportSettings.onSuccess) {\n mergedExportSettings.onSuccess = data.onSuccess;\n }\n if (data.onError && !mergedExportSettings.onError) {\n mergedExportSettings.onError = data.onError;\n }\n }\n }\n\n return (\n <NfsDefaultCatalogPage\n filters={<>{filters}</>}\n pagination={config.pagination}\n exportSettings={\n mergedExportSettings.enabled ? mergedExportSettings : undefined\n }\n />\n );\n },\n });\n },\n});\n\nexport const catalogEntityPage = PageBlueprint.makeWithOverrides({\n name: 'entity',\n inputs: {\n headerLayouts: createExtensionInput([\n EntityHeaderLayoutBlueprint.dataRefs.component,\n EntityHeaderLayoutBlueprint.dataRefs.filterFunction.optional(),\n ]),\n headers: createExtensionInput([\n EntityHeaderBlueprint.dataRefs.element.optional(),\n EntityHeaderBlueprint.dataRefs.filterFunction.optional(),\n ]),\n contents: createExtensionInput([\n coreExtensionData.reactElement,\n coreExtensionData.routePath,\n coreExtensionData.routeRef.optional(),\n EntityContentBlueprint.dataRefs.title,\n EntityContentBlueprint.dataRefs.filterFunction.optional(),\n EntityContentBlueprint.dataRefs.filterExpression.optional(),\n EntityContentBlueprint.dataRefs.group.optional(),\n EntityContentBlueprint.dataRefs.icon.optional(),\n ]),\n contextMenuItems: createExtensionInput([\n EntityContextMenuItemBlueprint.dataRefs.data,\n EntityContextMenuItemBlueprint.dataRefs.filterFunction.optional(),\n ]),\n },\n configSchema: {\n groups: z\n .array(\n z.record(\n z.string(),\n z.object({\n title: z.string(),\n icon: z.string().optional(),\n aliases: z.array(z.string()).optional(),\n contentOrder: z.enum(['title', 'natural']).optional(),\n }),\n ),\n )\n .optional(),\n defaultContentOrder: z\n .enum(['title', 'natural'])\n .optional()\n .default('title'),\n showNavItemIcons: z.boolean().optional().default(false),\n },\n factory(originalFactory, { config, inputs }) {\n return originalFactory({\n path: '/catalog/:namespace/:kind/:name',\n // NOTE: The `convertLegacyRouteRef` call here ensures that this route ref\n // is mutated to support the new frontend system. Removing this conversion\n // is a potentially breaking change since this is a singleton and the\n // route refs from `core-plugin-api` used to not support the new format.\n // This shouldn't be removed until we completely deprecate the\n // `core-compat-api` package.\n routeRef: convertLegacyRouteRef(entityRouteRef), // READ THE ABOVE\n loader: async () => {\n const { CatalogEntityPage } = await import(\n './components/CatalogEntityPage'\n );\n\n const menuItems = inputs.contextMenuItems.map(item => ({\n data: item.get(EntityContextMenuItemBlueprint.dataRefs.data),\n node: item.node,\n filter:\n item.get(EntityContextMenuItemBlueprint.dataRefs.filterFunction) ??\n (() => true),\n }));\n\n // Get available headers, sorted by if they have a filter function or not.\n // TODO(blam): we should really have priority or some specificity here which can be used to sort the headers.\n // That can be done with embedding the priority in the dataRef alongside the filter function.\n const headerLayouts = inputs.headerLayouts\n .map(layout => {\n const filterFunction = layout.get(\n EntityHeaderLayoutBlueprint.dataRefs.filterFunction,\n );\n return {\n Component: layout.get(\n EntityHeaderLayoutBlueprint.dataRefs.component,\n ),\n filter: filterFunction ?? (() => true),\n hasFilter: Boolean(filterFunction),\n };\n })\n .sort((a, b) => Number(b.hasFilter) - Number(a.hasFilter));\n\n const headers = inputs.headers\n .map(header => {\n const filterFunction = header.get(\n EntityHeaderBlueprint.dataRefs.filterFunction,\n );\n return {\n element: header.get(EntityHeaderBlueprint.dataRefs.element),\n filter: filterFunction ?? (() => true),\n hasFilter: Boolean(filterFunction),\n };\n })\n .sort((a, b) => Number(b.hasFilter) - Number(a.hasFilter));\n\n const groupDefinitions =\n config.groups?.reduce(\n (rest, group) => ({ ...rest, ...group }),\n {} as EntityContentGroupDefinitions,\n ) ?? defaultEntityContentGroupDefinitions;\n\n const routes = inputs.contents.map(output => ({\n group: output.get(EntityContentBlueprint.dataRefs.group),\n path: output.get(coreExtensionData.routePath),\n title: output.get(EntityContentBlueprint.dataRefs.title),\n icon: output.get(EntityContentBlueprint.dataRefs.icon),\n if: buildFilterFn(\n output.get(EntityContentBlueprint.dataRefs.filterFunction),\n output.get(EntityContentBlueprint.dataRefs.filterExpression),\n ),\n children: output.get(coreExtensionData.reactElement),\n }));\n\n return (\n <CatalogEntityPage\n menuItems={menuItems}\n headerLayouts={headerLayouts}\n headers={headers}\n routes={routes}\n groupDefinitions={groupDefinitions}\n defaultContentOrder={config.defaultContentOrder}\n showNavItemIcons={config.showNavItemIcons}\n />\n );\n },\n });\n },\n});\n\nexport default [catalogPage, catalogEntityPage];\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useCallback } from 'react';
3
3
  import IconButton from '@material-ui/core/IconButton';
4
4
  import CachedIcon from '@material-ui/icons/Cached';
@@ -6,10 +6,9 @@ import EditIcon from '@material-ui/icons/Edit';
6
6
  import DocsIcon from '@material-ui/icons/Description';
7
7
  import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
8
8
  import { Link, AppIcon, HeaderIconLinkRow } from '@backstage/core-components';
9
- import { useEntity, catalogApiRef, EntityInfoCard, getEntitySourceLocation } from '@backstage/plugin-catalog-react';
9
+ import { useEntity, catalogApiRef, EntityInfoCard } from '@backstage/plugin-catalog-react';
10
10
  import { useApi, alertApiRef, errorApiRef, useRouteRef, useApp } from '@backstage/core-plugin-api';
11
11
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
12
- import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
13
12
  import { ANNOTATION_EDIT_URL, ANNOTATION_LOCATION, stringifyEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
14
13
  import { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';
15
14
  import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha';
@@ -23,6 +22,7 @@ import { catalogTranslationRef } from '../../alpha/translation.esm.js';
23
22
  import { useSourceTemplateCompoundEntityRef } from './hooks.esm.js';
24
23
  import { AboutContent } from './AboutContent.esm.js';
25
24
  import { makeStyles } from '@material-ui/core/styles';
25
+ import { useCatalogSourceIconLinkProps } from './useCatalogSourceIconLinkProps.esm.js';
26
26
 
27
27
  const useStyles = makeStyles({
28
28
  linkContainer: {
@@ -32,21 +32,6 @@ const useStyles = makeStyles({
32
32
  marginBottom: "var(--bui-space-6)"
33
33
  }
34
34
  });
35
- function useCatalogSourceIconLinkProps() {
36
- const { entity } = useEntity();
37
- const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
38
- const { t } = useTranslationRef(catalogTranslationRef);
39
- const entitySourceLocation = getEntitySourceLocation(
40
- entity,
41
- scmIntegrationsApi
42
- );
43
- return {
44
- label: t("aboutCard.viewSource"),
45
- disabled: !entitySourceLocation,
46
- icon: /* @__PURE__ */ jsx(ScmIntegrationIcon, { type: entitySourceLocation?.integrationType }),
47
- href: entitySourceLocation?.locationTargetUrl
48
- };
49
- }
50
35
  function useTechdocsReaderIconLinkProps() {
51
36
  const { entity } = useEntity();
52
37
  const viewTechdocLink = useRouteRef(viewTechDocRouteRef);
@@ -165,5 +150,5 @@ function AboutCard() {
165
150
  return /* @__PURE__ */ jsx(InternalAboutCard, {});
166
151
  }
167
152
 
168
- export { AboutCard, InternalAboutCard, useCatalogSourceIconLinkProps };
153
+ export { AboutCard, InternalAboutCard };
169
154
  //# sourceMappingURL=AboutCard.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AboutCard.esm.js","sources":["../../../src/components/AboutCard/AboutCard.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback } from 'react';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport CachedIcon from '@material-ui/icons/Cached';\nimport EditIcon from '@material-ui/icons/Edit';\nimport DocsIcon from '@material-ui/icons/Description';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\n\nimport {\n AppIcon,\n HeaderIconLinkRow,\n IconLinkVerticalProps,\n Link,\n} from '@backstage/core-components';\nimport { EntityInfoCard } from '@backstage/plugin-catalog-react';\nimport {\n alertApiRef,\n errorApiRef,\n useApp,\n useApi,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nimport {\n ScmIntegrationIcon,\n scmIntegrationsApiRef,\n} from '@backstage/integration-react';\n\nimport {\n DEFAULT_NAMESPACE,\n ANNOTATION_EDIT_URL,\n ANNOTATION_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n catalogApiRef,\n getEntitySourceLocation,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';\nimport { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha';\n\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\n\nimport { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { taskCreatePermission } from '@backstage/plugin-scaffolder-common/alpha';\n\nimport { usePermission } from '@backstage/plugin-permission-react';\n\nimport { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useSourceTemplateCompoundEntityRef } from './hooks';\nimport { AboutContent } from './AboutContent';\nimport { makeStyles } from '@material-ui/core/styles';\n\nconst useStyles = makeStyles({\n linkContainer: {\n border: '1px solid var(--bui-border-1)',\n borderLeft: 'none',\n borderRight: 'none',\n marginBottom: 'var(--bui-space-6)',\n },\n});\n\nexport function useCatalogSourceIconLinkProps() {\n const { entity } = useEntity();\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const entitySourceLocation = getEntitySourceLocation(\n entity,\n scmIntegrationsApi,\n );\n return {\n label: t('aboutCard.viewSource'),\n disabled: !entitySourceLocation,\n icon: <ScmIntegrationIcon type={entitySourceLocation?.integrationType} />,\n href: entitySourceLocation?.locationTargetUrl,\n };\n}\n\n// TODO: This hook is duplicated from the TechDocs plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useTechdocsReaderIconLinkProps(): IconLinkVerticalProps {\n const { entity } = useEntity();\n const viewTechdocLink = useRouteRef(viewTechDocRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return {\n label: t('aboutCard.viewTechdocs'),\n disabled:\n !(\n entity.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) || !viewTechdocLink,\n icon: <DocsIcon />,\n href: buildTechDocsURL(entity, viewTechdocLink),\n };\n}\n\n// TODO: This hook is duplicated from the Scaffolder plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useScaffolderTemplateIconLinkProps(): IconLinkVerticalProps {\n const app = useApp();\n const { entity } = useEntity();\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon;\n const { allowed: canCreateTemplateTask } = usePermission({\n permission: taskCreatePermission,\n });\n\n return {\n label: t('aboutCard.launchTemplate'),\n icon: <Icon />,\n disabled: !templateRoute || !canCreateTemplateTask,\n href:\n templateRoute &&\n templateRoute({\n templateName: entity.metadata.name,\n namespace: entity.metadata.namespace || DEFAULT_NAMESPACE,\n }),\n };\n}\n\nfunction DefaultAboutCardSubheader() {\n const { entity } = useEntity();\n const catalogSourceIconLink = useCatalogSourceIconLinkProps();\n const techdocsreaderIconLink = useTechdocsReaderIconLinkProps();\n const scaffolderTemplateIconLink = useScaffolderTemplateIconLinkProps();\n\n const links = [catalogSourceIconLink, techdocsreaderIconLink];\n if (isTemplateEntityV1beta3(entity)) {\n links.push(scaffolderTemplateIconLink);\n }\n\n return <HeaderIconLinkRow links={links} />;\n}\n\nexport interface InternalAboutCardProps {\n /** Icon link row rendered at the top of the card body. */\n iconLinks?: JSX.Element;\n}\n\nexport function InternalAboutCard(props: InternalAboutCardProps) {\n const { iconLinks } = props;\n const classes = useStyles();\n const { entity } = useEntity();\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n const errorApi = useApi(errorApiRef);\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const sourceTemplateRef = useSourceTemplateCompoundEntityRef(entity);\n const { allowed: canRefresh } = useEntityPermission(\n catalogEntityRefreshPermission,\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const entityMetadataEditUrl =\n entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n\n const entityLocation = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n // Limiting the ability to manually refresh to the less expensive locations\n const allowRefresh =\n entityLocation?.startsWith('url:') || entityLocation?.startsWith('file:');\n const refreshEntity = useCallback(async () => {\n try {\n await catalogApi.refreshEntity(stringifyEntityRef(entity));\n alertApi.post({\n message: t('aboutCard.refreshScheduledMessage'),\n severity: 'info',\n display: 'transient',\n });\n } catch (e) {\n errorApi.post(e);\n }\n }, [catalogApi, entity, alertApi, t, errorApi]);\n\n return (\n <EntityInfoCard\n title={t('aboutCard.title')}\n headerActions={\n <>\n {allowRefresh && canRefresh && (\n <IconButton\n aria-label={t('aboutCard.refreshButtonAriaLabel')}\n title={t('aboutCard.refreshButtonTitle')}\n onClick={refreshEntity}\n >\n <CachedIcon />\n </IconButton>\n )}\n <IconButton\n component={Link}\n aria-label={t('aboutCard.editButtonAriaLabel')}\n disabled={!entityMetadataEditUrl}\n title={t('aboutCard.editButtonTitle')}\n to={entityMetadataEditUrl ?? '#'}\n >\n <EditIcon />\n </IconButton>\n {sourceTemplateRef && templateRoute && (\n <IconButton\n component={Link}\n title={t('aboutCard.createSimilarButtonTitle')}\n to={templateRoute({\n namespace: sourceTemplateRef.namespace,\n templateName: sourceTemplateRef.name,\n })}\n >\n <AppIcon id=\"scaffolder\" />\n </IconButton>\n )}\n </>\n }\n >\n <div className={classes.linkContainer}>\n {iconLinks ?? <DefaultAboutCardSubheader />}\n </div>\n <AboutContent entity={entity} />\n </EntityInfoCard>\n );\n}\n\n/**\n * Exported publicly via the EntityAboutCard\n *\n * NOTE: We generally do not accept pull requests to extend this class with props\n * and customizability. If you need to tweak it, consider making a bespoke card\n * in your own repository instead, that is perfect for your own needs.\n */\nexport function AboutCard() {\n return <InternalAboutCard />;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AboutCard.esm.js","sources":["../../../src/components/AboutCard/AboutCard.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback } from 'react';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport CachedIcon from '@material-ui/icons/Cached';\nimport EditIcon from '@material-ui/icons/Edit';\nimport DocsIcon from '@material-ui/icons/Description';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\n\nimport {\n AppIcon,\n HeaderIconLinkRow,\n IconLinkVerticalProps,\n Link,\n} from '@backstage/core-components';\nimport { EntityInfoCard } from '@backstage/plugin-catalog-react';\nimport {\n alertApiRef,\n errorApiRef,\n useApp,\n useApi,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nimport {\n DEFAULT_NAMESPACE,\n ANNOTATION_EDIT_URL,\n ANNOTATION_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';\nimport { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha';\n\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\n\nimport { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { taskCreatePermission } from '@backstage/plugin-scaffolder-common/alpha';\n\nimport { usePermission } from '@backstage/plugin-permission-react';\n\nimport { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useSourceTemplateCompoundEntityRef } from './hooks';\nimport { AboutContent } from './AboutContent';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useCatalogSourceIconLinkProps } from './useCatalogSourceIconLinkProps';\n\nconst useStyles = makeStyles({\n linkContainer: {\n border: '1px solid var(--bui-border-1)',\n borderLeft: 'none',\n borderRight: 'none',\n marginBottom: 'var(--bui-space-6)',\n },\n});\n\n// TODO: This hook is duplicated from the TechDocs plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useTechdocsReaderIconLinkProps(): IconLinkVerticalProps {\n const { entity } = useEntity();\n const viewTechdocLink = useRouteRef(viewTechDocRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return {\n label: t('aboutCard.viewTechdocs'),\n disabled:\n !(\n entity.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) || !viewTechdocLink,\n icon: <DocsIcon />,\n href: buildTechDocsURL(entity, viewTechdocLink),\n };\n}\n\n// TODO: This hook is duplicated from the Scaffolder plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useScaffolderTemplateIconLinkProps(): IconLinkVerticalProps {\n const app = useApp();\n const { entity } = useEntity();\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon;\n const { allowed: canCreateTemplateTask } = usePermission({\n permission: taskCreatePermission,\n });\n\n return {\n label: t('aboutCard.launchTemplate'),\n icon: <Icon />,\n disabled: !templateRoute || !canCreateTemplateTask,\n href:\n templateRoute &&\n templateRoute({\n templateName: entity.metadata.name,\n namespace: entity.metadata.namespace || DEFAULT_NAMESPACE,\n }),\n };\n}\n\nfunction DefaultAboutCardSubheader() {\n const { entity } = useEntity();\n const catalogSourceIconLink = useCatalogSourceIconLinkProps();\n const techdocsreaderIconLink = useTechdocsReaderIconLinkProps();\n const scaffolderTemplateIconLink = useScaffolderTemplateIconLinkProps();\n\n const links = [catalogSourceIconLink, techdocsreaderIconLink];\n if (isTemplateEntityV1beta3(entity)) {\n links.push(scaffolderTemplateIconLink);\n }\n\n return <HeaderIconLinkRow links={links} />;\n}\n\nexport interface InternalAboutCardProps {\n /** Icon link row rendered at the top of the card body. */\n iconLinks?: JSX.Element;\n}\n\nexport function InternalAboutCard(props: InternalAboutCardProps) {\n const { iconLinks } = props;\n const classes = useStyles();\n const { entity } = useEntity();\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n const errorApi = useApi(errorApiRef);\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const sourceTemplateRef = useSourceTemplateCompoundEntityRef(entity);\n const { allowed: canRefresh } = useEntityPermission(\n catalogEntityRefreshPermission,\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const entityMetadataEditUrl =\n entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n\n const entityLocation = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n // Limiting the ability to manually refresh to the less expensive locations\n const allowRefresh =\n entityLocation?.startsWith('url:') || entityLocation?.startsWith('file:');\n const refreshEntity = useCallback(async () => {\n try {\n await catalogApi.refreshEntity(stringifyEntityRef(entity));\n alertApi.post({\n message: t('aboutCard.refreshScheduledMessage'),\n severity: 'info',\n display: 'transient',\n });\n } catch (e) {\n errorApi.post(e);\n }\n }, [catalogApi, entity, alertApi, t, errorApi]);\n\n return (\n <EntityInfoCard\n title={t('aboutCard.title')}\n headerActions={\n <>\n {allowRefresh && canRefresh && (\n <IconButton\n aria-label={t('aboutCard.refreshButtonAriaLabel')}\n title={t('aboutCard.refreshButtonTitle')}\n onClick={refreshEntity}\n >\n <CachedIcon />\n </IconButton>\n )}\n <IconButton\n component={Link}\n aria-label={t('aboutCard.editButtonAriaLabel')}\n disabled={!entityMetadataEditUrl}\n title={t('aboutCard.editButtonTitle')}\n to={entityMetadataEditUrl ?? '#'}\n >\n <EditIcon />\n </IconButton>\n {sourceTemplateRef && templateRoute && (\n <IconButton\n component={Link}\n title={t('aboutCard.createSimilarButtonTitle')}\n to={templateRoute({\n namespace: sourceTemplateRef.namespace,\n templateName: sourceTemplateRef.name,\n })}\n >\n <AppIcon id=\"scaffolder\" />\n </IconButton>\n )}\n </>\n }\n >\n <div className={classes.linkContainer}>\n {iconLinks ?? <DefaultAboutCardSubheader />}\n </div>\n <AboutContent entity={entity} />\n </EntityInfoCard>\n );\n}\n\n/**\n * Exported publicly via the EntityAboutCard\n *\n * NOTE: We generally do not accept pull requests to extend this class with props\n * and customizability. If you need to tweak it, consider making a bespoke card\n * in your own repository instead, that is perfect for your own needs.\n */\nexport function AboutCard() {\n return <InternalAboutCard />;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useApi } from '@backstage/core-plugin-api';
3
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
4
+ import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
5
+ import { useEntity, getEntitySourceLocation } from '@backstage/plugin-catalog-react';
6
+ import { catalogTranslationRef } from '../../alpha/translation.esm.js';
7
+
8
+ function useCatalogSourceIconLinkProps() {
9
+ const { entity } = useEntity();
10
+ const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
11
+ const { t } = useTranslationRef(catalogTranslationRef);
12
+ const entitySourceLocation = getEntitySourceLocation(
13
+ entity,
14
+ scmIntegrationsApi
15
+ );
16
+ return {
17
+ label: t("aboutCard.viewSource"),
18
+ disabled: !entitySourceLocation,
19
+ icon: /* @__PURE__ */ jsx(ScmIntegrationIcon, { type: entitySourceLocation?.integrationType }),
20
+ href: entitySourceLocation?.locationTargetUrl
21
+ };
22
+ }
23
+
24
+ export { useCatalogSourceIconLinkProps };
25
+ //# sourceMappingURL=useCatalogSourceIconLinkProps.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCatalogSourceIconLinkProps.esm.js","sources":["../../../src/components/AboutCard/useCatalogSourceIconLinkProps.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n ScmIntegrationIcon,\n scmIntegrationsApiRef,\n} from '@backstage/integration-react';\nimport {\n getEntitySourceLocation,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { catalogTranslationRef } from '../../alpha/translation';\n\nexport function useCatalogSourceIconLinkProps() {\n const { entity } = useEntity();\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const entitySourceLocation = getEntitySourceLocation(\n entity,\n scmIntegrationsApi,\n );\n return {\n label: t('aboutCard.viewSource'),\n disabled: !entitySourceLocation,\n icon: <ScmIntegrationIcon type={entitySourceLocation?.integrationType} />,\n href: entitySourceLocation?.locationTargetUrl,\n };\n}\n"],"names":[],"mappings":";;;;;;;AA4BO,SAAS,6BAAA,GAAgC;AAC9C,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,kBAAA,GAAqB,OAAO,qBAAqB,CAAA;AACvD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,qBAAqB,CAAA;AACrD,EAAA,MAAM,oBAAA,GAAuB,uBAAA;AAAA,IAC3B,MAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,EAAE,sBAAsB,CAAA;AAAA,IAC/B,UAAU,CAAC,oBAAA;AAAA,IACX,IAAA,kBAAM,GAAA,CAAC,kBAAA,EAAA,EAAmB,IAAA,EAAM,sBAAsB,eAAA,EAAiB,CAAA;AAAA,IACvE,MAAM,oBAAA,EAAsB;AAAA,GAC9B;AACF;;;;"}
@@ -7,12 +7,8 @@ import { catalogTranslationRef } from '../../alpha/translation.esm.js';
7
7
  import { ButtonIcon, Button, Dialog, DialogHeader, DialogBody, Flex, Select, Text, Checkbox, DialogFooter } from '@backstage/ui';
8
8
  import { useStreamingExport } from './file-download/useStreamingExport.esm.js';
9
9
  import { getColumnTitle } from './file-download/serializeEntities.esm.js';
10
+ import { CatalogExportType } from './CatalogExportType.esm.js';
10
11
 
11
- var CatalogExportType = /* @__PURE__ */ ((CatalogExportType2) => {
12
- CatalogExportType2["CSV"] = "csv";
13
- CatalogExportType2["JSON"] = "json";
14
- return CatalogExportType2;
15
- })(CatalogExportType || {});
16
12
  const DEFAULT_EXPORT_COLUMNS = [
17
13
  { entityFilterKey: "metadata.name", title: "Name" },
18
14
  { entityFilterKey: "spec.type", title: "Type" },
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogExportButton.esm.js","sources":["../../../src/components/CatalogExportButton/CatalogExportButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\nimport { RiDownloadLine } from '@remixicon/react';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef, toastApiRef } from '@backstage/frontend-plugin-api';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport {\n Button,\n ButtonIcon,\n Checkbox,\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n Flex,\n Select,\n Text,\n} from '@backstage/ui';\nimport { useStreamingExport } from './file-download';\nimport type { CatalogExportSettingsColumn } from './file-download/serializeEntities';\nimport { getColumnTitle } from './file-download/serializeEntities';\nimport type { CatalogExporter } from './file-download/useStreamingExport';\n\n/**\n * Custom exporter configuration for a catalog export format.\n * @public\n */\nexport interface CatalogExporterConfig {\n /** The exporter function that generates the export content. */\n exporter: CatalogExporter;\n /** Optional display label shown in the format selector. Defaults to the format key in uppercase. */\n label?: string;\n}\n\n/**\n * Settings for configuring the catalog export functionality.\n *\n * @public\n */\nexport interface CatalogExportSettings {\n /**\n * When true, displays the export button in the catalog interface.\n * Defaults to false if not specified.\n */\n enabled?: boolean;\n\n /**\n * Custom columns to include in the export.\n * Each column specifies an entity field path and a display title.\n * If not specified, uses default columns: Name, Type, Owner, Description.\n */\n columns?: CatalogExportSettingsColumn[];\n\n /**\n * Map of custom export format handlers beyond the built-in CSV and JSON formats.\n * Key is the format name (e.g., 'xml', 'yaml'), value is the exporter configuration.\n * Custom formats will appear as options in the export dialog.\n */\n exporters?: Record<string, CatalogExporterConfig>;\n\n /**\n * When true, hides the built-in CSV and JSON export options from the dialog.\n * Useful when only custom exporters should be available.\n */\n disableBuiltinExporters?: boolean;\n\n /**\n * Callback function invoked when the export completes successfully.\n * Useful for showing notifications or performing post-export actions.\n */\n onSuccess?: () => void;\n\n /**\n * Callback function invoked when the export fails.\n * Receives an object containing the error for custom error handling.\n */\n onError?: (options: { error: Error }) => void;\n}\n\n/**\n * The available export formats for the catalog export.\n * Currently supports CSV and JSON.\n *\n * @public\n */\nexport enum CatalogExportType {\n CSV = 'csv',\n JSON = 'json',\n}\n\n/**\n * The available default export columns for the catalog export.\n * These can be overridden by providing custom columns in the export button options.\n *\n * @private\n */\nconst DEFAULT_EXPORT_COLUMNS = [\n { entityFilterKey: 'metadata.name', title: 'Name' },\n { entityFilterKey: 'spec.type', title: 'Type' },\n { entityFilterKey: 'spec.owner', title: 'Owner' },\n { entityFilterKey: 'metadata.description', title: 'Description' },\n];\n\n/**\n * A button that opens a dialog to export the current catalog selection.\n *\n * @param settings - Optional export configuration settings including columns, custom exporters, and callbacks\n * @public\n */\nexport const CatalogExportButton = ({\n settings,\n iconOnly = false,\n}: {\n settings?: CatalogExportSettings;\n iconOnly?: boolean;\n}) => {\n const { t } = useTranslationRef(catalogTranslationRef);\n const { exportStream, loading, error } = useStreamingExport();\n const [open, setOpen] = useState(false);\n const exporters = settings?.exporters;\n const disableBuiltinExporters = settings?.disableBuiltinExporters;\n const onSuccess = settings?.onSuccess;\n const onError = settings?.onError;\n const apis = useApiHolder();\n const toastApi = apis.get(toastApiRef)!;\n const [isExporting, setIsExporting] = useState(false);\n\n const effectiveColumns = settings?.columns ?? DEFAULT_EXPORT_COLUMNS;\n\n const allExportOptions = [\n ...(disableBuiltinExporters\n ? []\n : Object.values(CatalogExportType).map(format => ({\n value: format,\n label: format.toUpperCase(),\n }))),\n ...Object.entries(exporters ?? {}).map(([key, exporter]) => ({\n value: key,\n label: exporter.label ?? key.toUpperCase(),\n })),\n ];\n\n const [exportFormat, setExportFormat] = useState<string>(\n allExportOptions[0]?.value ?? '',\n );\n const [selectedColumnTitles, setSelectedColumnTitles] = useState<Set<string>>(\n () => new Set(effectiveColumns.map(c => getColumnTitle(c))),\n );\n const selectedColumns = effectiveColumns.filter(c =>\n selectedColumnTitles.has(getColumnTitle(c)),\n );\n\n const handleOpenDialog = () => {\n setSelectedColumnTitles(\n new Set(effectiveColumns.map(c => getColumnTitle(c))),\n );\n setOpen(true);\n };\n\n const toggleColumn = (title: string) => {\n setSelectedColumnTitles(prev => {\n const next = new Set(prev);\n if (next.has(title)) {\n next.delete(title);\n } else {\n next.add(title);\n }\n return next;\n });\n };\n\n useEffect(() => {\n if (isExporting && !loading) {\n if (error) {\n if (onError) {\n onError({ error });\n } else {\n toastApi.post({\n title: t('catalogExportButton.errorMessage', {\n errorMessage: error.message,\n }),\n status: 'danger',\n });\n }\n } else {\n if (onSuccess) {\n onSuccess();\n } else {\n toastApi.post({\n title: t('catalogExportButton.successMessage'),\n status: 'success',\n });\n }\n }\n setOpen(false);\n setIsExporting(false);\n }\n }, [isExporting, loading, error, toastApi, onSuccess, onError, t]);\n\n const handleExport = useCallback(async () => {\n setIsExporting(true);\n const exporterFn = exporters?.[exportFormat];\n await exportStream({\n exportFormat,\n filename: `catalog-export.${exportFormat}`,\n columns: selectedColumns,\n exporter: exporterFn?.exporter,\n });\n }, [exportFormat, exportStream, selectedColumns, exporters]);\n\n return (\n <>\n {iconOnly ? (\n <ButtonIcon\n variant=\"secondary\"\n icon={<RiDownloadLine />}\n aria-label={t('catalogExportButton.triggerButtonTitle')}\n onPress={handleOpenDialog}\n />\n ) : (\n <Button\n variant=\"secondary\"\n iconStart={<RiDownloadLine />}\n onPress={handleOpenDialog}\n >\n {t('catalogExportButton.triggerButtonTitle')}\n </Button>\n )}\n\n <Dialog isOpen={open} onOpenChange={isOpen => !isOpen && setOpen(false)}>\n <DialogHeader>{t('catalogExportButton.dialogTitle')}</DialogHeader>\n <DialogBody>\n <Flex direction=\"column\" gap=\"4\">\n <Select\n data-testid=\"format-select\"\n label={t('catalogExportButton.formatLabel')}\n options={allExportOptions}\n value={exportFormat}\n onChange={key => setExportFormat(key as string)}\n />\n <Flex direction=\"column\" gap=\"1\">\n <Text variant=\"body-small\" weight=\"bold\">\n {t('catalogExportButton.columnsLabel')}\n </Text>\n {effectiveColumns.map(col => (\n <Checkbox\n key={col.entityFilterKey}\n isSelected={selectedColumnTitles.has(getColumnTitle(col))}\n onChange={() => toggleColumn(getColumnTitle(col))}\n >\n {getColumnTitle(col)}\n </Checkbox>\n ))}\n </Flex>\n </Flex>\n </DialogBody>\n <DialogFooter>\n <Button variant=\"secondary\" onPress={() => setOpen(false)}>\n {t('catalogExportButton.cancelButtonTitle')}\n </Button>\n <Button\n variant=\"primary\"\n onPress={() => handleExport()}\n isDisabled={\n !exportFormat || loading || selectedColumns.length === 0\n }\n loading={loading}\n >\n {loading\n ? t('catalogExportButton.exportingButtonTitle')\n : t('catalogExportButton.confirmButtonTitle')}\n </Button>\n </DialogFooter>\n </Dialog>\n </>\n );\n};\n"],"names":["CatalogExportType"],"mappings":";;;;;;;;;;AAmGO,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AACL,EAAAA,mBAAA,KAAA,CAAA,GAAM,KAAA;AACN,EAAAA,mBAAA,MAAA,CAAA,GAAO,MAAA;AAFG,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;AAWZ,MAAM,sBAAA,GAAyB;AAAA,EAC7B,EAAE,eAAA,EAAiB,eAAA,EAAiB,KAAA,EAAO,MAAA,EAAO;AAAA,EAClD,EAAE,eAAA,EAAiB,WAAA,EAAa,KAAA,EAAO,MAAA,EAAO;AAAA,EAC9C,EAAE,eAAA,EAAiB,YAAA,EAAc,KAAA,EAAO,OAAA,EAAQ;AAAA,EAChD,EAAE,eAAA,EAAiB,sBAAA,EAAwB,KAAA,EAAO,aAAA;AACpD,CAAA;AAQO,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA,QAAA,GAAW;AACb,CAAA,KAGM;AACJ,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,qBAAqB,CAAA;AACrD,EAAA,MAAM,EAAE,YAAA,EAAc,OAAA,EAAS,KAAA,KAAU,kBAAA,EAAmB;AAC5D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,YAAY,QAAA,EAAU,SAAA;AAC5B,EAAA,MAAM,0BAA0B,QAAA,EAAU,uBAAA;AAC1C,EAAA,MAAM,YAAY,QAAA,EAAU,SAAA;AAC5B,EAAA,MAAM,UAAU,QAAA,EAAU,OAAA;AAC1B,EAAA,MAAM,OAAO,YAAA,EAAa;AAC1B,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AAEpD,EAAA,MAAM,gBAAA,GAAmB,UAAU,OAAA,IAAW,sBAAA;AAE9C,EAAA,MAAM,gBAAA,GAAmB;AAAA,IACvB,GAAI,0BACA,EAAC,GACD,OAAO,MAAA,CAAO,iBAAiB,CAAA,CAAE,GAAA,CAAI,CAAA,MAAA,MAAW;AAAA,MAC9C,KAAA,EAAO,MAAA;AAAA,MACP,KAAA,EAAO,OAAO,WAAA;AAAY,KAC5B,CAAE,CAAA;AAAA,IACN,GAAG,MAAA,CAAO,OAAA,CAAQ,SAAA,IAAa,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,QAAQ,CAAA,MAAO;AAAA,MAC3D,KAAA,EAAO,GAAA;AAAA,MACP,KAAA,EAAO,QAAA,CAAS,KAAA,IAAS,GAAA,CAAI,WAAA;AAAY,KAC3C,CAAE;AAAA,GACJ;AAEA,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA;AAAA,IACtC,gBAAA,CAAiB,CAAC,CAAA,EAAG,KAAA,IAAS;AAAA,GAChC;AACA,EAAA,MAAM,CAAC,oBAAA,EAAsB,uBAAuB,CAAA,GAAI,QAAA;AAAA,IACtD,MAAM,IAAI,GAAA,CAAI,gBAAA,CAAiB,IAAI,CAAA,CAAA,KAAK,cAAA,CAAe,CAAC,CAAC,CAAC;AAAA,GAC5D;AACA,EAAA,MAAM,kBAAkB,gBAAA,CAAiB,MAAA;AAAA,IAAO,CAAA,CAAA,KAC9C,oBAAA,CAAqB,GAAA,CAAI,cAAA,CAAe,CAAC,CAAC;AAAA,GAC5C;AAEA,EAAA,MAAM,mBAAmB,MAAM;AAC7B,IAAA,uBAAA;AAAA,MACE,IAAI,IAAI,gBAAA,CAAiB,GAAA,CAAI,OAAK,cAAA,CAAe,CAAC,CAAC,CAAC;AAAA,KACtD;AACA,IAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,EACd,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAAkB;AACtC,IAAA,uBAAA,CAAwB,CAAA,IAAA,KAAQ;AAC9B,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AACnB,QAAA,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,MACnB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AAAA,MAChB;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAA,IAAe,CAAC,OAAA,EAAS;AAC3B,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,OAAA,CAAQ,EAAE,OAAO,CAAA;AAAA,QACnB,CAAA,MAAO;AACL,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,KAAA,EAAO,EAAE,kCAAA,EAAoC;AAAA,cAC3C,cAAc,KAAA,CAAM;AAAA,aACrB,CAAA;AAAA,YACD,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,SAAA,EAAU;AAAA,QACZ,CAAA,MAAO;AACL,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,KAAA,EAAO,EAAE,oCAAoC,CAAA;AAAA,YAC7C,MAAA,EAAQ;AAAA,WACT,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,OAAA,EAAS,OAAO,QAAA,EAAU,SAAA,EAAW,OAAA,EAAS,CAAC,CAAC,CAAA;AAEjE,EAAA,MAAM,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,MAAM,UAAA,GAAa,YAAY,YAAY,CAAA;AAC3C,IAAA,MAAM,YAAA,CAAa;AAAA,MACjB,YAAA;AAAA,MACA,QAAA,EAAU,kBAAkB,YAAY,CAAA,CAAA;AAAA,MACxC,OAAA,EAAS,eAAA;AAAA,MACT,UAAU,UAAA,EAAY;AAAA,KACvB,CAAA;AAAA,EACH,GAAG,CAAC,YAAA,EAAc,YAAA,EAAc,eAAA,EAAiB,SAAS,CAAC,CAAA;AAE3D,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA,mBACC,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,WAAA;AAAA,QACR,IAAA,sBAAO,cAAA,EAAA,EAAe,CAAA;AAAA,QACtB,YAAA,EAAY,EAAE,wCAAwC,CAAA;AAAA,QACtD,OAAA,EAAS;AAAA;AAAA,KACX,mBAEA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,WAAA;AAAA,QACR,SAAA,sBAAY,cAAA,EAAA,EAAe,CAAA;AAAA,QAC3B,OAAA,EAAS,gBAAA;AAAA,QAER,YAAE,wCAAwC;AAAA;AAAA,KAC7C;AAAA,oBAGF,IAAA,CAAC,MAAA,EAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,YAAA,EAAc,YAAU,CAAC,MAAA,IAAU,OAAA,CAAQ,KAAK,CAAA,EACpE,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,YAAA,EAAA,EAAc,QAAA,EAAA,CAAA,CAAE,iCAAiC,CAAA,EAAE,CAAA;AAAA,0BACnD,UAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,QAAK,SAAA,EAAU,QAAA,EAAS,KAAI,GAAA,EAC3B,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,eAAA;AAAA,YACZ,KAAA,EAAO,EAAE,iCAAiC,CAAA;AAAA,YAC1C,OAAA,EAAS,gBAAA;AAAA,YACT,KAAA,EAAO,YAAA;AAAA,YACP,QAAA,EAAU,CAAA,GAAA,KAAO,eAAA,CAAgB,GAAa;AAAA;AAAA,SAChD;AAAA,wBACA,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,KAAI,GAAA,EAC3B,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAK,OAAA,EAAQ,YAAA,EAAa,QAAO,MAAA,EAC/B,QAAA,EAAA,CAAA,CAAE,kCAAkC,CAAA,EACvC,CAAA;AAAA,UACC,gBAAA,CAAiB,IAAI,CAAA,GAAA,qBACpB,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,UAAA,EAAY,oBAAA,CAAqB,GAAA,CAAI,cAAA,CAAe,GAAG,CAAC,CAAA;AAAA,cACxD,QAAA,EAAU,MAAM,YAAA,CAAa,cAAA,CAAe,GAAG,CAAC,CAAA;AAAA,cAE/C,yBAAe,GAAG;AAAA,aAAA;AAAA,YAJd,GAAA,CAAI;AAAA,WAMZ;AAAA,SAAA,EACH;AAAA,OAAA,EACF,CAAA,EACF,CAAA;AAAA,2BACC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,WAAA,EAAY,OAAA,EAAS,MAAM,QAAQ,KAAK,CAAA,EACrD,QAAA,EAAA,CAAA,CAAE,uCAAuC,CAAA,EAC5C,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,SAAA;AAAA,YACR,OAAA,EAAS,MAAM,YAAA,EAAa;AAAA,YAC5B,UAAA,EACE,CAAC,YAAA,IAAgB,OAAA,IAAW,gBAAgB,MAAA,KAAW,CAAA;AAAA,YAEzD,OAAA;AAAA,YAEC,QAAA,EAAA,OAAA,GACG,CAAA,CAAE,0CAA0C,CAAA,GAC5C,EAAE,wCAAwC;AAAA;AAAA;AAChD,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"CatalogExportButton.esm.js","sources":["../../../src/components/CatalogExportButton/CatalogExportButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\nimport { RiDownloadLine } from '@remixicon/react';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef, toastApiRef } from '@backstage/frontend-plugin-api';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport {\n Button,\n ButtonIcon,\n Checkbox,\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n Flex,\n Select,\n Text,\n} from '@backstage/ui';\nimport { useStreamingExport } from './file-download/useStreamingExport';\nimport type { CatalogExportSettingsColumn } from './file-download/serializeEntities';\nimport { getColumnTitle } from './file-download/serializeEntities';\nimport type { CatalogExporter } from './file-download/useStreamingExport';\nimport { CatalogExportType } from './CatalogExportType';\n\nexport { CatalogExportType } from './CatalogExportType';\n\n/**\n * Custom exporter configuration for a catalog export format.\n * @public\n */\nexport interface CatalogExporterConfig {\n /** The exporter function that generates the export content. */\n exporter: CatalogExporter;\n /** Optional display label shown in the format selector. Defaults to the format key in uppercase. */\n label?: string;\n}\n\n/**\n * Settings for configuring the catalog export functionality.\n *\n * @public\n */\nexport interface CatalogExportSettings {\n /**\n * When true, displays the export button in the catalog interface.\n * Defaults to false if not specified.\n */\n enabled?: boolean;\n\n /**\n * Custom columns to include in the export.\n * Each column specifies an entity field path and a display title.\n * If not specified, uses default columns: Name, Type, Owner, Description.\n */\n columns?: CatalogExportSettingsColumn[];\n\n /**\n * Map of custom export format handlers beyond the built-in CSV and JSON formats.\n * Key is the format name (e.g., 'xml', 'yaml'), value is the exporter configuration.\n * Custom formats will appear as options in the export dialog.\n */\n exporters?: Record<string, CatalogExporterConfig>;\n\n /**\n * When true, hides the built-in CSV and JSON export options from the dialog.\n * Useful when only custom exporters should be available.\n */\n disableBuiltinExporters?: boolean;\n\n /**\n * Callback function invoked when the export completes successfully.\n * Useful for showing notifications or performing post-export actions.\n */\n onSuccess?: () => void;\n\n /**\n * Callback function invoked when the export fails.\n * Receives an object containing the error for custom error handling.\n */\n onError?: (options: { error: Error }) => void;\n}\n\n/**\n * The available default export columns for the catalog export.\n * These can be overridden by providing custom columns in the export button options.\n *\n * @private\n */\nconst DEFAULT_EXPORT_COLUMNS = [\n { entityFilterKey: 'metadata.name', title: 'Name' },\n { entityFilterKey: 'spec.type', title: 'Type' },\n { entityFilterKey: 'spec.owner', title: 'Owner' },\n { entityFilterKey: 'metadata.description', title: 'Description' },\n];\n\n/**\n * A button that opens a dialog to export the current catalog selection.\n *\n * @param settings - Optional export configuration settings including columns, custom exporters, and callbacks\n * @public\n */\nexport const CatalogExportButton = ({\n settings,\n iconOnly = false,\n}: {\n settings?: CatalogExportSettings;\n iconOnly?: boolean;\n}) => {\n const { t } = useTranslationRef(catalogTranslationRef);\n const { exportStream, loading, error } = useStreamingExport();\n const [open, setOpen] = useState(false);\n const exporters = settings?.exporters;\n const disableBuiltinExporters = settings?.disableBuiltinExporters;\n const onSuccess = settings?.onSuccess;\n const onError = settings?.onError;\n const apis = useApiHolder();\n const toastApi = apis.get(toastApiRef)!;\n const [isExporting, setIsExporting] = useState(false);\n\n const effectiveColumns = settings?.columns ?? DEFAULT_EXPORT_COLUMNS;\n\n const allExportOptions = [\n ...(disableBuiltinExporters\n ? []\n : Object.values(CatalogExportType).map(format => ({\n value: format,\n label: format.toUpperCase(),\n }))),\n ...Object.entries(exporters ?? {}).map(([key, exporter]) => ({\n value: key,\n label: exporter.label ?? key.toUpperCase(),\n })),\n ];\n\n const [exportFormat, setExportFormat] = useState<string>(\n allExportOptions[0]?.value ?? '',\n );\n const [selectedColumnTitles, setSelectedColumnTitles] = useState<Set<string>>(\n () => new Set(effectiveColumns.map(c => getColumnTitle(c))),\n );\n const selectedColumns = effectiveColumns.filter(c =>\n selectedColumnTitles.has(getColumnTitle(c)),\n );\n\n const handleOpenDialog = () => {\n setSelectedColumnTitles(\n new Set(effectiveColumns.map(c => getColumnTitle(c))),\n );\n setOpen(true);\n };\n\n const toggleColumn = (title: string) => {\n setSelectedColumnTitles(prev => {\n const next = new Set(prev);\n if (next.has(title)) {\n next.delete(title);\n } else {\n next.add(title);\n }\n return next;\n });\n };\n\n useEffect(() => {\n if (isExporting && !loading) {\n if (error) {\n if (onError) {\n onError({ error });\n } else {\n toastApi.post({\n title: t('catalogExportButton.errorMessage', {\n errorMessage: error.message,\n }),\n status: 'danger',\n });\n }\n } else {\n if (onSuccess) {\n onSuccess();\n } else {\n toastApi.post({\n title: t('catalogExportButton.successMessage'),\n status: 'success',\n });\n }\n }\n setOpen(false);\n setIsExporting(false);\n }\n }, [isExporting, loading, error, toastApi, onSuccess, onError, t]);\n\n const handleExport = useCallback(async () => {\n setIsExporting(true);\n const exporterFn = exporters?.[exportFormat];\n await exportStream({\n exportFormat,\n filename: `catalog-export.${exportFormat}`,\n columns: selectedColumns,\n exporter: exporterFn?.exporter,\n });\n }, [exportFormat, exportStream, selectedColumns, exporters]);\n\n return (\n <>\n {iconOnly ? (\n <ButtonIcon\n variant=\"secondary\"\n icon={<RiDownloadLine />}\n aria-label={t('catalogExportButton.triggerButtonTitle')}\n onPress={handleOpenDialog}\n />\n ) : (\n <Button\n variant=\"secondary\"\n iconStart={<RiDownloadLine />}\n onPress={handleOpenDialog}\n >\n {t('catalogExportButton.triggerButtonTitle')}\n </Button>\n )}\n\n <Dialog isOpen={open} onOpenChange={isOpen => !isOpen && setOpen(false)}>\n <DialogHeader>{t('catalogExportButton.dialogTitle')}</DialogHeader>\n <DialogBody>\n <Flex direction=\"column\" gap=\"4\">\n <Select\n data-testid=\"format-select\"\n label={t('catalogExportButton.formatLabel')}\n options={allExportOptions}\n value={exportFormat}\n onChange={key => setExportFormat(key as string)}\n />\n <Flex direction=\"column\" gap=\"1\">\n <Text variant=\"body-small\" weight=\"bold\">\n {t('catalogExportButton.columnsLabel')}\n </Text>\n {effectiveColumns.map(col => (\n <Checkbox\n key={col.entityFilterKey}\n isSelected={selectedColumnTitles.has(getColumnTitle(col))}\n onChange={() => toggleColumn(getColumnTitle(col))}\n >\n {getColumnTitle(col)}\n </Checkbox>\n ))}\n </Flex>\n </Flex>\n </DialogBody>\n <DialogFooter>\n <Button variant=\"secondary\" onPress={() => setOpen(false)}>\n {t('catalogExportButton.cancelButtonTitle')}\n </Button>\n <Button\n variant=\"primary\"\n onPress={() => handleExport()}\n isDisabled={\n !exportFormat || loading || selectedColumns.length === 0\n }\n loading={loading}\n >\n {loading\n ? t('catalogExportButton.exportingButtonTitle')\n : t('catalogExportButton.confirmButtonTitle')}\n </Button>\n </DialogFooter>\n </Dialog>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ var CatalogExportType = /* @__PURE__ */ ((CatalogExportType2) => {
2
+ CatalogExportType2["CSV"] = "csv";
3
+ CatalogExportType2["JSON"] = "json";
4
+ return CatalogExportType2;
5
+ })(CatalogExportType || {});
6
+
7
+ export { CatalogExportType };
8
+ //# sourceMappingURL=CatalogExportType.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CatalogExportType.esm.js","sources":["../../../src/components/CatalogExportButton/CatalogExportType.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The available export formats for the catalog export.\n * Currently supports CSV and JSON.\n *\n * @public\n */\nexport enum CatalogExportType {\n CSV = 'csv',\n JSON = 'json',\n}\n"],"names":["CatalogExportType"],"mappings":"AAsBO,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AACL,EAAAA,mBAAA,KAAA,CAAA,GAAM,KAAA;AACN,EAAAA,mBAAA,MAAA,CAAA,GAAO,MAAA;AAFG,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;;;;"}
@@ -3,7 +3,7 @@ import { useApiHolder } from '@backstage/core-plugin-api';
3
3
  import { catalogApiRef, useEntityList } from '@backstage/plugin-catalog-react';
4
4
  import { createStreamFromAsyncGenerator, streamDownload } from './downloadFile.esm.js';
5
5
  import { serializeEntitiesToCsv, serializeEntityToJsonRow } from './serializeEntities.esm.js';
6
- import { CatalogExportType } from '../CatalogExportButton.esm.js';
6
+ import { CatalogExportType } from '../CatalogExportType.esm.js';
7
7
  import { toStreamRequest } from './toStreamRequest.esm.js';
8
8
 
9
9
  async function* streamEntitiesCsvGenerator({
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamingExport.esm.js","sources":["../../../../src/components/CatalogExportButton/file-download/useStreamingExport.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState, useCallback } from 'react';\nimport { useApiHolder, type ApiHolder } from '@backstage/core-plugin-api';\nimport { catalogApiRef, useEntityList } from '@backstage/plugin-catalog-react';\nimport { streamDownload, createStreamFromAsyncGenerator } from './downloadFile';\nimport {\n serializeEntitiesToCsv,\n serializeEntityToJsonRow,\n CatalogExportSettingsColumn,\n} from './serializeEntities';\nimport { CatalogExportType } from '../CatalogExportButton';\nimport type {\n CatalogApi,\n StreamEntitiesRequest,\n} from '@backstage/catalog-client';\nimport { toStreamRequest } from './toStreamRequest';\n\n/**\n * A custom exporter function that returns an async generator for streaming exports.\n * The generator should yield string chunks that will be streamed to the download.\n * @public\n */\nexport type CatalogExporter = (options: {\n apis: ApiHolder;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}) => {\n generator: AsyncGenerator<string, void, unknown>;\n contentType: string;\n};\n\n/**\n * @public\n */\nexport interface StreamingExportOptions {\n exportFormat: CatalogExportType | string;\n filename: string;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n exporter?: CatalogExporter;\n}\n\n/**\n * Async generator that streams and serializes catalog entities to CSV format.\n * Yields CSV chunks as they're generated, enabling streaming downloads.\n */\nasync function* streamEntitiesCsvGenerator({\n catalogApi,\n columns,\n streamRequest,\n}: {\n catalogApi: CatalogApi;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}): AsyncGenerator<string, void, unknown> {\n let isFirstPage = true;\n\n const entityStream = catalogApi.streamEntities(streamRequest);\n\n for await (const entityPage of entityStream) {\n const pageCsv = serializeEntitiesToCsv(entityPage, columns, isFirstPage);\n yield pageCsv;\n isFirstPage = false;\n }\n}\n\n/**\n * Async generator that streams and serializes catalog entities to JSON format.\n * Yields JSON chunks as they're generated, enabling streaming downloads.\n */\nasync function* streamEntitiesJsonGenerator({\n catalogApi,\n columns,\n streamRequest,\n}: {\n catalogApi: CatalogApi;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}): AsyncGenerator<string, void, unknown> {\n let isFirst = true;\n\n yield '[';\n\n const entityStream = catalogApi.streamEntities(streamRequest);\n\n for await (const entityPage of entityStream) {\n for (const entity of entityPage) {\n const row = serializeEntityToJsonRow(entity, columns);\n if (isFirst) {\n yield `\\n ${row}`;\n isFirst = false;\n } else {\n yield `,\\n ${row}`;\n }\n }\n }\n\n yield '\\n]';\n}\n\n/**\n * A hook for streaming and exporting catalog entities from the frontend.\n *\n * This hook uses the catalog API's `streamEntities` method to efficiently\n * stream entities in pages and serialize them to CSV or JSON format directly\n * on the frontend, without requiring a backend export endpoint.\n *\n * @returns An object containing:\n * - `exportStream`: The function to trigger the streaming export.\n * - `loading`: A boolean indicating if the export is in progress.\n * - `error`: An error object if the export fails.\n */\nexport const useStreamingExport = (): {\n exportStream: (options: StreamingExportOptions) => Promise<void>;\n loading: boolean;\n error: Error | null;\n} => {\n const apis = useApiHolder();\n const catalogApi = apis.get(catalogApiRef)!;\n const { filters } = useEntityList();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const exportStream = useCallback(\n async ({\n exportFormat,\n filename,\n columns,\n streamRequest,\n onSuccess,\n onError,\n exporter,\n }: StreamingExportOptions) => {\n setLoading(true);\n setError(null);\n\n try {\n // If caller didn't provide a streamRequest, derive it from the\n // current EntityList filters so exports reflect the user's view.\n const resolvedStreamRequest = streamRequest ?? toStreamRequest(filters);\n\n if (exporter) {\n const { generator, contentType } = exporter({\n apis,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else if (exportFormat === CatalogExportType.CSV) {\n const generator = streamEntitiesCsvGenerator({\n catalogApi,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const contentType = 'text/csv; charset=utf-8';\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else if (exportFormat === CatalogExportType.JSON) {\n const generator = streamEntitiesJsonGenerator({\n catalogApi,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const contentType = 'application/json; charset=utf-8';\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else {\n throw new Error(`Unsupported export format: ${exportFormat}`);\n }\n\n if (onSuccess) {\n onSuccess();\n }\n } catch (e: any) {\n setError(e);\n if (onError) {\n onError(e);\n }\n } finally {\n setLoading(false);\n }\n },\n [filters, apis, catalogApi],\n );\n\n return { exportStream, loading, error };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useStreamingExport.esm.js","sources":["../../../../src/components/CatalogExportButton/file-download/useStreamingExport.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState, useCallback } from 'react';\nimport { useApiHolder, type ApiHolder } from '@backstage/core-plugin-api';\nimport { catalogApiRef, useEntityList } from '@backstage/plugin-catalog-react';\nimport { streamDownload, createStreamFromAsyncGenerator } from './downloadFile';\nimport {\n serializeEntitiesToCsv,\n serializeEntityToJsonRow,\n CatalogExportSettingsColumn,\n} from './serializeEntities';\nimport { CatalogExportType } from '../CatalogExportType';\nimport type {\n CatalogApi,\n StreamEntitiesRequest,\n} from '@backstage/catalog-client';\nimport { toStreamRequest } from './toStreamRequest';\n\n/**\n * A custom exporter function that returns an async generator for streaming exports.\n * The generator should yield string chunks that will be streamed to the download.\n * @public\n */\nexport type CatalogExporter = (options: {\n apis: ApiHolder;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}) => {\n generator: AsyncGenerator<string, void, unknown>;\n contentType: string;\n};\n\n/**\n * @public\n */\nexport interface StreamingExportOptions {\n exportFormat: CatalogExportType | string;\n filename: string;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n exporter?: CatalogExporter;\n}\n\n/**\n * Async generator that streams and serializes catalog entities to CSV format.\n * Yields CSV chunks as they're generated, enabling streaming downloads.\n */\nasync function* streamEntitiesCsvGenerator({\n catalogApi,\n columns,\n streamRequest,\n}: {\n catalogApi: CatalogApi;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}): AsyncGenerator<string, void, unknown> {\n let isFirstPage = true;\n\n const entityStream = catalogApi.streamEntities(streamRequest);\n\n for await (const entityPage of entityStream) {\n const pageCsv = serializeEntitiesToCsv(entityPage, columns, isFirstPage);\n yield pageCsv;\n isFirstPage = false;\n }\n}\n\n/**\n * Async generator that streams and serializes catalog entities to JSON format.\n * Yields JSON chunks as they're generated, enabling streaming downloads.\n */\nasync function* streamEntitiesJsonGenerator({\n catalogApi,\n columns,\n streamRequest,\n}: {\n catalogApi: CatalogApi;\n columns: CatalogExportSettingsColumn[];\n streamRequest?: StreamEntitiesRequest;\n}): AsyncGenerator<string, void, unknown> {\n let isFirst = true;\n\n yield '[';\n\n const entityStream = catalogApi.streamEntities(streamRequest);\n\n for await (const entityPage of entityStream) {\n for (const entity of entityPage) {\n const row = serializeEntityToJsonRow(entity, columns);\n if (isFirst) {\n yield `\\n ${row}`;\n isFirst = false;\n } else {\n yield `,\\n ${row}`;\n }\n }\n }\n\n yield '\\n]';\n}\n\n/**\n * A hook for streaming and exporting catalog entities from the frontend.\n *\n * This hook uses the catalog API's `streamEntities` method to efficiently\n * stream entities in pages and serialize them to CSV or JSON format directly\n * on the frontend, without requiring a backend export endpoint.\n *\n * @returns An object containing:\n * - `exportStream`: The function to trigger the streaming export.\n * - `loading`: A boolean indicating if the export is in progress.\n * - `error`: An error object if the export fails.\n */\nexport const useStreamingExport = (): {\n exportStream: (options: StreamingExportOptions) => Promise<void>;\n loading: boolean;\n error: Error | null;\n} => {\n const apis = useApiHolder();\n const catalogApi = apis.get(catalogApiRef)!;\n const { filters } = useEntityList();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const exportStream = useCallback(\n async ({\n exportFormat,\n filename,\n columns,\n streamRequest,\n onSuccess,\n onError,\n exporter,\n }: StreamingExportOptions) => {\n setLoading(true);\n setError(null);\n\n try {\n // If caller didn't provide a streamRequest, derive it from the\n // current EntityList filters so exports reflect the user's view.\n const resolvedStreamRequest = streamRequest ?? toStreamRequest(filters);\n\n if (exporter) {\n const { generator, contentType } = exporter({\n apis,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else if (exportFormat === CatalogExportType.CSV) {\n const generator = streamEntitiesCsvGenerator({\n catalogApi,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const contentType = 'text/csv; charset=utf-8';\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else if (exportFormat === CatalogExportType.JSON) {\n const generator = streamEntitiesJsonGenerator({\n catalogApi,\n columns,\n streamRequest: resolvedStreamRequest,\n });\n const contentType = 'application/json; charset=utf-8';\n const stream = createStreamFromAsyncGenerator(generator);\n await streamDownload(stream, filename, contentType);\n } else {\n throw new Error(`Unsupported export format: ${exportFormat}`);\n }\n\n if (onSuccess) {\n onSuccess();\n }\n } catch (e: any) {\n setError(e);\n if (onError) {\n onError(e);\n }\n } finally {\n setLoading(false);\n }\n },\n [filters, apis, catalogApi],\n );\n\n return { exportStream, loading, error };\n};\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { SupportButton, CreateButton, PageWithHeader, Content, ContentHeader } from '@backstage/core-components';
2
+ import { CreateButton, SupportButton, PageWithHeader, Content, ContentHeader } from '@backstage/core-components';
3
3
  import { useApi, configApiRef, useRouteRef } from '@backstage/core-plugin-api';
4
4
  import { Header, ButtonLink, Container } from '@backstage/ui';
5
5
  import { RiAddLine } from '@remixicon/react';
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultCatalogPage.esm.js","sources":["../../../src/components/CatalogPage/DefaultCatalogPage.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { ButtonLink, Container, Header } from '@backstage/ui';\nimport { RiAddLine } from '@remixicon/react';\nimport {\n CatalogFilterLayout,\n DefaultFilters,\n EntityListPagination,\n EntityListProvider,\n EntityOwnerPickerProps,\n UserListFilterKind,\n} from '@backstage/plugin-catalog-react';\nimport { ReactNode } from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable, CatalogTableRow } from '../CatalogTable';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { CatalogTableColumnsFunc } from '../CatalogTable/types';\nimport { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { CatalogExportButton } from '../CatalogExportButton/CatalogExportButton';\nimport type { CatalogExportSettings } from '../CatalogExportButton';\nimport Box from '@material-ui/core/Box';\nimport styles from './DefaultCatalogPage.module.css';\n\n/** @internal */\nexport type BaseCatalogPageProps = {\n filters: ReactNode;\n content?: ReactNode;\n pagination?: EntityListPagination;\n exportSettings?: CatalogExportSettings;\n};\n\nfunction CatalogPageContent(props: BaseCatalogPageProps) {\n const { filters, content = <CatalogTable /> } = props;\n\n return (\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>{filters}</CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>{content}</CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n );\n}\n\n/** @internal */\nexport function BaseCatalogPage(props: BaseCatalogPageProps) {\n const { pagination, exportSettings } = props;\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n const headerActions = (\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n {exportSettings?.enabled && (\n <Box ml={2}>\n <CatalogExportButton settings={exportSettings} />\n </Box>\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n );\n\n return (\n <EntityListProvider pagination={pagination}>\n <PageWithHeader title={t('indexPage.title', { orgName })} themeId=\"home\">\n <Content>\n <ContentHeader title=\"\">{headerActions}</ContentHeader>\n <CatalogPageContent {...props} />\n </Content>\n </PageWithHeader>\n </EntityListProvider>\n );\n}\n\n/** @internal */\nexport function NfsBaseCatalogPage(props: BaseCatalogPageProps) {\n const { pagination, exportSettings } = props;\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const createComponentHref = createComponentLink?.();\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n\n return (\n <EntityListProvider pagination={pagination}>\n <Header\n title={t('indexPage.title', { orgName })}\n customActions={\n <>\n {allowed && createComponentHref && (\n <ButtonLink\n variant=\"primary\"\n href={createComponentHref}\n iconStart={<RiAddLine />}\n >\n {t('indexPage.createButtonTitle')}\n </ButtonLink>\n )}\n {exportSettings?.enabled && (\n <CatalogExportButton settings={exportSettings} iconOnly />\n )}\n <div className={styles.supportButton}>\n <SupportButton>\n {t('indexPage.supportButtonContent')}\n </SupportButton>\n </div>\n </>\n }\n />\n <Container>\n <CatalogPageContent {...props} />\n </Container>\n </EntityListProvider>\n );\n}\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n initialKind?: string;\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n filters?: ReactNode;\n initiallySelectedNamespaces?: string[];\n pagination?: EntityListPagination;\n exportSettings?: CatalogExportSettings;\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n exportSettings,\n } = props;\n\n return (\n <BaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n exportSettings={exportSettings}\n />\n );\n}\n\n/** @public */\nexport function NfsDefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n exportSettings,\n } = props;\n\n return (\n <NfsBaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n exportSettings={exportSettings}\n />\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DefaultCatalogPage.esm.js","sources":["../../../src/components/CatalogPage/DefaultCatalogPage.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport { ButtonLink, Container, Header } from '@backstage/ui';\nimport { RiAddLine } from '@remixicon/react';\nimport {\n CatalogFilterLayout,\n DefaultFilters,\n EntityListPagination,\n EntityListProvider,\n EntityOwnerPickerProps,\n UserListFilterKind,\n} from '@backstage/plugin-catalog-react';\nimport { ReactNode } from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable } from '../CatalogTable/CatalogTable';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n CatalogTableColumnsFunc,\n CatalogTableRow,\n} from '../CatalogTable/types';\nimport { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { CatalogExportButton } from '../CatalogExportButton/CatalogExportButton';\nimport type { CatalogExportSettings } from '../CatalogExportButton';\nimport Box from '@material-ui/core/Box';\nimport styles from './DefaultCatalogPage.module.css';\n\n/** @internal */\nexport type BaseCatalogPageProps = {\n filters: ReactNode;\n content?: ReactNode;\n pagination?: EntityListPagination;\n exportSettings?: CatalogExportSettings;\n};\n\nfunction CatalogPageContent(props: BaseCatalogPageProps) {\n const { filters, content = <CatalogTable /> } = props;\n\n return (\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>{filters}</CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>{content}</CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n );\n}\n\n/** @internal */\nexport function BaseCatalogPage(props: BaseCatalogPageProps) {\n const { pagination, exportSettings } = props;\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n const headerActions = (\n <>\n {allowed && (\n <CreateButton\n title={t('indexPage.createButtonTitle')}\n to={createComponentLink && createComponentLink()}\n />\n )}\n {exportSettings?.enabled && (\n <Box ml={2}>\n <CatalogExportButton settings={exportSettings} />\n </Box>\n )}\n <SupportButton>{t('indexPage.supportButtonContent')}</SupportButton>\n </>\n );\n\n return (\n <EntityListProvider pagination={pagination}>\n <PageWithHeader title={t('indexPage.title', { orgName })} themeId=\"home\">\n <Content>\n <ContentHeader title=\"\">{headerActions}</ContentHeader>\n <CatalogPageContent {...props} />\n </Content>\n </PageWithHeader>\n </EntityListProvider>\n );\n}\n\n/** @internal */\nexport function NfsBaseCatalogPage(props: BaseCatalogPageProps) {\n const { pagination, exportSettings } = props;\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const createComponentHref = createComponentLink?.();\n const { t } = useTranslationRef(catalogTranslationRef);\n const { allowed } = usePermission({\n permission: catalogEntityCreatePermission,\n });\n\n return (\n <EntityListProvider pagination={pagination}>\n <Header\n title={t('indexPage.title', { orgName })}\n customActions={\n <>\n {allowed && createComponentHref && (\n <ButtonLink\n variant=\"primary\"\n href={createComponentHref}\n iconStart={<RiAddLine />}\n >\n {t('indexPage.createButtonTitle')}\n </ButtonLink>\n )}\n {exportSettings?.enabled && (\n <CatalogExportButton settings={exportSettings} iconOnly />\n )}\n <div className={styles.supportButton}>\n <SupportButton>\n {t('indexPage.supportButtonContent')}\n </SupportButton>\n </div>\n </>\n }\n />\n <Container>\n <CatalogPageContent {...props} />\n </Container>\n </EntityListProvider>\n );\n}\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n initialKind?: string;\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n filters?: ReactNode;\n initiallySelectedNamespaces?: string[];\n pagination?: EntityListPagination;\n exportSettings?: CatalogExportSettings;\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n exportSettings,\n } = props;\n\n return (\n <BaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n exportSettings={exportSettings}\n />\n );\n}\n\n/** @public */\nexport function NfsDefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n pagination,\n ownerPickerMode,\n filters,\n initiallySelectedNamespaces,\n exportSettings,\n } = props;\n\n return (\n <NfsBaseCatalogPage\n filters={\n filters ?? (\n <DefaultFilters\n initialKind={initialKind}\n initiallySelectedFilter={initiallySelectedFilter}\n ownerPickerMode={ownerPickerMode}\n initiallySelectedNamespaces={initiallySelectedNamespaces}\n />\n )\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n pagination={pagination}\n exportSettings={exportSettings}\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable.esm.j
16
16
  import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc.esm.js';
17
17
  import { useApiHolder } from '@backstage/core-plugin-api';
18
18
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
19
- import { catalogTranslationRef } from '../../alpha.esm.js';
19
+ import { catalogTranslationRef } from '../../alpha/translation.esm.js';
20
20
 
21
21
  const sortEntities = (entities, api) => {
22
22
  return sortBy(
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogTable.esm.js","sources":["../../../src/components/CatalogTable/CatalogTable.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ANNOTATION_EDIT_URL,\n ANNOTATION_VIEW_URL,\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n getEntityRelations,\n useEntityList,\n useStarredEntities,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport Typography from '@material-ui/core/Typography';\nimport { visuallyHidden } from '@mui/utils';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize, sortBy } from 'lodash';\nimport pluralize from 'pluralize';\nimport { ReactNode, useMemo, useRef } from 'react';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\nimport { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable';\nimport { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable';\nimport { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha';\nimport { FavoriteToggleIcon } from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n /**\n * A static title to use for the table. If not provided, a title will be\n * generated based on the current Kind and Type filters and total number of items.\n */\n title?: string;\n subtitle?: string;\n}\n\nconst sortEntities = (entities: Entity[], api?: EntityPresentationApi) => {\n return sortBy(\n entities,\n e =>\n entityPresentationSnapshot(e, { defaultKind: 'Component' }, api)\n .primaryTitle,\n );\n};\n\n/**\n * CatalogTable is a wrapper around the Table component that is pre-configured\n * to display catalog entities.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/features/software-catalog/catalog-customization}\n *\n * @public\n */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const {\n columns = defaultCatalogTableColumnsFunc,\n tableOptions,\n subtitle,\n emptyContent,\n } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const entityListContext = useEntityList();\n\n const {\n loading,\n error,\n entities,\n filters,\n pageInfo,\n totalItems,\n totalItemsLoading,\n paginationMode,\n } = entityListContext;\n\n // Track whether we've ever received data. The full-table spinner should\n // only show on the truly initial load — not when a filter change\n // empties the client-side entity list before the backend responds.\n const hasHadData = useRef(false);\n if (entities.length > 0) {\n hasHadData.current = true;\n }\n const isLoading = loading && !hasHadData.current;\n\n const tableColumns = useMemo(\n () =>\n typeof columns === 'function' ? columns(entityListContext) : columns,\n [columns, entityListContext],\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title={t('catalogTable.warningPanelTitle')}\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<CatalogTableRow>['actions'] = [\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL];\n const title = t('catalogTable.viewActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <OpenInNew fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n const title = t('catalogTable.editActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <Edit fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n const title = isStarred\n ? t('catalogTable.unStarActionTitle')\n : t('catalogTable.starActionTitle');\n\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => <FavoriteToggleIcon isFavorite={isStarred} />,\n tooltip: title,\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n // Derive the title's kind label from the displayed entities so the\n // title stays consistent with the rows during filter transitions.\n // Use the filter's label when it matches (it has proper casing),\n // otherwise fall back to the entity's kind field directly.\n const displayedKind = entities[0]?.kind ?? filters.kind?.value;\n const displayedKindLabel =\n displayedKind?.toLocaleLowerCase('en-US') ===\n filters.kind?.value?.toLocaleLowerCase('en-US')\n ? filters.kind?.label || ''\n : displayedKind || '';\n const currentType = filters.type?.value || '';\n // Show the count as long as we have one. Hide it only when new rows\n // have arrived but the count hasn't caught up yet — at that point\n // the old count would be wrong for the new data.\n const countIsStale = !loading && totalItemsLoading;\n const currentCount =\n typeof totalItems === 'number' && !countIsStale ? ` (${totalItems})` : '';\n const somethingIsLoading = loading || totalItemsLoading;\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(\n filters.user?.value ?? t('catalogTable.allFilters'),\n );\n const titleBase =\n props.title ||\n [titlePreamble, currentType, pluralize(displayedKindLabel)]\n .filter(s => s)\n .join(' ');\n const title = props.title ? (\n titleBase\n ) : (\n <span\n style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5em' }}\n >\n {titleBase}\n {currentCount}\n {somethingIsLoading && !isLoading && (\n <CircularProgress size=\"0.8em\" data-testid=\"loading-indicator\" />\n )}\n </span>\n );\n\n const actions = props.actions || defaultActions;\n const options: TableProps['options'] = {\n actionsColumnIndex: -1,\n loadingType: 'linear' as const,\n showEmptyDataSourceMessage: !isLoading,\n padding: 'dense' as const,\n ...tableOptions,\n };\n\n if (paginationMode === 'cursor') {\n return (\n <CursorPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n next={pageInfo?.next}\n prev={pageInfo?.prev}\n />\n );\n } else if (paginationMode === 'offset') {\n return (\n <OffsetPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n />\n );\n }\n\n const rows = sortEntities(entities, entityPresentationApi).map(e =>\n toEntityRow(e, entityPresentationApi),\n );\n const pageSize = 20;\n const showPagination = rows.length > pageSize;\n\n return (\n <Table<CatalogTableRow>\n isLoading={isLoading}\n columns={tableColumns}\n options={{\n paging: showPagination,\n pageSize: pageSize,\n pageSizeOptions: [20, 50, 100],\n ...options,\n }}\n title={title}\n data={rows}\n actions={actions}\n subtitle={subtitle}\n emptyContent={emptyContent}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\nCatalogTable.defaultColumnsFunc = defaultCatalogTableColumnsFunc;\n\nfunction toEntityRow(entity: Entity, api?: EntityPresentationApi) {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n // This name is here for backwards compatibility mostly; the\n // presentation of refs in the table should in general be handled with\n // EntityRefLink / EntityName components\n name: entityPresentationSnapshot(\n entity,\n { defaultKind: 'Component' },\n api,\n ).primaryTitle,\n entityRef: stringifyEntityRef(entity),\n ownedByRelationsTitle: ownedByRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'group' }, api)\n .primaryTitle,\n )\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'system' }, api)\n .primaryTitle,\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n}\n"],"names":["title","Edit"],"mappings":"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"}
1
+ {"version":3,"file":"CatalogTable.esm.js","sources":["../../../src/components/CatalogTable/CatalogTable.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ANNOTATION_EDIT_URL,\n ANNOTATION_VIEW_URL,\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n entityPresentationApiRef,\n entityPresentationSnapshot,\n getEntityRelations,\n useEntityList,\n useStarredEntities,\n type EntityPresentationApi,\n} from '@backstage/plugin-catalog-react';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport Typography from '@material-ui/core/Typography';\nimport { visuallyHidden } from '@mui/utils';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize, sortBy } from 'lodash';\nimport pluralize from 'pluralize';\nimport { ReactNode, useMemo, useRef } from 'react';\nimport { columnFactories } from './columns';\nimport { CatalogTableColumnsFunc, CatalogTableRow } from './types';\nimport { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable';\nimport { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable';\nimport { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc';\nimport { useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { FavoriteToggleIcon } from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[] | CatalogTableColumnsFunc;\n actions?: TableProps<CatalogTableRow>['actions'];\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n /**\n * A static title to use for the table. If not provided, a title will be\n * generated based on the current Kind and Type filters and total number of items.\n */\n title?: string;\n subtitle?: string;\n}\n\nconst sortEntities = (entities: Entity[], api?: EntityPresentationApi) => {\n return sortBy(\n entities,\n e =>\n entityPresentationSnapshot(e, { defaultKind: 'Component' }, api)\n .primaryTitle,\n );\n};\n\n/**\n * CatalogTable is a wrapper around the Table component that is pre-configured\n * to display catalog entities.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/features/software-catalog/catalog-customization}\n *\n * @public\n */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const {\n columns = defaultCatalogTableColumnsFunc,\n tableOptions,\n subtitle,\n emptyContent,\n } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const apis = useApiHolder();\n const entityPresentationApi = apis.get(entityPresentationApiRef);\n const entityListContext = useEntityList();\n\n const {\n loading,\n error,\n entities,\n filters,\n pageInfo,\n totalItems,\n totalItemsLoading,\n paginationMode,\n } = entityListContext;\n\n // Track whether we've ever received data. The full-table spinner should\n // only show on the truly initial load — not when a filter change\n // empties the client-side entity list before the backend responds.\n const hasHadData = useRef(false);\n if (entities.length > 0) {\n hasHadData.current = true;\n }\n const isLoading = loading && !hasHadData.current;\n\n const tableColumns = useMemo(\n () =>\n typeof columns === 'function' ? columns(entityListContext) : columns,\n [columns, entityListContext],\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title={t('catalogTable.warningPanelTitle')}\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<CatalogTableRow>['actions'] = [\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL];\n const title = t('catalogTable.viewActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <OpenInNew fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n const title = t('catalogTable.editActionTitle');\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <Edit fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n const title = isStarred\n ? t('catalogTable.unStarActionTitle')\n : t('catalogTable.starActionTitle');\n\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => <FavoriteToggleIcon isFavorite={isStarred} />,\n tooltip: title,\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n // Derive the title's kind label from the displayed entities so the\n // title stays consistent with the rows during filter transitions.\n // Use the filter's label when it matches (it has proper casing),\n // otherwise fall back to the entity's kind field directly.\n const displayedKind = entities[0]?.kind ?? filters.kind?.value;\n const displayedKindLabel =\n displayedKind?.toLocaleLowerCase('en-US') ===\n filters.kind?.value?.toLocaleLowerCase('en-US')\n ? filters.kind?.label || ''\n : displayedKind || '';\n const currentType = filters.type?.value || '';\n // Show the count as long as we have one. Hide it only when new rows\n // have arrived but the count hasn't caught up yet — at that point\n // the old count would be wrong for the new data.\n const countIsStale = !loading && totalItemsLoading;\n const currentCount =\n typeof totalItems === 'number' && !countIsStale ? ` (${totalItems})` : '';\n const somethingIsLoading = loading || totalItemsLoading;\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(\n filters.user?.value ?? t('catalogTable.allFilters'),\n );\n const titleBase =\n props.title ||\n [titlePreamble, currentType, pluralize(displayedKindLabel)]\n .filter(s => s)\n .join(' ');\n const title = props.title ? (\n titleBase\n ) : (\n <span\n style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5em' }}\n >\n {titleBase}\n {currentCount}\n {somethingIsLoading && !isLoading && (\n <CircularProgress size=\"0.8em\" data-testid=\"loading-indicator\" />\n )}\n </span>\n );\n\n const actions = props.actions || defaultActions;\n const options: TableProps['options'] = {\n actionsColumnIndex: -1,\n loadingType: 'linear' as const,\n showEmptyDataSourceMessage: !isLoading,\n padding: 'dense' as const,\n ...tableOptions,\n };\n\n if (paginationMode === 'cursor') {\n return (\n <CursorPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n next={pageInfo?.next}\n prev={pageInfo?.prev}\n />\n );\n } else if (paginationMode === 'offset') {\n return (\n <OffsetPaginatedCatalogTable\n columns={tableColumns}\n emptyContent={emptyContent}\n isLoading={isLoading}\n title={title}\n actions={actions}\n subtitle={subtitle}\n options={options}\n data={entities.map(e => toEntityRow(e, entityPresentationApi))}\n />\n );\n }\n\n const rows = sortEntities(entities, entityPresentationApi).map(e =>\n toEntityRow(e, entityPresentationApi),\n );\n const pageSize = 20;\n const showPagination = rows.length > pageSize;\n\n return (\n <Table<CatalogTableRow>\n isLoading={isLoading}\n columns={tableColumns}\n options={{\n paging: showPagination,\n pageSize: pageSize,\n pageSizeOptions: [20, 50, 100],\n ...options,\n }}\n title={title}\n data={rows}\n actions={actions}\n subtitle={subtitle}\n emptyContent={emptyContent}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\nCatalogTable.defaultColumnsFunc = defaultCatalogTableColumnsFunc;\n\nfunction toEntityRow(entity: Entity, api?: EntityPresentationApi) {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n // This name is here for backwards compatibility mostly; the\n // presentation of refs in the table should in general be handled with\n // EntityRefLink / EntityName components\n name: entityPresentationSnapshot(\n entity,\n { defaultKind: 'Component' },\n api,\n ).primaryTitle,\n entityRef: stringifyEntityRef(entity),\n ownedByRelationsTitle: ownedByRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'group' }, api)\n .primaryTitle,\n )\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(\n r =>\n entityPresentationSnapshot(r, { defaultKind: 'system' }, api)\n .primaryTitle,\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n}\n"],"names":["title","Edit"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useAsyncEntity } from '@backstage/plugin-catalog-react';
3
- import { useApiHolder, useElementFilter, attachComponentData } from '@backstage/core-plugin-api';
3
+ import { attachComponentData, useApiHolder, useElementFilter } from '@backstage/core-plugin-api';
4
4
  import useAsync from 'react-use/esm/useAsync';
5
5
 
6
6
  const ENTITY_SWITCH_KEY = "core.backstage.entitySwitch";
@@ -1,5 +1,5 @@
1
1
  var name = "@backstage/plugin-catalog";
2
- var version = "2.0.8";
2
+ var version = "2.0.9-next.1";
3
3
  var description = "The Backstage plugin for browsing the Backstage catalog";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog",
3
- "version": "2.0.8",
3
+ "version": "2.0.9-next.1",
4
4
  "description": "The Backstage plugin for browsing the Backstage catalog",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -70,25 +70,25 @@
70
70
  "test": "backstage-cli package test"
71
71
  },
72
72
  "dependencies": {
73
- "@backstage/catalog-client": "^1.16.1",
74
- "@backstage/catalog-model": "^1.10.0",
75
- "@backstage/core-compat-api": "^0.5.14",
76
- "@backstage/core-components": "^0.18.13",
77
- "@backstage/core-plugin-api": "^1.12.9",
78
- "@backstage/errors": "^1.3.1",
79
- "@backstage/frontend-plugin-api": "^0.18.0",
80
- "@backstage/integration-react": "^1.2.21",
81
- "@backstage/plugin-catalog-common": "^1.1.10",
82
- "@backstage/plugin-catalog-react": "^3.2.1",
83
- "@backstage/plugin-permission-react": "^0.5.4",
84
- "@backstage/plugin-scaffolder-common": "^2.2.2",
85
- "@backstage/plugin-search-common": "^1.2.24",
86
- "@backstage/plugin-search-react": "^1.11.7",
87
- "@backstage/plugin-techdocs-common": "^0.1.1",
88
- "@backstage/plugin-techdocs-react": "^1.3.14",
89
- "@backstage/types": "^1.2.2",
90
- "@backstage/ui": "^0.17.1",
91
- "@backstage/version-bridge": "^1.0.12",
73
+ "@backstage/catalog-client": "1.16.2-next.0",
74
+ "@backstage/catalog-model": "1.10.0",
75
+ "@backstage/core-compat-api": "0.5.15-next.1",
76
+ "@backstage/core-components": "0.18.14-next.1",
77
+ "@backstage/core-plugin-api": "1.12.10-next.0",
78
+ "@backstage/errors": "1.3.1",
79
+ "@backstage/frontend-plugin-api": "0.18.1-next.0",
80
+ "@backstage/integration-react": "1.2.22-next.0",
81
+ "@backstage/plugin-catalog-common": "1.1.10",
82
+ "@backstage/plugin-catalog-react": "3.2.3-next.1",
83
+ "@backstage/plugin-permission-react": "0.5.5-next.0",
84
+ "@backstage/plugin-scaffolder-common": "2.3.0-next.1",
85
+ "@backstage/plugin-search-common": "1.2.24",
86
+ "@backstage/plugin-search-react": "1.11.8-next.1",
87
+ "@backstage/plugin-techdocs-common": "0.1.1",
88
+ "@backstage/plugin-techdocs-react": "1.3.15-next.1",
89
+ "@backstage/types": "1.2.2",
90
+ "@backstage/ui": "0.18.0-next.1",
91
+ "@backstage/version-bridge": "1.0.12",
92
92
  "@material-ui/core": "^4.12.2",
93
93
  "@material-ui/icons": "^4.9.1",
94
94
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -105,12 +105,12 @@
105
105
  "zod": "^4.0.0"
106
106
  },
107
107
  "devDependencies": {
108
- "@backstage/cli": "^0.36.5",
109
- "@backstage/core-app-api": "^1.20.4",
110
- "@backstage/dev-utils": "^1.1.26",
111
- "@backstage/frontend-test-utils": "^0.6.3",
112
- "@backstage/plugin-permission-common": "^0.9.10",
113
- "@backstage/test-utils": "^1.7.21",
108
+ "@backstage/cli": "0.36.6-next.0",
109
+ "@backstage/core-app-api": "1.20.5-next.1",
110
+ "@backstage/dev-utils": "1.1.27-next.1",
111
+ "@backstage/frontend-test-utils": "0.6.4-next.1",
112
+ "@backstage/plugin-permission-common": "0.9.10",
113
+ "@backstage/test-utils": "1.7.22-next.1",
114
114
  "@testing-library/dom": "^10.0.0",
115
115
  "@testing-library/jest-dom": "^6.0.0",
116
116
  "@testing-library/react": "^16.0.0",
@@ -1,2 +0,0 @@
1
- export { EntityLayout } from './EntityLayout.esm.js';
2
- //# sourceMappingURL=index.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}