From 5a317f59c025cb6522fc277e8377bac799a9f162 Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Sat, 23 Sep 2023 11:09:29 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8feat(homePlugin):=20changed=20list?= =?UTF-8?q?=20view=20of=20starredEntities=20to=20facilitate=20distinguish?= =?UTF-8?q?=20entities=20with=20same=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Bergas --- .changeset/healthy-feet-kick.md | 5 ++ .../StarredEntities/Content.tsx | 80 ++++++++++++------- 2 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 .changeset/healthy-feet-kick.md diff --git a/.changeset/healthy-feet-kick.md b/.changeset/healthy-feet-kick.md new file mode 100644 index 0000000000..732f2164c3 --- /dev/null +++ b/.changeset/healthy-feet-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': minor +--- + +Added view of entities grouped by kind to make it easier to distinguish entities with different kind but same name diff --git a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx index 4654a7f860..4818aad809 100644 --- a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx +++ b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx @@ -20,7 +20,11 @@ import { entityRouteParams, entityRouteRef, } from '@backstage/plugin-catalog-react'; -import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; +import { + Entity, + parseEntityRef, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { useApi, useRouteRef } from '@backstage/core-plugin-api'; import { Link, Progress, ResponseErrorPanel } from '@backstage/core-components'; import { @@ -87,37 +91,55 @@ export const Content = (props: { if (entities.loading) { return ; } + const groupedEntities: { [kind: string]: Entity[] } = {}; + + entities.value?.forEach(entity => { + const kind = entity.kind; + if (!groupedEntities[kind]) { + groupedEntities[kind] = []; + } + groupedEntities[kind].push(entity); + }); + + const entityEntries = Object.entries(groupedEntities); return entities.error ? ( ) : ( - - {entities.value - ?.sort((a, b) => - (a.metadata.title ?? a.metadata.name).localeCompare( - b.metadata.title ?? b.metadata.name, - ), - ) - .map(entity => ( - - - - - - - toggleStarredEntity(entity)} - > - - - - - - ))} - +
+ {entityEntries.map(([kind, entitiesByKind]) => ( +
+ {kind} {/* Kind as Title */} + + {entitiesByKind + ?.sort((a, b) => + (a.metadata.title ?? a.metadata.name).localeCompare( + b.metadata.title ?? b.metadata.name, + ), + ) + .map(entity => ( + + + + + + + toggleStarredEntity(entity)} + > + + + + + + ))} + +
+ ))} +
); }; From e0e10b272be4a870560556bf3d641ab5ee0f4b0b Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Sat, 11 Nov 2023 12:21:36 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20feat(HomePlugin):=20split=20Sta?= =?UTF-8?q?rredEntities=20groupByKind=20in=20tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Bergas --- .../StarredEntityListItem.tsx | 60 ++++++++++++ .../StarredEntities/Content.tsx | 96 +++++++++++-------- plugins/home/src/plugin.ts | 3 +- 3 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx diff --git a/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx new file mode 100644 index 0000000000..2a8960e469 --- /dev/null +++ b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx @@ -0,0 +1,60 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { entityRouteParams } from '@backstage/plugin-catalog-react'; +import { + ListItem, + ListItemIcon, + Tooltip, + IconButton, + ListItemText, +} from '@material-ui/core'; +import React from 'react'; +import { Link } from 'react-router-dom'; +import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import StarIcon from '@material-ui/icons/Star'; + +type EntityListItemProps = { + entity: Entity; + onToggleStarredEntity: (entity: Entity) => void; +}; + +export const StarredEntityListItem = ({ + entity, + onToggleStarredEntity, +}: EntityListItemProps) => { + const catalogEntityRoute = useRouteRef(entityRouteRef); + + return ( + + + + onToggleStarredEntity(entity)} + > + + + + + + + + + ); +}; diff --git a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx index 4818aad809..e98065b392 100644 --- a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx +++ b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx @@ -17,28 +17,18 @@ import { catalogApiRef, useStarredEntities, - entityRouteParams, - entityRouteRef, } from '@backstage/plugin-catalog-react'; import { Entity, parseEntityRef, stringifyEntityRef, } from '@backstage/catalog-model'; -import { useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { Link, Progress, ResponseErrorPanel } from '@backstage/core-components'; -import { - List, - ListItem, - ListItemSecondaryAction, - IconButton, - ListItemText, - Tooltip, - Typography, -} from '@material-ui/core'; -import StarIcon from '@material-ui/icons/Star'; +import { useApi } from '@backstage/core-plugin-api'; +import { Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { List, Typography, Tabs, Tab } from '@material-ui/core'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; +import { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem'; /** * A component to display a list of starred entities for the user. @@ -46,12 +36,18 @@ import useAsync from 'react-use/lib/useAsync'; * @public */ -export const Content = (props: { +export type StarredEntitiesProps = { noStarredEntitiesMessage?: React.ReactNode | undefined; -}) => { + groupByKind?: boolean; +}; + +export const Content = ({ + noStarredEntitiesMessage, + groupByKind, +}: StarredEntitiesProps) => { const catalogApi = useApi(catalogApiRef); - const catalogEntityRoute = useRouteRef(entityRouteRef); const { starredEntities, toggleStarredEntity } = useStarredEntities(); + const [activeTab, setActiveTab] = React.useState(0); // Grab starred entities from catalog to ensure they still exist and also retrieve display titles const entities = useAsync(async () => { @@ -83,7 +79,7 @@ export const Content = (props: { if (starredEntities.size === 0) return ( - {props.noStarredEntitiesMessage || + {noStarredEntitiesMessage || 'Click the star beside an entity name to add it to this list!'} ); @@ -91,8 +87,8 @@ export const Content = (props: { if (entities.loading) { return ; } - const groupedEntities: { [kind: string]: Entity[] } = {}; + const groupedEntities: { [kind: string]: Entity[] } = {}; entities.value?.forEach(entity => { const kind = entity.kind; if (!groupedEntities[kind]) { @@ -101,15 +97,46 @@ export const Content = (props: { groupedEntities[kind].push(entity); }); - const entityEntries = Object.entries(groupedEntities); + const groupByKindEntries = Object.entries(groupedEntities); return entities.error ? ( ) : (
- {entityEntries.map(([kind, entitiesByKind]) => ( -
- {kind} {/* Kind as Title */} + {!groupByKind && ( + + {entities.value + ?.sort((a, b) => + (a.metadata.title ?? a.metadata.name).localeCompare( + b.metadata.title ?? b.metadata.name, + ), + ) + .map(entity => ( + + ))} + + )} + + {groupByKind && ( + setActiveTab(newValue)} + variant="scrollable" + scrollButtons="auto" + aria-label="entity-tabs" + > + {groupByKindEntries.map(([kind]) => ( + + ))} + + )} + + {groupByKindEntries.map(([kind, entitiesByKind], index) => ( + diff --git a/plugins/home/src/plugin.ts b/plugins/home/src/plugin.ts index ab8c46baa1..ce288a1cb2 100644 --- a/plugins/home/src/plugin.ts +++ b/plugins/home/src/plugin.ts @@ -26,6 +26,7 @@ import { createCardExtension } from '@backstage/plugin-home-react'; import { ToolkitContentProps, VisitedByTypeProps } from './homePageComponents'; import { rootRouteRef } from './routes'; import { VisitsStorageApi, visitsApiRef } from './api'; +import { StarredEntitiesProps } from './homePageComponents/StarredEntities/Content'; /** @public */ export const homePlugin = createPlugin({ @@ -164,7 +165,7 @@ export const HomePageToolkit = homePlugin.provide( * @public */ export const HomePageStarredEntities = homePlugin.provide( - createCardExtension({ + createCardExtension>({ name: 'HomePageStarredEntities', title: 'Your Starred Entities', components: () => import('./homePageComponents/StarredEntities'), From 3181be9f21adfc5659870b75afafa556c50f0657 Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Sat, 11 Nov 2023 12:45:25 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20feat(HomePlugin):=20fix=20Starr?= =?UTF-8?q?edEntitieProps=20export=20for=20report=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Bergas --- plugins/home/api-report.md | 8 +++++++- .../components/StarredEntityListItem/index.ts | 17 +++++++++++++++++ .../homePageComponents/StarredEntities/index.ts | 2 +- plugins/home/src/homePageComponents/index.ts | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 plugins/home/src/components/StarredEntityListItem/index.ts diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 14f685cfc1..3d947d9641 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -133,7 +133,7 @@ export const HomePageRecentlyVisited: ( // @public export const HomePageStarredEntities: ( - props: CardExtensionProps_2, + props: CardExtensionProps_2>, ) => JSX_2.Element; // @public @@ -177,6 +177,12 @@ export const SettingsModal: (props: { children: JSX.Element; }) => JSX_2.Element; +// @public +export type StarredEntitiesProps = { + noStarredEntitiesMessage?: React_2.ReactNode | undefined; + groupByKind?: boolean; +}; + // @public (undocumented) export const TemplateBackstageLogo: (props: { classes: { diff --git a/plugins/home/src/components/StarredEntityListItem/index.ts b/plugins/home/src/components/StarredEntityListItem/index.ts new file mode 100644 index 0000000000..5419e0cdf7 --- /dev/null +++ b/plugins/home/src/components/StarredEntityListItem/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { StarredEntityListItem } from './StarredEntityListItem'; diff --git a/plugins/home/src/homePageComponents/StarredEntities/index.ts b/plugins/home/src/homePageComponents/StarredEntities/index.ts index 1faa9a2426..32e9213ea6 100644 --- a/plugins/home/src/homePageComponents/StarredEntities/index.ts +++ b/plugins/home/src/homePageComponents/StarredEntities/index.ts @@ -13,5 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - export { Content } from './Content'; +export type { StarredEntitiesProps } from './Content'; diff --git a/plugins/home/src/homePageComponents/index.ts b/plugins/home/src/homePageComponents/index.ts index 9149afa295..03902debe4 100644 --- a/plugins/home/src/homePageComponents/index.ts +++ b/plugins/home/src/homePageComponents/index.ts @@ -18,3 +18,4 @@ export type { ToolkitContentProps, Tool } from './Toolkit'; export type { ClockConfig } from './HeaderWorldClock'; export type { WelcomeTitleLanguageProps } from './WelcomeTitle'; export type { VisitedByTypeProps, VisitedByTypeKind } from './VisitedByType'; +export type { StarredEntitiesProps } from './StarredEntities'; From 04e03a4e872f547495545527d8af24588f6fcf7d Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Sat, 11 Nov 2023 14:22:17 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=A8=20feat(HomePlugin):=20fix=20shoul?= =?UTF-8?q?d=20render=20entities=20list=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Bergas --- .../StarredEntities/Content.tsx | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx index e98065b392..ed5eec857b 100644 --- a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx +++ b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx @@ -135,25 +135,26 @@ export const Content = ({ )} - {groupByKindEntries.map(([kind, entitiesByKind], index) => ( - - ))} + {groupByKind && + groupByKindEntries.map(([kind, entitiesByKind], index) => ( + + ))}
); };