From 4c8d8ffdbd79ab66767a6c86680f60e6c3fb44e8 Mon Sep 17 00:00:00 2001 From: Jacob Filik Date: Thu, 11 Jul 2024 13:06:14 +0100 Subject: [PATCH] Sampleform (#18) * Stop hosting client in fastapi * fix lint * add code for sample form enum * fix tests --- database/tables.sql | 4 ++- .../src/xas_standards_api/crud.py | 12 +++++++ .../src/xas_standards_api/models/models.py | 8 ++++- .../models/response_models.py | 1 + .../src/xas_standards_api/routers/open.py | 14 +++++++- .../xas_standards_api/routers/protected.py | 2 ++ .../tests/test_protected_router.py | 1 + xas-standards-api/tests/utils.py | 2 ++ .../src/components/submission/SampleForm.tsx | 36 +++++++++++++++---- .../submission/StandardSubmission.tsx | 8 ++++- xas-standards-client/src/hooks/useMetadata.ts | 1 + xas-standards-client/src/models.ts | 1 + 12 files changed, 79 insertions(+), 11 deletions(-) diff --git a/database/tables.sql b/database/tables.sql index a65ace6..aff6a3f 100644 --- a/database/tables.sql +++ b/database/tables.sql @@ -224,7 +224,8 @@ CREATE TABLE xas_standard_data ( COMMENT ON TABLE xas_standard_data IS 'Data file storing the standard data'; CREATE TYPE review_status_enum AS ENUM('pending', 'approved', 'rejected'); -CREATE TYPE licence_enum AS ENUM('cc_by', 'cc_0', 'logged_in_only'); +CREATE TYPE licence_enum AS ENUM('cc_by', 'cc_0'); +CREATE TYPE sample_form_enum AS ENUM('other', 'foil', 'pellet'); CREATE Table xas_standard ( id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, @@ -241,6 +242,7 @@ CREATE Table xas_standard ( sample_name TEXT, sample_prep TEXT, sample_comp TEXT, + sample_form sample_form_enum, beamline_id INTEGER, mono_name TEXT, mono_dspacing TEXT, diff --git a/xas-standards-api/src/xas_standards_api/crud.py b/xas-standards-api/src/xas_standards_api/crud.py index faf774d..9d1da4d 100644 --- a/xas-standards-api/src/xas_standards_api/crud.py +++ b/xas-standards-api/src/xas_standards_api/crud.py @@ -17,6 +17,7 @@ Person, PersonInput, ReviewStatus, + SampleForm, XASStandard, XASStandardAdminReviewInput, XASStandardData, @@ -82,6 +83,7 @@ def get_metadata(session): output["edges"] = select_all(session, Edge) output["beamlines"] = select_all(session, Beamline) output["licences"] = list(LicenceType) + output["sample_forms"] = list(SampleForm) return output @@ -260,3 +262,13 @@ def is_admin_user(session: Session, user_id: str): raise HTTPException(status_code=401, detail=f"User {user_id} not admin") return True + + +def get_registered_elements(session: Session): + statement = ( + select(Element) + .where(XASStandard.element_z == Element.z) + .where(XASStandard.review_status == ReviewStatus.approved) + ) + results = session.exec(statement) + return results.unique().all() diff --git a/xas-standards-api/src/xas_standards_api/models/models.py b/xas-standards-api/src/xas_standards_api/models/models.py index 2af0f80..3e286b5 100644 --- a/xas-standards-api/src/xas_standards_api/models/models.py +++ b/xas-standards-api/src/xas_standards_api/models/models.py @@ -14,7 +14,12 @@ class ReviewStatus(enum.Enum): class LicenceType(enum.Enum): cc_by = "cc_by" cc_0 = "cc_0" - logged_in_only = "logged_in_only" + + +class SampleForm(enum.Enum): + other = "other" + foil = "foil" + pellet = "pellet" class PersonInput(SQLModel): @@ -102,6 +107,7 @@ class XASStandardInput(SQLModel): sample_name: str sample_prep: Optional[str] sample_comp: Optional[str] + sample_form: SampleForm = Field(sa_column=Column(Enum(SampleForm))) beamline_id: int = Field(foreign_key="beamline.id") licence: LicenceType = Field(sa_column=Column(Enum(LicenceType))) diff --git a/xas-standards-api/src/xas_standards_api/models/response_models.py b/xas-standards-api/src/xas_standards_api/models/response_models.py index a7c8ab8..28c2bc4 100644 --- a/xas-standards-api/src/xas_standards_api/models/response_models.py +++ b/xas-standards-api/src/xas_standards_api/models/response_models.py @@ -36,3 +36,4 @@ class MetadataResponse(SQLModel): elements: List[Element] edges: List[Edge] licences: List[str] + sample_forms: List[str] diff --git a/xas-standards-api/src/xas_standards_api/routers/open.py b/xas-standards-api/src/xas_standards_api/routers/open.py index 529e445..5314002 100644 --- a/xas-standards-api/src/xas_standards_api/routers/open.py +++ b/xas-standards-api/src/xas_standards_api/routers/open.py @@ -4,7 +4,14 @@ from fastapi_pagination.cursor import CursorPage from sqlmodel import Session -from ..crud import get_data, get_file, get_metadata, get_standard, read_standards_page +from ..crud import ( + get_data, + get_file, + get_metadata, + get_registered_elements, + get_standard, + read_standards_page, +) from ..database import get_session from ..models.models import ReviewStatus from ..models.response_models import ( @@ -48,3 +55,8 @@ async def read_data( return get_file(session, id) return get_data(session, id) + + +@router.get("/api/elements/metrics") +async def read_elements(session: Session = Depends(get_session)): + return get_registered_elements(session) diff --git a/xas-standards-api/src/xas_standards_api/routers/protected.py b/xas-standards-api/src/xas_standards_api/routers/protected.py index 15deb0f..7c4fa40 100644 --- a/xas-standards-api/src/xas_standards_api/routers/protected.py +++ b/xas-standards-api/src/xas_standards_api/routers/protected.py @@ -38,6 +38,7 @@ def add_standard_file( beamline_id: Annotated[int, Form()], sample_name: Annotated[str, Form()], sample_prep: Annotated[str, Form()], + sample_form: Annotated[str, Form()], doi: Annotated[str, Form()], citation: Annotated[str, Form()], comments: Annotated[str, Form()], @@ -62,6 +63,7 @@ def add_standard_file( edge_id=edge_id, sample_name=sample_name, sample_prep=sample_prep, + sample_form=sample_form, submitter_comments=comments, citation=citation, licence=licence, diff --git a/xas-standards-api/tests/test_protected_router.py b/xas-standards-api/tests/test_protected_router.py index a5ecf2b..1fbfefb 100644 --- a/xas-standards-api/tests/test_protected_router.py +++ b/xas-standards-api/tests/test_protected_router.py @@ -69,6 +69,7 @@ def get_admin_user(): "beamline_id": 1, "sample_name": unique_sample_name, "sample_prep": "test", + "sample_form": "foil", "doi": "doi", "citation": "citation", "comments": "comments", diff --git a/xas-standards-api/tests/utils.py b/xas-standards-api/tests/utils.py index 09e35af..f749a7a 100644 --- a/xas-standards-api/tests/utils.py +++ b/xas-standards-api/tests/utils.py @@ -86,6 +86,7 @@ def build_test_database(session: Session): sample_name="sample", sample_prep="pellet", sample_comp="H", + sample_form="foil", beamline_id=1, licence=LicenceType.cc_0, id=1, @@ -108,6 +109,7 @@ def build_test_database(session: Session): sample_name="sample", sample_prep="pellet", sample_comp="He", + sample_form="pellet", beamline_id=1, licence=LicenceType.cc_0, id=2, diff --git a/xas-standards-client/src/components/submission/SampleForm.tsx b/xas-standards-client/src/components/submission/SampleForm.tsx index 43c332f..5326010 100644 --- a/xas-standards-client/src/components/submission/SampleForm.tsx +++ b/xas-standards-client/src/components/submission/SampleForm.tsx @@ -1,4 +1,11 @@ -import { Grid, TextField } from "@mui/material"; +import { + Grid, + TextField, + FormControl, + InputLabel, + Select, + MenuItem, +} from "@mui/material"; function SampleForm(props: { sampleName: string; @@ -7,6 +14,9 @@ function SampleForm(props: { setSampleComp: (composition: string) => void; samplePrep: string; setSamplePrep: (preparation: string) => void; + sampleForm: string; + setSampleForm: (preparation: string) => void; + sampleFormOptions: string[]; }) { const sampleName = props.sampleName; const setSampleName = props.setSampleName; @@ -49,12 +59,24 @@ function SampleForm(props: { /> - + + + Sample Form + + + ); diff --git a/xas-standards-client/src/components/submission/StandardSubmission.tsx b/xas-standards-client/src/components/submission/StandardSubmission.tsx index 51800e8..8328455 100644 --- a/xas-standards-client/src/components/submission/StandardSubmission.tsx +++ b/xas-standards-client/src/components/submission/StandardSubmission.tsx @@ -32,7 +32,8 @@ import { const standards_url = "/api/standards"; function StandardSubmission() { - const { elements, edges, beamlines, licences } = useContext(MetadataContext); + const { elements, edges, beamlines, licences, sample_forms } = + useContext(MetadataContext); const [file, setFile] = useState(); // const [file2, setFile2] = useState(); @@ -42,6 +43,7 @@ function StandardSubmission() { const [sampleName, setSampleName] = useState(""); const [sampleComp, setSampleComp] = useState(""); const [samplePrep, setSamplePrep] = useState(""); + const [sampleForm, setSampleForm] = useState(sample_forms[0]); const [beamlineId, setBeamlineId] = useState(1); const [beamlineHeader, setBeamlineHeader] = useState(""); const [doi, setDOI] = useState(""); @@ -72,6 +74,7 @@ function StandardSubmission() { form.append("sample_name", sampleName); form.append("sample_comp", sampleComp); form.append("sample_prep", samplePrep); + form.append("sample_form", sampleForm); form.append("doi", doi); form.append("citation", citation); form.append("comments", comments); @@ -203,6 +206,9 @@ function StandardSubmission() { setSampleComp={setSampleComp} samplePrep={samplePrep} setSamplePrep={setSamplePrep} + sampleForm={sampleForm} + setSampleForm={setSampleForm} + sampleFormOptions={sample_forms} /> diff --git a/xas-standards-client/src/hooks/useMetadata.ts b/xas-standards-client/src/hooks/useMetadata.ts index 0d51aaf..69240a8 100644 --- a/xas-standards-client/src/hooks/useMetadata.ts +++ b/xas-standards-client/src/hooks/useMetadata.ts @@ -11,6 +11,7 @@ function useMetadata(): AppMetadata { elements: [], edges: [], licences: [], + sample_forms: [] }); useEffect(() => { diff --git a/xas-standards-client/src/models.ts b/xas-standards-client/src/models.ts index 42827e9..cc90454 100644 --- a/xas-standards-client/src/models.ts +++ b/xas-standards-client/src/models.ts @@ -57,6 +57,7 @@ export interface AppMetadata { elements: Element[]; edges: Edge[]; licences: string[]; + sample_forms: string[]; } export interface User {