@backstage/plugin-catalog-react 1.21.3-next.1 → 1.21.3

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 (21) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/alpha.d.ts +24 -0
  3. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.esm.js +1 -1
  4. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.esm.js.map +1 -1
  5. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.esm.js +1 -1
  6. package/dist/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.esm.js.map +1 -1
  7. package/dist/components/InspectEntityDialog/InspectEntityDialog.esm.js +15 -12
  8. package/dist/components/InspectEntityDialog/InspectEntityDialog.esm.js.map +1 -1
  9. package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js +3 -7
  10. package/dist/components/InspectEntityDialog/components/AncestryPage.esm.js.map +1 -1
  11. package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js +8 -2
  12. package/dist/components/InspectEntityDialog/components/ColocatedPage.esm.js.map +1 -1
  13. package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js +24 -10
  14. package/dist/components/InspectEntityDialog/components/OverviewPage.esm.js.map +1 -1
  15. package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js +17 -27
  16. package/dist/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.esm.js.map +1 -1
  17. package/dist/hooks/useEntityListProvider.esm.js +55 -39
  18. package/dist/hooks/useEntityListProvider.esm.js.map +1 -1
  19. package/dist/translation.esm.js +41 -5
  20. package/dist/translation.esm.js.map +1 -1
  21. package/package.json +20 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @backstage/plugin-catalog-react
2
2
 
3
+ ## 1.21.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 36d7582: Added missing i18n
8
+ - 2b7924b: Apply default ordering of templates
9
+ - 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility.
10
+ - 904d136: Fixed catalog filter "all" not appearing as selected when set as the initially selected filter.
11
+ - Updated dependencies
12
+ - @backstage/frontend-plugin-api@0.13.0
13
+ - @backstage/core-compat-api@0.5.4
14
+ - @backstage/core-components@0.18.3
15
+ - @backstage/core-plugin-api@1.12.0
16
+ - @backstage/plugin-permission-common@0.9.3
17
+ - @backstage/plugin-permission-react@0.4.38
18
+ - @backstage/catalog-model@1.7.6
19
+ - @backstage/frontend-test-utils@0.4.1
20
+ - @backstage/catalog-client@1.12.1
21
+ - @backstage/integration-react@1.2.12
22
+ - @backstage/plugin-catalog-common@1.1.7
23
+
24
+ ## 1.21.3-next.2
25
+
26
+ ### Patch Changes
27
+
28
+ - 36d7582: Added missing i18n
29
+ - Updated dependencies
30
+ - @backstage/frontend-plugin-api@0.12.2-next.2
31
+ - @backstage/core-components@0.18.3-next.2
32
+
3
33
  ## 1.21.3-next.1
4
34
 
5
35
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -333,8 +333,10 @@ declare const catalogReactTranslationRef: _backstage_core_plugin_api_alpha.Trans
333
333
  readonly "entityProcessingStatusPicker.title": "Processing Status";
334
334
  readonly "entityTagPicker.title": "Tags";
335
335
  readonly "entityPeekAheadPopover.title": "Drill into the entity to see all of the tags.";
336
+ readonly "entityPeekAheadPopover.entityCardActionsAriaLabel": "Show";
336
337
  readonly "entityPeekAheadPopover.entityCardActionsTitle": "Show details";
337
338
  readonly "entityPeekAheadPopover.emailCardAction.title": "Email {{email}}";
339
+ readonly "entityPeekAheadPopover.emailCardAction.ariaLabel": "Email";
338
340
  readonly "entityPeekAheadPopover.emailCardAction.subTitle": "mailto {{email}}";
339
341
  readonly "entitySearchBar.placeholder": "Search";
340
342
  readonly "entityTypePicker.title": "Type";
@@ -344,16 +346,33 @@ declare const catalogReactTranslationRef: _backstage_core_plugin_api_alpha.Trans
344
346
  readonly "favoriteEntity.removeFromFavorites": "Remove from favorites";
345
347
  readonly "inspectEntityDialog.title": "Entity Inspector";
346
348
  readonly "inspectEntityDialog.closeButtonTitle": "Close";
349
+ readonly "inspectEntityDialog.tabsAriaLabel": "Inspector options";
347
350
  readonly "inspectEntityDialog.ancestryPage.title": "Ancestry";
351
+ readonly "inspectEntityDialog.ancestryPage.description": "This is the ancestry of entities above the current one - as in, the chain(s) of entities down to the current one, where {{processorsLink}} child entities that ultimately led to the current one existing. Note that this is a completely different mechanism from relations.";
352
+ readonly "inspectEntityDialog.ancestryPage.processorsLink": "processors emitted";
348
353
  readonly "inspectEntityDialog.colocatedPage.title": "Colocated";
349
354
  readonly "inspectEntityDialog.colocatedPage.description": "These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).";
350
355
  readonly "inspectEntityDialog.colocatedPage.alertNoLocation": "Entity had no location information.";
351
356
  readonly "inspectEntityDialog.colocatedPage.alertNoEntity": "There were no other entities on this location.";
357
+ readonly "inspectEntityDialog.colocatedPage.locationHeader": "At the same location";
358
+ readonly "inspectEntityDialog.colocatedPage.originHeader": "At the same origin";
352
359
  readonly "inspectEntityDialog.jsonPage.title": "Entity as JSON";
353
360
  readonly "inspectEntityDialog.jsonPage.description": "This is the raw entity data as received from the catalog, on JSON form.";
354
361
  readonly "inspectEntityDialog.overviewPage.title": "Overview";
362
+ readonly "inspectEntityDialog.overviewPage.metadata.title": "Metadata";
363
+ readonly "inspectEntityDialog.overviewPage.labels": "Labels";
364
+ readonly "inspectEntityDialog.overviewPage.status.title": "Status";
365
+ readonly "inspectEntityDialog.overviewPage.identity.title": "Identity";
366
+ readonly "inspectEntityDialog.overviewPage.annotations": "Annotations";
367
+ readonly "inspectEntityDialog.overviewPage.tags": "Tags";
368
+ readonly "inspectEntityDialog.overviewPage.relation.title": "Relations";
355
369
  readonly "inspectEntityDialog.yamlPage.title": "Entity as YAML";
356
370
  readonly "inspectEntityDialog.yamlPage.description": "This is the raw entity data as received from the catalog, on YAML form.";
371
+ readonly "inspectEntityDialog.tabNames.json": "Raw JSON";
372
+ readonly "inspectEntityDialog.tabNames.yaml": "Raw YAML";
373
+ readonly "inspectEntityDialog.tabNames.overview": "Overview";
374
+ readonly "inspectEntityDialog.tabNames.ancestry": "Ancestry";
375
+ readonly "inspectEntityDialog.tabNames.colocated": "Colocated";
357
376
  readonly "unregisterEntityDialog.title": "Are you sure you want to unregister this entity?";
358
377
  readonly "unregisterEntityDialog.cancelButtonTitle": "Cancel";
359
378
  readonly "unregisterEntityDialog.deleteButtonTitle": "Delete Entity";
@@ -386,6 +405,11 @@ declare const catalogReactTranslationRef: _backstage_core_plugin_api_alpha.Trans
386
405
  readonly "entityTableColumnTitle.lifecycle": "Lifecycle";
387
406
  readonly "entityTableColumnTitle.owner": "Owner";
388
407
  readonly "entityTableColumnTitle.targets": "Targets";
408
+ readonly "missingAnnotationEmptyState.title": "Missing Annotation";
409
+ readonly "missingAnnotationEmptyState.readMore": "Read more";
410
+ readonly "missingAnnotationEmptyState.annotationYaml": "Add the annotation to your {{entityKind}} YAML as shown in the highlighted example below:";
411
+ readonly "missingAnnotationEmptyState.generateDescription_one": "The annotation {{annotations}} is missing. You need to add the annotation to your {{entityKind}} if you want to enable this tool.";
412
+ readonly "missingAnnotationEmptyState.generateDescription_other": "The annotations {{annotations}} are missing. You need to add the annotations to your {{entityKind}} if you want to enable this tool.";
389
413
  }>;
390
414
 
391
415
  /**
@@ -11,7 +11,7 @@ const EmailCardAction = (props) => {
11
11
  IconButton,
12
12
  {
13
13
  component: Link,
14
- "aria-label": "Email",
14
+ "aria-label": t("entityPeekAheadPopover.emailCardAction.ariaLabel"),
15
15
  title: t("entityPeekAheadPopover.emailCardAction.title", {
16
16
  email: props.email
17
17
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"EmailCardAction.esm.js","sources":["../../../../src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 IconButton from '@material-ui/core/IconButton';\nimport EmailIcon from '@material-ui/icons/Email';\nimport { Link } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Email Card action link\n *\n * @private\n */\nexport const EmailCardAction = (props: { email: string }) => {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <IconButton\n component={Link}\n aria-label=\"Email\"\n title={t('entityPeekAheadPopover.emailCardAction.title', {\n email: props.email,\n })}\n to={t('entityPeekAheadPopover.emailCardAction.subTitle', {\n email: props.email,\n })}\n >\n <EmailIcon />\n </IconButton>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2BO,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA6B;AAC3D,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,0BAA0B,CAAA;AAC1D,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,IAAA;AAAA,MACX,YAAA,EAAW,OAAA;AAAA,MACX,KAAA,EAAO,EAAE,8CAAA,EAAgD;AAAA,QACvD,OAAO,KAAA,CAAM;AAAA,OACd,CAAA;AAAA,MACD,EAAA,EAAI,EAAE,iDAAA,EAAmD;AAAA,QACvD,OAAO,KAAA,CAAM;AAAA,OACd,CAAA;AAAA,MAED,8BAAC,SAAA,EAAA,EAAU;AAAA;AAAA,GACb;AAEJ;;;;"}
1
+ {"version":3,"file":"EmailCardAction.esm.js","sources":["../../../../src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 IconButton from '@material-ui/core/IconButton';\nimport EmailIcon from '@material-ui/icons/Email';\nimport { Link } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Email Card action link\n *\n * @private\n */\nexport const EmailCardAction = (props: { email: string }) => {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <IconButton\n component={Link}\n aria-label={t('entityPeekAheadPopover.emailCardAction.ariaLabel')}\n title={t('entityPeekAheadPopover.emailCardAction.title', {\n email: props.email,\n })}\n to={t('entityPeekAheadPopover.emailCardAction.subTitle', {\n email: props.email,\n })}\n >\n <EmailIcon />\n </IconButton>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2BO,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA6B;AAC3D,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,0BAA0B,CAAA;AAC1D,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,IAAA;AAAA,MACX,YAAA,EAAY,EAAE,kDAAkD,CAAA;AAAA,MAChE,KAAA,EAAO,EAAE,8CAAA,EAAgD;AAAA,QACvD,OAAO,KAAA,CAAM;AAAA,OACd,CAAA;AAAA,MACD,EAAA,EAAI,EAAE,iDAAA,EAAmD;AAAA,QACvD,OAAO,KAAA,CAAM;AAAA,OACd,CAAA;AAAA,MAED,8BAAC,SAAA,EAAA,EAAU;AAAA;AAAA,GACb;AAEJ;;;;"}
@@ -15,7 +15,7 @@ const EntityCardActions = (props) => {
15
15
  IconButton,
16
16
  {
17
17
  component: Link,
18
- "aria-label": "Show",
18
+ "aria-label": t("entityPeekAheadPopover.entityCardActionsAriaLabel"),
19
19
  title: t("entityPeekAheadPopover.entityCardActionsTitle"),
20
20
  to: entityRoute(getCompoundEntityRef(props.entity)),
21
21
  children: /* @__PURE__ */ jsx(InfoIcon, {})
@@ -1 +1 @@
1
- {"version":3,"file":"EntityCardActions.esm.js","sources":["../../../../src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { entityRouteRef } from '../../../routes';\nimport IconButton from '@material-ui/core/IconButton';\nimport InfoIcon from '@material-ui/icons/Info';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { Entity, getCompoundEntityRef } from '@backstage/catalog-model';\nimport { Link } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Card actions that show for all entities\n *\n * @private\n */\nexport const EntityCardActions = (props: { entity: Entity }) => {\n const entityRoute = useRouteRef(entityRouteRef);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <IconButton\n component={Link}\n aria-label=\"Show\"\n title={t('entityPeekAheadPopover.entityCardActionsTitle')}\n to={entityRoute(getCompoundEntityRef(props.entity))}\n >\n <InfoIcon />\n </IconButton>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAA8B;AAC9D,EAAA,MAAM,WAAA,GAAc,YAAY,cAAc,CAAA;AAC9C,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,0BAA0B,CAAA;AAE1D,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,IAAA;AAAA,MACX,YAAA,EAAW,MAAA;AAAA,MACX,KAAA,EAAO,EAAE,+CAA+C,CAAA;AAAA,MACxD,EAAA,EAAI,WAAA,CAAY,oBAAA,CAAqB,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,MAElD,8BAAC,QAAA,EAAA,EAAS;AAAA;AAAA,GACZ;AAEJ;;;;"}
1
+ {"version":3,"file":"EntityCardActions.esm.js","sources":["../../../../src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { entityRouteRef } from '../../../routes';\nimport IconButton from '@material-ui/core/IconButton';\nimport InfoIcon from '@material-ui/icons/Info';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { Entity, getCompoundEntityRef } from '@backstage/catalog-model';\nimport { Link } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Card actions that show for all entities\n *\n * @private\n */\nexport const EntityCardActions = (props: { entity: Entity }) => {\n const entityRoute = useRouteRef(entityRouteRef);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n return (\n <IconButton\n component={Link}\n aria-label={t('entityPeekAheadPopover.entityCardActionsAriaLabel')}\n title={t('entityPeekAheadPopover.entityCardActionsTitle')}\n to={entityRoute(getCompoundEntityRef(props.entity))}\n >\n <InfoIcon />\n </IconButton>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAA8B;AAC9D,EAAA,MAAM,WAAA,GAAc,YAAY,cAAc,CAAA;AAC9C,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,0BAA0B,CAAA;AAE1D,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,IAAA;AAAA,MACX,YAAA,EAAY,EAAE,mDAAmD,CAAA;AAAA,MACjE,KAAA,EAAO,EAAE,+CAA+C,CAAA;AAAA,MACxD,EAAA,EAAI,WAAA,CAAY,oBAAA,CAAqB,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,MAElD,8BAAC,QAAA,EAAA,EAAS;AAAA;AAAA,GACZ;AAEJ;;;;"}
@@ -8,7 +8,7 @@ import DialogTitle from '@material-ui/core/DialogTitle';
8
8
  import Tab from '@material-ui/core/Tab';
9
9
  import Tabs from '@material-ui/core/Tabs';
10
10
  import { makeStyles } from '@material-ui/core/styles';
11
- import { useState, useEffect } from 'react';
11
+ import { useMemo, useState, useEffect } from 'react';
12
12
  import { AncestryPage } from './components/AncestryPage.esm.js';
13
13
  import { ColocatedPage } from './components/ColocatedPage.esm.js';
14
14
  import { JsonPage } from './components/JsonPage.esm.js';
@@ -58,23 +58,26 @@ function a11yProps(index) {
58
58
  "aria-controls": `vertical-tabpanel-${index}`
59
59
  };
60
60
  }
61
- const tabNames = {
62
- overview: "Overview",
63
- ancestry: "Ancestry",
64
- colocated: "Colocated",
65
- json: "Raw JSON",
66
- yaml: "Raw YAML"
67
- };
68
- const tabs = Object.keys(tabNames);
69
61
  function InspectEntityDialog(props) {
70
62
  const classes = useStyles();
63
+ const { t } = useTranslationRef(catalogReactTranslationRef);
64
+ const tabNames = useMemo(
65
+ () => ({
66
+ overview: t("inspectEntityDialog.tabNames.overview"),
67
+ ancestry: t("inspectEntityDialog.tabNames.ancestry"),
68
+ colocated: t("inspectEntityDialog.tabNames.colocated"),
69
+ json: t("inspectEntityDialog.tabNames.json"),
70
+ yaml: t("inspectEntityDialog.tabNames.yaml")
71
+ }),
72
+ [t]
73
+ );
74
+ const tabs = Object.keys(tabNames);
71
75
  const [activeTab, setActiveTab] = useState(
72
76
  getTabIndex(tabs, props.initialTab)
73
77
  );
74
- const { t } = useTranslationRef(catalogReactTranslationRef);
75
78
  useEffect(() => {
76
79
  getTabIndex(tabs, props.initialTab);
77
- }, [props.open, props.initialTab]);
80
+ }, [props.open, props.initialTab, tabs]);
78
81
  if (!props.entity) {
79
82
  return null;
80
83
  }
@@ -100,7 +103,7 @@ function InspectEntityDialog(props) {
100
103
  setActiveTab(tabIndex);
101
104
  props.onSelect?.(tabs[tabIndex]);
102
105
  },
103
- "aria-label": "Inspector options",
106
+ "aria-label": t("inspectEntityDialog.tabsAriaLabel"),
104
107
  className: classes.tabs,
105
108
  children: tabs.map((tab, index) => /* @__PURE__ */ jsx(Tab, { label: tabNames[tab], ...a11yProps(index) }, tab))
106
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"InspectEntityDialog.esm.js","sources":["../../../src/components/InspectEntityDialog/InspectEntityDialog.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { Entity } from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ComponentProps, useEffect, useState, ReactNode } from 'react';\nimport { AncestryPage } from './components/AncestryPage';\nimport { ColocatedPage } from './components/ColocatedPage';\nimport { JsonPage } from './components/JsonPage';\nimport { OverviewPage } from './components/OverviewPage';\nimport { YamlPage } from './components/YamlPage';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n fullHeightDialog: {\n height: 'calc(100% - 64px)',\n },\n root: {\n display: 'flex',\n flexGrow: 1,\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabs: {\n borderRight: `1px solid ${theme.palette.divider}`,\n flexShrink: 0,\n },\n tabContents: {\n flexGrow: 1,\n overflowX: 'auto',\n },\n}));\n\nfunction TabPanel(props: {\n children?: ReactNode;\n index: number;\n value: number;\n}) {\n const { children, value, index, ...other } = props;\n const classes = useStyles();\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`vertical-tabpanel-${index}`}\n aria-labelledby={`vertical-tab-${index}`}\n className={classes.tabContents}\n {...other}\n >\n {value === index && (\n <Box pl={3} pr={3}>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `vertical-tab-${index}`,\n 'aria-controls': `vertical-tabpanel-${index}`,\n };\n}\n\nconst tabNames: Record<\n NonNullable<ComponentProps<typeof InspectEntityDialog>['initialTab']>,\n string\n> = {\n overview: 'Overview',\n ancestry: 'Ancestry',\n colocated: 'Colocated',\n json: 'Raw JSON',\n yaml: 'Raw YAML',\n} as const;\n\nconst tabs = Object.keys(tabNames) as Array<keyof typeof tabNames>;\n\n/**\n * A dialog that lets users inspect the low level details of their entities.\n *\n * @public\n */\nexport function InspectEntityDialog(props: {\n open: boolean;\n entity: Entity;\n initialTab?: 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n onClose: () => void;\n onSelect?: (tab: string) => void;\n}) {\n const classes = useStyles();\n\n const [activeTab, setActiveTab] = useState(\n getTabIndex(tabs, props.initialTab),\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n useEffect(() => {\n getTabIndex(tabs, props.initialTab);\n }, [props.open, props.initialTab]);\n\n if (!props.entity) {\n return null;\n }\n\n return (\n <Dialog\n fullWidth\n maxWidth=\"xl\"\n open={props.open}\n onClose={props.onClose}\n aria-labelledby=\"entity-inspector-dialog-title\"\n PaperProps={{ className: classes.fullHeightDialog }}\n >\n <DialogTitle id=\"entity-inspector-dialog-title\">\n {t('inspectEntityDialog.title')}\n </DialogTitle>\n <DialogContent dividers>\n <div className={classes.root}>\n <Tabs\n orientation=\"vertical\"\n variant=\"scrollable\"\n value={activeTab}\n onChange={(_, tabIndex) => {\n setActiveTab(tabIndex);\n props.onSelect?.(tabs[tabIndex]);\n }}\n aria-label=\"Inspector options\"\n className={classes.tabs}\n >\n {tabs.map((tab, index) => (\n <Tab key={tab} label={tabNames[tab]} {...a11yProps(index)} />\n ))}\n </Tabs>\n\n <TabPanel value={activeTab} index={0}>\n <OverviewPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={1}>\n <AncestryPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={2}>\n <ColocatedPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={3}>\n <JsonPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={4}>\n <YamlPage entity={props.entity} />\n </TabPanel>\n </div>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} color=\"primary\">\n {t('inspectEntityDialog.closeButtonTitle')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n\nfunction getTabIndex(\n allTabs: string[],\n initialTab: keyof typeof tabNames | undefined,\n) {\n return initialTab ? allTabs.indexOf(initialTab) : 0;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InspectEntityDialog.esm.js","sources":["../../../src/components/InspectEntityDialog/InspectEntityDialog.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { Entity } from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ComponentProps, useEffect, useState, ReactNode, useMemo } from 'react';\nimport { AncestryPage } from './components/AncestryPage';\nimport { ColocatedPage } from './components/ColocatedPage';\nimport { JsonPage } from './components/JsonPage';\nimport { OverviewPage } from './components/OverviewPage';\nimport { YamlPage } from './components/YamlPage';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n fullHeightDialog: {\n height: 'calc(100% - 64px)',\n },\n root: {\n display: 'flex',\n flexGrow: 1,\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabs: {\n borderRight: `1px solid ${theme.palette.divider}`,\n flexShrink: 0,\n },\n tabContents: {\n flexGrow: 1,\n overflowX: 'auto',\n },\n}));\n\nfunction TabPanel(props: {\n children?: ReactNode;\n index: number;\n value: number;\n}) {\n const { children, value, index, ...other } = props;\n const classes = useStyles();\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`vertical-tabpanel-${index}`}\n aria-labelledby={`vertical-tab-${index}`}\n className={classes.tabContents}\n {...other}\n >\n {value === index && (\n <Box pl={3} pr={3}>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `vertical-tab-${index}`,\n 'aria-controls': `vertical-tabpanel-${index}`,\n };\n}\n\ntype TabKey = 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n\ntype TabNames = Record<\n NonNullable<ComponentProps<typeof InspectEntityDialog>['initialTab']>,\n string\n>;\n\n/**\n * A dialog that lets users inspect the low level details of their entities.\n *\n * @public\n */\nexport function InspectEntityDialog(props: {\n open: boolean;\n entity: Entity;\n initialTab?: 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n onClose: () => void;\n onSelect?: (tab: string) => void;\n}) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const tabNames: TabNames = useMemo(\n () => ({\n overview: t('inspectEntityDialog.tabNames.overview'),\n ancestry: t('inspectEntityDialog.tabNames.ancestry'),\n colocated: t('inspectEntityDialog.tabNames.colocated'),\n json: t('inspectEntityDialog.tabNames.json'),\n yaml: t('inspectEntityDialog.tabNames.yaml'),\n }),\n [t],\n );\n\n const tabs = Object.keys(tabNames) as TabKey[];\n\n const [activeTab, setActiveTab] = useState(\n getTabIndex(tabs, props.initialTab),\n );\n\n useEffect(() => {\n getTabIndex(tabs, props.initialTab);\n }, [props.open, props.initialTab, tabs]);\n\n if (!props.entity) {\n return null;\n }\n\n return (\n <Dialog\n fullWidth\n maxWidth=\"xl\"\n open={props.open}\n onClose={props.onClose}\n aria-labelledby=\"entity-inspector-dialog-title\"\n PaperProps={{ className: classes.fullHeightDialog }}\n >\n <DialogTitle id=\"entity-inspector-dialog-title\">\n {t('inspectEntityDialog.title')}\n </DialogTitle>\n <DialogContent dividers>\n <div className={classes.root}>\n <Tabs\n orientation=\"vertical\"\n variant=\"scrollable\"\n value={activeTab}\n onChange={(_, tabIndex) => {\n setActiveTab(tabIndex);\n props.onSelect?.(tabs[tabIndex]);\n }}\n aria-label={t('inspectEntityDialog.tabsAriaLabel')}\n className={classes.tabs}\n >\n {tabs.map((tab, index) => (\n <Tab key={tab} label={tabNames[tab]} {...a11yProps(index)} />\n ))}\n </Tabs>\n\n <TabPanel value={activeTab} index={0}>\n <OverviewPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={1}>\n <AncestryPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={2}>\n <ColocatedPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={3}>\n <JsonPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={4}>\n <YamlPage entity={props.entity} />\n </TabPanel>\n </div>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} color=\"primary\">\n {t('inspectEntityDialog.closeButtonTitle')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n\nfunction getTabIndex(allTabs: string[], initialTab: TabKey | undefined) {\n return initialTab ? allTabs.indexOf(initialTab) : 0;\n}\n"],"names":[],"mappings":"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"}
@@ -165,13 +165,9 @@ function AncestryPage(props) {
165
165
  }
166
166
  return /* @__PURE__ */ jsxs(Fragment, { children: [
167
167
  /* @__PURE__ */ jsx(DialogContentText, { variant: "h2", children: t("inspectEntityDialog.ancestryPage.title") }),
168
- /* @__PURE__ */ jsxs(DialogContentText, { gutterBottom: true, children: [
169
- "This is the ancestry of entities above the current one - as in, the chain(s) of entities down to the current one, where",
170
- " ",
171
- /* @__PURE__ */ jsx(Link, { to: "https://backstage.io/docs/features/software-catalog/life-of-an-entity", children: "processors emitted" }),
172
- " ",
173
- "child entities that ultimately led to the current one existing. Note that this is a completely different mechanism from relations."
174
- ] }),
168
+ /* @__PURE__ */ jsx(DialogContentText, { gutterBottom: true, children: t("inspectEntityDialog.ancestryPage.description", {
169
+ processorsLink: /* @__PURE__ */ jsx(Link, { to: "https://backstage.io/docs/features/software-catalog/life-of-an-entity", children: t("inspectEntityDialog.ancestryPage.processorsLink") })
170
+ }) }),
175
171
  /* @__PURE__ */ jsx(Box, { mt: 4, children: /* @__PURE__ */ jsx(
176
172
  DependencyGraph,
177
173
  {
@@ -1 +1 @@
1
- {"version":3,"file":"AncestryPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/AncestryPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 Entity,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n DependencyGraph,\n DependencyGraphTypes,\n Link,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { useApi, useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport classNames from 'classnames';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { humanizeEntityRef } from '../../EntityRefLink';\nimport { entityRouteRef } from '../../../routes';\nimport { EntityKindIcon } from './EntityKindIcon';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n node: {\n fill: theme.palette.grey[300],\n stroke: theme.palette.grey[300],\n '&.primary': {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n '&.secondary': {\n fill: theme.palette.secondary.light,\n stroke: theme.palette.secondary.light,\n },\n },\n text: {\n fill: theme.palette.getContrastText(theme.palette.grey[300]),\n '&.primary': {\n fill: theme.palette.primary.contrastText,\n },\n '&.secondary': {\n fill: theme.palette.secondary.contrastText,\n },\n '&.focused': {\n fontWeight: 'bold',\n },\n },\n clickable: {\n cursor: 'pointer',\n },\n}));\n\ntype NodeType = Entity & { root: boolean };\n\nfunction useAncestry(root: Entity): {\n loading: boolean;\n error?: Error;\n nodes: DependencyGraphTypes.DependencyNode<NodeType>[];\n edges: DependencyGraphTypes.DependencyEdge[];\n} {\n const catalogClient = useApi(catalogApiRef);\n const entityRef = stringifyEntityRef(root);\n\n const { loading, error, value } = useAsync(async () => {\n const response = await catalogClient.getEntityAncestors({ entityRef });\n const nodes = new Array<DependencyGraphTypes.DependencyNode<NodeType>>();\n const edges = new Array<DependencyGraphTypes.DependencyEdge>();\n for (const current of response.items) {\n const currentRef = stringifyEntityRef(current.entity);\n const isRootNode = currentRef === response.rootEntityRef;\n nodes.push({ id: currentRef, root: isRootNode, ...current.entity });\n for (const parentRef of current.parentEntityRefs) {\n edges.push({ from: currentRef, to: parentRef });\n }\n }\n return { nodes, edges };\n }, [entityRef]);\n\n return {\n loading,\n error,\n nodes: value?.nodes || [],\n edges: value?.edges || [],\n };\n}\n\nfunction CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {\n const classes = useStyles();\n const navigate = useNavigate();\n const entityRoute = useRouteRef(entityRouteRef);\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const app = useApp();\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const hasKindIcon = app.getSystemIcon(\n `kind:${node.kind.toLocaleLowerCase('en-US')}`,\n );\n const padding = 10;\n const iconSize = height;\n const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;\n const paddedWidth = paddedIconWidth + width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n const displayTitle =\n node.metadata.title ||\n (node.kind && node.metadata.name && node.metadata.namespace\n ? humanizeEntityRef({\n kind: node.kind,\n name: node.metadata.name,\n namespace: node.metadata.namespace || '',\n })\n : node.id);\n\n const onClick = () => {\n navigate(\n entityRoute({\n kind: node.kind,\n namespace: node.metadata.namespace || DEFAULT_NAMESPACE,\n name: node.metadata.name,\n }),\n );\n };\n\n return (\n <g onClick={onClick} className={classes.clickable}>\n <rect\n className={classNames(\n classes.node,\n node.root ? 'secondary' : 'primary',\n )}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n {hasKindIcon && (\n <EntityKindIcon\n kind={node.kind}\n y={padding}\n x={padding}\n width={iconSize}\n height={iconSize}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n />\n )}\n <text\n ref={idRef}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n y={paddedHeight / 2}\n x={paddedIconWidth + (width + padding * 2) / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {displayTitle}\n </text>\n </g>\n );\n}\n\nexport function AncestryPage(props: { entity: Entity }) {\n const { loading, error, nodes, edges } = useAncestry(props.entity);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.ancestryPage.title')}\n </DialogContentText>\n <DialogContentText gutterBottom>\n This is the ancestry of entities above the current one - as in, the\n chain(s) of entities down to the current one, where{' '}\n <Link to=\"https://backstage.io/docs/features/software-catalog/life-of-an-entity\">\n processors emitted\n </Link>{' '}\n child entities that ultimately led to the current one existing. Note\n that this is a completely different mechanism from relations.\n </DialogContentText>\n <Box mt={4}>\n <DependencyGraph\n nodes={nodes}\n edges={edges}\n renderNode={CustomNode}\n direction={DependencyGraphTypes.Direction.BOTTOM_TOP}\n zoom=\"enable-on-click\"\n />\n </Box>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AncestryPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/AncestryPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 Entity,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n DependencyGraph,\n DependencyGraphTypes,\n Link,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { useApi, useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport classNames from 'classnames';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { humanizeEntityRef } from '../../EntityRefLink';\nimport { entityRouteRef } from '../../../routes';\nimport { EntityKindIcon } from './EntityKindIcon';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n node: {\n fill: theme.palette.grey[300],\n stroke: theme.palette.grey[300],\n '&.primary': {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n '&.secondary': {\n fill: theme.palette.secondary.light,\n stroke: theme.palette.secondary.light,\n },\n },\n text: {\n fill: theme.palette.getContrastText(theme.palette.grey[300]),\n '&.primary': {\n fill: theme.palette.primary.contrastText,\n },\n '&.secondary': {\n fill: theme.palette.secondary.contrastText,\n },\n '&.focused': {\n fontWeight: 'bold',\n },\n },\n clickable: {\n cursor: 'pointer',\n },\n}));\n\ntype NodeType = Entity & { root: boolean };\n\nfunction useAncestry(root: Entity): {\n loading: boolean;\n error?: Error;\n nodes: DependencyGraphTypes.DependencyNode<NodeType>[];\n edges: DependencyGraphTypes.DependencyEdge[];\n} {\n const catalogClient = useApi(catalogApiRef);\n const entityRef = stringifyEntityRef(root);\n\n const { loading, error, value } = useAsync(async () => {\n const response = await catalogClient.getEntityAncestors({ entityRef });\n const nodes = new Array<DependencyGraphTypes.DependencyNode<NodeType>>();\n const edges = new Array<DependencyGraphTypes.DependencyEdge>();\n for (const current of response.items) {\n const currentRef = stringifyEntityRef(current.entity);\n const isRootNode = currentRef === response.rootEntityRef;\n nodes.push({ id: currentRef, root: isRootNode, ...current.entity });\n for (const parentRef of current.parentEntityRefs) {\n edges.push({ from: currentRef, to: parentRef });\n }\n }\n return { nodes, edges };\n }, [entityRef]);\n\n return {\n loading,\n error,\n nodes: value?.nodes || [],\n edges: value?.edges || [],\n };\n}\n\nfunction CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {\n const classes = useStyles();\n const navigate = useNavigate();\n const entityRoute = useRouteRef(entityRouteRef);\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const app = useApp();\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const hasKindIcon = app.getSystemIcon(\n `kind:${node.kind.toLocaleLowerCase('en-US')}`,\n );\n const padding = 10;\n const iconSize = height;\n const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;\n const paddedWidth = paddedIconWidth + width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n const displayTitle =\n node.metadata.title ||\n (node.kind && node.metadata.name && node.metadata.namespace\n ? humanizeEntityRef({\n kind: node.kind,\n name: node.metadata.name,\n namespace: node.metadata.namespace || '',\n })\n : node.id);\n\n const onClick = () => {\n navigate(\n entityRoute({\n kind: node.kind,\n namespace: node.metadata.namespace || DEFAULT_NAMESPACE,\n name: node.metadata.name,\n }),\n );\n };\n\n return (\n <g onClick={onClick} className={classes.clickable}>\n <rect\n className={classNames(\n classes.node,\n node.root ? 'secondary' : 'primary',\n )}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n {hasKindIcon && (\n <EntityKindIcon\n kind={node.kind}\n y={padding}\n x={padding}\n width={iconSize}\n height={iconSize}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n />\n )}\n <text\n ref={idRef}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n y={paddedHeight / 2}\n x={paddedIconWidth + (width + padding * 2) / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {displayTitle}\n </text>\n </g>\n );\n}\n\nexport function AncestryPage(props: { entity: Entity }) {\n const { loading, error, nodes, edges } = useAncestry(props.entity);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.ancestryPage.title')}\n </DialogContentText>\n <DialogContentText gutterBottom>\n {t('inspectEntityDialog.ancestryPage.description', {\n processorsLink: (\n <Link to=\"https://backstage.io/docs/features/software-catalog/life-of-an-entity\">\n {t('inspectEntityDialog.ancestryPage.processorsLink')}\n </Link>\n ),\n })}\n </DialogContentText>\n <Box mt={4}>\n <DependencyGraph\n nodes={nodes}\n edges={edges}\n renderNode={CustomNode}\n direction={DependencyGraphTypes.Direction.BOTTOM_TOP}\n zoom=\"enable-on-click\"\n />\n </Box>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -83,14 +83,20 @@ function Contents(props) {
83
83
  EntityList,
84
84
  {
85
85
  entities: atLocation,
86
- header: ["At the same location", location]
86
+ header: [
87
+ t("inspectEntityDialog.colocatedPage.locationHeader"),
88
+ location
89
+ ]
87
90
  }
88
91
  ),
89
92
  atOrigin.length > 0 && /* @__PURE__ */ jsx(
90
93
  EntityList,
91
94
  {
92
95
  entities: atOrigin,
93
- header: ["At the same origin", originLocation]
96
+ header: [
97
+ t("inspectEntityDialog.colocatedPage.originHeader"),
98
+ originLocation
99
+ ]
94
100
  }
95
101
  )
96
102
  ] });
@@ -1 +1 @@
1
- {"version":3,"file":"ColocatedPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/ColocatedPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 Entity,\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Alert from '@material-ui/lab/Alert';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport { KeyValueListItem, ListItemText } from './common';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nfunction useColocated(entity: Entity): {\n loading: boolean;\n error?: Error;\n location?: string;\n originLocation?: string;\n colocatedEntities?: Entity[];\n} {\n const catalogApi = useApi(catalogApiRef);\n const currentEntityRef = stringifyEntityRef(entity);\n const location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n const origin = entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n\n const { loading, error, value } = useAsync(async () => {\n if (!location && !origin) {\n return [];\n }\n const response = await catalogApi.getEntities({\n filter: [\n ...(location\n ? [{ [`metadata.annotations.${ANNOTATION_LOCATION}`]: location }]\n : []),\n ...(origin\n ? [{ [`metadata.annotations.${ANNOTATION_ORIGIN_LOCATION}`]: origin }]\n : []),\n ],\n });\n return response.items;\n }, [location, origin]);\n\n return {\n loading,\n error,\n location,\n originLocation: origin,\n colocatedEntities: value?.filter(\n colocated => stringifyEntityRef(colocated) !== currentEntityRef,\n ),\n };\n}\n\nfunction EntityList(props: { entities: Entity[]; header?: [string, string] }) {\n return (\n <List dense>\n {props.header && <KeyValueListItem key=\"header\" entry={props.header} />}\n {props.entities.map(entity => (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemText primary={<EntityRefLink entityRef={entity} />} />\n </ListItem>\n ))}\n </List>\n );\n}\n\nfunction Contents(props: { entity: Entity }) {\n const { entity } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const { loading, error, location, originLocation, colocatedEntities } =\n useColocated(entity);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n if (!location && !originLocation) {\n return (\n <Alert severity=\"warning\">\n {t('inspectEntityDialog.colocatedPage.alertNoLocation')}\n </Alert>\n );\n } else if (!colocatedEntities?.length) {\n return (\n <Alert severity=\"info\">\n {t('inspectEntityDialog.colocatedPage.alertNoEntity')}\n </Alert>\n );\n }\n\n if (location === originLocation) {\n return <EntityList entities={colocatedEntities} />;\n }\n\n const atLocation = colocatedEntities.filter(\n e => e.metadata.annotations?.[ANNOTATION_LOCATION] === location,\n );\n const atOrigin = colocatedEntities.filter(\n e =>\n e.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION] === originLocation,\n );\n\n return (\n <>\n {atLocation.length > 0 && (\n <EntityList\n entities={atLocation}\n header={['At the same location', location!]}\n />\n )}\n {atOrigin.length > 0 && (\n <EntityList\n entities={atOrigin}\n header={['At the same origin', originLocation!]}\n />\n )}\n </>\n );\n}\n\nexport function ColocatedPage(props: { entity: Entity }) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.colocatedPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.colocatedPage.description')}\n </DialogContentText>\n <div className={classes.root}>\n <Contents entity={props.entity} />\n </div>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ColocatedPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/ColocatedPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 Entity,\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Alert from '@material-ui/lab/Alert';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport { KeyValueListItem, ListItemText } from './common';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nfunction useColocated(entity: Entity): {\n loading: boolean;\n error?: Error;\n location?: string;\n originLocation?: string;\n colocatedEntities?: Entity[];\n} {\n const catalogApi = useApi(catalogApiRef);\n const currentEntityRef = stringifyEntityRef(entity);\n const location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n const origin = entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n\n const { loading, error, value } = useAsync(async () => {\n if (!location && !origin) {\n return [];\n }\n const response = await catalogApi.getEntities({\n filter: [\n ...(location\n ? [{ [`metadata.annotations.${ANNOTATION_LOCATION}`]: location }]\n : []),\n ...(origin\n ? [{ [`metadata.annotations.${ANNOTATION_ORIGIN_LOCATION}`]: origin }]\n : []),\n ],\n });\n return response.items;\n }, [location, origin]);\n\n return {\n loading,\n error,\n location,\n originLocation: origin,\n colocatedEntities: value?.filter(\n colocated => stringifyEntityRef(colocated) !== currentEntityRef,\n ),\n };\n}\n\nfunction EntityList(props: { entities: Entity[]; header?: [string, string] }) {\n return (\n <List dense>\n {props.header && <KeyValueListItem key=\"header\" entry={props.header} />}\n {props.entities.map(entity => (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemText primary={<EntityRefLink entityRef={entity} />} />\n </ListItem>\n ))}\n </List>\n );\n}\n\nfunction Contents(props: { entity: Entity }) {\n const { entity } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const { loading, error, location, originLocation, colocatedEntities } =\n useColocated(entity);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n if (!location && !originLocation) {\n return (\n <Alert severity=\"warning\">\n {t('inspectEntityDialog.colocatedPage.alertNoLocation')}\n </Alert>\n );\n } else if (!colocatedEntities?.length) {\n return (\n <Alert severity=\"info\">\n {t('inspectEntityDialog.colocatedPage.alertNoEntity')}\n </Alert>\n );\n }\n\n if (location === originLocation) {\n return <EntityList entities={colocatedEntities} />;\n }\n\n const atLocation = colocatedEntities.filter(\n e => e.metadata.annotations?.[ANNOTATION_LOCATION] === location,\n );\n const atOrigin = colocatedEntities.filter(\n e =>\n e.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION] === originLocation,\n );\n\n return (\n <>\n {atLocation.length > 0 && (\n <EntityList\n entities={atLocation}\n header={[\n t('inspectEntityDialog.colocatedPage.locationHeader'),\n location!,\n ]}\n />\n )}\n {atOrigin.length > 0 && (\n <EntityList\n entities={atOrigin}\n header={[\n t('inspectEntityDialog.colocatedPage.originHeader'),\n originLocation!,\n ]}\n />\n )}\n </>\n );\n}\n\nexport function ColocatedPage(props: { entity: Entity }) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.colocatedPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.colocatedPage.description')}\n </DialogContentText>\n <div className={classes.root}>\n <Contents entity={props.entity} />\n </div>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -43,7 +43,7 @@ function OverviewPage(props) {
43
43
  return /* @__PURE__ */ jsxs(Fragment, { children: [
44
44
  /* @__PURE__ */ jsx(DialogContentText, { variant: "h2", children: t("inspectEntityDialog.overviewPage.title") }),
45
45
  /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
46
- /* @__PURE__ */ jsx(Container, { title: "Identity", children: /* @__PURE__ */ jsxs(List, { dense: true, children: [
46
+ /* @__PURE__ */ jsx(Container, { title: t("inspectEntityDialog.overviewPage.identity.title"), children: /* @__PURE__ */ jsxs(List, { dense: true, children: [
47
47
  /* @__PURE__ */ jsx(ListItem, { children: /* @__PURE__ */ jsx(ListItemText, { primary: "apiVersion", secondary: apiVersion }) }),
48
48
  /* @__PURE__ */ jsx(ListItem, { children: /* @__PURE__ */ jsx(ListItemText, { primary: "kind", secondary: kind }) }),
49
49
  spec?.type && /* @__PURE__ */ jsx(ListItem, { children: /* @__PURE__ */ jsx(
@@ -66,28 +66,42 @@ function OverviewPage(props) {
66
66
  /* @__PURE__ */ jsx(ListItemSecondaryAction, { children: /* @__PURE__ */ jsx(CopyTextButton, { text: entityRef }) })
67
67
  ] })
68
68
  ] }) }),
69
- /* @__PURE__ */ jsxs(Container, { title: "Metadata", children: [
69
+ /* @__PURE__ */ jsxs(Container, { title: t("inspectEntityDialog.overviewPage.metadata.title"), children: [
70
70
  !!Object.keys(metadata.annotations || {}).length && /* @__PURE__ */ jsx(
71
71
  List,
72
72
  {
73
73
  dense: true,
74
74
  subheader: /* @__PURE__ */ jsxs(ListSubheader, { children: [
75
- "Annotations",
75
+ t("inspectEntityDialog.overviewPage.annotations"),
76
76
  /* @__PURE__ */ jsx(HelpIcon, { to: "https://backstage.io/docs/features/software-catalog/well-known-annotations" })
77
77
  ] }),
78
78
  children: Object.entries(metadata.annotations).map((entry) => /* @__PURE__ */ jsx(KeyValueListItem, { indent: true, entry }, entry[0]))
79
79
  }
80
80
  ),
81
- !!Object.keys(metadata.labels || {}).length && /* @__PURE__ */ jsx(List, { dense: true, subheader: /* @__PURE__ */ jsx(ListSubheader, { children: "Labels" }), children: Object.entries(metadata.labels).map((entry) => /* @__PURE__ */ jsx(KeyValueListItem, { indent: true, entry }, entry[0])) }),
82
- !!metadata.tags?.length && /* @__PURE__ */ jsx(List, { dense: true, subheader: /* @__PURE__ */ jsx(ListSubheader, { children: "Tags" }), children: metadata.tags.map((tag, index) => /* @__PURE__ */ jsxs(ListItem, { children: [
83
- /* @__PURE__ */ jsx(ListItemIcon, {}),
84
- /* @__PURE__ */ jsx(ListItemText, { primary: tag })
85
- ] }, `${tag}-${index}`)) })
81
+ !!Object.keys(metadata.labels || {}).length && /* @__PURE__ */ jsx(
82
+ List,
83
+ {
84
+ dense: true,
85
+ subheader: /* @__PURE__ */ jsx(ListSubheader, { children: t("inspectEntityDialog.overviewPage.labels") }),
86
+ children: Object.entries(metadata.labels).map((entry) => /* @__PURE__ */ jsx(KeyValueListItem, { indent: true, entry }, entry[0]))
87
+ }
88
+ ),
89
+ !!metadata.tags?.length && /* @__PURE__ */ jsx(
90
+ List,
91
+ {
92
+ dense: true,
93
+ subheader: /* @__PURE__ */ jsx(ListSubheader, { children: t("inspectEntityDialog.overviewPage.tags") }),
94
+ children: metadata.tags.map((tag, index) => /* @__PURE__ */ jsxs(ListItem, { children: [
95
+ /* @__PURE__ */ jsx(ListItemIcon, {}),
96
+ /* @__PURE__ */ jsx(ListItemText, { primary: tag })
97
+ ] }, `${tag}-${index}`))
98
+ }
99
+ )
86
100
  ] }),
87
101
  !!relations.length && /* @__PURE__ */ jsx(
88
102
  Container,
89
103
  {
90
- title: "Relations",
104
+ title: t("inspectEntityDialog.overviewPage.relation.title"),
91
105
  helpLink: "https://backstage.io/docs/features/software-catalog/well-known-relations",
92
106
  children: Object.entries(groupedRelations).map(
93
107
  ([type, groupRelations], index) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(List, { dense: true, subheader: /* @__PURE__ */ jsx(ListSubheader, { children: type }), children: groupRelations.map((group) => /* @__PURE__ */ jsx(ListItem, { children: /* @__PURE__ */ jsx(
@@ -102,7 +116,7 @@ function OverviewPage(props) {
102
116
  !!status.items?.length && /* @__PURE__ */ jsx(
103
117
  Container,
104
118
  {
105
- title: "Status",
119
+ title: t("inspectEntityDialog.overviewPage.status.title"),
106
120
  helpLink: "https://backstage.io/docs/features/software-catalog/well-known-statuses",
107
121
  children: status.items.map((item, index) => /* @__PURE__ */ jsxs("div", { children: [
108
122
  /* @__PURE__ */ jsxs(Typography, { children: [
@@ -1 +1 @@
1
- {"version":3,"file":"OverviewPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/OverviewPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport groupBy from 'lodash/groupBy';\nimport sortBy from 'lodash/sortBy';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport {\n Container,\n HelpIcon,\n KeyValueListItem,\n ListItemText,\n ListSubheader,\n} from './common';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CopyTextButton } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nexport function OverviewPage(props: { entity: AlphaEntity }) {\n const classes = useStyles();\n const {\n apiVersion,\n kind,\n metadata,\n spec,\n relations = [],\n status = {},\n } = props.entity;\n\n const groupedRelations = groupBy(\n sortBy(relations, r => r.targetRef),\n 'type',\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const entityRef = stringifyEntityRef(props.entity);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.overviewPage.title')}\n </DialogContentText>\n <div className={classes.root}>\n <Container title=\"Identity\">\n <List dense>\n <ListItem>\n <ListItemText primary=\"apiVersion\" secondary={apiVersion} />\n </ListItem>\n <ListItem>\n <ListItemText primary=\"kind\" secondary={kind} />\n </ListItem>\n {spec?.type && (\n <ListItem>\n <ListItemText\n primary=\"spec.type\"\n secondary={spec.type?.toString()}\n />\n </ListItem>\n )}\n {metadata.uid && (\n <ListItem>\n <ListItemText primary=\"uid\" secondary={metadata.uid} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.uid} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n {metadata.etag && (\n <ListItem>\n <ListItemText primary=\"etag\" secondary={metadata.etag} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.etag} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n <ListItem>\n <ListItemText primary=\"entityRef\" secondary={entityRef} />\n <ListItemSecondaryAction>\n <CopyTextButton text={entityRef} />\n </ListItemSecondaryAction>\n </ListItem>\n </List>\n </Container>\n\n <Container title=\"Metadata\">\n {!!Object.keys(metadata.annotations || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n Annotations\n <HelpIcon to=\"https://backstage.io/docs/features/software-catalog/well-known-annotations\" />\n </ListSubheader>\n }\n >\n {Object.entries(metadata.annotations!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!Object.keys(metadata.labels || {}).length && (\n <List dense subheader={<ListSubheader>Labels</ListSubheader>}>\n {Object.entries(metadata.labels!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!metadata.tags?.length && (\n <List dense subheader={<ListSubheader>Tags</ListSubheader>}>\n {metadata.tags.map((tag, index) => (\n <ListItem key={`${tag}-${index}`}>\n <ListItemIcon />\n <ListItemText primary={tag} />\n </ListItem>\n ))}\n </List>\n )}\n </Container>\n\n {!!relations.length && (\n <Container\n title=\"Relations\"\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-relations\"\n >\n {Object.entries(groupedRelations).map(\n ([type, groupRelations], index) => (\n <div key={index}>\n <List dense subheader={<ListSubheader>{type}</ListSubheader>}>\n {groupRelations.map(group => (\n <ListItem key={group.targetRef}>\n <ListItemText\n primary={\n <EntityRefLink entityRef={group.targetRef} />\n }\n />\n </ListItem>\n ))}\n </List>\n </div>\n ),\n )}\n </Container>\n )}\n\n {!!status.items?.length && (\n <Container\n title=\"Status\"\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-statuses\"\n >\n {status.items.map((item, index) => (\n <div key={index}>\n <Typography>\n {item.level}: {item.type}\n </Typography>\n <Box ml={2}>{item.message}</Box>\n </div>\n ))}\n </Container>\n )}\n </div>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OverviewPage.esm.js","sources":["../../../../src/components/InspectEntityDialog/components/OverviewPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport groupBy from 'lodash/groupBy';\nimport sortBy from 'lodash/sortBy';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport {\n Container,\n HelpIcon,\n KeyValueListItem,\n ListItemText,\n ListSubheader,\n} from './common';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CopyTextButton } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nexport function OverviewPage(props: { entity: AlphaEntity }) {\n const classes = useStyles();\n const {\n apiVersion,\n kind,\n metadata,\n spec,\n relations = [],\n status = {},\n } = props.entity;\n\n const groupedRelations = groupBy(\n sortBy(relations, r => r.targetRef),\n 'type',\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const entityRef = stringifyEntityRef(props.entity);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.overviewPage.title')}\n </DialogContentText>\n <div className={classes.root}>\n <Container title={t('inspectEntityDialog.overviewPage.identity.title')}>\n <List dense>\n <ListItem>\n <ListItemText primary=\"apiVersion\" secondary={apiVersion} />\n </ListItem>\n <ListItem>\n <ListItemText primary=\"kind\" secondary={kind} />\n </ListItem>\n {spec?.type && (\n <ListItem>\n <ListItemText\n primary=\"spec.type\"\n secondary={spec.type?.toString()}\n />\n </ListItem>\n )}\n {metadata.uid && (\n <ListItem>\n <ListItemText primary=\"uid\" secondary={metadata.uid} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.uid} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n {metadata.etag && (\n <ListItem>\n <ListItemText primary=\"etag\" secondary={metadata.etag} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.etag} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n <ListItem>\n <ListItemText primary=\"entityRef\" secondary={entityRef} />\n <ListItemSecondaryAction>\n <CopyTextButton text={entityRef} />\n </ListItemSecondaryAction>\n </ListItem>\n </List>\n </Container>\n\n <Container title={t('inspectEntityDialog.overviewPage.metadata.title')}>\n {!!Object.keys(metadata.annotations || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.annotations')}\n <HelpIcon to=\"https://backstage.io/docs/features/software-catalog/well-known-annotations\" />\n </ListSubheader>\n }\n >\n {Object.entries(metadata.annotations!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!Object.keys(metadata.labels || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.labels')}\n </ListSubheader>\n }\n >\n {Object.entries(metadata.labels!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!metadata.tags?.length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.tags')}\n </ListSubheader>\n }\n >\n {metadata.tags.map((tag, index) => (\n <ListItem key={`${tag}-${index}`}>\n <ListItemIcon />\n <ListItemText primary={tag} />\n </ListItem>\n ))}\n </List>\n )}\n </Container>\n\n {!!relations.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.relation.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-relations\"\n >\n {Object.entries(groupedRelations).map(\n ([type, groupRelations], index) => (\n <div key={index}>\n <List dense subheader={<ListSubheader>{type}</ListSubheader>}>\n {groupRelations.map(group => (\n <ListItem key={group.targetRef}>\n <ListItemText\n primary={\n <EntityRefLink entityRef={group.targetRef} />\n }\n />\n </ListItem>\n ))}\n </List>\n </div>\n ),\n )}\n </Container>\n )}\n\n {!!status.items?.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.status.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-statuses\"\n >\n {status.items.map((item, index) => (\n <div key={index}>\n <Typography>\n {item.level}: {item.type}\n </Typography>\n <Box ml={2}>{item.message}</Box>\n </div>\n ))}\n </Container>\n )}\n </div>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import Button from '@material-ui/core/Button';
4
4
  import { makeStyles } from '@material-ui/core/styles';
5
5
  import Typography from '@material-ui/core/Typography';
6
6
  import { EmptyState, CodeSnippet, Link } from '@backstage/core-components';
7
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
7
8
  import { useEntity } from '../../hooks/useEntity.esm.js';
8
9
  import '../../hooks/useEntityListProvider.esm.js';
9
10
  import 'react';
@@ -18,6 +19,7 @@ import '../../apis/EntityPresentationApi/EntityPresentationApi.esm.js';
18
19
  import 'lodash/get';
19
20
  import '../../apis/StarredEntitiesApi/StarredEntitiesApi.esm.js';
20
21
  import 'zen-observable';
22
+ import { catalogReactTranslationRef } from '../../translation.esm.js';
21
23
 
22
24
  const useStyles = makeStyles(
23
25
  (theme) => ({
@@ -54,28 +56,20 @@ spec:
54
56
  lineNumbers
55
57
  };
56
58
  }
57
- function generateDescription(annotations, entityKind = "Component") {
58
- const isSingular = annotations.length <= 1;
59
- return /* @__PURE__ */ jsxs(Fragment, { children: [
60
- "The ",
61
- isSingular ? "annotation" : "annotations",
62
- " ",
63
- annotations.map((ann) => /* @__PURE__ */ jsx("code", { children: ann })).reduce((prev, curr) => /* @__PURE__ */ jsxs(Fragment, { children: [
64
- prev,
65
- ", ",
66
- curr
67
- ] })),
68
- " ",
69
- isSingular ? "is" : "are",
70
- " missing. You need to add the",
71
- " ",
72
- isSingular ? "annotation" : "annotations",
73
- " to your ",
59
+ function generateDescription(annotations, entityKind = "Component", t) {
60
+ const annotationList = annotations.map((ann) => /* @__PURE__ */ jsx("code", { children: ann }, ann)).reduce((prev, curr) => /* @__PURE__ */ jsxs(Fragment, { children: [
61
+ prev,
62
+ ", ",
63
+ curr
64
+ ] }));
65
+ return t("missingAnnotationEmptyState.generateDescription", {
66
+ count: annotations.length,
74
67
  entityKind,
75
- " if you want to enable this tool."
76
- ] });
68
+ annotations: annotationList
69
+ });
77
70
  }
78
71
  function MissingAnnotationEmptyState(props) {
72
+ const { t } = useTranslationRef(catalogReactTranslationRef);
79
73
  let entity;
80
74
  try {
81
75
  const entityContext = useEntity();
@@ -92,14 +86,10 @@ function MissingAnnotationEmptyState(props) {
92
86
  EmptyState,
93
87
  {
94
88
  missing: "field",
95
- title: "Missing Annotation",
96
- description: generateDescription(annotations, entityKind),
89
+ title: t("missingAnnotationEmptyState.title"),
90
+ description: generateDescription(annotations, entityKind, t),
97
91
  action: /* @__PURE__ */ jsxs(Fragment, { children: [
98
- /* @__PURE__ */ jsxs(Typography, { variant: "body1", children: [
99
- "Add the annotation to your ",
100
- entityKind,
101
- " YAML as shown in the highlighted example below:"
102
- ] }),
92
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", children: t("missingAnnotationEmptyState.annotationYaml", { entityKind }) }),
103
93
  /* @__PURE__ */ jsx(Box, { className: classes.code, children: /* @__PURE__ */ jsx(
104
94
  CodeSnippet,
105
95
  {
@@ -110,7 +100,7 @@ function MissingAnnotationEmptyState(props) {
110
100
  customStyle: { background: "inherit", fontSize: "115%" }
111
101
  }
112
102
  ) }),
113
- /* @__PURE__ */ jsx(Button, { color: "primary", component: Link, to: url, children: "Read more" })
103
+ /* @__PURE__ */ jsx(Button, { color: "primary", component: Link, to: url, children: t("missingAnnotationEmptyState.readMore") })
114
104
  ] })
115
105
  }
116
106
  );
@@ -1 +1 @@
1
- {"version":3,"file":"MissingAnnotationEmptyState.esm.js","sources":["../../../src/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.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 Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { CodeSnippet, Link, EmptyState } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '../../hooks';\n\n/** @public */\nexport type MissingAnnotationEmptyStateClassKey = 'code';\n\nconst useStyles = makeStyles(\n theme => ({\n code: {\n borderRadius: 6,\n margin: theme.spacing(2, 0),\n background:\n theme.palette.type === 'dark' ? '#444' : theme.palette.common.white,\n },\n }),\n { name: 'BackstageMissingAnnotationEmptyState' },\n);\n\nfunction generateYamlExample(\n annotations: string[],\n entity?: Entity,\n): { yamlText: string; lineNumbers: number[] } {\n const kind = entity?.kind || 'Component';\n const name = entity?.metadata.name || 'example';\n const type = entity?.spec?.type || 'website';\n const owner = entity?.spec?.owner || 'user:default/guest';\n\n const yamlText = `apiVersion: backstage.io/v1alpha1\nkind: ${kind}\nmetadata:\n name: ${name}\n annotations:${annotations.map(ann => `\\n ${ann}: value`).join('')}\nspec:\n type: ${type}\n owner: ${owner}`;\n\n let line = 6; // Line 6 is the line number that annotations are added to.\n const lineNumbers: number[] = [];\n annotations.forEach(() => {\n lineNumbers.push(line);\n line++;\n });\n\n return {\n yamlText,\n lineNumbers,\n };\n}\n\nfunction generateDescription(annotations: string[], entityKind = 'Component') {\n const isSingular = annotations.length <= 1;\n return (\n <>\n The {isSingular ? 'annotation' : 'annotations'}{' '}\n {annotations\n .map(ann => <code>{ann}</code>)\n .reduce((prev, curr) => (\n <>\n {prev}, {curr}\n </>\n ))}{' '}\n {isSingular ? 'is' : 'are'} missing. You need to add the{' '}\n {isSingular ? 'annotation' : 'annotations'} to your {entityKind} if you\n want to enable this tool.\n </>\n );\n}\n\n/**\n * @public\n * Renders an empty state when an annotation is missing from an entity.\n */\nexport function MissingAnnotationEmptyState(props: {\n annotation: string | string[];\n readMoreUrl?: string;\n}) {\n let entity: Entity | undefined;\n try {\n const entityContext = useEntity();\n entity = entityContext.entity;\n } catch (err) {\n // ignore when entity context doesnt exist\n }\n\n const { annotation, readMoreUrl } = props;\n const annotations = Array.isArray(annotation) ? annotation : [annotation];\n const url =\n readMoreUrl ||\n 'https://backstage.io/docs/features/software-catalog/well-known-annotations';\n const classes = useStyles();\n\n const entityKind = entity?.kind || 'Component';\n const { yamlText, lineNumbers } = generateYamlExample(annotations, entity);\n return (\n <EmptyState\n missing=\"field\"\n title=\"Missing Annotation\"\n description={generateDescription(annotations, entityKind)}\n action={\n <>\n <Typography variant=\"body1\">\n Add the annotation to your {entityKind} YAML as shown in the\n highlighted example below:\n </Typography>\n <Box className={classes.code}>\n <CodeSnippet\n text={yamlText}\n language=\"yaml\"\n showLineNumbers\n highlightedNumbers={lineNumbers}\n customStyle={{ background: 'inherit', fontSize: '115%' }}\n />\n </Box>\n <Button color=\"primary\" component={Link} to={url}>\n Read more\n </Button>\n </>\n }\n />\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MissingAnnotationEmptyState.esm.js","sources":["../../../src/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.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 Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { CodeSnippet, Link, EmptyState } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { useEntity } from '../../hooks';\nimport { catalogReactTranslationRef } from '../../translation';\n\n/** @public */\nexport type MissingAnnotationEmptyStateClassKey = 'code';\n\nconst useStyles = makeStyles(\n theme => ({\n code: {\n borderRadius: 6,\n margin: theme.spacing(2, 0),\n background:\n theme.palette.type === 'dark' ? '#444' : theme.palette.common.white,\n },\n }),\n { name: 'BackstageMissingAnnotationEmptyState' },\n);\n\nfunction generateYamlExample(\n annotations: string[],\n entity?: Entity,\n): { yamlText: string; lineNumbers: number[] } {\n const kind = entity?.kind || 'Component';\n const name = entity?.metadata.name || 'example';\n const type = entity?.spec?.type || 'website';\n const owner = entity?.spec?.owner || 'user:default/guest';\n\n const yamlText = `apiVersion: backstage.io/v1alpha1\nkind: ${kind}\nmetadata:\n name: ${name}\n annotations:${annotations.map(ann => `\\n ${ann}: value`).join('')}\nspec:\n type: ${type}\n owner: ${owner}`;\n\n let line = 6; // Line 6 is the line number that annotations are added to.\n const lineNumbers: number[] = [];\n annotations.forEach(() => {\n lineNumbers.push(line);\n line++;\n });\n\n return {\n yamlText,\n lineNumbers,\n };\n}\n\nfunction generateDescription(\n annotations: string[],\n entityKind = 'Component',\n t: TranslationFunction<typeof catalogReactTranslationRef.T>,\n) {\n const annotationList = annotations\n .map(ann => <code key={ann}>{ann}</code>)\n .reduce((prev, curr) => (\n <>\n {prev}, {curr}\n </>\n ));\n\n return t('missingAnnotationEmptyState.generateDescription', {\n count: annotations.length,\n entityKind,\n annotations: annotationList,\n });\n}\n\n/**\n * @public\n * Renders an empty state when an annotation is missing from an entity.\n */\nexport function MissingAnnotationEmptyState(props: {\n annotation: string | string[];\n readMoreUrl?: string;\n}) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n let entity: Entity | undefined;\n try {\n const entityContext = useEntity();\n entity = entityContext.entity;\n } catch (err) {\n // ignore when entity context doesnt exist\n }\n\n const { annotation, readMoreUrl } = props;\n const annotations = Array.isArray(annotation) ? annotation : [annotation];\n const url =\n readMoreUrl ||\n 'https://backstage.io/docs/features/software-catalog/well-known-annotations';\n const classes = useStyles();\n\n const entityKind = entity?.kind || 'Component';\n const { yamlText, lineNumbers } = generateYamlExample(annotations, entity);\n return (\n <EmptyState\n missing=\"field\"\n title={t('missingAnnotationEmptyState.title')}\n description={generateDescription(annotations, entityKind, t)}\n action={\n <>\n <Typography variant=\"body1\">\n {t('missingAnnotationEmptyState.annotationYaml', { entityKind })}\n </Typography>\n <Box className={classes.code}>\n <CodeSnippet\n text={yamlText}\n language=\"yaml\"\n showLineNumbers\n highlightedNumbers={lineNumbers}\n customStyle={{ background: 'inherit', fontSize: '115%' }}\n />\n </Box>\n <Button color=\"primary\" component={Link} to={url}>\n {t('missingAnnotationEmptyState.readMore')}\n </Button>\n </>\n }\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -70,10 +70,10 @@ const EntityListProvider = (props) => {
70
70
  const kindValue = requestedFilters.kind?.value?.toLocaleLowerCase("en-US");
71
71
  const adjustedFilters = kindValue === "user" || kindValue === "group" ? { ...requestedFilters, owners: void 0 } : requestedFilters;
72
72
  const compacted = compact(Object.values(adjustedFilters));
73
+ const entityFilter = reduceEntityFilters(compacted);
73
74
  if (paginationMode !== "none") {
74
75
  if (cursor) {
75
76
  if (cursor !== outputState.appliedCursor) {
76
- const entityFilter = reduceEntityFilters(compacted);
77
77
  const response = await catalogApi.queryEntities({
78
78
  cursor,
79
79
  limit
@@ -87,58 +87,74 @@ const EntityListProvider = (props) => {
87
87
  totalItems: response.totalItems
88
88
  };
89
89
  }
90
- } else {
91
- const entityFilter = reduceEntityFilters(compacted);
92
- const backendFilter = reduceCatalogFilters(compacted);
93
- const previousBackendFilter = reduceCatalogFilters(
94
- compact(Object.values(outputState.appliedFilters))
95
- );
96
- if (paginationMode === "offset" && (outputState.limit !== limit || outputState.offset !== offset) || !isEqual(previousBackendFilter, backendFilter)) {
97
- const response = await catalogApi.queryEntities({
98
- ...backendFilter,
99
- limit,
100
- offset
101
- });
102
- return {
103
- appliedFilters: requestedFilters,
104
- backendEntities: response.items,
105
- entities: response.items.filter(entityFilter),
106
- pageInfo: response.pageInfo,
107
- totalItems: response.totalItems,
108
- limit,
109
- offset
110
- };
111
- }
90
+ const entities3 = outputState.backendEntities.filter(entityFilter);
91
+ return {
92
+ appliedFilters: requestedFilters,
93
+ appliedCursor: outputState.appliedCursor,
94
+ backendEntities: outputState.backendEntities,
95
+ entities: entities3,
96
+ pageInfo: outputState.pageInfo,
97
+ totalItems: outputState.totalItems,
98
+ limit: outputState.limit,
99
+ offset: outputState.offset
100
+ };
112
101
  }
113
- } else {
114
- const entityFilter = reduceEntityFilters(compacted);
115
- const backendFilter = reduceBackendCatalogFilters(compacted);
116
- const { orderFields } = reduceCatalogFilters(compacted);
117
- const previousBackendFilter = reduceBackendCatalogFilters(
102
+ const backendFilter2 = reduceCatalogFilters(compacted);
103
+ const previousBackendFilter2 = reduceCatalogFilters(
118
104
  compact(Object.values(outputState.appliedFilters))
119
105
  );
120
- if (!isEqual(previousBackendFilter, backendFilter)) {
121
- const response = await catalogApi.getEntities({
122
- filter: backendFilter,
123
- order: orderFields
106
+ if (paginationMode === "offset" && (outputState.limit !== limit || outputState.offset !== offset) || !isEqual(previousBackendFilter2, backendFilter2)) {
107
+ const response = await catalogApi.queryEntities({
108
+ ...backendFilter2,
109
+ limit,
110
+ offset
124
111
  });
125
- const entities2 = response.items.filter(entityFilter);
126
112
  return {
127
113
  appliedFilters: requestedFilters,
128
114
  backendEntities: response.items,
129
- entities: entities2,
130
- totalItems: entities2.length
115
+ entities: response.items.filter(entityFilter),
116
+ pageInfo: response.pageInfo,
117
+ totalItems: response.totalItems,
118
+ limit,
119
+ offset
131
120
  };
132
121
  }
133
- const entities = outputState.backendEntities.filter(entityFilter);
122
+ const entities2 = outputState.backendEntities.filter(entityFilter);
134
123
  return {
135
124
  appliedFilters: requestedFilters,
136
125
  backendEntities: outputState.backendEntities,
137
- entities,
138
- totalItems: entities.length
126
+ entities: entities2,
127
+ pageInfo: outputState.pageInfo,
128
+ totalItems: outputState.totalItems,
129
+ limit: outputState.limit,
130
+ offset: outputState.offset
139
131
  };
140
132
  }
141
- return void 0;
133
+ const backendFilter = reduceBackendCatalogFilters(compacted);
134
+ const { orderFields } = reduceCatalogFilters(compacted);
135
+ const previousBackendFilter = reduceBackendCatalogFilters(
136
+ compact(Object.values(outputState.appliedFilters))
137
+ );
138
+ if (!isEqual(previousBackendFilter, backendFilter)) {
139
+ const response = await catalogApi.getEntities({
140
+ filter: backendFilter,
141
+ order: orderFields
142
+ });
143
+ const entities2 = response.items.filter(entityFilter);
144
+ return {
145
+ appliedFilters: requestedFilters,
146
+ backendEntities: response.items,
147
+ entities: entities2,
148
+ totalItems: entities2.length
149
+ };
150
+ }
151
+ const entities = outputState.backendEntities.filter(entityFilter);
152
+ return {
153
+ appliedFilters: requestedFilters,
154
+ backendEntities: outputState.backendEntities,
155
+ entities,
156
+ totalItems: entities.length
157
+ };
142
158
  },
143
159
  [
144
160
  catalogApi,
@@ -1 +1 @@
1
- {"version":3,"file":"useEntityListProvider.esm.js","sources":["../../src/hooks/useEntityListProvider.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 { QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { useLocation } from 'react-router-dom';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport useMountedState from 'react-use/esm/useMountedState';\nimport { catalogApiRef } from '../api';\nimport {\n EntityErrorFilter,\n EntityKindFilter,\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityTypeFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityFilter, EntityListPagination } from '../types';\nimport {\n reduceBackendCatalogFilters,\n reduceCatalogFilters,\n reduceEntityFilters,\n} from '../utils/filters';\n\n/** @public */\nexport type DefaultEntityFilters = {\n kind?: EntityKindFilter;\n type?: EntityTypeFilter;\n user?: UserListFilter | EntityUserFilter;\n owners?: EntityOwnerFilter;\n lifecycles?: EntityLifecycleFilter;\n tags?: EntityTagFilter;\n text?: EntityTextFilter;\n orphan?: EntityOrphanFilter;\n error?: EntityErrorFilter;\n namespace?: EntityNamespaceFilter;\n order?: EntityOrderFilter;\n};\n\n/** @public */\nexport type PaginationMode = 'cursor' | 'offset' | 'none';\n\n/** @public */\nexport type EntityListContextProps<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n> = {\n /**\n * The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension\n * of that default (to add custom filter types).\n */\n filters: EntityFilters;\n\n /**\n * The resolved list of catalog entities, after all filters are applied.\n */\n entities: Entity[];\n\n /**\n * The resolved list of catalog entities, after _only catalog-backend_ filters are applied.\n */\n backendEntities: Entity[];\n\n /**\n * Update one or more of the registered filters. Optional filters can be set to `undefined` to\n * reset the filter.\n */\n updateFilters: (\n filters:\n | Partial<EntityFilters>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => void;\n\n /**\n * Filter values from query parameters.\n */\n queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;\n\n loading: boolean;\n error?: Error;\n\n pageInfo?: {\n next?: () => void;\n prev?: () => void;\n };\n totalItems?: number;\n limit: number;\n offset?: number;\n setLimit: (limit: number) => void;\n setOffset?: (offset: number) => void;\n paginationMode: PaginationMode;\n};\n\n/**\n * Creates new context for entity listing and filtering.\n * @public\n */\nexport const EntityListContext = createContext<\n EntityListContextProps<any> | undefined\n>(undefined);\n\ntype OutputState<EntityFilters extends DefaultEntityFilters> = {\n appliedFilters: EntityFilters;\n appliedCursor?: string;\n entities: Entity[];\n backendEntities: Entity[];\n pageInfo?: QueryEntitiesResponse['pageInfo'];\n totalItems?: number;\n offset?: number;\n limit?: number;\n};\n\n/**\n * @public\n */\nexport type EntityListProviderProps = PropsWithChildren<{\n pagination?: EntityListPagination;\n}>;\n\n/**\n * Provides entities and filters for a catalog listing.\n * @public\n */\nexport const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(\n props: EntityListProviderProps,\n) => {\n const isMounted = useMountedState();\n const catalogApi = useApi(catalogApiRef);\n const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(\n {} as EntityFilters,\n );\n\n // We use react-router's useLocation hook so updates from external sources trigger an update to\n // the queryParameters in outputState. Updates from this hook use replaceState below and won't\n // trigger a useLocation change; this would instead come from an external source, such as a manual\n // update of the URL or two catalog sidebar links with different catalog filters.\n const location = useLocation();\n\n const getPaginationMode = (): PaginationMode => {\n if (props.pagination === true) {\n return 'cursor';\n }\n return typeof props.pagination === 'object'\n ? props.pagination.mode ?? 'cursor'\n : 'none';\n };\n\n const paginationMode = getPaginationMode();\n const paginationLimit =\n typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20;\n\n const {\n queryParameters,\n cursor: initialCursor,\n offset: initialOffset,\n limit: initialLimit,\n } = useMemo(() => {\n const parsed = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n });\n\n let limit = paginationLimit;\n if (typeof parsed.limit === 'string') {\n const queryLimit = Number.parseInt(parsed.limit, 10);\n if (!isNaN(queryLimit)) {\n limit = queryLimit;\n }\n }\n\n const offset =\n typeof parsed.offset === 'string' && paginationMode === 'offset'\n ? Number.parseInt(parsed.offset, 10)\n : undefined;\n\n return {\n queryParameters: (parsed.filters ?? {}) as Record<\n string,\n string | string[]\n >,\n cursor:\n typeof parsed.cursor === 'string' && paginationMode === 'cursor'\n ? parsed.cursor\n : undefined,\n offset:\n paginationMode === 'offset' && offset && !isNaN(offset)\n ? offset\n : undefined,\n limit,\n };\n }, [paginationMode, location.search, paginationLimit]);\n\n const [cursor, setCursor] = useState(initialCursor);\n const [offset, setOffset] = useState<number | undefined>(initialOffset);\n const [limit, setLimit] = useState(initialLimit);\n\n const [outputState, setOutputState] = useState<OutputState<EntityFilters>>(\n () => {\n return {\n appliedFilters: {} as EntityFilters,\n entities: [],\n backendEntities: [],\n pageInfo: {},\n offset,\n limit,\n };\n },\n );\n\n // The main async filter worker. Note that while it has a lot of dependencies\n // in terms of its implementation, the triggering only happens (debounced)\n // based on the requested filters changing.\n const [{ value: resolvedValue, loading, error }, refresh] = useAsyncFn(\n async () => {\n const kindValue =\n requestedFilters.kind?.value?.toLocaleLowerCase('en-US');\n const adjustedFilters =\n kindValue === 'user' || kindValue === 'group'\n ? { ...requestedFilters, owners: undefined }\n : requestedFilters;\n const compacted = compact(Object.values(adjustedFilters));\n\n if (paginationMode !== 'none') {\n if (cursor) {\n if (cursor !== outputState.appliedCursor) {\n const entityFilter = reduceEntityFilters(compacted);\n const response = await catalogApi.queryEntities({\n cursor,\n limit,\n });\n return {\n appliedFilters: requestedFilters,\n appliedCursor: cursor,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n };\n }\n } else {\n const entityFilter = reduceEntityFilters(compacted);\n const backendFilter = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n if (\n (paginationMode === 'offset' &&\n (outputState.limit !== limit || outputState.offset !== offset)) ||\n !isEqual(previousBackendFilter, backendFilter)\n ) {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit,\n offset,\n });\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n limit,\n offset,\n };\n }\n }\n } else {\n const entityFilter = reduceEntityFilters(compacted);\n const backendFilter = reduceBackendCatalogFilters(compacted);\n const { orderFields } = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceBackendCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n // TODO(mtlewis): currently entities will never be requested unless\n // there's at least one filter, we should allow an initial request\n // to happen with no filters.\n if (!isEqual(previousBackendFilter, backendFilter)) {\n // TODO(timbonicus): should limit fields here, but would need filter\n // fields + table columns\n const response = await catalogApi.getEntities({\n filter: backendFilter,\n order: orderFields,\n });\n const entities = response.items.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities,\n totalItems: entities.length,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n totalItems: entities.length,\n };\n }\n return undefined;\n },\n [\n catalogApi,\n queryParameters,\n requestedFilters,\n outputState,\n cursor,\n paginationMode,\n limit,\n offset,\n ],\n { loading: true },\n );\n\n // Slight debounce on the refresh, since (especially on page load) several\n // filters will be calling this in rapid succession.\n useDebounce(refresh, 10, [requestedFilters, cursor, limit, offset]);\n\n useEffect(() => {\n if (resolvedValue === undefined) {\n return;\n }\n setOutputState(resolvedValue);\n if (isMounted()) {\n const queryParams = Object.keys(requestedFilters).reduce(\n (params, key) => {\n const filter = requestedFilters[key as keyof EntityFilters] as\n | EntityFilter\n | undefined;\n if (filter?.toQueryValue) {\n params[key] = filter.toQueryValue();\n }\n return params;\n },\n {} as Record<string, string | string[]>,\n );\n\n const oldParams = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n });\n const newParams = qs.stringify(\n {\n ...oldParams,\n filters: queryParams,\n ...(paginationMode === 'none' ? {} : { cursor, limit, offset }),\n },\n { addQueryPrefix: true, arrayFormat: 'repeat' },\n );\n const newUrl = `${window.location.pathname}${newParams}`;\n // We use direct history manipulation since useSearchParams and\n // useNavigate in react-router-dom cause unnecessary extra rerenders.\n // Also make sure to replace the state rather than pushing, since we\n // don't want there to be back/forward slots for every single filter\n // change.\n window.history?.replaceState(null, document.title, newUrl);\n }\n }, [\n cursor,\n isMounted,\n limit,\n location.search,\n offset,\n requestedFilters,\n resolvedValue,\n paginationMode,\n ]);\n\n const updateFilters = useCallback(\n (\n update:\n | Partial<EntityFilter>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => {\n // changing filters will affect pagination, so we need to reset\n // the cursor and start from the first page.\n // TODO(vinzscam): this is currently causing issues at page reload\n // where the state is not kept. Unfortunately we need to rethink\n // the way filters work in order to fix this.\n if (paginationMode === 'cursor') {\n setCursor(undefined);\n } else if (paginationMode === 'offset') {\n // Same thing with offset\n setOffset(0);\n }\n setRequestedFilters(prevFilters => {\n const newFilters =\n typeof update === 'function' ? update(prevFilters) : update;\n return { ...prevFilters, ...newFilters };\n });\n },\n [paginationMode],\n );\n\n const pageInfo = useMemo(() => {\n if (paginationMode !== 'cursor') {\n return undefined;\n }\n\n const prevCursor = outputState.pageInfo?.prevCursor;\n const nextCursor = outputState.pageInfo?.nextCursor;\n return {\n prev: prevCursor ? () => setCursor(prevCursor) : undefined,\n next: nextCursor ? () => setCursor(nextCursor) : undefined,\n };\n }, [paginationMode, outputState.pageInfo]);\n\n const value = useMemo(\n () => ({\n filters: outputState.appliedFilters,\n entities: outputState.entities,\n backendEntities: outputState.backendEntities,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n totalItems: outputState.totalItems,\n limit,\n offset,\n setLimit,\n setOffset,\n paginationMode,\n }),\n [\n outputState,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n limit,\n offset,\n paginationMode,\n setLimit,\n setOffset,\n ],\n );\n\n return (\n <EntityListContext.Provider value={value}>\n {props.children}\n </EntityListContext.Provider>\n );\n};\n\n/**\n * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.\n * @public\n */\nexport function useEntityList<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n>(): EntityListContextProps<EntityFilters> {\n const context = useContext(EntityListContext);\n if (!context)\n throw new Error('useEntityList must be used within EntityListProvider');\n return context;\n}\n"],"names":["limit","offset","entities"],"mappings":"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"}
1
+ {"version":3,"file":"useEntityListProvider.esm.js","sources":["../../src/hooks/useEntityListProvider.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 { QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { compact, isEqual } from 'lodash';\nimport qs from 'qs';\nimport {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { useLocation } from 'react-router-dom';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport useMountedState from 'react-use/esm/useMountedState';\nimport { catalogApiRef } from '../api';\nimport {\n EntityErrorFilter,\n EntityKindFilter,\n EntityLifecycleFilter,\n EntityNamespaceFilter,\n EntityOrderFilter,\n EntityOrphanFilter,\n EntityOwnerFilter,\n EntityTagFilter,\n EntityTextFilter,\n EntityTypeFilter,\n EntityUserFilter,\n UserListFilter,\n} from '../filters';\nimport { EntityFilter, EntityListPagination } from '../types';\nimport {\n reduceBackendCatalogFilters,\n reduceCatalogFilters,\n reduceEntityFilters,\n} from '../utils/filters';\n\n/** @public */\nexport type DefaultEntityFilters = {\n kind?: EntityKindFilter;\n type?: EntityTypeFilter;\n user?: UserListFilter | EntityUserFilter;\n owners?: EntityOwnerFilter;\n lifecycles?: EntityLifecycleFilter;\n tags?: EntityTagFilter;\n text?: EntityTextFilter;\n orphan?: EntityOrphanFilter;\n error?: EntityErrorFilter;\n namespace?: EntityNamespaceFilter;\n order?: EntityOrderFilter;\n};\n\n/** @public */\nexport type PaginationMode = 'cursor' | 'offset' | 'none';\n\n/** @public */\nexport type EntityListContextProps<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n> = {\n /**\n * The currently registered filters, adhering to the shape of DefaultEntityFilters or an extension\n * of that default (to add custom filter types).\n */\n filters: EntityFilters;\n\n /**\n * The resolved list of catalog entities, after all filters are applied.\n */\n entities: Entity[];\n\n /**\n * The resolved list of catalog entities, after _only catalog-backend_ filters are applied.\n */\n backendEntities: Entity[];\n\n /**\n * Update one or more of the registered filters. Optional filters can be set to `undefined` to\n * reset the filter.\n */\n updateFilters: (\n filters:\n | Partial<EntityFilters>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => void;\n\n /**\n * Filter values from query parameters.\n */\n queryParameters: Partial<Record<keyof EntityFilters, string | string[]>>;\n\n loading: boolean;\n error?: Error;\n\n pageInfo?: {\n next?: () => void;\n prev?: () => void;\n };\n totalItems?: number;\n limit: number;\n offset?: number;\n setLimit: (limit: number) => void;\n setOffset?: (offset: number) => void;\n paginationMode: PaginationMode;\n};\n\n/**\n * Creates new context for entity listing and filtering.\n * @public\n */\nexport const EntityListContext = createContext<\n EntityListContextProps<any> | undefined\n>(undefined);\n\ntype OutputState<EntityFilters extends DefaultEntityFilters> = {\n appliedFilters: EntityFilters;\n appliedCursor?: string;\n entities: Entity[];\n backendEntities: Entity[];\n pageInfo?: QueryEntitiesResponse['pageInfo'];\n totalItems?: number;\n offset?: number;\n limit?: number;\n};\n\n/**\n * @public\n */\nexport type EntityListProviderProps = PropsWithChildren<{\n pagination?: EntityListPagination;\n}>;\n\n/**\n * Provides entities and filters for a catalog listing.\n * @public\n */\nexport const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(\n props: EntityListProviderProps,\n) => {\n const isMounted = useMountedState();\n const catalogApi = useApi(catalogApiRef);\n const [requestedFilters, setRequestedFilters] = useState<EntityFilters>(\n {} as EntityFilters,\n );\n\n // We use react-router's useLocation hook so updates from external sources trigger an update to\n // the queryParameters in outputState. Updates from this hook use replaceState below and won't\n // trigger a useLocation change; this would instead come from an external source, such as a manual\n // update of the URL or two catalog sidebar links with different catalog filters.\n const location = useLocation();\n\n const getPaginationMode = (): PaginationMode => {\n if (props.pagination === true) {\n return 'cursor';\n }\n return typeof props.pagination === 'object'\n ? props.pagination.mode ?? 'cursor'\n : 'none';\n };\n\n const paginationMode = getPaginationMode();\n const paginationLimit =\n typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20;\n\n const {\n queryParameters,\n cursor: initialCursor,\n offset: initialOffset,\n limit: initialLimit,\n } = useMemo(() => {\n const parsed = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n });\n\n let limit = paginationLimit;\n if (typeof parsed.limit === 'string') {\n const queryLimit = Number.parseInt(parsed.limit, 10);\n if (!isNaN(queryLimit)) {\n limit = queryLimit;\n }\n }\n\n const offset =\n typeof parsed.offset === 'string' && paginationMode === 'offset'\n ? Number.parseInt(parsed.offset, 10)\n : undefined;\n\n return {\n queryParameters: (parsed.filters ?? {}) as Record<\n string,\n string | string[]\n >,\n cursor:\n typeof parsed.cursor === 'string' && paginationMode === 'cursor'\n ? parsed.cursor\n : undefined,\n offset:\n paginationMode === 'offset' && offset && !isNaN(offset)\n ? offset\n : undefined,\n limit,\n };\n }, [paginationMode, location.search, paginationLimit]);\n\n const [cursor, setCursor] = useState(initialCursor);\n const [offset, setOffset] = useState<number | undefined>(initialOffset);\n const [limit, setLimit] = useState(initialLimit);\n\n const [outputState, setOutputState] = useState<OutputState<EntityFilters>>(\n () => {\n return {\n appliedFilters: {} as EntityFilters,\n entities: [],\n backendEntities: [],\n pageInfo: {},\n offset,\n limit,\n };\n },\n );\n\n // The main async filter worker. Note that while it has a lot of dependencies\n // in terms of its implementation, the triggering only happens (debounced)\n // based on the requested filters changing.\n const [{ value: resolvedValue, loading, error }, refresh] = useAsyncFn(\n async () => {\n const kindValue =\n requestedFilters.kind?.value?.toLocaleLowerCase('en-US');\n const adjustedFilters =\n kindValue === 'user' || kindValue === 'group'\n ? { ...requestedFilters, owners: undefined }\n : requestedFilters;\n const compacted = compact(Object.values(adjustedFilters));\n const entityFilter = reduceEntityFilters(compacted);\n\n if (paginationMode !== 'none') {\n if (cursor) {\n if (cursor !== outputState.appliedCursor) {\n const response = await catalogApi.queryEntities({\n cursor,\n limit,\n });\n return {\n appliedFilters: requestedFilters,\n appliedCursor: cursor,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n appliedCursor: outputState.appliedCursor,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n if (\n (paginationMode === 'offset' &&\n (outputState.limit !== limit || outputState.offset !== offset)) ||\n !isEqual(previousBackendFilter, backendFilter)\n ) {\n const response = await catalogApi.queryEntities({\n ...backendFilter,\n limit,\n offset,\n });\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities: response.items.filter(entityFilter),\n pageInfo: response.pageInfo,\n totalItems: response.totalItems,\n limit,\n offset,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n pageInfo: outputState.pageInfo,\n totalItems: outputState.totalItems,\n limit: outputState.limit,\n offset: outputState.offset,\n };\n }\n\n const backendFilter = reduceBackendCatalogFilters(compacted);\n const { orderFields } = reduceCatalogFilters(compacted);\n const previousBackendFilter = reduceBackendCatalogFilters(\n compact(Object.values(outputState.appliedFilters)),\n );\n\n // TODO(mtlewis): currently entities will never be requested unless\n // there's at least one filter, we should allow an initial request\n // to happen with no filters.\n if (!isEqual(previousBackendFilter, backendFilter)) {\n // TODO(timbonicus): should limit fields here, but would need filter\n // fields + table columns\n const response = await catalogApi.getEntities({\n filter: backendFilter,\n order: orderFields,\n });\n const entities = response.items.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: response.items,\n entities,\n totalItems: entities.length,\n };\n }\n const entities = outputState.backendEntities.filter(entityFilter);\n return {\n appliedFilters: requestedFilters,\n backendEntities: outputState.backendEntities,\n entities,\n totalItems: entities.length,\n };\n },\n [\n catalogApi,\n queryParameters,\n requestedFilters,\n outputState,\n cursor,\n paginationMode,\n limit,\n offset,\n ],\n { loading: true },\n );\n\n // Slight debounce on the refresh, since (especially on page load) several\n // filters will be calling this in rapid succession.\n useDebounce(refresh, 10, [requestedFilters, cursor, limit, offset]);\n\n useEffect(() => {\n if (resolvedValue === undefined) {\n return;\n }\n setOutputState(resolvedValue);\n if (isMounted()) {\n const queryParams = Object.keys(requestedFilters).reduce(\n (params, key) => {\n const filter = requestedFilters[key as keyof EntityFilters] as\n | EntityFilter\n | undefined;\n if (filter?.toQueryValue) {\n params[key] = filter.toQueryValue();\n }\n return params;\n },\n {} as Record<string, string | string[]>,\n );\n\n const oldParams = qs.parse(location.search, {\n ignoreQueryPrefix: true,\n });\n const newParams = qs.stringify(\n {\n ...oldParams,\n filters: queryParams,\n ...(paginationMode === 'none' ? {} : { cursor, limit, offset }),\n },\n { addQueryPrefix: true, arrayFormat: 'repeat' },\n );\n const newUrl = `${window.location.pathname}${newParams}`;\n // We use direct history manipulation since useSearchParams and\n // useNavigate in react-router-dom cause unnecessary extra rerenders.\n // Also make sure to replace the state rather than pushing, since we\n // don't want there to be back/forward slots for every single filter\n // change.\n window.history?.replaceState(null, document.title, newUrl);\n }\n }, [\n cursor,\n isMounted,\n limit,\n location.search,\n offset,\n requestedFilters,\n resolvedValue,\n paginationMode,\n ]);\n\n const updateFilters = useCallback(\n (\n update:\n | Partial<EntityFilter>\n | ((prevFilters: EntityFilters) => Partial<EntityFilters>),\n ) => {\n // changing filters will affect pagination, so we need to reset\n // the cursor and start from the first page.\n // TODO(vinzscam): this is currently causing issues at page reload\n // where the state is not kept. Unfortunately we need to rethink\n // the way filters work in order to fix this.\n if (paginationMode === 'cursor') {\n setCursor(undefined);\n } else if (paginationMode === 'offset') {\n // Same thing with offset\n setOffset(0);\n }\n setRequestedFilters(prevFilters => {\n const newFilters =\n typeof update === 'function' ? update(prevFilters) : update;\n return { ...prevFilters, ...newFilters };\n });\n },\n [paginationMode],\n );\n\n const pageInfo = useMemo(() => {\n if (paginationMode !== 'cursor') {\n return undefined;\n }\n\n const prevCursor = outputState.pageInfo?.prevCursor;\n const nextCursor = outputState.pageInfo?.nextCursor;\n return {\n prev: prevCursor ? () => setCursor(prevCursor) : undefined,\n next: nextCursor ? () => setCursor(nextCursor) : undefined,\n };\n }, [paginationMode, outputState.pageInfo]);\n\n const value = useMemo(\n () => ({\n filters: outputState.appliedFilters,\n entities: outputState.entities,\n backendEntities: outputState.backendEntities,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n totalItems: outputState.totalItems,\n limit,\n offset,\n setLimit,\n setOffset,\n paginationMode,\n }),\n [\n outputState,\n updateFilters,\n queryParameters,\n loading,\n error,\n pageInfo,\n limit,\n offset,\n paginationMode,\n setLimit,\n setOffset,\n ],\n );\n\n return (\n <EntityListContext.Provider value={value}>\n {props.children}\n </EntityListContext.Provider>\n );\n};\n\n/**\n * Hook for interacting with the entity list context provided by the {@link EntityListProvider}.\n * @public\n */\nexport function useEntityList<\n EntityFilters extends DefaultEntityFilters = DefaultEntityFilters,\n>(): EntityListContextProps<EntityFilters> {\n const context = useContext(EntityListContext);\n if (!context)\n throw new Error('useEntityList must be used within EntityListProvider');\n return context;\n}\n"],"names":["limit","offset","entities","backendFilter","previousBackendFilter"],"mappings":"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"}
@@ -30,8 +30,10 @@ const catalogReactTranslationRef = createTranslationRef({
30
30
  title: "Drill into the entity to see all of the tags.",
31
31
  emailCardAction: {
32
32
  title: "Email {{email}}",
33
- subTitle: "mailto {{email}}"
33
+ subTitle: "mailto {{email}}",
34
+ ariaLabel: "Email"
34
35
  },
36
+ entityCardActionsAriaLabel: "Show",
35
37
  entityCardActionsTitle: "Show details"
36
38
  },
37
39
  entitySearchBar: {
@@ -50,25 +52,52 @@ const catalogReactTranslationRef = createTranslationRef({
50
52
  title: "Entity Inspector",
51
53
  closeButtonTitle: "Close",
52
54
  ancestryPage: {
53
- title: "Ancestry"
55
+ title: "Ancestry",
56
+ description: "This is the ancestry of entities above the current one - as in, the chain(s) of entities down to the current one, where {{processorsLink}} child entities that ultimately led to the current one existing. Note that this is a completely different mechanism from relations.",
57
+ processorsLink: "processors emitted"
54
58
  },
55
59
  colocatedPage: {
56
60
  title: "Colocated",
57
61
  description: "These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).",
58
62
  alertNoLocation: "Entity had no location information.",
59
- alertNoEntity: "There were no other entities on this location."
63
+ alertNoEntity: "There were no other entities on this location.",
64
+ locationHeader: "At the same location",
65
+ originHeader: "At the same origin"
60
66
  },
61
67
  jsonPage: {
62
68
  title: "Entity as JSON",
63
69
  description: "This is the raw entity data as received from the catalog, on JSON form."
64
70
  },
65
71
  overviewPage: {
66
- title: "Overview"
72
+ title: "Overview",
73
+ relation: {
74
+ title: "Relations"
75
+ },
76
+ status: {
77
+ title: "Status"
78
+ },
79
+ identity: {
80
+ title: "Identity"
81
+ },
82
+ metadata: {
83
+ title: "Metadata"
84
+ },
85
+ annotations: "Annotations",
86
+ labels: "Labels",
87
+ tags: "Tags"
67
88
  },
68
89
  yamlPage: {
69
90
  title: "Entity as YAML",
70
91
  description: "This is the raw entity data as received from the catalog, on YAML form."
71
- }
92
+ },
93
+ tabNames: {
94
+ overview: "Overview",
95
+ ancestry: "Ancestry",
96
+ colocated: "Colocated",
97
+ json: "Raw JSON",
98
+ yaml: "Raw YAML"
99
+ },
100
+ tabsAriaLabel: "Inspector options"
72
101
  },
73
102
  unregisterEntityDialog: {
74
103
  title: "Are you sure you want to unregister this entity?",
@@ -113,6 +142,13 @@ const catalogReactTranslationRef = createTranslationRef({
113
142
  title: "Title",
114
143
  label: "Label",
115
144
  domain: "Domain"
145
+ },
146
+ missingAnnotationEmptyState: {
147
+ title: "Missing Annotation",
148
+ readMore: "Read more",
149
+ annotationYaml: "Add the annotation to your {{entityKind}} YAML as shown in the highlighted example below:",
150
+ generateDescription_one: "The annotation {{annotations}} is missing. You need to add the annotation to your {{entityKind}} if you want to enable this tool.",
151
+ generateDescription_other: "The annotations {{annotations}} are missing. You need to add the annotations to your {{entityKind}} if you want to enable this tool."
116
152
  }
117
153
  }
118
154
  });
@@ -1 +1 @@
1
- {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport const catalogReactTranslationRef = createTranslationRef({\n id: 'catalog-react',\n messages: {\n catalogFilter: {\n title: 'Filters',\n buttonTitle: 'Filters',\n },\n entityKindPicker: {\n title: 'Kind',\n errorMessage: 'Failed to load entity kinds',\n },\n entityLifecyclePicker: {\n title: 'Lifecycle',\n },\n entityNamespacePicker: {\n title: 'Namespace',\n },\n entityOwnerPicker: {\n title: 'Owner',\n },\n entityProcessingStatusPicker: {\n title: 'Processing Status',\n },\n entityTagPicker: {\n title: 'Tags',\n },\n entityPeekAheadPopover: {\n title: 'Drill into the entity to see all of the tags.',\n emailCardAction: {\n title: 'Email {{email}}',\n subTitle: 'mailto {{email}}',\n },\n entityCardActionsTitle: 'Show details',\n },\n entitySearchBar: {\n placeholder: 'Search',\n },\n entityTypePicker: {\n title: 'Type',\n errorMessage: 'Failed to load entity types',\n optionAllTitle: 'all',\n },\n favoriteEntity: {\n addToFavorites: 'Add to favorites',\n removeFromFavorites: 'Remove from favorites',\n },\n inspectEntityDialog: {\n title: 'Entity Inspector',\n closeButtonTitle: 'Close',\n ancestryPage: {\n title: 'Ancestry',\n },\n colocatedPage: {\n title: 'Colocated',\n description:\n 'These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).',\n alertNoLocation: 'Entity had no location information.',\n alertNoEntity: 'There were no other entities on this location.',\n },\n jsonPage: {\n title: 'Entity as JSON',\n description:\n 'This is the raw entity data as received from the catalog, on JSON form.',\n },\n overviewPage: {\n title: 'Overview',\n },\n yamlPage: {\n title: 'Entity as YAML',\n description:\n 'This is the raw entity data as received from the catalog, on YAML form.',\n },\n },\n unregisterEntityDialog: {\n title: 'Are you sure you want to unregister this entity?',\n cancelButtonTitle: 'Cancel',\n deleteButtonTitle: 'Delete Entity',\n deleteEntitySuccessMessage: 'Removed entity {{entityName}}',\n bootstrapState: {\n title:\n 'You cannot unregister this entity, since it originates from a protected Backstage configuration (location \"{{location}}\"). If you believe this is in error, please contact the {{appTitle}} integrator.',\n advancedDescription:\n 'You have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.',\n advancedOptions: 'Advanced Options',\n },\n onlyDeleteStateTitle:\n 'This entity does not seem to originate from a registered location. You therefore only have the option to delete it outright from the catalog.',\n unregisterState: {\n title: 'This action will unregister the following entities:',\n subTitle: 'Located at the following location:',\n description: 'To undo, just re-register the entity in {{appTitle}}.',\n unregisterButtonTitle: 'Unregister Location',\n advancedOptions: 'Advanced Options',\n advancedDescription:\n 'You also have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.',\n },\n errorStateTitle: 'Internal error: Unknown state',\n },\n userListPicker: {\n defaultOrgName: 'Company',\n personalFilter: {\n title: 'Personal',\n ownedLabel: 'Owned',\n starredLabel: 'Starred',\n },\n orgFilterAllLabel: 'All',\n },\n entityTableColumnTitle: {\n name: 'Name',\n system: 'System',\n owner: 'Owner',\n type: 'Type',\n lifecycle: 'Lifecycle',\n namespace: 'Namespace',\n description: 'Description',\n tags: 'Tags',\n targets: 'Targets',\n title: 'Title',\n label: 'Label',\n domain: 'Domain',\n },\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport const catalogReactTranslationRef = createTranslationRef({\n id: 'catalog-react',\n messages: {\n catalogFilter: {\n title: 'Filters',\n buttonTitle: 'Filters',\n },\n entityKindPicker: {\n title: 'Kind',\n errorMessage: 'Failed to load entity kinds',\n },\n entityLifecyclePicker: {\n title: 'Lifecycle',\n },\n entityNamespacePicker: {\n title: 'Namespace',\n },\n entityOwnerPicker: {\n title: 'Owner',\n },\n entityProcessingStatusPicker: {\n title: 'Processing Status',\n },\n entityTagPicker: {\n title: 'Tags',\n },\n entityPeekAheadPopover: {\n title: 'Drill into the entity to see all of the tags.',\n emailCardAction: {\n title: 'Email {{email}}',\n subTitle: 'mailto {{email}}',\n ariaLabel: 'Email',\n },\n entityCardActionsAriaLabel: 'Show',\n entityCardActionsTitle: 'Show details',\n },\n entitySearchBar: {\n placeholder: 'Search',\n },\n entityTypePicker: {\n title: 'Type',\n errorMessage: 'Failed to load entity types',\n optionAllTitle: 'all',\n },\n favoriteEntity: {\n addToFavorites: 'Add to favorites',\n removeFromFavorites: 'Remove from favorites',\n },\n inspectEntityDialog: {\n title: 'Entity Inspector',\n closeButtonTitle: 'Close',\n ancestryPage: {\n title: 'Ancestry',\n description:\n 'This is the ancestry of entities above the current one - as in, the chain(s) of entities down to the current one, where {{processorsLink}} child entities that ultimately led to the current one existing. Note that this is a completely different mechanism from relations.',\n processorsLink: 'processors emitted',\n },\n colocatedPage: {\n title: 'Colocated',\n description:\n 'These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).',\n alertNoLocation: 'Entity had no location information.',\n alertNoEntity: 'There were no other entities on this location.',\n locationHeader: 'At the same location',\n originHeader: 'At the same origin',\n },\n jsonPage: {\n title: 'Entity as JSON',\n description:\n 'This is the raw entity data as received from the catalog, on JSON form.',\n },\n overviewPage: {\n title: 'Overview',\n relation: {\n title: 'Relations',\n },\n status: {\n title: 'Status',\n },\n identity: {\n title: 'Identity',\n },\n metadata: {\n title: 'Metadata',\n },\n annotations: 'Annotations',\n labels: 'Labels',\n tags: 'Tags',\n },\n yamlPage: {\n title: 'Entity as YAML',\n description:\n 'This is the raw entity data as received from the catalog, on YAML form.',\n },\n tabNames: {\n overview: 'Overview',\n ancestry: 'Ancestry',\n colocated: 'Colocated',\n json: 'Raw JSON',\n yaml: 'Raw YAML',\n },\n tabsAriaLabel: 'Inspector options',\n },\n unregisterEntityDialog: {\n title: 'Are you sure you want to unregister this entity?',\n cancelButtonTitle: 'Cancel',\n deleteButtonTitle: 'Delete Entity',\n deleteEntitySuccessMessage: 'Removed entity {{entityName}}',\n bootstrapState: {\n title:\n 'You cannot unregister this entity, since it originates from a protected Backstage configuration (location \"{{location}}\"). If you believe this is in error, please contact the {{appTitle}} integrator.',\n advancedDescription:\n 'You have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.',\n advancedOptions: 'Advanced Options',\n },\n onlyDeleteStateTitle:\n 'This entity does not seem to originate from a registered location. You therefore only have the option to delete it outright from the catalog.',\n unregisterState: {\n title: 'This action will unregister the following entities:',\n subTitle: 'Located at the following location:',\n description: 'To undo, just re-register the entity in {{appTitle}}.',\n unregisterButtonTitle: 'Unregister Location',\n advancedOptions: 'Advanced Options',\n advancedDescription:\n 'You also have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.',\n },\n errorStateTitle: 'Internal error: Unknown state',\n },\n userListPicker: {\n defaultOrgName: 'Company',\n personalFilter: {\n title: 'Personal',\n ownedLabel: 'Owned',\n starredLabel: 'Starred',\n },\n orgFilterAllLabel: 'All',\n },\n entityTableColumnTitle: {\n name: 'Name',\n system: 'System',\n owner: 'Owner',\n type: 'Type',\n lifecycle: 'Lifecycle',\n namespace: 'Namespace',\n description: 'Description',\n tags: 'Tags',\n targets: 'Targets',\n title: 'Title',\n label: 'Label',\n domain: 'Domain',\n },\n missingAnnotationEmptyState: {\n title: 'Missing Annotation',\n readMore: 'Read more',\n annotationYaml:\n 'Add the annotation to your {{entityKind}} YAML as shown in the highlighted example below:',\n generateDescription_one:\n 'The annotation {{annotations}} is missing. You need to add the annotation to your {{entityKind}} if you want to enable this tool.',\n generateDescription_other:\n 'The annotations {{annotations}} are missing. You need to add the annotations to your {{entityKind}} if you want to enable this tool.',\n },\n },\n});\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-react",
3
- "version": "1.21.3-next.1",
3
+ "version": "1.21.3",
4
4
  "description": "A frontend library that helps other Backstage plugins interact with the catalog",
5
5
  "backstage": {
6
6
  "role": "web-library",
@@ -73,20 +73,20 @@
73
73
  "test": "backstage-cli package test"
74
74
  },
75
75
  "dependencies": {
76
- "@backstage/catalog-client": "1.12.1-next.0",
77
- "@backstage/catalog-model": "1.7.6-next.0",
78
- "@backstage/core-compat-api": "0.5.4-next.0",
79
- "@backstage/core-components": "0.18.3-next.1",
80
- "@backstage/core-plugin-api": "1.11.2-next.1",
81
- "@backstage/errors": "1.2.7",
82
- "@backstage/frontend-plugin-api": "0.12.2-next.1",
83
- "@backstage/frontend-test-utils": "0.4.1-next.0",
84
- "@backstage/integration-react": "1.2.12-next.0",
85
- "@backstage/plugin-catalog-common": "1.1.7-next.0",
86
- "@backstage/plugin-permission-common": "0.9.3-next.1",
87
- "@backstage/plugin-permission-react": "0.4.38-next.0",
88
- "@backstage/types": "1.2.2",
89
- "@backstage/version-bridge": "1.0.11",
76
+ "@backstage/catalog-client": "^1.12.1",
77
+ "@backstage/catalog-model": "^1.7.6",
78
+ "@backstage/core-compat-api": "^0.5.4",
79
+ "@backstage/core-components": "^0.18.3",
80
+ "@backstage/core-plugin-api": "^1.12.0",
81
+ "@backstage/errors": "^1.2.7",
82
+ "@backstage/frontend-plugin-api": "^0.13.0",
83
+ "@backstage/frontend-test-utils": "^0.4.1",
84
+ "@backstage/integration-react": "^1.2.12",
85
+ "@backstage/plugin-catalog-common": "^1.1.7",
86
+ "@backstage/plugin-permission-common": "^0.9.3",
87
+ "@backstage/plugin-permission-react": "^0.4.38",
88
+ "@backstage/types": "^1.2.2",
89
+ "@backstage/version-bridge": "^1.0.11",
90
90
  "@material-ui/core": "^4.12.2",
91
91
  "@material-ui/icons": "^4.9.1",
92
92
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -100,11 +100,11 @@
100
100
  "zen-observable": "^0.10.0"
101
101
  },
102
102
  "devDependencies": {
103
- "@backstage/cli": "0.34.5-next.1",
104
- "@backstage/core-app-api": "1.19.2-next.1",
105
- "@backstage/plugin-catalog-common": "1.1.7-next.0",
106
- "@backstage/plugin-scaffolder-common": "1.7.3-next.0",
107
- "@backstage/test-utils": "1.7.13-next.0",
103
+ "@backstage/cli": "^0.34.5",
104
+ "@backstage/core-app-api": "^1.19.2",
105
+ "@backstage/plugin-catalog-common": "^1.1.7",
106
+ "@backstage/plugin-scaffolder-common": "^1.7.3",
107
+ "@backstage/test-utils": "^1.7.13",
108
108
  "@testing-library/dom": "^10.0.0",
109
109
  "@testing-library/jest-dom": "^6.0.0",
110
110
  "@testing-library/react": "^16.0.0",