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) => (
+
{entitiesByKind
?.sort((a, b) =>
@@ -118,24 +145,11 @@ export const Content = (props: {
),
)
.map(entity => (
-
-
-
-
-
-
- toggleStarredEntity(entity)}
- >
-
-
-
-
-
+
))}
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'),