diff --git a/compose.yaml b/docker-compose.yaml similarity index 100% rename from compose.yaml rename to docker-compose.yaml diff --git a/xas-standards-client/src/App.tsx b/xas-standards-client/src/App.tsx index 8902844..8fcf423 100644 --- a/xas-standards-client/src/App.tsx +++ b/xas-standards-client/src/App.tsx @@ -11,7 +11,7 @@ import LogInPage from "./components/LogInPage.tsx"; import RequireAuth from "./components/RequireAuth.tsx"; import { CssBaseline } from "@mui/material"; -import {useMediaQuery} from "@mui/material"; +import { useMediaQuery } from "@mui/material"; import { useState, useMemo } from "react"; import { Stack } from "@mui/material"; @@ -20,9 +20,10 @@ import { createTheme, ThemeProvider } from "@mui/material/styles"; import ReviewPage from "./components/ReviewPage.tsx"; function App() { - - const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); - const [mode, setMode] = useState<"light" | "dark">(prefersDarkMode ? "dark" : "light"); + const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)"); + const [mode, setMode] = useState<"light" | "dark">( + prefersDarkMode ? "dark" : "light" + ); const colorMode = useMemo( () => ({ toggleColorMode: () => { @@ -43,31 +44,33 @@ function App() { ); return ( - - - - -
- - - } /> - } /> - - - - } - /> - } /> - } /> - {/* } /> */} - - - - - + + + + +
+ + + } /> + } /> + + + + } + /> + } /> + } /> + + + + + ); } diff --git a/xas-standards-client/src/components/DarkModeIcon.tsx b/xas-standards-client/src/components/DarkModeIcon.tsx index 192e642..b69773a 100644 --- a/xas-standards-client/src/components/DarkModeIcon.tsx +++ b/xas-standards-client/src/components/DarkModeIcon.tsx @@ -1,12 +1,17 @@ - - -import { SvgIcon } from "@mui/material" +import { SvgIcon } from "@mui/material"; export default function DarkModeIcon() { - return ( - - - - - ) -} \ No newline at end of file + return ( + + + + + + ); +} diff --git a/xas-standards-client/src/components/Header.tsx b/xas-standards-client/src/components/Header.tsx index 2d8fd18..13d2f32 100644 --- a/xas-standards-client/src/components/Header.tsx +++ b/xas-standards-client/src/components/Header.tsx @@ -10,7 +10,7 @@ import ListItem from "@mui/material/ListItem"; import List from "@mui/material/List"; import ListItemText from "@mui/material/ListItemText"; import Stack from "@mui/material/Stack"; -import {Checkbox, Switch } from "@mui/material"; +import { Checkbox } from "@mui/material"; import { NavLink } from "react-router-dom"; @@ -41,11 +41,14 @@ function NavListItem(props: { to: string; label: string }) { ); } -export default function Header(props : {colorMode : string; toggleColorMode : any }) { +export default function Header(props: { + colorMode: string; + toggleColorMode: () => void; +}) { const user = useContext(UserContext); console.log(user); const loggedIn = user != null; - const admin = user != null && user.admin + const admin = user != null && user.admin; console.log(loggedIn); const navitems = { @@ -57,47 +60,47 @@ export default function Header(props : {colorMode : string; toggleColorMode : an return ( - + - - - XAS Standards - - - {Object.entries(navitems).map(([key, value]) => ( - - theme.palette.text.secondary, - }, - }} - > - - - - ))} - {loggedIn && ( - - ) } - {admin && ( - - ) } - + + + XAS Standards + + + {Object.entries(navitems).map(([key, value]) => ( + + theme.palette.text.secondary, + }, + }} + > + + + + ))} + {loggedIn && } + {admin && } + - } checkedIcon={} checked={props.colorMode === "dark"} onChange={props.toggleColorMode.toggleColorMode}> - {!loggedIn ? ( + } + checkedIcon={} + checked={props.colorMode === "dark"} + onChange={props.toggleColorMode} + > + {!loggedIn ? ( - ) : ( - - - {user.identifier} - - - )} + ) : ( + + + {user.identifier} + + )} diff --git a/xas-standards-client/src/components/LightModeIcon.tsx b/xas-standards-client/src/components/LightModeIcon.tsx index 198cc84..227279e 100644 --- a/xas-standards-client/src/components/LightModeIcon.tsx +++ b/xas-standards-client/src/components/LightModeIcon.tsx @@ -1,11 +1,17 @@ -import { SvgIcon } from "@mui/material" +import { SvgIcon } from "@mui/material"; export default function LightModeIcon() { - return ( - - - - - - ) -} \ No newline at end of file + return ( + + + + + + ); +} diff --git a/xas-standards-client/src/components/ReviewPage.tsx b/xas-standards-client/src/components/ReviewPage.tsx index b00612e..ea0a607 100644 --- a/xas-standards-client/src/components/ReviewPage.tsx +++ b/xas-standards-client/src/components/ReviewPage.tsx @@ -9,7 +9,7 @@ import { useState } from "react"; import { XASData, AdminXASStandard } from "../models"; -const data_url = "/api/data"; +const data_url = "/api/admin/data"; function ReviewPage() { const [standards, setStandardsList] = useState([]); @@ -20,11 +20,9 @@ function ReviewPage() { const [showRef, setShowRef] = useState(false); const [contains, setContains] = useState([false, false, false]); - - - function getData(setXASData: React.Dispatch) { + function getData() { return (id: number) => { - axios.get(data_url + "/" + id).then((response) => { + axios.get(data_url + "/" + id + "/?format=json").then((response) => { const output: XASData = response.data as XASData; const containsTrans = output != null && output.mutrans.length != 0; const containsFluor = output != null && output.mufluor.length != 0; @@ -40,7 +38,7 @@ function ReviewPage() { }; } - const onClick = getData(setXASData); + const onClick = getData(); return ( diff --git a/xas-standards-client/src/components/ReviewTab.tsx b/xas-standards-client/src/components/ReviewTab.tsx index 1da2a5b..459ce40 100644 --- a/xas-standards-client/src/components/ReviewTab.tsx +++ b/xas-standards-client/src/components/ReviewTab.tsx @@ -1,5 +1,4 @@ - -import { Tab, Tabs, Box} from "@mui/material"; +import { Tab, Tabs, Box } from "@mui/material"; import StandardMetadataCard from "./StandardMetadataCard"; import ReviewTextView from "./ReviewTextView"; @@ -7,60 +6,66 @@ import ReviewTextView from "./ReviewTextView"; import { useState } from "react"; import ReviewCard from "./ReviewCard"; +import { AdminXASStandard } from "../models"; + interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; - } - - function CustomTabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; - - return ( - - ); - } - - function a11yProps(index: number) { - return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, - }; - } + children?: React.ReactNode; + index: number; + value: number; +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + "aria-controls": `simple-tabpanel-${index}`, + }; +} -export default function ReviewTab(props: { standard: XASStandard }) { - const [value, setValue] = useState(0); +export default function ReviewTab(props: { standard: AdminXASStandard }) { + const [value, setValue] = useState(0); const handleChange = (event: React.SyntheticEvent, newValue: number) => { setValue(newValue); }; return ( - - - + + + - + - + - + ); -} \ No newline at end of file +} diff --git a/xas-standards-client/src/components/ReviewTable.tsx b/xas-standards-client/src/components/ReviewTable.tsx index 775ba3d..2c000fb 100644 --- a/xas-standards-client/src/components/ReviewTable.tsx +++ b/xas-standards-client/src/components/ReviewTable.tsx @@ -1,6 +1,4 @@ import StandardsTableView from "./StandardsTableView" -import StandardMetadataCard from "./StandardMetadataCard"; -import ReviewCard from "./ReviewCard"; import { Stack } from "@mui/material"; @@ -18,8 +16,8 @@ const nResults = 7; export default function ReviewTable(props : { standards: AdminXASStandard[]; - setStandards: React.Dispatch; - updatePlot: React.Dispatch; + setStandards: (standards : XASStandard[]) => void; + updatePlot: (id : number) => void; }) { const [selectedStandard, setSelectedStandard] = useState(); diff --git a/xas-standards-client/src/components/StandardViewer.tsx b/xas-standards-client/src/components/StandardViewer.tsx index 52f2523..888867f 100644 --- a/xas-standards-client/src/components/StandardViewer.tsx +++ b/xas-standards-client/src/components/StandardViewer.tsx @@ -22,7 +22,7 @@ function StandardViewer() { const { elements } = useContext(MetadataContext); - function getData(setXASData: React.Dispatch) { + function getData() { return (id: number) => { axios.get(data_url + "/" + id).then((response) => { const output: XASData = response.data as XASData; @@ -40,7 +40,7 @@ function StandardViewer() { }; } - const onClick = getData(setXASData); + const onClick = getData(); return ( diff --git a/xas-standards-client/src/components/StandardsChart.tsx b/xas-standards-client/src/components/StandardsChart.tsx index bc7cd02..8008f34 100644 --- a/xas-standards-client/src/components/StandardsChart.tsx +++ b/xas-standards-client/src/components/StandardsChart.tsx @@ -35,9 +35,9 @@ function XASChart(props: { showTrans: boolean; showFluor: boolean; showRef: boolean; - setShowTrans: React.Dispatch>; - setShowFluor: React.Dispatch>; - setShowRef: React.Dispatch>; + setShowTrans: (show: boolean) => void; + setShowFluor: (show: boolean) => void; + setShowRef: (show: boolean) => void; contains: boolean[]; }) { const curveOptions: CurveType[] = Object.values( diff --git a/xas-standards-client/src/components/StandardsTable.tsx b/xas-standards-client/src/components/StandardsTable.tsx index 0cd7f15..4fdcc09 100644 --- a/xas-standards-client/src/components/StandardsTable.tsx +++ b/xas-standards-client/src/components/StandardsTable.tsx @@ -17,8 +17,8 @@ const nResults = 7; function StandardsTable(props: { standards: XASStandard[]; elements: Element[]; - setStandards: React.Dispatch; - updatePlot: React.Dispatch; + setStandards: (standards : XASStandard[]) => void; + updatePlot: (id: number) => void; }): JSX.Element { const [selectedStandard, setSelectedStandard] = useState(); const [selectedElement, setSelectedElement] = useState(0); diff --git a/xas-standards-client/src/components/StandardsTableView.tsx b/xas-standards-client/src/components/StandardsTableView.tsx index 1c5e608..64eb1a9 100644 --- a/xas-standards-client/src/components/StandardsTableView.tsx +++ b/xas-standards-client/src/components/StandardsTableView.tsx @@ -6,7 +6,7 @@ import { tableCellClasses } from "@mui/material/TableCell"; import { styled } from "@mui/material/styles"; import { useState } from "react"; -import { XASStandard } from "../models"; +import { XASStandard, AdminXASStandard } from "../models"; const nResults = 7; @@ -32,14 +32,10 @@ const StyledTableCell = styled(TableCell)(({ theme }) => ({ }, })); - - - - function StandardMetadata(props: { key: number; xasstandard: XASStandard | null; - selected: XASStandard | undefined; + selected: AdminXASStandard | XASStandard | undefined; updatePlot: React.Dispatch; selectedRow: number; setSelectedRow: React.Dispatch>; @@ -79,19 +75,20 @@ function StandardMetadata(props: { export default function StandardsTableView(props : { standards : XASStandard[]; - updatePlot : React.Dispatch; + updatePlot : (id: number) => void; selectedStandard: XASStandard | undefined; - setSelectedStandard : React.Dispatch>; - setCurrent: React.Dispatch>; + setSelectedStandard : (x: XASStandard | AdminXASStandard | undefined) => void; + setCurrent: (cursor : string | null) => void; prevNext: string[] | null}) { + const [selectedRow, setSelectedRow] = useState(-1); const nextPage = () => { - props.setCurrent(props.prevNext[1]); + props.setCurrent(props.prevNext == null ? null : props.prevNext[1]); }; const prevPage = () => { - props.setCurrent(props.prevNext[0]); + props.setCurrent(props.prevNext == null ? null : props.prevNext[0]); }; const clickStandard = (standard: XASStandard) => { diff --git a/xas-standards-client/src/components/UserIcon.tsx b/xas-standards-client/src/components/UserIcon.tsx index 859450f..6a3b336 100644 --- a/xas-standards-client/src/components/UserIcon.tsx +++ b/xas-standards-client/src/components/UserIcon.tsx @@ -3,8 +3,13 @@ import { SvgIcon } from "@mui/material" export default function UserIcon() { return ( - - - + + + + ) } \ No newline at end of file diff --git a/xas-standards-client/src/components/submission/AdditionalInfoForm.tsx b/xas-standards-client/src/components/submission/AdditionalInfoForm.tsx index dae8311..505da5c 100644 --- a/xas-standards-client/src/components/submission/AdditionalInfoForm.tsx +++ b/xas-standards-client/src/components/submission/AdditionalInfoForm.tsx @@ -1,13 +1,11 @@ - -import { Grid, TextField, Button} from "@mui/material"; +import { Grid, TextField, Button } from "@mui/material"; import VisuallyHiddenInput from "./VisuallyHiddenInput"; -function AdditionalInformationForm(props : { - comments : string; - setComments: React.Dispatch>; - handleFile2 : React.ChangeEventHandler; - +function AdditionalInformationForm(props: { + comments: string; + setComments: (comments: string) => void; + handleFile2: React.ChangeEventHandler; }) { const comments = props.comments; const setComments = props.setComments; @@ -18,7 +16,7 @@ function AdditionalInformationForm(props : { Additional Information - - + ); diff --git a/xas-standards-client/src/components/submission/CitationForm.tsx b/xas-standards-client/src/components/submission/CitationForm.tsx index 3f15060..fc243ac 100644 --- a/xas-standards-client/src/components/submission/CitationForm.tsx +++ b/xas-standards-client/src/components/submission/CitationForm.tsx @@ -6,11 +6,11 @@ import { Grid, TextField, Button, Typography } from "@mui/material"; const crossref_url = "https://api.crossref.org/works/"; const mailto = "?mailto=dataanalysis@diamond.ac.uk"; -function CitationForm(props : { - citation : string; - setCitation: React.Dispatch>; +function CitationForm(props: { + citation: string; + setCitation: (citation: string) => void; doi: string; - setDOI: React.Dispatch>; + setDOI: (doi: string) => void; }) { const citation = props.citation; const setCitation = props.setCitation; @@ -60,13 +60,11 @@ function CitationForm(props : { /> - + - {isValidDOI ? "Valid DOI" : "Invalid DOI"} - + {isValidDOI ? "Valid DOI" : "Invalid DOI"} + ); } diff --git a/xas-standards-client/src/components/submission/ElementForm.tsx b/xas-standards-client/src/components/submission/ElementForm.tsx index e0cb5a7..ea5bc7a 100644 --- a/xas-standards-client/src/components/submission/ElementForm.tsx +++ b/xas-standards-client/src/components/submission/ElementForm.tsx @@ -1,12 +1,19 @@ -import { Select, Box, MenuItem, FormControl, InputLabel, Stack } from "@mui/material"; +import { + Select, + Box, + MenuItem, + FormControl, + InputLabel, + Stack, +} from "@mui/material"; import { Element, Edge } from "../../models"; function ElementForm(props: { elementId: number; - setElementId: React.Dispatch>; + setElementId: (id: number) => void; edgeId: number; - setEdgeId: React.Dispatch>; + setEdgeId: (id: number) => void; elements: Element[]; edges: Edge[]; }) { @@ -24,7 +31,7 @@ function ElementForm(props: { Element - + ); } diff --git a/xas-standards-client/src/components/submission/InstrumentForm.tsx b/xas-standards-client/src/components/submission/InstrumentForm.tsx index e418a5f..09620e1 100644 --- a/xas-standards-client/src/components/submission/InstrumentForm.tsx +++ b/xas-standards-client/src/components/submission/InstrumentForm.tsx @@ -10,13 +10,13 @@ import { import { Beamline } from "../../models"; -function InstrumentForm(props : { - beamlines : Beamline[] +function InstrumentForm(props: { + beamlines: Beamline[]; beamlineHeader: string; beamlineId: number; - setBeamlineId: React.Dispatch>; + setBeamlineId: (id: number) => void; date: string; - setDate: React.Dispatch>; + setDate: (data: string) => void; }) { const beamlines = props.beamlines; const beamlineHeader = props.beamlineHeader; @@ -26,11 +26,18 @@ function InstrumentForm(props : { const setDate = props.setDate; return ( - + Instrument - Beamline + + Beamline + setLicence(e.target.value)} - > - {licences.map((x, y) => ( - - {x} - - ))} - - - - } label="By ticking I confirm info is correct and I grant permission for - diamond to publish data under selected licence" /> - + + + Licence + + + + + } + label="By ticking I confirm info is correct and I grant permission for + diamond to publish data under selected licence" + /> + - - diff --git a/xas-standards-client/src/components/submission/VisuallyHiddenInput.tsx b/xas-standards-client/src/components/submission/VisuallyHiddenInput.tsx index e32a05a..11b3395 100644 --- a/xas-standards-client/src/components/submission/VisuallyHiddenInput.tsx +++ b/xas-standards-client/src/components/submission/VisuallyHiddenInput.tsx @@ -1,15 +1,15 @@ -import { styled } from '@mui/material/styles'; +import { styled } from "@mui/material/styles"; -const VisuallyHiddenInput = styled('input')({ - clip: 'rect(0 0 0 0)', - clipPath: 'inset(50%)', - height: 1, - overflow: 'hidden', - position: 'absolute', - bottom: 0, - left: 0, - whiteSpace: 'nowrap', - width: 1, - }); +const VisuallyHiddenInput = styled("input")({ + clip: "rect(0 0 0 0)", + clipPath: "inset(50%)", + height: 1, + overflow: "hidden", + position: "absolute", + bottom: 0, + left: 0, + whiteSpace: "nowrap", + width: 1, +}); - export default VisuallyHiddenInput \ No newline at end of file +export default VisuallyHiddenInput; diff --git a/xas-standards-client/src/main.tsx b/xas-standards-client/src/main.tsx index 29b2765..83f5e20 100644 --- a/xas-standards-client/src/main.tsx +++ b/xas-standards-client/src/main.tsx @@ -10,7 +10,7 @@ async function enableMocking() { return; } - axios.defaults.headers.common['Authorization'] = 'Bearer Test User' + axios.defaults.headers.common["Authorization"] = "Bearer Test User"; const { worker } = await import("./mocks/browser"); diff --git a/xas-standards-client/src/mocks/data_response.ts b/xas-standards-client/src/mocks/data_response.ts index ff74262..f6a1019 100644 --- a/xas-standards-client/src/mocks/data_response.ts +++ b/xas-standards-client/src/mocks/data_response.ts @@ -1,4 +1,4 @@ -export const response = { +export const data_response = { energy: [ 11649.994, 11660.005, 11669.997, 11680.006, 11689.996, 11700.005, 11709.994, 11720.002, 11730.003, 11739.995, 11749.996, 11760.0, 11769.997, 11779.999, diff --git a/xas-standards-client/src/mocks/handlers.ts b/xas-standards-client/src/mocks/handlers.ts index 567152a..2c00132 100644 --- a/xas-standards-client/src/mocks/handlers.ts +++ b/xas-standards-client/src/mocks/handlers.ts @@ -10,7 +10,7 @@ import { AdminXASStandard, } from "../models"; -import { response } from "./data_response"; +import { data_response } from "./data_response"; //api/user @@ -139,11 +139,20 @@ export const handlers = [ http.get("/api/data/*", () => { // ...and respond to them using this JSON response. - return HttpResponse.json(response); + return HttpResponse.json(data_response); }), - http.get("/api/admin/data/*", () => { + http.get("/api/admin/data/*", ({request}) => { + + const url = new URL(request.url) + + const format = url.searchParams.get('format') + + if (format === "json") { + return HttpResponse.json(data_response); + } + const file_content = "# XDI/1.0\n# Column.1: energy eV\n# Column.2: i0\n# Column.3: itrans\n# Column.4: irefer\n# Beamline.name: SSRL 4-3\n# Detector.I0: N2 15cm\n# Detector.I1: N2 30cm\n# Detector.I2: N2 15cm\n# Element.edge: K\n# Element.symbol: Mn\n# Mono.d_spacing: 1.92009\n# Mono.name: Si(220)\n# Mono.notes: unfocused, detuned 10%\n# Sample.formula: MnO\n# Sample.name: MnO\n# Sample.prep: powder, mixed with B(OH)3\n# Sample.reference: Mn filter\n# Sample.temperature: room temperature\n# Scan.start_time: 1995-06-20 02:43:21\n# ///\n# Note: mono d_spacing is nominal!\n# 217 E XMU I0\n#-------------\n# energy i0 itrans irefer\n 6520.0030 31260.500000 39559.300308 21748.998701\n 6521.0010 31244.500000 39558.301090 21716.000970\n 6522.0000 31237.500000 39580.299067 21723.999044\n 6523.0000 31219.500000 39528.301127 21592.000515\n 6523.9990 31208.500000 39531.301203 21565.999852\n 6524.9990 31201.500000 39519.300411 21505.000093\n 6525.9990 31194.500000 39532.301500 21492.999925\n 6527.0000 31185.500000 39519.299329 21431.998092\n 6528.0000 31175.500000 39487.301134 21332.000793\n 6529.0020 31166.500000 39494.301671 21298.999505\n 6530.0030 31163.500000 39482.302684 21245.999911\n 6531.0060 31152.500000 39481.302240 21203.000376\n 6532.0080 31148.500000 39485.301549 21151.000091\n 6533.0110 31127.500000 39419.301134 21016.000430\n" return HttpResponse.text(file_content) }), diff --git a/xas-standards-client/src/models.ts b/xas-standards-client/src/models.ts index 3a631fd..42827e9 100644 --- a/xas-standards-client/src/models.ts +++ b/xas-standards-client/src/models.ts @@ -8,6 +8,10 @@ export interface Edge { id: number; } +export interface Person { + identifier: string; +} + export interface XASData { energy: Array; mutrans: Array; @@ -39,6 +43,10 @@ export interface XASStandard { beamline: Beamline; } +export interface AdminXASStandard extends XASStandard { + submitter: Person +} + export interface XASStandardInput { file1: File; licence: string;