@backstage/plugin-home 0.8.0 → 0.8.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @backstage/plugin-home
2
2
 
3
+ ## 0.8.1-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/theme@0.6.1-next.0
9
+ - @backstage/catalog-client@1.8.0-next.0
10
+ - @backstage/catalog-model@1.7.0
11
+ - @backstage/config@1.2.0
12
+ - @backstage/core-app-api@1.15.1
13
+ - @backstage/core-compat-api@0.3.2-next.1
14
+ - @backstage/core-components@0.16.0-next.1
15
+ - @backstage/core-plugin-api@1.10.0
16
+ - @backstage/frontend-plugin-api@0.9.1-next.1
17
+ - @backstage/plugin-catalog-react@1.14.1-next.1
18
+ - @backstage/plugin-home-react@0.1.19-next.1
19
+
20
+ ## 0.8.1-next.0
21
+
22
+ ### Patch Changes
23
+
24
+ - 8b1b2cf: Improve Starred Entities UI to reduce whitespace and provide more context on the entities:
25
+
26
+ - Use the Entity Presentation API (via `<EntityDisplayName>`) to display the entity's name
27
+ - Component's `kind` and `spec.type` are displayed as a secondary text
28
+ - List items are condensed to reduce unnecessary spacing
29
+
30
+ - Updated dependencies
31
+ - @backstage/core-components@0.16.0-next.0
32
+ - @backstage/catalog-client@1.8.0-next.0
33
+ - @backstage/catalog-model@1.7.0
34
+ - @backstage/config@1.2.0
35
+ - @backstage/core-app-api@1.15.1
36
+ - @backstage/core-compat-api@0.3.2-next.0
37
+ - @backstage/core-plugin-api@1.10.0
38
+ - @backstage/frontend-plugin-api@0.9.1-next.0
39
+ - @backstage/theme@0.6.0
40
+ - @backstage/plugin-catalog-react@1.14.1-next.0
41
+ - @backstage/plugin-home-react@0.1.19-next.0
42
+
3
43
  ## 0.8.0
4
44
 
5
45
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home__alpha",
3
- "version": "0.8.0",
3
+ "version": "0.8.1-next.1",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
@@ -1,5 +1,4 @@
1
- import { stringifyEntityRef } from '@backstage/catalog-model';
2
- import { entityRouteRef, entityRouteParams } from '@backstage/plugin-catalog-react';
1
+ import { entityRouteRef, entityRouteParams, EntityDisplayName } from '@backstage/plugin-catalog-react';
3
2
  import ListItem from '@material-ui/core/ListItem';
4
3
  import ListItemIcon from '@material-ui/core/ListItemIcon';
5
4
  import ListItemText from '@material-ui/core/ListItemText';
@@ -7,21 +6,70 @@ import React from 'react';
7
6
  import { Link } from 'react-router-dom';
8
7
  import { useRouteRef } from '@backstage/core-plugin-api';
9
8
  import { FavoriteToggle } from '@backstage/core-components';
9
+ import { makeStyles } from '@material-ui/core/styles';
10
10
 
11
+ const useStyles = makeStyles((theme) => ({
12
+ listItem: {
13
+ paddingBottom: theme.spacing(0),
14
+ paddingTop: theme.spacing(0)
15
+ },
16
+ secondary: {
17
+ textTransform: "uppercase"
18
+ }
19
+ }));
11
20
  const StarredEntityListItem = ({
12
21
  entity,
13
- onToggleStarredEntity
22
+ onToggleStarredEntity,
23
+ showKind
14
24
  }) => {
25
+ const classes = useStyles();
15
26
  const catalogEntityRoute = useRouteRef(entityRouteRef);
16
- return /* @__PURE__ */ React.createElement(ListItem, { key: stringifyEntityRef(entity) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(
17
- FavoriteToggle,
18
- {
19
- id: `remove-favorite-${entity.metadata.uid}`,
20
- title: "Remove entity from favorites",
21
- isFavorite: true,
22
- onToggle: () => onToggleStarredEntity(entity)
27
+ let secondaryText = "";
28
+ if (showKind) {
29
+ secondaryText += entity.kind.toLocaleLowerCase("en-US");
30
+ }
31
+ if (entity.spec && "type" in entity.spec) {
32
+ if (showKind) {
33
+ secondaryText += " \u2014 ";
23
34
  }
24
- )), /* @__PURE__ */ React.createElement(Link, { to: catalogEntityRoute(entityRouteParams(entity)) }, /* @__PURE__ */ React.createElement(ListItemText, { primary: entity.metadata.title ?? entity.metadata.name })));
35
+ secondaryText += entity.spec.type.toLocaleLowerCase(
36
+ "en-US"
37
+ );
38
+ }
39
+ return /* @__PURE__ */ React.createElement(
40
+ ListItem,
41
+ {
42
+ dense: true,
43
+ className: classes.listItem,
44
+ component: Link,
45
+ button: true,
46
+ to: catalogEntityRoute(entityRouteParams(entity))
47
+ },
48
+ /* @__PURE__ */ React.createElement(
49
+ ListItemIcon,
50
+ {
51
+ onClick: (e) => {
52
+ e.preventDefault();
53
+ }
54
+ },
55
+ /* @__PURE__ */ React.createElement(
56
+ FavoriteToggle,
57
+ {
58
+ id: `remove-favorite-${entity.metadata.uid}`,
59
+ title: "Remove entity from favorites",
60
+ isFavorite: true,
61
+ onToggle: () => onToggleStarredEntity(entity)
62
+ }
63
+ )
64
+ ),
65
+ /* @__PURE__ */ React.createElement(
66
+ ListItemText,
67
+ {
68
+ primary: /* @__PURE__ */ React.createElement(EntityDisplayName, { hideIcon: true, entityRef: entity }),
69
+ secondary: secondaryText
70
+ }
71
+ )
72
+ );
25
73
  };
26
74
 
27
75
  export { StarredEntityListItem };
@@ -1 +1 @@
1
- {"version":3,"file":"StarredEntityListItem.esm.js","sources":["../../../src/components/StarredEntityListItem/StarredEntityListItem.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { entityRouteParams } from '@backstage/plugin-catalog-react';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { FavoriteToggle } from '@backstage/core-components';\n\ntype EntityListItemProps = {\n entity: Entity;\n onToggleStarredEntity: (entity: Entity) => void;\n};\n\nexport const StarredEntityListItem = ({\n entity,\n onToggleStarredEntity,\n}: EntityListItemProps) => {\n const catalogEntityRoute = useRouteRef(entityRouteRef);\n\n return (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemIcon>\n <FavoriteToggle\n id={`remove-favorite-${entity.metadata.uid}`}\n title=\"Remove entity from favorites\"\n isFavorite\n onToggle={() => onToggleStarredEntity(entity)}\n />\n </ListItemIcon>\n <Link to={catalogEntityRoute(entityRouteParams(entity))}>\n <ListItemText primary={entity.metadata.title ?? entity.metadata.name} />\n </Link>\n </ListItem>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA+BO,MAAM,wBAAwB,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,qBAAA;AACF,CAA2B,KAAA;AACzB,EAAM,MAAA,kBAAA,GAAqB,YAAY,cAAc,CAAA,CAAA;AAErD,EAAA,2CACG,QAAS,EAAA,EAAA,GAAA,EAAK,mBAAmB,MAAM,CAAA,EAAA,sCACrC,YACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA,CAAA,gBAAA,EAAmB,MAAO,CAAA,QAAA,CAAS,GAAG,CAAA,CAAA;AAAA,MAC1C,KAAM,EAAA,8BAAA;AAAA,MACN,UAAU,EAAA,IAAA;AAAA,MACV,QAAA,EAAU,MAAM,qBAAA,CAAsB,MAAM,CAAA;AAAA,KAAA;AAAA,GAEhD,mBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,kBAAmB,CAAA,iBAAA,CAAkB,MAAM,CAAC,CAAA,EAAA,sCACnD,YAAa,EAAA,EAAA,OAAA,EAAS,OAAO,QAAS,CAAA,KAAA,IAAS,OAAO,QAAS,CAAA,IAAA,EAAM,CACxE,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"StarredEntityListItem.esm.js","sources":["../../../src/components/StarredEntityListItem/StarredEntityListItem.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport {\n EntityDisplayName,\n entityRouteParams,\n} from '@backstage/plugin-catalog-react';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { FavoriteToggle } from '@backstage/core-components';\nimport { makeStyles } from '@material-ui/core/styles';\n\ntype EntityListItemProps = {\n entity: Entity;\n onToggleStarredEntity: (entity: Entity) => void;\n showKind?: boolean;\n};\n\nconst useStyles = makeStyles(theme => ({\n listItem: {\n paddingBottom: theme.spacing(0),\n paddingTop: theme.spacing(0),\n },\n secondary: {\n textTransform: 'uppercase',\n },\n}));\n\nexport const StarredEntityListItem = ({\n entity,\n onToggleStarredEntity,\n showKind,\n}: EntityListItemProps) => {\n const classes = useStyles();\n const catalogEntityRoute = useRouteRef(entityRouteRef);\n\n let secondaryText = '';\n if (showKind) {\n secondaryText += entity.kind.toLocaleLowerCase('en-US');\n }\n if (entity.spec && 'type' in entity.spec) {\n if (showKind) {\n secondaryText += ' — ';\n }\n secondaryText += (entity.spec as { type: string }).type.toLocaleLowerCase(\n 'en-US',\n );\n }\n\n return (\n <ListItem\n dense\n className={classes.listItem}\n component={Link}\n button\n to={catalogEntityRoute(entityRouteParams(entity))}\n >\n <ListItemIcon\n // Prevent following the link when clicking on the icon\n onClick={e => {\n e.preventDefault();\n }}\n >\n <FavoriteToggle\n id={`remove-favorite-${entity.metadata.uid}`}\n title=\"Remove entity from favorites\"\n isFavorite\n onToggle={() => onToggleStarredEntity(entity)}\n />\n </ListItemIcon>\n <ListItemText\n primary={<EntityDisplayName hideIcon entityRef={entity} />}\n secondary={secondaryText}\n />\n </ListItem>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAoCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,QAAU,EAAA;AAAA,IACR,aAAA,EAAe,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC9B,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC7B;AAAA,EACA,SAAW,EAAA;AAAA,IACT,aAAe,EAAA,WAAA;AAAA,GACjB;AACF,CAAE,CAAA,CAAA,CAAA;AAEK,MAAM,wBAAwB,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,qBAAA;AAAA,EACA,QAAA;AACF,CAA2B,KAAA;AACzB,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,kBAAA,GAAqB,YAAY,cAAc,CAAA,CAAA;AAErD,EAAA,IAAI,aAAgB,GAAA,EAAA,CAAA;AACpB,EAAA,IAAI,QAAU,EAAA;AACZ,IAAiB,aAAA,IAAA,MAAA,CAAO,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AAAA,GACxD;AACA,EAAA,IAAI,MAAO,CAAA,IAAA,IAAQ,MAAU,IAAA,MAAA,CAAO,IAAM,EAAA;AACxC,IAAA,IAAI,QAAU,EAAA;AACZ,MAAiB,aAAA,IAAA,UAAA,CAAA;AAAA,KACnB;AACA,IAAkB,aAAA,IAAA,MAAA,CAAO,KAA0B,IAAK,CAAA,iBAAA;AAAA,MACtD,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAK,EAAA,IAAA;AAAA,MACL,WAAW,OAAQ,CAAA,QAAA;AAAA,MACnB,SAAW,EAAA,IAAA;AAAA,MACX,MAAM,EAAA,IAAA;AAAA,MACN,EAAI,EAAA,kBAAA,CAAmB,iBAAkB,CAAA,MAAM,CAAC,CAAA;AAAA,KAAA;AAAA,oBAEhD,KAAA,CAAA,aAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QAEC,SAAS,CAAK,CAAA,KAAA;AACZ,UAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AAAA,SACnB;AAAA,OAAA;AAAA,sBAEA,KAAA,CAAA,aAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,EAAI,EAAA,CAAA,gBAAA,EAAmB,MAAO,CAAA,QAAA,CAAS,GAAG,CAAA,CAAA;AAAA,UAC1C,KAAM,EAAA,8BAAA;AAAA,UACN,UAAU,EAAA,IAAA;AAAA,UACV,QAAA,EAAU,MAAM,qBAAA,CAAsB,MAAM,CAAA;AAAA,SAAA;AAAA,OAC9C;AAAA,KACF;AAAA,oBACA,KAAA,CAAA,aAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,yBAAU,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,QAAQ,EAAA,IAAA,EAAC,WAAW,MAAQ,EAAA,CAAA;AAAA,QACxD,SAAW,EAAA,aAAA;AAAA,OAAA;AAAA,KACb;AAAA,GACF,CAAA;AAEJ;;;;"}
@@ -9,11 +9,22 @@ import Tab from '@material-ui/core/Tab';
9
9
  import React from 'react';
10
10
  import useAsync from 'react-use/esm/useAsync';
11
11
  import { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem.esm.js';
12
+ import { makeStyles } from '@material-ui/core/styles';
12
13
 
14
+ const useStyles = makeStyles((theme) => ({
15
+ tabs: {
16
+ marginBottom: theme.spacing(1)
17
+ },
18
+ list: {
19
+ paddingTop: 0,
20
+ paddingBottom: 0
21
+ }
22
+ }));
13
23
  const Content = ({
14
24
  noStarredEntitiesMessage,
15
25
  groupByKind
16
26
  }) => {
27
+ const classes = useStyles();
17
28
  const catalogApi = useApi(catalogApiRef);
18
29
  const { starredEntities, toggleStarredEntity } = useStarredEntities();
19
30
  const [activeTab, setActiveTab] = React.useState(0);
@@ -23,12 +34,7 @@ const Content = ({
23
34
  }
24
35
  return (await catalogApi.getEntitiesByRefs({
25
36
  entityRefs: [...starredEntities],
26
- fields: [
27
- "kind",
28
- "metadata.namespace",
29
- "metadata.name",
30
- "metadata.title"
31
- ]
37
+ fields: ["kind", "metadata.namespace", "metadata.name", "spec.type"]
32
38
  })).items.filter((e) => !!e);
33
39
  }, [catalogApi, starredEntities]);
34
40
  if (starredEntities.size === 0)
@@ -45,7 +51,7 @@ const Content = ({
45
51
  groupedEntities[kind].push(entity);
46
52
  });
47
53
  const groupByKindEntries = Object.entries(groupedEntities);
48
- return entities.error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, { error: entities.error }) : /* @__PURE__ */ React.createElement("div", null, !groupByKind && /* @__PURE__ */ React.createElement(List, null, entities.value?.sort(
54
+ return entities.error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, { error: entities.error }) : /* @__PURE__ */ React.createElement("div", null, !groupByKind && /* @__PURE__ */ React.createElement(List, { className: classes.list }, entities.value?.sort(
49
55
  (a, b) => (a.metadata.title ?? a.metadata.name).localeCompare(
50
56
  b.metadata.title ?? b.metadata.name
51
57
  )
@@ -54,11 +60,13 @@ const Content = ({
54
60
  {
55
61
  key: stringifyEntityRef(entity),
56
62
  entity,
57
- onToggleStarredEntity: toggleStarredEntity
63
+ onToggleStarredEntity: toggleStarredEntity,
64
+ showKind: true
58
65
  }
59
66
  ))), groupByKind && /* @__PURE__ */ React.createElement(
60
67
  Tabs,
61
68
  {
69
+ className: classes.tabs,
62
70
  value: activeTab,
63
71
  onChange: (_, newValue) => setActiveTab(newValue),
64
72
  variant: "scrollable",
@@ -66,7 +74,7 @@ const Content = ({
66
74
  "aria-label": "entity-tabs"
67
75
  },
68
76
  groupByKindEntries.map(([kind]) => /* @__PURE__ */ React.createElement(Tab, { key: kind, label: kind }))
69
- ), groupByKind && groupByKindEntries.map(([kind, entitiesByKind], index) => /* @__PURE__ */ React.createElement("div", { key: kind, hidden: groupByKind && activeTab !== index }, /* @__PURE__ */ React.createElement(List, null, entitiesByKind?.sort(
77
+ ), groupByKind && groupByKindEntries.map(([kind, entitiesByKind], index) => /* @__PURE__ */ React.createElement("div", { key: kind, hidden: groupByKind && activeTab !== index }, /* @__PURE__ */ React.createElement(List, { className: classes.list }, entitiesByKind?.sort(
70
78
  (a, b) => (a.metadata.title ?? a.metadata.name).localeCompare(
71
79
  b.metadata.title ?? b.metadata.name
72
80
  )
@@ -75,7 +83,8 @@ const Content = ({
75
83
  {
76
84
  key: stringifyEntityRef(entity),
77
85
  entity,
78
- onToggleStarredEntity: toggleStarredEntity
86
+ onToggleStarredEntity: toggleStarredEntity,
87
+ showKind: false
79
88
  }
80
89
  ))))));
81
90
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/StarredEntities/Content.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 catalogApiRef,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport List from '@material-ui/core/List';\nimport Typography from '@material-ui/core/Typography';\nimport Tabs from '@material-ui/core/Tabs';\nimport Tab from '@material-ui/core/Tab';\nimport React from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem';\n\n/**\n * A component to display a list of starred entities for the user.\n *\n * @public\n */\n\nexport type StarredEntitiesProps = {\n noStarredEntitiesMessage?: React.ReactNode | undefined;\n groupByKind?: boolean;\n};\n\nexport const Content = ({\n noStarredEntitiesMessage,\n groupByKind,\n}: StarredEntitiesProps) => {\n const catalogApi = useApi(catalogApiRef);\n const { starredEntities, toggleStarredEntity } = useStarredEntities();\n const [activeTab, setActiveTab] = React.useState(0);\n\n // Grab starred entities from catalog to ensure they still exist and also retrieve display titles\n const entities = useAsync(async () => {\n if (!starredEntities.size) {\n return [];\n }\n\n return (\n await catalogApi.getEntitiesByRefs({\n entityRefs: [...starredEntities],\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n ],\n })\n ).items.filter((e): e is Entity => !!e);\n }, [catalogApi, starredEntities]);\n\n if (starredEntities.size === 0)\n return (\n <Typography variant=\"body1\">\n {noStarredEntitiesMessage ||\n 'Click the star beside an entity name to add it to this list!'}\n </Typography>\n );\n\n if (entities.loading) {\n return <Progress />;\n }\n\n const groupedEntities: { [kind: string]: Entity[] } = {};\n entities.value?.forEach(entity => {\n const kind = entity.kind;\n if (!groupedEntities[kind]) {\n groupedEntities[kind] = [];\n }\n groupedEntities[kind].push(entity);\n });\n\n const groupByKindEntries = Object.entries(groupedEntities);\n\n return entities.error ? (\n <ResponseErrorPanel error={entities.error} />\n ) : (\n <div>\n {!groupByKind && (\n <List>\n {entities.value\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n )}\n\n {groupByKind && (\n <Tabs\n value={activeTab}\n onChange={(_, newValue) => setActiveTab(newValue)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"entity-tabs\"\n >\n {groupByKindEntries.map(([kind]) => (\n <Tab key={kind} label={kind} />\n ))}\n </Tabs>\n )}\n\n {groupByKind &&\n groupByKindEntries.map(([kind, entitiesByKind], index) => (\n <div key={kind} hidden={groupByKind && activeTab !== index}>\n <List>\n {entitiesByKind\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n </div>\n ))}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/StarredEntities/Content.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 catalogApiRef,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport List from '@material-ui/core/List';\nimport Typography from '@material-ui/core/Typography';\nimport Tabs from '@material-ui/core/Tabs';\nimport Tab from '@material-ui/core/Tab';\nimport React from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem';\nimport { makeStyles } from '@material-ui/core/styles';\n\nconst useStyles = makeStyles(theme => ({\n tabs: {\n marginBottom: theme.spacing(1),\n },\n list: {\n paddingTop: 0,\n paddingBottom: 0,\n },\n}));\n\n/**\n * Props for the StarredEntities component\n *\n * @public\n */\nexport type StarredEntitiesProps = {\n noStarredEntitiesMessage?: React.ReactNode | undefined;\n groupByKind?: boolean;\n};\n\n/**\n * A component to display a list of starred entities for the user.\n *\n * @public\n */\nexport const Content = ({\n noStarredEntitiesMessage,\n groupByKind,\n}: StarredEntitiesProps) => {\n const classes = useStyles();\n const catalogApi = useApi(catalogApiRef);\n const { starredEntities, toggleStarredEntity } = useStarredEntities();\n const [activeTab, setActiveTab] = React.useState(0);\n\n // Grab starred entities from catalog to ensure they still exist and also retrieve display titles\n const entities = useAsync(async () => {\n if (!starredEntities.size) {\n return [];\n }\n\n return (\n await catalogApi.getEntitiesByRefs({\n entityRefs: [...starredEntities],\n fields: ['kind', 'metadata.namespace', 'metadata.name', 'spec.type'],\n })\n ).items.filter((e): e is Entity => !!e);\n }, [catalogApi, starredEntities]);\n\n if (starredEntities.size === 0)\n return (\n <Typography variant=\"body1\">\n {noStarredEntitiesMessage ||\n 'Click the star beside an entity name to add it to this list!'}\n </Typography>\n );\n\n if (entities.loading) {\n return <Progress />;\n }\n\n const groupedEntities: { [kind: string]: Entity[] } = {};\n entities.value?.forEach(entity => {\n const kind = entity.kind;\n if (!groupedEntities[kind]) {\n groupedEntities[kind] = [];\n }\n groupedEntities[kind].push(entity);\n });\n\n const groupByKindEntries = Object.entries(groupedEntities);\n\n return entities.error ? (\n <ResponseErrorPanel error={entities.error} />\n ) : (\n <div>\n {!groupByKind && (\n <List className={classes.list}>\n {entities.value\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n showKind\n />\n ))}\n </List>\n )}\n\n {groupByKind && (\n <Tabs\n className={classes.tabs}\n value={activeTab}\n onChange={(_, newValue) => setActiveTab(newValue)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"entity-tabs\"\n >\n {groupByKindEntries.map(([kind]) => (\n <Tab key={kind} label={kind} />\n ))}\n </Tabs>\n )}\n\n {groupByKind &&\n groupByKindEntries.map(([kind, entitiesByKind], index) => (\n <div key={kind} hidden={groupByKind && activeTab !== index}>\n <List className={classes.list}>\n {entitiesByKind\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n showKind={false}\n />\n ))}\n </List>\n </div>\n ))}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AAgCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC/B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,UAAY,EAAA,CAAA;AAAA,IACZ,aAAe,EAAA,CAAA;AAAA,GACjB;AACF,CAAE,CAAA,CAAA,CAAA;AAiBK,MAAM,UAAU,CAAC;AAAA,EACtB,wBAAA;AAAA,EACA,WAAA;AACF,CAA4B,KAAA;AAC1B,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA,CAAA;AACvC,EAAA,MAAM,EAAE,eAAA,EAAiB,mBAAoB,EAAA,GAAI,kBAAmB,EAAA,CAAA;AACpE,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,CAAI,GAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AAGlD,EAAM,MAAA,QAAA,GAAW,SAAS,YAAY;AACpC,IAAI,IAAA,CAAC,gBAAgB,IAAM,EAAA;AACzB,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAEA,IACE,OAAA,CAAA,MAAM,WAAW,iBAAkB,CAAA;AAAA,MACjC,UAAA,EAAY,CAAC,GAAG,eAAe,CAAA;AAAA,MAC/B,MAAQ,EAAA,CAAC,MAAQ,EAAA,oBAAA,EAAsB,iBAAiB,WAAW,CAAA;AAAA,KACpE,GACD,KAAM,CAAA,MAAA,CAAO,CAAC,CAAmB,KAAA,CAAC,CAAC,CAAC,CAAA,CAAA;AAAA,GACrC,EAAA,CAAC,UAAY,EAAA,eAAe,CAAC,CAAA,CAAA;AAEhC,EAAA,IAAI,gBAAgB,IAAS,KAAA,CAAA;AAC3B,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,OAAA,EAAA,EACjB,4BACC,8DACJ,CAAA,CAAA;AAGJ,EAAA,IAAI,SAAS,OAAS,EAAA;AACpB,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,GACnB;AAEA,EAAA,MAAM,kBAAgD,EAAC,CAAA;AACvD,EAAS,QAAA,CAAA,KAAA,EAAO,QAAQ,CAAU,MAAA,KAAA;AAChC,IAAA,MAAM,OAAO,MAAO,CAAA,IAAA,CAAA;AACpB,IAAI,IAAA,CAAC,eAAgB,CAAA,IAAI,CAAG,EAAA;AAC1B,MAAgB,eAAA,CAAA,IAAI,IAAI,EAAC,CAAA;AAAA,KAC3B;AACA,IAAgB,eAAA,CAAA,IAAI,CAAE,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,GAClC,CAAA,CAAA;AAED,EAAM,MAAA,kBAAA,GAAqB,MAAO,CAAA,OAAA,CAAQ,eAAe,CAAA,CAAA;AAEzD,EAAA,OAAO,SAAS,KACd,mBAAA,KAAA,CAAA,aAAA,CAAC,sBAAmB,KAAO,EAAA,QAAA,CAAS,OAAO,CAE3C,mBAAA,KAAA,CAAA,aAAA,CAAC,KACE,EAAA,IAAA,EAAA,CAAC,+BACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,WAAW,OAAQ,CAAA,IAAA,EAAA,EACtB,SAAS,KACN,EAAA,IAAA;AAAA,IAAK,CAAC,GAAG,CACR,KAAA,CAAA,CAAA,CAAE,SAAS,KAAS,IAAA,CAAA,CAAE,SAAS,IAAM,EAAA,aAAA;AAAA,MACpC,CAAE,CAAA,QAAA,CAAS,KAAS,IAAA,CAAA,CAAE,QAAS,CAAA,IAAA;AAAA,KACjC;AAAA,GACF,CACC,IAAI,CACH,MAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,mBAAmB,MAAM,CAAA;AAAA,MAC9B,MAAA;AAAA,MACA,qBAAuB,EAAA,mBAAA;AAAA,MACvB,QAAQ,EAAA,IAAA;AAAA,KAAA;AAAA,GAEX,CACL,CAAA,EAGD,WACC,oBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,IAAA;AAAA,MACnB,KAAO,EAAA,SAAA;AAAA,MACP,QAAU,EAAA,CAAC,CAAG,EAAA,QAAA,KAAa,aAAa,QAAQ,CAAA;AAAA,MAChD,OAAQ,EAAA,YAAA;AAAA,MACR,aAAc,EAAA,MAAA;AAAA,MACd,YAAW,EAAA,aAAA;AAAA,KAAA;AAAA,IAEV,kBAAmB,CAAA,GAAA,CAAI,CAAC,CAAC,IAAI,CAAA,qBAC3B,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,GAAK,EAAA,IAAA,EAAM,KAAO,EAAA,IAAA,EAAM,CAC9B,CAAA;AAAA,GACH,EAGD,eACC,kBAAmB,CAAA,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,cAAc,CAAA,EAAG,KAC9C,qBAAA,KAAA,CAAA,aAAA,CAAC,SAAI,GAAK,EAAA,IAAA,EAAM,MAAQ,EAAA,WAAA,IAAe,SAAc,KAAA,KAAA,EAAA,sCAClD,IAAK,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,IAAA,EAAA,EACtB,cACG,EAAA,IAAA;AAAA,IAAK,CAAC,GAAG,CACR,KAAA,CAAA,CAAA,CAAE,SAAS,KAAS,IAAA,CAAA,CAAE,SAAS,IAAM,EAAA,aAAA;AAAA,MACpC,CAAE,CAAA,QAAA,CAAS,KAAS,IAAA,CAAA,CAAE,QAAS,CAAA,IAAA;AAAA,KACjC;AAAA,GACF,CACC,IAAI,CACH,MAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,mBAAmB,MAAM,CAAA;AAAA,MAC9B,MAAA;AAAA,MACA,qBAAuB,EAAA,mBAAA;AAAA,MACvB,QAAU,EAAA,KAAA;AAAA,KAAA;AAAA,GAEb,CACL,CACF,CACD,CACL,CAAA,CAAA;AAEJ;;;;"}
package/dist/index.d.ts CHANGED
@@ -218,7 +218,7 @@ type FeaturedDocsCardProps = {
218
218
  };
219
219
 
220
220
  /**
221
- * A component to display a list of starred entities for the user.
221
+ * Props for the StarredEntities component
222
222
  *
223
223
  * @public
224
224
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
- "version": "0.8.0",
3
+ "version": "0.8.1-next.1",
4
4
  "description": "A Backstage plugin that helps you build a home page",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -56,17 +56,17 @@
56
56
  "test": "backstage-cli package test"
57
57
  },
58
58
  "dependencies": {
59
- "@backstage/catalog-client": "^1.7.1",
60
- "@backstage/catalog-model": "^1.7.0",
61
- "@backstage/config": "^1.2.0",
62
- "@backstage/core-app-api": "^1.15.1",
63
- "@backstage/core-compat-api": "^0.3.1",
64
- "@backstage/core-components": "^0.15.1",
65
- "@backstage/core-plugin-api": "^1.10.0",
66
- "@backstage/frontend-plugin-api": "^0.9.0",
67
- "@backstage/plugin-catalog-react": "^1.14.0",
68
- "@backstage/plugin-home-react": "^0.1.18",
69
- "@backstage/theme": "^0.6.0",
59
+ "@backstage/catalog-client": "1.8.0-next.0",
60
+ "@backstage/catalog-model": "1.7.0",
61
+ "@backstage/config": "1.2.0",
62
+ "@backstage/core-app-api": "1.15.1",
63
+ "@backstage/core-compat-api": "0.3.2-next.1",
64
+ "@backstage/core-components": "0.16.0-next.1",
65
+ "@backstage/core-plugin-api": "1.10.0",
66
+ "@backstage/frontend-plugin-api": "0.9.1-next.1",
67
+ "@backstage/plugin-catalog-react": "1.14.1-next.1",
68
+ "@backstage/plugin-home-react": "0.1.19-next.1",
69
+ "@backstage/theme": "0.6.1-next.0",
70
70
  "@material-ui/core": "^4.12.2",
71
71
  "@material-ui/icons": "^4.9.1",
72
72
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -82,9 +82,9 @@
82
82
  "zod": "^3.22.4"
83
83
  },
84
84
  "devDependencies": {
85
- "@backstage/cli": "^0.28.0",
86
- "@backstage/dev-utils": "^1.1.2",
87
- "@backstage/test-utils": "^1.7.0",
85
+ "@backstage/cli": "0.29.0-next.1",
86
+ "@backstage/dev-utils": "1.1.3-next.1",
87
+ "@backstage/test-utils": "1.7.1-next.0",
88
88
  "@testing-library/dom": "^10.0.0",
89
89
  "@testing-library/jest-dom": "^6.0.0",
90
90
  "@testing-library/react": "^16.0.0",