From dae33a48d6e40fcb6705b7586135000d4a2e256e Mon Sep 17 00:00:00 2001 From: Lykke Axlin Date: Mon, 27 Sep 2021 13:53:42 +0200 Subject: [PATCH] change useAsync to useAsyncFn and refactored states Signed-off-by: Lykke Axlin Co-authored-by: klaraab --- plugins/bazaar/src/api.ts | 24 +++--- .../AddProjectDialog/AddProjectDialog.tsx | 33 +++----- .../DeleteProjectDialog.tsx | 8 +- .../EntityBazaarInfoCard.tsx | 15 ++-- .../src/components/SortView/SortView.tsx | 76 +++++++++++++------ 5 files changed, 88 insertions(+), 68 deletions(-) diff --git a/plugins/bazaar/src/api.ts b/plugins/bazaar/src/api.ts index ca082c69c6..5cdbfb8928 100644 --- a/plugins/bazaar/src/api.ts +++ b/plugins/bazaar/src/api.ts @@ -20,7 +20,7 @@ import { DiscoveryApi, IdentityApi, } from '@backstage/core-plugin-api'; -import { Status } from './types'; +import { BazaarProject, Status } from './types'; export const bazaarApiRef = createApiRef({ id: 'bazaar', @@ -48,7 +48,7 @@ export interface BazaarApi { getEntities(): Promise; - deleteEntity(entity: Entity): Promise; + deleteEntity(bazaarProject: BazaarProject): Promise; } export class BazaarClient implements BazaarApi { @@ -153,22 +153,24 @@ export class BazaarClient implements BazaarApi { }).then(resp => resp.json()); } - async deleteEntity(entity: Entity): Promise { + async deleteEntity(bazaarProject: BazaarProject): Promise { const baseUrl = await this.discoveryApi.getBaseUrl('bazaar'); await fetch(`${baseUrl}/metadata`, { method: 'DELETE', headers: { - entity_ref: stringifyEntityRef(entity), + entity_ref: bazaarProject.entityRef as string, }, }); - await fetch(`${baseUrl}/members`, { - method: 'DELETE', - headers: { - user_id: this.identityApi.getUserId(), - entity_ref: stringifyEntityRef(entity), - }, - }); + if (bazaarProject.membersCount > 0) { + await fetch(`${baseUrl}/members`, { + method: 'DELETE', + headers: { + user_id: this.identityApi.getUserId(), + entity_ref: bazaarProject.entityRef as string, + }, + }); + } } } diff --git a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx index 8aeff2e997..039537029e 100644 --- a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx +++ b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx @@ -14,8 +14,8 @@ * limitations under the License. */ -import React, { useState, useEffect, Dispatch, SetStateAction } from 'react'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import React, { useState, useEffect } from 'react'; +import { Entity } from '@backstage/catalog-model'; import { SubmitHandler } from 'react-hook-form'; import { useApi } from '@backstage/core-plugin-api'; import { ProjectDialog } from '../ProjectDialog'; @@ -27,16 +27,16 @@ type Props = { catalogEntities: Entity[]; open: boolean; handleClose: () => void; - setBazaarProjects: Dispatch>; - setCatalogEntities: Dispatch>; + fetchBazaarProjects: () => Promise; + fetchCatalogEntities: () => Promise; }; export const AddProjectDialog = ({ catalogEntities, open, handleClose, - setBazaarProjects, - setCatalogEntities, + fetchBazaarProjects, + fetchCatalogEntities, }: Props) => { const bazaarApi = useApi(bazaarApiRef); const [selectedEntity, setSelectedEntity] = useState( @@ -64,24 +64,6 @@ export const AddProjectDialog = ({ ) => { const formValues = getValues(); - const bazaarProject: BazaarProject = { - entityRef: stringifyEntityRef(selectedEntity!), - name: selectedEntity!.metadata.name, - community: formValues.community, - announcement: formValues.announcement, - status: formValues.status, - updatedAt: new Date().toISOString(), - membersCount: 0, - }; - - setBazaarProjects((oldProjects: BazaarProject[]) => { - return [...oldProjects, bazaarProject]; - }); - - setCatalogEntities((oldEntities: Entity[]) => { - return oldEntities.filter(entity => entity !== selectedEntity); - }); - await bazaarApi.updateMetadata( selectedEntity!, selectedEntity!.metadata.name, @@ -90,6 +72,9 @@ export const AddProjectDialog = ({ formValues.status, ); + fetchBazaarProjects(); + fetchCatalogEntities(); + handleClose(); reset(defaultValues); }; diff --git a/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx b/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx index a1ac9c060b..737fa437da 100644 --- a/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx +++ b/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx @@ -29,9 +29,9 @@ import MuiDialogActions from '@material-ui/core/DialogActions'; import IconButton from '@material-ui/core/IconButton'; import CloseIcon from '@material-ui/icons/Close'; import Typography from '@material-ui/core/Typography'; -import { Entity } from '@backstage/catalog-model'; import { useApi } from '@backstage/core-plugin-api'; import { bazaarApiRef } from '../../api'; +import { BazaarProject } from '../../types'; const styles = (theme: Theme) => createStyles({ @@ -89,14 +89,14 @@ const DialogActions = withStyles((theme: Theme) => ({ }))(MuiDialogActions); type Props = { - entity: Entity; + bazaarProject: BazaarProject; openDelete: boolean; handleClose: () => void; setIsBazaar: Dispatch>; }; export const DeleteProjectDialog = ({ - entity, + bazaarProject, openDelete, handleClose, setIsBazaar, @@ -108,7 +108,7 @@ export const DeleteProjectDialog = ({ const bazaarApi = useApi(bazaarApiRef); const handleSubmit = async () => { - await bazaarApi.deleteEntity(entity); + await bazaarApi.deleteEntity(bazaarProject); setIsBazaar(false); handleCloseAndClear(); }; diff --git a/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx b/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx index eb6b3763ce..192954d84a 100644 --- a/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx +++ b/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx @@ -57,6 +57,7 @@ import { Member, BazaarProject } from '../../types'; import { bazaarApiRef } from '../../api'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { rootRouteRef } from '../../routes'; +import { Alert } from '@material-ui/lab'; const useStyles = makeStyles({ description: { @@ -135,18 +136,18 @@ export const EntityBazaarInfoCard = () => { const data = await response.json().then((resp: any) => resp.data); setBazaarProject({ - entityRef: data[0].entityRef, + entityRef: data[0].entity_ref, name: data[0].name, community: data[0].community, announcement: data[0].announcement, status: data[0].status, - updatedAt: data[0].updatedAt, - membersCount: data[0].membersCount, + updatedAt: data[0].updated_at, + membersCount: data[0].members_count, }); } }; - const { loading } = useAsync(async () => { + const { loading, error } = useAsync(async () => { await getInitMemberStatus(); await getMetadata(); }); @@ -213,6 +214,8 @@ export const EntityBazaarInfoCard = () => { if (loading) { return ; + } else if (error) { + return {error.message}; } else if (!isBazaar) { return ( @@ -246,7 +249,7 @@ export const EntityBazaarInfoCard = () => { /> { }} > - + { + const bazaarProjectRefs = bazaarProjects?.value?.map( + (project: BazaarProject) => project.entityRef, + ); + + const filtered = catalogEntities?.value?.filter((entity: Entity) => { + return !bazaarProjectRefs?.includes(stringifyEntityRef(entity)); + }); + + // setFilteredCatalogEntities(filtered); + return filtered; +}; + export const SortView = () => { const classes = useStyles(); const [openAdd, setOpenAdd] = useState(false); const [openNoProjects, setOpenNoProjects] = useState(false); - const [catalogEntities, setCatalogEntities] = useState([]); - const [bazaarProjects, setBazaarProjects] = useState([]); const bazaarApi = useApi(bazaarApiRef); const catalogApi = useApi(catalogApiRef); + const [filteredCatalogEntites, setFilteredCatalogEntities] = + useState(); const compareProjectsByDate = ( a: BazaarProject, @@ -60,17 +74,20 @@ export const SortView = () => { setOpenNoProjects(false); }; - const { loading } = useAsync(async () => { + const [catalogEntities, fetchCatalogEntities] = useAsyncFn(async () => { const entities = await catalogApi.getEntities({ filter: { - kind: ['Component', 'API', 'Resource', 'System', 'Domain'], + kind: ['Component', 'Resource'], }, fields: ['kind', 'metadata.name', 'metadata.namespace'], }); + return entities.items; + }); + + const [bazaarProjects, fetchBazaarProjects] = useAsyncFn(async () => { const response = await bazaarApi.getEntities(); const dbProjects: BazaarProject[] = []; - const bazaarProjectRefs: string[] = []; response.data.forEach((project: any) => { dbProjects.push({ @@ -82,21 +99,34 @@ export const SortView = () => { updatedAt: project.updated_at, membersCount: project.members_count, }); - - bazaarProjectRefs.push(project.entity_ref); }); - setBazaarProjects(dbProjects); - setCatalogEntities( - entities.items.filter((entity: Entity) => { - return !bazaarProjectRefs.includes(stringifyEntityRef(entity)); - }), - ); + return dbProjects; }); - if (loading) { - return ; - } + useEffect(() => { + fetchCatalogEntities(); + fetchBazaarProjects(); + }, [fetchBazaarProjects, fetchCatalogEntities]); + + useEffect(() => { + const filteredCatalogEntities = filterCatalogEntities( + bazaarProjects, + catalogEntities, + ); + + if (filteredCatalogEntities) { + setFilteredCatalogEntities(filteredCatalogEntities); + } + }, [bazaarProjects, catalogEntities]); + + if (catalogEntities.loading || bazaarProjects.loading) return ; + + if (catalogEntities.error) + return {catalogEntities.error.message}; + + if (bazaarProjects.error) + return {bazaarProjects.error.message}; return ( @@ -121,7 +151,7 @@ export const SortView = () => { variant="contained" color="primary" onClick={() => { - if (catalogEntities.length !== 0) { + if (filteredCatalogEntites?.length !== 0) { setOpenAdd(true); } else { setOpenNoProjects(true); @@ -131,18 +161,18 @@ export const SortView = () => { Add project { setOpenAdd(false); }} open={openAdd} - setBazaarProjects={setBazaarProjects} - setCatalogEntities={setCatalogEntities} + fetchBazaarProjects={fetchBazaarProjects} + fetchCatalogEntities={fetchCatalogEntities} />