From 82c9c4965a05499293350475088f9171fa2a149d Mon Sep 17 00:00:00 2001 From: Klara Date: Thu, 16 Sep 2021 14:10:47 +0200 Subject: [PATCH] created bazaarApiRef Signed-off-by: Klara Co-authored-by: lykkeaxlin --- plugins/bazaar-backend/src/service/router.ts | 20 +- plugins/bazaar/README.md | 1 + plugins/bazaar/dev/index.tsx | 2 +- plugins/bazaar/src/api.ts | 177 ++++++++++++++++++ .../AddProjectDialog/AddProjectDialog.tsx | 9 +- .../DeleteProjectDialog.tsx | 12 +- .../EditProjectDialog/EditProjectDialog.tsx | 10 +- .../EntityBazaarInfoCard.tsx | 43 ++--- .../components/EntityBazaarInfoCard/index.ts | 2 +- .../src/components/InputField/InputField.tsx | 2 +- .../InputSelector/InputSelector.tsx | 2 +- .../components/ProjectCard/ProjectCard.tsx | 2 +- .../ProjectDialog/ProjectDialog.tsx | 2 +- .../ProjectPreview/ProjectPreview.tsx | 2 +- .../src/components/SortView/SortView.tsx | 12 +- .../src/components/StatusTag/StatusTag.tsx | 2 +- plugins/bazaar/src/plugin.ts | 15 +- plugins/bazaar/src/{util => }/types.ts | 0 plugins/bazaar/src/util/dbRequests.ts | 86 --------- 19 files changed, 248 insertions(+), 153 deletions(-) create mode 100644 plugins/bazaar/src/api.ts rename plugins/bazaar/src/{util => }/types.ts (100%) delete mode 100644 plugins/bazaar/src/util/dbRequests.ts diff --git a/plugins/bazaar-backend/src/service/router.ts b/plugins/bazaar-backend/src/service/router.ts index 7af6adb42f..e814c0a695 100644 --- a/plugins/bazaar-backend/src/service/router.ts +++ b/plugins/bazaar-backend/src/service/router.ts @@ -70,7 +70,7 @@ export async function createRouter( } }); - router.put('/members/add', async (request, response) => { + router.put('/member', async (request, response) => { const userId = request.headers.user_id; const entityRef = request.headers.entity_ref; @@ -83,10 +83,12 @@ export async function createRouter( response.send({ status: 'ok' }); }); - router.delete('/members/remove', async (request, response) => { + router.delete('/member', async (request, response) => { const userId = request.headers.user_id; const entityRef = request.headers.entity_ref; + console.log('------- user id ----- ', userId, entityRef); + const count = await db?.('public.members') .where({ entity_ref: entityRef }) .andWhere('user_id', userId) @@ -99,6 +101,20 @@ export async function createRouter( } }); + router.delete('/members', async (request, response) => { + const entityRef = request.headers.entity_ref; + + const count = await db?.('public.members') + .where({ entity_ref: entityRef }) + .del(); + + if (count) { + response.send({ status: 'ok' }); + } else { + response.status(404).json({ message: 'Record not found' }); + } + }); + router.get('/metadata', async (request, response) => { const entityRef = request.headers.entity_ref; diff --git a/plugins/bazaar/README.md b/plugins/bazaar/README.md index 2f4bd67f67..b0cf9c5514 100644 --- a/plugins/bazaar/README.md +++ b/plugins/bazaar/README.md @@ -50,6 +50,7 @@ Add a **Bazaar icon** to the Sidebar to easily access the Bazaar. In `packages/a Add a **Bazaar card** to the overview tab on the `packages/app/src/components/catalog/EntityPage.tsx` add: ```diff ++ import { EntityBazaarInfoCard } from '@backstage/plugin-bazaar'; const overviewContent = ( diff --git a/plugins/bazaar/dev/index.tsx b/plugins/bazaar/dev/index.tsx index 425b89e3fd..a4509bc1fc 100644 --- a/plugins/bazaar/dev/index.tsx +++ b/plugins/bazaar/dev/index.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2021 Spotify AB + * Copyright 2021 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/bazaar/src/api.ts b/plugins/bazaar/src/api.ts new file mode 100644 index 0000000000..29a635070d --- /dev/null +++ b/plugins/bazaar/src/api.ts @@ -0,0 +1,177 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { createApiRef, IdentityApi } from '@backstage/core-plugin-api'; +import { BazaarProject, Status } from './types'; + +export const getEntityRef = (entity: Entity) => { + return `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`; +}; + +export const bazaarApiRef = createApiRef({ + id: 'bazaar', + description: 'Used to make requests towards the bazaar backend', +}); + +export interface BazaarApi { + updateMetadata( + baseUrl: string, + entity: Entity, + name: string, + announcement: string, + status: Status, + ): Promise; + + getMetadata(baseUrl: string, entity: Entity): Promise; + + getMemberCounts( + bazaarProjects: BazaarProject[], + baseUrl: string, + ): Promise>; + + getMembers(baseUrl: string, entity: Entity): Promise; + + deleteMember(baseUrl: string, entity: Entity): Promise; + + deleteMembers(baseUrl: string, entity: Entity): Promise; + + addMember(baseUrl: string, entity: Entity): Promise; + + getEntities(baseUrl: string): Promise; + + deleteEntity(baseUrl: string, entity: Entity): Promise; +} + +export class BazaarClient implements BazaarApi { + private readonly identityApi: IdentityApi; + + constructor(options: { identityApi: IdentityApi }) { + this.identityApi = options.identityApi; + } + + async updateMetadata( + baseUrl: string, + entity: Entity, + name: string, + announcement: string, + status: Status, + ): Promise { + return await fetch(`${baseUrl}/api/bazaar/metadata`, { + method: 'PUT', + headers: { + entity_ref: getEntityRef(entity), + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: name, + announcement: announcement, + status: status, + }), + }).then(resp => resp.json()); + } + + async getMetadata(baseUrl: string, entity: Entity): Promise { + return await fetch(`${baseUrl}/api/bazaar/metadata`, { + method: 'GET', + headers: { + entity_ref: getEntityRef(entity), + }, + }); + } + + async getMemberCounts( + bazaarProjects: BazaarProject[], + baseUrl: string, + ): Promise> { + const members = new Map(); + for (const project of bazaarProjects) { + const response = await fetch(`${baseUrl}/api/bazaar/members`, { + method: 'GET', + headers: { + entity_ref: project.entityRef, + }, + }); + + const json = await response.json(); + const nbrOfMembers = await json.data.length; + members.set(project.entityRef, nbrOfMembers); + } + return members; + } + + async getMembers(baseUrl: string, entity: Entity): Promise { + return await fetch(`${baseUrl}/api/bazaar/members`, { + method: 'GET', + headers: { + entity_ref: getEntityRef(entity), + }, + }).then(resp => resp.json()); + } + + async addMember(baseUrl: string, entity: Entity): Promise { + await fetch(`${baseUrl}/api/bazaar/member`, { + method: 'PUT', + headers: { + user_id: this.identityApi.getUserId(), + entity_ref: getEntityRef(entity), + }, + }); + } + + async deleteMember(baseUrl: string, entity: Entity): Promise { + await fetch(`${baseUrl}/api/bazaar/member`, { + method: 'DELETE', + headers: { + user_id: this.identityApi.getUserId(), + entity_ref: getEntityRef(entity), + }, + }); + } + + async deleteMembers(baseUrl: string, entity: Entity): Promise { + await fetch(`${baseUrl}/api/bazaar/members`, { + method: 'DELETE', + headers: { + entity_ref: getEntityRef(entity), + }, + }); + } + + async getEntities(baseUrl: string): Promise { + return await fetch(`${baseUrl}/api/bazaar/entities`, { + method: 'GET', + }).then(resp => resp.json()); + } + + async deleteEntity(baseUrl: string, entity: Entity): Promise { + await fetch(`${baseUrl}/api/bazaar/metadata`, { + method: 'DELETE', + headers: { + entity_ref: getEntityRef(entity), + }, + }); + + await fetch(`${baseUrl}/api/bazaar/members`, { + method: 'DELETE', + headers: { + user_id: this.identityApi.getUserId(), + entity_ref: getEntityRef(entity), + }, + }); + } +} diff --git a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx index 0792dc639b..61f8025862 100644 --- a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx +++ b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx @@ -17,11 +17,11 @@ import React, { useState, useEffect, Dispatch, SetStateAction } from 'react'; import { Entity } from '@backstage/catalog-model'; import { SubmitHandler } from 'react-hook-form'; -import { updateMetadata } from '../../util/dbRequests'; import { useApi, configApiRef } from '@backstage/core-plugin-api'; import { ProjectDialog } from '../ProjectDialog'; import { ProjectSelector } from '../ProjectSelector'; -import { BazaarProject, FormValues, Status } from '../../util/types'; +import { BazaarProject, FormValues, Status } from '../../types'; +import { bazaarApiRef } from '../../api'; type Props = { catalogEntities: Entity[]; @@ -38,6 +38,7 @@ export const AddProjectDialog = ({ setBazaarProjects, setCatalogEntities, }: Props) => { + const bazaarApi = useApi(bazaarApiRef); const baseUrl = useApi(configApiRef) .getConfig('backend') .getString('baseUrl'); @@ -83,12 +84,12 @@ export const AddProjectDialog = ({ return oldEntities.filter(entity => entity !== selectedEntity); }); - await updateMetadata( + await bazaarApi.updateMetadata( + baseUrl, selectedEntity!, selectedEntity!.metadata.name, formValues.announcement, formValues.status, - baseUrl, ); handleClose(); diff --git a/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx b/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx index 50a38a7dfa..7b00cc5cd1 100644 --- a/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx +++ b/plugins/bazaar/src/components/DeleteProjectDialog/DeleteProjectDialog.tsx @@ -30,12 +30,8 @@ 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 { deleteEntity } from '../../util/dbRequests'; -import { - useApi, - configApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; +import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { bazaarApiRef } from '../../api'; const styles = (theme: Theme) => createStyles({ @@ -113,10 +109,10 @@ export const DeleteProjectDialog = ({ handleClose(); }; - const identity = useApi(identityApiRef); + const bazaarApi = useApi(bazaarApiRef); const handleSubmit = async () => { - await deleteEntity(baseUrl, entity, identity); + await bazaarApi.deleteEntity(baseUrl, entity); setIsBazaar(false); handleCloseAndClear(); }; diff --git a/plugins/bazaar/src/components/EditProjectDialog/EditProjectDialog.tsx b/plugins/bazaar/src/components/EditProjectDialog/EditProjectDialog.tsx index 6d2f3d650f..4f605a55ae 100644 --- a/plugins/bazaar/src/components/EditProjectDialog/EditProjectDialog.tsx +++ b/plugins/bazaar/src/components/EditProjectDialog/EditProjectDialog.tsx @@ -16,10 +16,10 @@ import React, { useState, useEffect, Dispatch, SetStateAction } from 'react'; import { Entity } from '@backstage/catalog-model'; -import { updateMetadata } from '../../util/dbRequests'; import { useApi, configApiRef } from '@backstage/core-plugin-api'; import { ProjectDialog } from '../ProjectDialog'; -import { BazaarProject, FormValues } from '../../util/types'; +import { BazaarProject, FormValues } from '../../types'; +import { bazaarApiRef } from '../../api'; type Props = { entity: Entity; @@ -46,6 +46,8 @@ export const EditProjectDialog = ({ status: bazaarProject.status, }); + const bazaarApi = useApi(bazaarApiRef); + useEffect(() => { setDefaultValues({ announcement: bazaarProject.announcement, @@ -56,12 +58,12 @@ export const EditProjectDialog = ({ const handleSave: any = async (getValues: any, _: any) => { const formValues = getValues(); - const updateResponse = await updateMetadata( + const updateResponse = await bazaarApi.updateMetadata( + baseUrl, entity!, entity.metadata.name, formValues.announcement, formValues.status, - baseUrl, ); if (updateResponse.status === 'ok') diff --git a/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx b/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx index eda80be660..2a5940a5fc 100644 --- a/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx +++ b/plugins/bazaar/src/components/EntityBazaarInfoCard/EntityBazaarInfoCard.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2021 Spotify AB + * Copyright 2021 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,9 +52,9 @@ import { identityApiRef, configApiRef, } from '@backstage/core-plugin-api'; -import { getEntityRef } from '../../util/dbRequests'; import { useAsync } from 'react-use'; -import { Member, BazaarProject } from '../../util/types'; +import { Member, BazaarProject } from '../../types'; +import { bazaarApiRef, getEntityRef } from '../../api'; const useStyles = makeStyles({ description: { @@ -82,11 +82,13 @@ const sortMembers = (m1: Member, m2: Member) => { export const EntityBazaarInfoCard = () => { const { entity } = useEntity(); const classes = useStyles(); + const bazaarApi = useApi(bazaarApiRef); + const identity = useApi(identityApiRef); const [anchorEl, setAnchorEl] = useState(); const [open, setOpen] = useState(false); const [popoverOpen, setPopoverOpen] = useState(false); const [openDelete, setOpenDelete] = useState(false); - const identity = useApi(identityApiRef); + const [isMember, setIsMember] = useState(false); const [members, setMembers] = useState([]); const [bazaarProject, setBazaarProject] = useState({ @@ -103,13 +105,7 @@ export const EntityBazaarInfoCard = () => { .getString('baseUrl'); const getInitMemberStatus = async () => { - const response = await fetch(`${baseUrl}/api/bazaar/members`, { - method: 'GET', - headers: { - entity_ref: getEntityRef(entity), - }, - }).then(resp => resp.json()); - + const response = await bazaarApi.getMembers(baseUrl, entity); const dbMembers = response.data.map((obj: any) => { const member: Member = { userId: obj.user_id, @@ -131,16 +127,11 @@ export const EntityBazaarInfoCard = () => { }; const getMetadata = async () => { - const response = await fetch(`${baseUrl}/api/bazaar/metadata`, { - method: 'GET', - headers: { - entity_ref: getEntityRef(entity), - }, - }); + const response = await bazaarApi.getMetadata(baseUrl, entity); if (response.status !== 404) { setIsBazaar(true); - const data = await response.json().then(resp => resp.data); + const data = await response.json().then((resp: any) => resp.data); setBazaarProject({ entityRef: data[0].entityRef, @@ -183,32 +174,20 @@ export const EntityBazaarInfoCard = () => { joinDate: new Date().toISOString(), }; - const headers = { - user_id: newMember.userId, - entity_ref: newMember.entityRef, - join_date: newMember.joinDate, - }; - if (!isMember) { setMembers((prevMembers: Member[]) => { const newMembers: Member[] = [...prevMembers, newMember]; newMembers.sort(sortMembers); return newMembers; }); - await fetch(`${baseUrl}/api/bazaar/members/add`, { - method: 'PUT', - headers: headers, - }); + await bazaarApi.addMember(baseUrl, entity); } else { setMembers( members.filter( (member: Member) => member.userId !== identity.getUserId(), ), ); - await fetch(`${baseUrl}/api/bazaar/members/remove`, { - method: 'DELETE', - headers: headers, - }); + await bazaarApi.deleteMember(baseUrl, entity); } }; diff --git a/plugins/bazaar/src/components/EntityBazaarInfoCard/index.ts b/plugins/bazaar/src/components/EntityBazaarInfoCard/index.ts index 7b76eb3fdf..89eee92f11 100644 --- a/plugins/bazaar/src/components/EntityBazaarInfoCard/index.ts +++ b/plugins/bazaar/src/components/EntityBazaarInfoCard/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 Spotify AB + * Copyright 2021 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/bazaar/src/components/InputField/InputField.tsx b/plugins/bazaar/src/components/InputField/InputField.tsx index 631abbee90..68dd201c55 100644 --- a/plugins/bazaar/src/components/InputField/InputField.tsx +++ b/plugins/bazaar/src/components/InputField/InputField.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { Controller, Control, FieldError } from 'react-hook-form'; import { TextField } from '@material-ui/core'; -import { FormValues } from '../../util/types'; +import { FormValues } from '../../types'; type Props = { inputType: string; diff --git a/plugins/bazaar/src/components/InputSelector/InputSelector.tsx b/plugins/bazaar/src/components/InputSelector/InputSelector.tsx index 2617eb1311..4aa7f265a0 100644 --- a/plugins/bazaar/src/components/InputSelector/InputSelector.tsx +++ b/plugins/bazaar/src/components/InputSelector/InputSelector.tsx @@ -20,7 +20,7 @@ import MenuItem from '@material-ui/core/MenuItem'; import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; import { Controller, Control, FieldError } from 'react-hook-form'; -import { FormValues } from '../../util/types'; +import { FormValues } from '../../types'; type Props = { options: string[]; diff --git a/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx b/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx index 6c0fe5986a..d7501c1501 100644 --- a/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx +++ b/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx @@ -28,7 +28,7 @@ import { Link as RouterLink } from 'react-router-dom'; import moment from 'moment'; import { catalogRouteRef } from '@backstage/plugin-catalog-react'; import { useRouteRef } from '@backstage/core-plugin-api'; -import { BazaarProject } from '../../util/types'; +import { BazaarProject } from '../../types'; const useStyles = makeStyles({ statusTag: { diff --git a/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx b/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx index cfc2a8b075..79a09d18a1 100644 --- a/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx +++ b/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx @@ -29,7 +29,7 @@ import { Button, Dialog, Typography, IconButton } from '@material-ui/core'; import { useForm, SubmitHandler } from 'react-hook-form'; import { InputField } from '../InputField/InputField'; import { InputSelector } from '../InputSelector/InputSelector'; -import { FormValues } from '../../util/types'; +import { FormValues } from '../../types'; const styles = (theme: Theme) => createStyles({ diff --git a/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx b/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx index 5d16fafcec..151fa19522 100644 --- a/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx +++ b/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx @@ -19,7 +19,7 @@ import { Content } from '@backstage/core-components'; import { ProjectCard } from '../ProjectCard/ProjectCard'; import { makeStyles, Grid } from '@material-ui/core'; import Pagination from '@material-ui/lab/Pagination'; -import { BazaarProject } from '../../util/types'; +import { BazaarProject } from '../../types'; type Props = { bazaarProjects: BazaarProject[]; diff --git a/plugins/bazaar/src/components/SortView/SortView.tsx b/plugins/bazaar/src/components/SortView/SortView.tsx index 775978b3a7..69f5b38cdf 100644 --- a/plugins/bazaar/src/components/SortView/SortView.tsx +++ b/plugins/bazaar/src/components/SortView/SortView.tsx @@ -27,13 +27,13 @@ import { ProjectPreview } from '../ProjectPreview/ProjectPreview'; import { Button, makeStyles, Link } from '@material-ui/core'; import { useAsync } from 'react-use'; import { Entity } from '@backstage/catalog-model'; -import { getBazaarMembers } from '../../util/dbRequests'; import { useApi, configApiRef } from '@backstage/core-plugin-api'; import { catalogApiRef, CATALOG_FILTER_EXISTS, } from '@backstage/plugin-catalog-react'; -import { BazaarProject } from '../../util/types'; +import { BazaarProject } from '../../types'; +import { bazaarApiRef } from '../../api'; const useStyles = makeStyles({ container: { @@ -50,6 +50,7 @@ export const SortView = () => { new Map(), ); const [bazaarProjects, setBazaarProjects] = useState([]); + const bazaarApi = useApi(bazaarApiRef); const catalogApi = useApi(catalogApiRef); const baseUrl = useApi(configApiRef) .getConfig('backend') @@ -77,10 +78,7 @@ export const SortView = () => { fields: ['apiVersion', 'kind', 'metadata', 'spec'], }); - const response = await fetch(`${baseUrl}/api/bazaar/entities`, { - method: 'GET', - }).then(resp => resp.json()); - + const response = await bazaarApi.getEntities(baseUrl); const dbProjects: BazaarProject[] = []; const bazaarProjectRefs: string[] = []; @@ -96,7 +94,7 @@ export const SortView = () => { bazaarProjectRefs.push(project.entity_ref); }); - setBazaarMembers(await getBazaarMembers(dbProjects, baseUrl)); + setBazaarMembers(await bazaarApi.getMemberCounts(dbProjects, baseUrl)); setBazaarProjects(dbProjects); setCatalogEntities( entities.items.filter((entity: Entity) => { diff --git a/plugins/bazaar/src/components/StatusTag/StatusTag.tsx b/plugins/bazaar/src/components/StatusTag/StatusTag.tsx index 69b07c35ca..eb01ea5350 100644 --- a/plugins/bazaar/src/components/StatusTag/StatusTag.tsx +++ b/plugins/bazaar/src/components/StatusTag/StatusTag.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { StatusOK, StatusWarning } from '@backstage/core-components'; -import { Status } from '../../util/types'; +import { Status } from '../../types'; interface StatusComponent { [key: string]: JSX.Element | undefined; diff --git a/plugins/bazaar/src/plugin.ts b/plugins/bazaar/src/plugin.ts index fe8ce45d2c..5fd884bd35 100644 --- a/plugins/bazaar/src/plugin.ts +++ b/plugins/bazaar/src/plugin.ts @@ -14,18 +14,29 @@ * limitations under the License. */ +import { rootRouteRef } from './routes'; import { + createApiFactory, createPlugin, createRoutableExtension, + identityApiRef, } from '@backstage/core-plugin-api'; - -import { rootRouteRef } from './routes'; +import { bazaarApiRef, BazaarClient } from './api'; export const bazaarPlugin = createPlugin({ id: 'bazaar', routes: { root: rootRouteRef, }, + apis: [ + createApiFactory({ + api: bazaarApiRef, + deps: { + identityApi: identityApiRef, + }, + factory: ({ identityApi }) => new BazaarClient({ identityApi }), + }), + ], }); export const BazaarPage = bazaarPlugin.provide( diff --git a/plugins/bazaar/src/util/types.ts b/plugins/bazaar/src/types.ts similarity index 100% rename from plugins/bazaar/src/util/types.ts rename to plugins/bazaar/src/types.ts diff --git a/plugins/bazaar/src/util/dbRequests.ts b/plugins/bazaar/src/util/dbRequests.ts deleted file mode 100644 index 3e51a7d0ad..0000000000 --- a/plugins/bazaar/src/util/dbRequests.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entity } from '@backstage/catalog-model'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { BazaarProject, Status } from './types'; - -export const getEntityRef = (entity: Entity) => { - return `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`; -}; - -export const updateMetadata = async ( - entity: Entity, - name: string, - announcement: string, - status: Status, - baseUrl: string, -) => { - return await fetch(`${baseUrl}/api/bazaar/metadata`, { - method: 'PUT', - headers: { - entity_ref: getEntityRef(entity), - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - name: name, - announcement: announcement, - status: status, - }), - }).then(resp => resp.json()); -}; - -export const getBazaarMembers = async ( - bazaarProjects: BazaarProject[], - baseUrl: string, -) => { - const bazaarMembers = new Map(); - for (const project of bazaarProjects) { - const response = await fetch(`${baseUrl}/api/bazaar/members`, { - method: 'GET', - headers: { - entity_ref: project.entityRef, - }, - }); - - const json = await response.json(); - const nbrOfMembers = await json.data.length; - bazaarMembers.set(project.entityRef, nbrOfMembers); - } - return bazaarMembers; -}; - -export const deleteEntity = async ( - baseUrl: string, - entity: Entity, - identity: IdentityApi, -) => { - await fetch(`${baseUrl}/api/bazaar/metadata`, { - method: 'DELETE', - headers: { - entity_ref: getEntityRef(entity), - }, - }); - - await fetch(`${baseUrl}/api/bazaar/members/remove`, { - method: 'DELETE', - headers: { - user_id: identity.getUserId(), - entity_ref: getEntityRef(entity), - }, - }); -};