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:
+13
-11
@@ -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} />
|
||||
|
||||
Reference in New Issue
Block a user