diff --git a/.changeset/wise-plants-tease.md b/.changeset/wise-plants-tease.md
new file mode 100644
index 0000000000..206704435d
--- /dev/null
+++ b/.changeset/wise-plants-tease.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-home': patch
+---
+
+Adds new StarredEntities component responsible for rendering a list of starred entities on the home page
diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md
index fab2b05bb6..264189ee07 100644
--- a/plugins/home/api-report.md
+++ b/plugins/home/api-report.md
@@ -113,6 +113,13 @@ export const HomePageRandomJoke: (
},
) => JSX.Element;
+// @public
+export const HomePageStarredEntities: (
+ props: ComponentRenderer & {
+ title?: string | undefined;
+ },
+) => JSX.Element;
+
// Warning: (ae-forgotten-export) The symbol "ToolkitContentProps" needs to be exported by the entry point index.d.ts
//
// @public
diff --git a/plugins/home/package.json b/plugins/home/package.json
index a1a09329f8..b1d4fc362e 100644
--- a/plugins/home/package.json
+++ b/plugins/home/package.json
@@ -21,10 +21,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
+ "@backstage/catalog-model": "^0.9.10",
"@backstage/core-components": "^0.8.7",
"@backstage/core-plugin-api": "^0.6.0",
- "@backstage/theme": "^0.2.14",
+ "@backstage/plugin-catalog-react": "^0.6.13",
"@backstage/plugin-search": "^0.6.1",
+ "@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
diff --git a/plugins/home/src/homePageComponents/StarredEntities/Content.test.tsx b/plugins/home/src/homePageComponents/StarredEntities/Content.test.tsx
new file mode 100644
index 0000000000..ccc36f6964
--- /dev/null
+++ b/plugins/home/src/homePageComponents/StarredEntities/Content.test.tsx
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2022 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 {
+ renderInTestApp,
+ TestApiProvider,
+ MockStorageApi,
+} from '@backstage/test-utils';
+import {
+ starredEntitiesApiRef,
+ entityRouteRef,
+ DefaultStarredEntitiesApi,
+} from '@backstage/plugin-catalog-react';
+import React from 'react';
+import { Content } from './Content';
+
+describe('StarredEntitiesContent', () => {
+ it('should render list of tools', async () => {
+ const mockStorageApi = MockStorageApi.create();
+ await mockStorageApi
+ .forBucket('starredEntities')
+ .set('entityRefs', [
+ 'component:default/mock-starred-entity',
+ 'component:default/mock-starred-entity-2',
+ ]);
+
+ const { getByText } = await renderInTestApp(
+
+
+ ,
+ {
+ mountedRoutes: {
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ },
+ },
+ );
+
+ expect(getByText('mock-starred-entity')).toBeInTheDocument();
+ expect(getByText('mock-starred-entity-2')).toBeInTheDocument();
+ expect(getByText('mock-starred-entity').closest('a')).toHaveAttribute(
+ 'href',
+ '/catalog/default/component/mock-starred-entity',
+ );
+ expect(getByText('mock-starred-entity-2').closest('a')).toHaveAttribute(
+ 'href',
+ '/catalog/default/component/mock-starred-entity-2',
+ );
+ });
+});
diff --git a/plugins/home/src/homePageComponents/StarredEntities/Content.tsx b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx
new file mode 100644
index 0000000000..6c9775c842
--- /dev/null
+++ b/plugins/home/src/homePageComponents/StarredEntities/Content.tsx
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 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 {
+ useStarredEntities,
+ entityRouteRef,
+} from '@backstage/plugin-catalog-react';
+import { parseEntityRef } from '@backstage/catalog-model';
+import { useRouteRef } from '@backstage/core-plugin-api';
+import { Link } from '@backstage/core-components';
+import {
+ List,
+ ListItem,
+ ListItemSecondaryAction,
+ IconButton,
+ ListItemText,
+ Tooltip,
+ Typography,
+} from '@material-ui/core';
+import StarIcon from '@material-ui/icons/Star';
+import React from 'react';
+
+/**
+ * A component to display a list of starred entities for the user.
+ *
+ * @public
+ */
+
+export const Content = () => {
+ const catalogEntityRoute = useRouteRef(entityRouteRef);
+ const { starredEntities, toggleStarredEntity } = useStarredEntities();
+
+ if (starredEntities.size === 0)
+ return (
+
+ You do not have any starred entities yet!
+
+ );
+
+ return (
+
+ {Array.from(starredEntities).map(entity => (
+
+
+
+
+
+
+ toggleStarredEntity(entity)}
+ >
+
+
+
+
+
+ ))}
+
+ );
+};
diff --git a/plugins/home/src/homePageComponents/StarredEntities/StarredEntities.stories.tsx b/plugins/home/src/homePageComponents/StarredEntities/StarredEntities.stories.tsx
new file mode 100644
index 0000000000..2e63762369
--- /dev/null
+++ b/plugins/home/src/homePageComponents/StarredEntities/StarredEntities.stories.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2022 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 { HomePageStarredEntities } from '../../plugin';
+import {
+ wrapInTestApp,
+ TestApiProvider,
+ MockStorageApi,
+} from '@backstage/test-utils';
+import {
+ starredEntitiesApiRef,
+ entityRouteRef,
+ DefaultStarredEntitiesApi,
+} from '@backstage/plugin-catalog-react';
+import { Grid } from '@material-ui/core';
+import React, { ComponentType } from 'react';
+
+const mockStorageApi = MockStorageApi.create();
+mockStorageApi
+ .forBucket('starredEntities')
+ .set('entityRefs', [
+ 'component:default/example-starred-entity',
+ 'component:default/example-starred-entity-2',
+ 'component:default/example-starred-entity-3',
+ 'component:default/example-starred-entity-4',
+ ]);
+
+export default {
+ title: 'Plugins/Home/Components/StarredEntities',
+ decorators: [
+ (Story: ComponentType<{}>) =>
+ wrapInTestApp(
+
+
+ ,
+ {
+ mountedRoutes: {
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ },
+ },
+ ),
+ ],
+};
+
+export const Default = () => {
+ return (
+
+
+
+ );
+};
diff --git a/plugins/home/src/homePageComponents/StarredEntities/index.ts b/plugins/home/src/homePageComponents/StarredEntities/index.ts
new file mode 100644
index 0000000000..1faa9a2426
--- /dev/null
+++ b/plugins/home/src/homePageComponents/StarredEntities/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2022 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 { Content } from './Content';
diff --git a/plugins/home/src/index.ts b/plugins/home/src/index.ts
index dcd61f1fa3..4871323677 100644
--- a/plugins/home/src/index.ts
+++ b/plugins/home/src/index.ts
@@ -26,6 +26,7 @@ export {
HomePageRandomJoke,
HomePageToolkit,
HomePageCompanyLogo,
+ HomePageStarredEntities,
ComponentAccordion,
ComponentTabs,
ComponentTab,
diff --git a/plugins/home/src/plugin.ts b/plugins/home/src/plugin.ts
index 135ac97af0..32005a9064 100644
--- a/plugins/home/src/plugin.ts
+++ b/plugins/home/src/plugin.ts
@@ -115,3 +115,16 @@ export const HomePageToolkit = homePlugin.provide(
components: () => import('./homePageComponents/Toolkit'),
}),
);
+
+/**
+ * A component to display a list of starred entities for the user.
+ *
+ * @public
+ */
+export const HomePageStarredEntities = homePlugin.provide(
+ createCardExtension({
+ name: 'HomePageStarredEntities',
+ title: 'Your Starred Entities',
+ components: () => import('./homePageComponents/StarredEntities'),
+ }),
+);
diff --git a/plugins/home/src/templates/DefaultTemplate.stories.tsx b/plugins/home/src/templates/DefaultTemplate.stories.tsx
index fb62591fbd..ba5e1f33fd 100644
--- a/plugins/home/src/templates/DefaultTemplate.stories.tsx
+++ b/plugins/home/src/templates/DefaultTemplate.stories.tsx
@@ -14,20 +14,38 @@
* limitations under the License.
*/
-import {TemplateBackstageLogo} from './TemplateBackstageLogo';
-import {TemplateBackstageLogoIcon} from './TemplateBackstageLogoIcon';
-import { HomePageToolkit, HomePageCompanyLogo } from '../plugin';
-import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
+import { TemplateBackstageLogo } from './TemplateBackstageLogo';
+import { TemplateBackstageLogoIcon } from './TemplateBackstageLogoIcon';
+import {
+ HomePageToolkit,
+ HomePageCompanyLogo,
+ HomePageStarredEntities,
+} from '../plugin';
+import { wrapInTestApp, TestApiProvider, MockStorageApi} from '@backstage/test-utils';
import { Content, Page, InfoCard } from '@backstage/core-components';
+import {
+ starredEntitiesApiRef,
+ entityRouteRef,
+ DefaultStarredEntitiesApi
+} from '@backstage/plugin-catalog-react';
import {
HomePageSearchBar,
SearchContextProvider,
searchApiRef,
- searchPlugin
+ searchPlugin,
} from '@backstage/plugin-search';
import { Grid, makeStyles } from '@material-ui/core';
-import React, { ComponentType} from 'react';
+import React, { ComponentType } from 'react';
+const mockStorageApi = MockStorageApi.create();
+mockStorageApi
+ .forBucket('starredEntities')
+ .set('entityRefs', [
+ 'component:default/example-starred-entity',
+ 'component:default/example-starred-entity-2',
+ 'component:default/example-starred-entity-3',
+ 'component:default/example-starred-entity-4'
+ ]);
export default {
title: 'Plugins/Home/Templates',
@@ -35,13 +53,26 @@ export default {
(Story: ComponentType<{}>) =>
wrapInTestApp(
<>
- Promise.resolve({results: []})}]]}>
-
+ Promise.resolve({ results: [] }) }],
+ ]}
+ >
+
>,
{
- mountedRoutes: {'/hello-company': searchPlugin.routes.root }
- }
+ mountedRoutes: {
+ '/hello-company': searchPlugin.routes.root,
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ },
+ },
),
],
};
@@ -82,20 +113,17 @@ export const DefaultTemplate = () => {
}
+ logo={}
/>
-
- {/* placeholder for content */}
-
-
+