From 02b97896c89dbedb7c4cfbc5b9f2521f5a7639a7 Mon Sep 17 00:00:00 2001 From: Ewan Cahen Date: Fri, 7 Oct 2022 16:49:50 +0200 Subject: [PATCH] feat: add simple admin page to add and delete ORCIDs to and from the whitelist --- frontend/config/userMenuItems.tsx | 9 ++ frontend/pages/admin/orcid-whitelist.tsx | 106 +++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 frontend/pages/admin/orcid-whitelist.tsx diff --git a/frontend/config/userMenuItems.tsx b/frontend/config/userMenuItems.tsx index b4f3b3fe5..57665deda 100644 --- a/frontend/config/userMenuItems.tsx +++ b/frontend/config/userMenuItems.tsx @@ -1,5 +1,7 @@ // SPDX-FileCopyrightText: 2021 - 2022 Dusan Mijatovic (dv4all) // SPDX-FileCopyrightText: 2021 - 2022 dv4all +// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) +// SPDX-FileCopyrightText: 2022 Netherlands eScience Center // // SPDX-License-Identifier: Apache-2.0 @@ -7,6 +9,7 @@ import TerminalIcon from '@mui/icons-material/Terminal' import ListAltIcon from '@mui/icons-material/ListAlt' import BusinessIcon from '@mui/icons-material/Business' import ManageAccountsIcon from '@mui/icons-material/ManageAccounts' +import PlaylistAddCheckIcon from '@mui/icons-material/PlaylistAddCheck'; import Logout from '@mui/icons-material/Logout' import {MenuItemType} from './menuItems' @@ -40,6 +43,12 @@ const userMenuItems: MenuItemType[] = [ label: 'Administration', path: '/admin/pages', icon: + }, { + role:['rsd_admin'], + type: 'link', + label: 'ORCID whitelist', + path: '/admin/orcid-whitelist', + icon: }, { role:['rsd_admin'], type: 'divider', diff --git a/frontend/pages/admin/orcid-whitelist.tsx b/frontend/pages/admin/orcid-whitelist.tsx new file mode 100644 index 000000000..b6e640115 --- /dev/null +++ b/frontend/pages/admin/orcid-whitelist.tsx @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) +// SPDX-FileCopyrightText: 2022 Netherlands eScience Center +// +// SPDX-License-Identifier: Apache-2.0 + +import Head from 'next/head' +import {GetServerSidePropsContext} from 'next' + +import {app} from '../../config/app' +import RsdAdminContent from '~/auth/RsdAdminContent' +import DefaultLayout from '~/components/layout/DefaultLayout' +import List from '@mui/material/List' +import ListItem from '@mui/material/ListItem' +import DeleteIcon from '@mui/icons-material/Delete' +import IconButton from '@mui/material/IconButton' +import {createJsonHeaders} from '~/utils/fetchHelpers' +import useSnackbar from '~/components/snackbar/useSnackbar' +import EditSectionTitle from '~/components/layout/EditSectionTitle' +import {useSession} from '~/auth' +import {useEffect, useState} from 'react' +import Link from '@mui/material/Link' +import {Button, TextField} from '@mui/material' + +export default function OrcidWitelistPage() { + const pageTitle = `ORCID whitelist | ${app.title}` + const {showErrorMessage, showInfoMessage} = useSnackbar() + + const [orcids, setOrcids] = useState([]) + const {token} = useSession() + + async function fetchWhitelistedOrcids() { + const resp = await fetch('/api/v1/orcid_whitelist', { + headers: createJsonHeaders(token) + }) + const respJson: {orcid: string}[] = await resp.json() + setOrcids(respJson.map(orcidObject => orcidObject.orcid)) + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + useEffect(() => {fetchWhitelistedOrcids()}, []) + + async function submitOrcid() { + const formField = document.getElementById('orcid-input') as HTMLInputElement + const submittedOrcid = formField.value + + const resp = await fetch('/api/v1/orcid_whitelist', { + body: JSON.stringify({'orcid': submittedOrcid}), + headers: createJsonHeaders(token), + method: 'POST' + }) + if (resp.status !== 201) showErrorMessage('Failed to add ORCID.') + + fetchWhitelistedOrcids() + } + + return ( + + + {pageTitle} + + + +
{e.preventDefault(); submitOrcid()}}> + + + + fetchWhitelistedOrcids()} + token={token}/> +
+
+ ) +} + +function OrcidWhitelist({orcids, onDeleteCallback, token}: {orcids: string[], onDeleteCallback: Function, token: string}) { + const {showErrorMessage, showInfoMessage} = useSnackbar() + + async function deleteOrcid(orcid: string) { + const resp = await fetch(`/api/v1/orcid_whitelist?orcid=eq.${orcid}`, { + headers: createJsonHeaders(token), + method: 'DELETE' + }) + if (resp.status !== 204) showErrorMessage('Failed to delete ORCID.') + onDeleteCallback() + } + + + return( + <> + + + {orcids.map(orcid => { + return ( + + + {orcid} + + deleteOrcid(orcid)}> + + ) + })} + + + ) +}