change useAsync to useAsyncFn and refactored states

Signed-off-by: Lykke Axlin <lykkeaxlin@hotmail.com>

Co-authored-by: klaraab <klarabroman@live.se>
This commit is contained in:
Lykke Axlin
2021-09-27 13:53:42 +02:00
parent bc9842feb5
commit dae33a48d6
5 changed files with 88 additions and 68 deletions
+13 -11
View File
@@ -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<BazaarApi>({
id: 'bazaar',
@@ -48,7 +48,7 @@ export interface BazaarApi {
getEntities(): Promise<any>;
deleteEntity(entity: Entity): Promise<void>;
deleteEntity(bazaarProject: BazaarProject): Promise<void>;
}
export class BazaarClient implements BazaarApi {
@@ -153,22 +153,24 @@ export class BazaarClient implements BazaarApi {
}).then(resp => resp.json());
}
async deleteEntity(entity: Entity): Promise<void> {
async deleteEntity(bazaarProject: BazaarProject): Promise<void> {
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,
},
});
}
}
}
@@ -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<SetStateAction<BazaarProject[]>>;
setCatalogEntities: Dispatch<SetStateAction<Entity[]>>;
fetchBazaarProjects: () => Promise<BazaarProject[]>;
fetchCatalogEntities: () => Promise<Entity[]>;
};
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);
};
@@ -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<SetStateAction<boolean>>;
};
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();
};
@@ -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 <Progress />;
} else if (error) {
return <Alert severity="error">{error.message}</Alert>;
} else if (!isBazaar) {
return (
<Card>
@@ -246,7 +249,7 @@ export const EntityBazaarInfoCard = () => {
/>
<DeleteProjectDialog
entity={entity}
bazaarProject={bazaarProject}
openDelete={openDelete}
handleClose={closeDelete}
setIsBazaar={setIsBazaar}
@@ -277,7 +280,7 @@ export const EntityBazaarInfoCard = () => {
}}
>
<EditIcon className={classes.icon} />
<ListItemText primary="Suggest changes" />
<ListItemText primary="Edit project" />
</MenuItem>
<Divider />
<MenuItem
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import {
Content,
ContentHeader,
@@ -25,12 +25,13 @@ import { AddProjectDialog } from '../AddProjectDialog';
import { AlertBanner } from '../AlertBanner';
import { ProjectPreview } from '../ProjectPreview/ProjectPreview';
import { Button, makeStyles, Link } from '@material-ui/core';
import { useAsync } from 'react-use';
import { useAsyncFn } from 'react-use';
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { useApi } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { BazaarProject } from '../../types';
import { bazaarApiRef } from '../../api';
import { Alert } from '@material-ui/lab';
const useStyles = makeStyles({
container: {
@@ -38,14 +39,27 @@ const useStyles = makeStyles({
},
});
const filterCatalogEntities = (bazaarProjects: any, catalogEntities: any) => {
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<Entity[]>([]);
const [bazaarProjects, setBazaarProjects] = useState<BazaarProject[]>([]);
const bazaarApi = useApi(bazaarApiRef);
const catalogApi = useApi(catalogApiRef);
const [filteredCatalogEntites, setFilteredCatalogEntities] =
useState<Entity[]>();
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 <Progress />;
}
useEffect(() => {
fetchCatalogEntities();
fetchBazaarProjects();
}, [fetchBazaarProjects, fetchCatalogEntities]);
useEffect(() => {
const filteredCatalogEntities = filterCatalogEntities(
bazaarProjects,
catalogEntities,
);
if (filteredCatalogEntities) {
setFilteredCatalogEntities(filteredCatalogEntities);
}
}, [bazaarProjects, catalogEntities]);
if (catalogEntities.loading || bazaarProjects.loading) return <Progress />;
if (catalogEntities.error)
return <Alert severity="error">{catalogEntities.error.message}</Alert>;
if (bazaarProjects.error)
return <Alert severity="error">{bazaarProjects.error.message}</Alert>;
return (
<Content noPadding>
@@ -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
</Button>
<AddProjectDialog
catalogEntities={catalogEntities}
catalogEntities={filteredCatalogEntites || []}
handleClose={() => {
setOpenAdd(false);
}}
open={openAdd}
setBazaarProjects={setBazaarProjects}
setCatalogEntities={setCatalogEntities}
fetchBazaarProjects={fetchBazaarProjects}
fetchCatalogEntities={fetchCatalogEntities}
/>
<SupportButton />
</ContentHeader>
<ProjectPreview
bazaarProjects={bazaarProjects || []}
bazaarProjects={bazaarProjects.value || []}
sortingMethod={compareProjectsByDate}
/>
<Content noPadding className={classes.container} />