diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index ea4c51adda..8670830584 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -137,11 +137,11 @@ export type DefaultEntityFilters = { export class DefaultStarredEntitiesApi implements StarredEntitiesApi { constructor(opts: { storageApi: StorageApi }); // (undocumented) - isStarred(entity: Entity): boolean; + isStarred(entityRef: string): boolean; // (undocumented) starredEntitie$(): Observable; // (undocumented) - toggleStarred(entity: Entity): Promise; + toggleStarred(entityRef: string): Promise; } // Warning: (ae-forgotten-export) The symbol "EntityLoadingStatus" needs to be exported by the entry point index.d.ts @@ -758,7 +758,7 @@ export const rootRoute: RouteRef; // @public export interface StarredEntitiesApi { starredEntitie$(): Observable; - toggleStarred(entity: Entity): Promise; + toggleStarred(entityRef: string): Promise; } // Warning: (ae-missing-release-tag) "StarredEntitiesApiObservable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -766,7 +766,7 @@ export interface StarredEntitiesApi { // @public (undocumented) export type StarredEntitiesApiObservable = { starredEntities: Set; - isStarred: (entity: Entity) => boolean; + isStarred: (entityRef: string) => boolean; }; // Warning: (ae-missing-release-tag) "starredEntitiesApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.test.ts b/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.test.ts index 95375aa0f6..e4f7c4ffa1 100644 --- a/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.test.ts +++ b/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { StorageApi } from '@backstage/core-plugin-api'; import { MockStorageApi } from '@backstage/test-utils'; import { DefaultStarredEntitiesApi } from './DefaultStarredEntitiesApi'; @@ -23,13 +23,13 @@ describe('DefaultStarredEntitiesApi', () => { let mockStorage: StorageApi; let starredEntitiesApi: DefaultStarredEntitiesApi; - const mockEntity: Entity = { + const mockEntityRef = stringifyEntityRef({ apiVersion: '1', kind: 'Component', metadata: { name: 'mock', }, - }; + }); beforeEach(() => { mockStorage = MockStorageApi.create(); @@ -44,22 +44,22 @@ describe('DefaultStarredEntitiesApi', () => { describe('toggleStarred', () => { it('should star unstarred entity', async () => { - expect(starredEntitiesApi.isStarred(mockEntity)).toBe(false); + expect(starredEntitiesApi.isStarred(mockEntityRef)).toBe(false); - await starredEntitiesApi.toggleStarred(mockEntity); + await starredEntitiesApi.toggleStarred(mockEntityRef); - expect(starredEntitiesApi.isStarred(mockEntity)).toBe(true); + expect(starredEntitiesApi.isStarred(mockEntityRef)).toBe(true); }); it('should unstar starred entity', async () => { const bucket = mockStorage.forBucket('starredEntities'); await bucket.set('entityRefs', ['component:default/mock']); - expect(starredEntitiesApi.isStarred(mockEntity)).toBe(true); + expect(starredEntitiesApi.isStarred(mockEntityRef)).toBe(true); - await starredEntitiesApi.toggleStarred(mockEntity); + await starredEntitiesApi.toggleStarred(mockEntityRef); - expect(starredEntitiesApi.isStarred(mockEntity)).toBe(false); + expect(starredEntitiesApi.isStarred(mockEntityRef)).toBe(false); }); }); @@ -96,8 +96,8 @@ describe('DefaultStarredEntitiesApi', () => { }); it('should receive isStarred function that operates on the latest state', async () => { - expect(handler.mock.calls[0][0].isStarred(mockEntity)).toBe(true); - expect(handler.mock.calls[1][0].isStarred(mockEntity)).toBe(true); + expect(handler.mock.calls[0][0].isStarred(mockEntityRef)).toBe(true); + expect(handler.mock.calls[1][0].isStarred(mockEntityRef)).toBe(true); }); }); }); diff --git a/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.ts b/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.ts index fa775679ca..8486d180b7 100644 --- a/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.ts +++ b/plugins/catalog-react/src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { Observable, StorageApi } from '@backstage/core-plugin-api'; import ObservableImpl from 'zen-observable'; import { @@ -46,13 +45,11 @@ export class DefaultStarredEntitiesApi implements StarredEntitiesApi { }); } - async toggleStarred(entity: Entity): Promise { - const entityKey = stringifyEntityRef(entity); - - if (this.starredEntities.has(entityKey)) { - this.starredEntities.delete(entityKey); + async toggleStarred(entityRef: string): Promise { + if (this.starredEntities.has(entityRef)) { + this.starredEntities.delete(entityRef); } else { - this.starredEntities.add(entityKey); + this.starredEntities.add(entityRef); } await this.settingsStore.set( @@ -65,9 +62,8 @@ export class DefaultStarredEntitiesApi implements StarredEntitiesApi { return this.observable; } - isStarred(entity: Entity): boolean { - const entityKey = stringifyEntityRef(entity); - return this.starredEntities.has(entityKey); + isStarred(entityRef: string): boolean { + return this.starredEntities.has(entityRef); } private readonly subscribers = new Set< diff --git a/plugins/catalog-react/src/apis/StarredEntitiesApi/StarredEntitiesApi.ts b/plugins/catalog-react/src/apis/StarredEntitiesApi/StarredEntitiesApi.ts index 0c8ec52445..68eae0b0a1 100644 --- a/plugins/catalog-react/src/apis/StarredEntitiesApi/StarredEntitiesApi.ts +++ b/plugins/catalog-react/src/apis/StarredEntitiesApi/StarredEntitiesApi.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; import { ApiRef, createApiRef, Observable } from '@backstage/core-plugin-api'; export const starredEntitiesApiRef: ApiRef = createApiRef({ @@ -30,10 +29,10 @@ export type StarredEntitiesApiObservable = { /** * A function to check if an entity is starred. * - * @param entity - the entity to check + * @param entityRef - an entity reference to check * @returns true, if the entity is starred. */ - isStarred: (entity: Entity) => boolean; + isStarred: (entityRef: string) => boolean; }; /** @@ -45,9 +44,9 @@ export interface StarredEntitiesApi { /** * Toggle the star state of the entity * - * @param entity - the entity to be toggled + * @param entityRef - an entity reference to toggle */ - toggleStarred(entity: Entity): Promise; + toggleStarred(entityRef: string): Promise; /** * Observe the state of starred entities and receive a handler diff --git a/plugins/catalog-react/src/hooks/useStarredEntities.ts b/plugins/catalog-react/src/hooks/useStarredEntities.ts index cb94d465bc..e79e605877 100644 --- a/plugins/catalog-react/src/hooks/useStarredEntities.ts +++ b/plugins/catalog-react/src/hooks/useStarredEntities.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { useApi } from '@backstage/core-plugin-api'; import { useCallback } from 'react'; import { useObservable } from 'react-use'; @@ -23,14 +23,19 @@ import { starredEntitiesApiRef } from '../apis'; export const useStarredEntities = () => { const starredEntitiesApi = useApi(starredEntitiesApiRef); - const { starredEntities, isStarred: isStarredEntity } = useObservable( + const { starredEntities, isStarred } = useObservable( starredEntitiesApi.starredEntitie$(), { starredEntities: new Set(), isStarred: _ => false }, ); + const isStarredEntity = useCallback( + (entity: Entity) => isStarred(stringifyEntityRef(entity)), + [isStarred], + ); + const toggleStarredEntity = useCallback( (entity: Entity) => { - starredEntitiesApi.toggleStarred(entity).then(); + starredEntitiesApi.toggleStarred(stringifyEntityRef(entity)).then(); }, [starredEntitiesApi], );