chore(catalog/star): reworking how the starring works, it now stores uri sort of references for entities
This commit is contained in:
@@ -64,7 +64,11 @@ const useStyles = makeStyles(theme => ({
|
||||
|
||||
const CatalogPage: FC<{}> = () => {
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const { starredEntities, toggleStarredEntity } = useStarredEntities();
|
||||
const {
|
||||
starredEntities,
|
||||
toggleStarredEntity,
|
||||
isStarredEntity,
|
||||
} = useStarredEntities();
|
||||
const [selectedFilter, setSelectedFilter] = useState<CatalogFilterItem>(
|
||||
defaultFilter,
|
||||
);
|
||||
@@ -118,12 +122,11 @@ const CatalogPage: FC<{}> = () => {
|
||||
};
|
||||
},
|
||||
(rowData: Component) => {
|
||||
const isStarred = isStarredEntity(rowData);
|
||||
return {
|
||||
icon: starredEntities.has(rowData.metadata.name) ? Star : StarOutline,
|
||||
toolTip: `${
|
||||
starredEntities.has(rowData.metadata.name) ? 'Unstar' : 'Star'
|
||||
} ${rowData.metadata.name}`,
|
||||
onClick: () => toggleStarredEntity(rowData.metadata.name),
|
||||
icon: isStarred ? Star : StarOutline,
|
||||
tooltip: isStarred ? 'Remove from favorites' : 'Add to favorites',
|
||||
onClick: () => toggleStarredEntity(rowData),
|
||||
};
|
||||
},
|
||||
];
|
||||
|
||||
@@ -16,14 +16,21 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useApi, storageApiRef } from '@backstage/core';
|
||||
import { useObservable } from 'react-use';
|
||||
import { Component } from '../data/component';
|
||||
|
||||
const buildEntityKey = (component: Component) =>
|
||||
`entity:${component.kind}:${component.metadata.namespace ?? 'default'}:${
|
||||
component.metadata.name
|
||||
}`;
|
||||
|
||||
export const useStarredEntities = () => {
|
||||
const storageApi = useApi(storageApiRef);
|
||||
const settingsStore = storageApi.forBucket('settings');
|
||||
const rawStarredItems = settingsStore.get<string[]>('starredEntities') ?? [];
|
||||
const rawStarredEntityKeys =
|
||||
settingsStore.get<string[]>('starredEntities') ?? [];
|
||||
|
||||
const [starredEntities, setStarredEntities] = useState(
|
||||
new Set(rawStarredItems),
|
||||
new Set(rawStarredEntityKeys),
|
||||
);
|
||||
|
||||
const observedItems = useObservable(
|
||||
@@ -38,19 +45,30 @@ export const useStarredEntities = () => {
|
||||
}, [observedItems?.newValue]);
|
||||
|
||||
const toggleStarredEntity = useCallback(
|
||||
(entity: string) => {
|
||||
if (starredEntities.has(entity)) {
|
||||
starredEntities.delete(entity);
|
||||
(entity: Component) => {
|
||||
const entityKey = buildEntityKey(entity);
|
||||
if (starredEntities.has(entityKey)) {
|
||||
starredEntities.delete(entityKey);
|
||||
} else {
|
||||
starredEntities.add(entity);
|
||||
starredEntities.add(entityKey);
|
||||
}
|
||||
|
||||
settingsStore.set('starredEntities', Array.from(starredEntities));
|
||||
},
|
||||
[starredEntities, settingsStore],
|
||||
);
|
||||
|
||||
const isStarredEntity = useCallback(
|
||||
(entity: Component) => {
|
||||
const entityKey = buildEntityKey(entity);
|
||||
return starredEntities.has(entityKey);
|
||||
},
|
||||
[starredEntities],
|
||||
);
|
||||
|
||||
return {
|
||||
starredEntities,
|
||||
toggleStarredEntity,
|
||||
isStarredEntity,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -24,9 +24,18 @@ import {
|
||||
StorageApi,
|
||||
} from '@backstage/core';
|
||||
import { MockErrorApi } from '@backstage/test-utils';
|
||||
import { Component } from '../data/component';
|
||||
|
||||
describe('useStarredEntities', () => {
|
||||
let mockStorage: StorageApi | undefined;
|
||||
const mockEntity: Component = {
|
||||
description: 'some mock description',
|
||||
kind: 'Component',
|
||||
name: 'mock',
|
||||
metadata: {
|
||||
name: 'mock',
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper: React.FC<{}> = ({ children }) => {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user