From 24fe69dd51350d57f615512ecf00100ed1a7c648 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 25 Nov 2023 18:06:36 +0000 Subject: [PATCH 1/3] Added database --- webserver/package.json | 3 +- webserver/src/App.tsx | 12 +- .../DatabaseComponents/BFactorVsRSCC.tsx | 92 ++++++++++ .../DatabaseComponents/CremerPopleGraph.tsx | 98 ++++++++++ .../DatabaseComponents/SNFGList.tsx | 152 ++++++++++++++++ .../DatabaseComponents/SNFGSection.tsx | 54 ++++++ .../DatabaseComponents/SugarList.tsx | 172 ++++++++++++++++++ .../DatabaseFetch/DatabaseFetch.jsx | 42 +++++ .../DatabaseResult/DatabaseResult.tsx | 33 ++++ webserver/src/data/Constants.tsx | 61 +++++++ webserver/src/interfaces/types.ts | 19 ++ webserver/src/layouts/DatabaseHeader.tsx | 28 +++ webserver/src/layouts/NavBar.tsx | 54 ++++-- webserver/src/main.tsx | 12 +- .../pages/DatabaseSection/DatabaseSection.tsx | 85 +++++++++ 15 files changed, 890 insertions(+), 27 deletions(-) create mode 100644 webserver/src/components/DatabaseComponents/BFactorVsRSCC.tsx create mode 100644 webserver/src/components/DatabaseComponents/CremerPopleGraph.tsx create mode 100644 webserver/src/components/DatabaseComponents/SNFGList.tsx create mode 100644 webserver/src/components/DatabaseComponents/SNFGSection.tsx create mode 100644 webserver/src/components/DatabaseComponents/SugarList.tsx create mode 100644 webserver/src/components/DatabaseFetch/DatabaseFetch.jsx create mode 100644 webserver/src/components/DatabaseResult/DatabaseResult.tsx create mode 100644 webserver/src/layouts/DatabaseHeader.tsx create mode 100644 webserver/src/pages/DatabaseSection/DatabaseSection.tsx diff --git a/webserver/package.json b/webserver/package.json index c88b25bb..b4e681a1 100644 --- a/webserver/package.json +++ b/webserver/package.json @@ -15,12 +15,12 @@ "moorhen": "file:moorhen-0.5.1.tgz", "plotly.js": "^2.26.0", "react": "^18.2.0", + "react-collapsed": "^4.1.2", "react-dom": "^18.2.0", "react-icons": "^4.11.0", "react-inlinesvg": "^3.0.2", "react-plotly.js": "^2.6.0", "react-responsive-carousel": "^3.2.23", - "react-router-dom": "^6.14.2", "react-spinners": "^0.13.8", "react-table": "^7.8.0", "styled-components": "^6.0.6", @@ -36,6 +36,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "postcss": "^8.4.27", + "react-router-dom": "^6.20.0", "tailwindcss": "^3.3.3", "typescript": "^5.2.2", "vite": "^4.4.5", diff --git a/webserver/src/App.tsx b/webserver/src/App.tsx index 2637582d..9652a3c9 100644 --- a/webserver/src/App.tsx +++ b/webserver/src/App.tsx @@ -1,14 +1,20 @@ import { useEffect, useState, Suspense } from 'react' import './App.css' import HomeSection from './pages/Home/HomeSection' +import DatabaseSection from './pages/DatabaseSection/DatabaseSection' + import PageLoad from './components/Loading/PageLoad' +import { Routes, Route } from "react-router-dom"; function App() { return ( - }> - + }>
- + + + }/> + } /> +
) diff --git a/webserver/src/components/DatabaseComponents/BFactorVsRSCC.tsx b/webserver/src/components/DatabaseComponents/BFactorVsRSCC.tsx new file mode 100644 index 00000000..8facd08d --- /dev/null +++ b/webserver/src/components/DatabaseComponents/BFactorVsRSCC.tsx @@ -0,0 +1,92 @@ +import { useEffect, useState, lazy } from 'react'; + +const Plot = lazy(() => import('react-plotly.js')); + +function calculate_points(data) { + let glycans = data.data.glycans + + let x_axis = [] + let y_axis = [] + let text = [] + + for (const key in glycans) { + let glycan_type = glycans[key] + for (let i = 0; i < glycan_type.length; i++) { + let sugars = glycan_type[i].Sugars + for (let j = 0; j < sugars.length; j++) { + x_axis.push(sugars[j].BFactor) + y_axis.push(sugars[j].RSCC) + text.push(sugars[j]["Sugar ID"]) + } + } + } + + + return [x_axis, y_axis, text] +} + +export default function BFactorVsRSCC(props) { + + const [trace, setTrace] = useState({}) + + useEffect(() => { + const [x_axis, y_axis, text] = calculate_points(props) + + setTrace({ + x: x_axis, + y: y_axis, + text: text, + hoverinfo: "text", + mode: 'markers', + type: 'scatter', + marker: { + size: 8, + color: 'green', + symbol: ['o'] + }, + }) + }, []) + + + return ( +
+ BFactor vs RSCC + +
+ ) + + + +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseComponents/CremerPopleGraph.tsx b/webserver/src/components/DatabaseComponents/CremerPopleGraph.tsx new file mode 100644 index 00000000..5c5e1ca4 --- /dev/null +++ b/webserver/src/components/DatabaseComponents/CremerPopleGraph.tsx @@ -0,0 +1,98 @@ +import { useEffect, useState, lazy } from 'react'; + +const Plot = lazy(() => import('react-plotly.js')); + +function calculate_points(data) { + let glycans = data.data.glycans + + let x_axis = [] + let y_axis = [] + let text = [] + + for (const key in glycans) { + let glycan_type = glycans[key] + for (let i = 0; i < glycan_type.length; i++) { + let sugars = glycan_type[i].Sugars + for (let j = 0; j < sugars.length; j++) { + + x_axis.push(sugars[j].Phi) + y_axis.push(sugars[j].Theta) + text.push(sugars[j]["Sugar ID"]) + } + } + } + + + return [x_axis, y_axis, text] +} + +export default function CremerPopleGraph(props) { + + const [trace, setTrace] = useState({}) + + useEffect(() => { + const [x_axis, y_axis, text] = calculate_points(props) + + setTrace({ + x: x_axis, + y: y_axis, + text: text, + hoverinfo: "text", + mode: 'markers', + type: 'scatter', + marker: { + size: 8, + color: 'green', + symbol: ['o'] + }, + }) + + }, []) + + + return ( +
+ Conformational landscape for pyranoses + + + +
+ + ) + + + +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseComponents/SNFGList.tsx b/webserver/src/components/DatabaseComponents/SNFGList.tsx new file mode 100644 index 00000000..527e3b31 --- /dev/null +++ b/webserver/src/components/DatabaseComponents/SNFGList.tsx @@ -0,0 +1,152 @@ +import { useMemo, useRef, useEffect, useState } from 'react'; +import { useTable } from 'react-table'; +import { DatabaseColumns } from "../../data/Constants" +import styled from 'styled-components' + +function custom_sort(a, b) { + a = a.chain + b = b.chain + if (a < b) return -1; + if (a > b) return 1; + return 0; +} + +function parse_results(data) { + let glycans = data.data.glycans + + let table_data = [] + + for (const key in glycans) { + let glycan_type = glycans[key] + for (let i = 0; i < glycan_type.length; i++) { + + let chain = glycan_type[i].RootSugarChainID + + let SNFG = glycan_type[i].SNFG + let WURCS = glycan_type[i].WURCS + + table_data.push( + { + "chain": chain, + "SNFG": SNFG, + "WURCS": WURCS + }) + } + } + + table_data.sort(custom_sort) + return table_data +} + +let Styles = styled.div` +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + // border: 0px solid #ddd; +} + +table th { + text-align: left; + padding: 16px; + // border: 1px solid #ddd; +} + +table td { + text-align: center; + padding: 16px; + border: 1px solid #ddd; + border-style: solid none; +} + +table td { + border-style: none none; +} + +table tr:nth-child(even) { + background-color: #f6f6f6; +} + +table tr:nth-child(even) { + background-color: #F4F9FF; + // color: #000000 +} + +table th { + padding-top: 12px; + padding-bottom: 12px; + text-align: center; + background-color: #F4F9FF; + color: black; +} + +table th:first-of-type { + border-top-left-radius: 30px; +} + +table th:last-of-type { + border-top-right-radius: 30px; +} + +table tr:last-of-type td:first-of-type { + border-bottom-left-radius: 30px; +} + +table tr:last-of-type td:last-of-type { + border-bottom-right-radius: 30px; +} + +` + +export default function SNFGList(props) { + + const [data, setData] = useState([]) + const columns = useMemo(() => DatabaseColumns, []); + const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns, data }); + + useEffect(() => { + let results = parse_results(props) + console.log(results) + setData(results) + }, []) + + return ( +
+ N- and O-glycan structure 2D descriptions + + + + + {headerGroups.map((headerGroup) => ( + + {headerGroup.headers.map((column) => ( + + ))} + + ))} + + + {rows.map((row) => { + prepareRow(row); + return ( + + {row.cells.map((cell) => { + return ( + + ); + })} + + ); + })} + +
+ {column.render('Header')} +
+ {cell.render('Cell')} +
+
+
+ + ) +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseComponents/SNFGSection.tsx b/webserver/src/components/DatabaseComponents/SNFGSection.tsx new file mode 100644 index 00000000..5caade8c --- /dev/null +++ b/webserver/src/components/DatabaseComponents/SNFGSection.tsx @@ -0,0 +1,54 @@ +import { useEffect, useState } from "react" + +export default function SNFGSection(props) { + + const [showSection, setShowSection] = useState(false) + + useEffect(() => {console.log(props)}, []) + + return ( +
+ Chain: {props.id} + + + + + {showSection ? + props.item.map((array_item, array_index) => { + return ( + + ) + }) + : <>} +
+ ) +} + +export function SNFGItem(props) { + + const [showWURCS, setShowWURCS] = useState(false) + + return ( +
+
WURCS: + + + {showWURCS ? props.item.WURCS : <>} +
+
+
+ ) +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseComponents/SugarList.tsx b/webserver/src/components/DatabaseComponents/SugarList.tsx new file mode 100644 index 00000000..cce90a53 --- /dev/null +++ b/webserver/src/components/DatabaseComponents/SugarList.tsx @@ -0,0 +1,172 @@ +import { useMemo, useRef, useEffect, useState } from 'react'; +import { useTable } from 'react-table'; +import { DatabaseColumns, SugarListColumns } from "../../data/Constants" +import styled from 'styled-components' + +function custom_sort(a, b) { + let split_a = a["Sugar ID"].split("-") + let split_b = b["Sugar ID"].split("-") + + if (split_a[1] < split_b[1]) { + return -1 + } + if (split_b[1] < split_a[1]) { + return 1; + } + + if (split_a[2] < split_b[2]) { + return -1; + } + + if (split_b[2] < split_a[2]) { + return 1; + } + + return 0; +} + + +function parse_results(data) { + let glycans = data.data.glycans + + let table_data = [] + + for (const key in glycans) { + let glycan_type = glycans[key] + for (let i = 0; i < glycan_type.length; i++) { + let sugars = glycan_type[i].Sugars + for (let j = 0; j < sugars.length; j++) { + let keys = Object.keys(sugars[j]) + let entry = {} + + for (let k = 0; k < keys.length; k++) { + let type_key = typeof (sugars[j][keys[k]]) + + if (type_key === "number") { + entry[keys[k]] = sugars[j][keys[k]].toFixed(2) + } + else { + entry[keys[k]] = sugars[j][keys[k]] + } + } + entry["type"] = key + table_data.push(entry) + } + } + } + + table_data.sort(custom_sort) + return table_data +} + +let Styles = styled.div` +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + // border: 0px solid #ddd; +} + +table th { + text-align: left; + padding: 16px; + // border: 1px solid #ddd; +} + +table td { + text-align: center; + padding: 16px; + border: 1px solid #ddd; + border-style: solid none; +} + +table td { + border-style: none none; +} + +table tr:nth-child(even) { + background-color: #f6f6f6; +} + +table tr:nth-child(even) { + background-color: #F4F9FF; + // color: #000000 +} + +table th { + padding-top: 12px; + padding-bottom: 12px; + text-align: center; + background-color: #F4F9FF; + color: black; +} + +table th:first-of-type { + border-top-left-radius: 30px; +} + +table th:last-of-type { + border-top-right-radius: 30px; +} + +table tr:last-of-type td:first-of-type { + border-bottom-left-radius: 30px; +} + +table tr:last-of-type td:last-of-type { + border-bottom-right-radius: 30px; +} + +` + +export default function SugarList(props) { + + const [data, setData] = useState([]) + const columns = useMemo(() => SugarListColumns, []); + const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns, data }); + + useEffect(() => { + let results = parse_results(props) + console.log(results) + setData(results) + }, []) + + return ( +
+ Detailed monosaccharide validation data + + + + + {headerGroups.map((headerGroup) => ( + + {headerGroup.headers.map((column) => ( + + ))} + + ))} + + + {rows.map((row) => { + prepareRow(row); + return ( + + {row.cells.map((cell) => { + return ( + + ); + })} + + ); + })} + +
+ {column.render('Header')} +
+ {cell.render('Cell')} +
+
+
+ ) +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx b/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx new file mode 100644 index 00000000..471418d2 --- /dev/null +++ b/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx @@ -0,0 +1,42 @@ +import { useEffect, useState } from "react"; + +export default function DatabaseFetch({ PDBCode, setPDBCode, submitPressed }) { + + const [pdb, setPDB] = useState("") + + useEffect(() => { + if (pdb.length != 4) { return } + if (!pdb.match(/^[a-z0-9]+$/i)) { return } + + setPDBCode(pdb) + submitPressed(true) + }, [pdb]) + + return ( + <> + {PDBCode != true ? +
+ +
: + <> + } + + ) +} \ No newline at end of file diff --git a/webserver/src/components/DatabaseResult/DatabaseResult.tsx b/webserver/src/components/DatabaseResult/DatabaseResult.tsx new file mode 100644 index 00000000..e6a61462 --- /dev/null +++ b/webserver/src/components/DatabaseResult/DatabaseResult.tsx @@ -0,0 +1,33 @@ +import { useEffect, useState } from "react" +import { DatabaseResultProps } from "../../interfaces/types" +import CremerPopleGraph from "../DatabaseComponents/CremerPopleGraph" +import BFactorVsRSCC from "../DatabaseComponents/BFactorVsRSCC" +import SNFGList from "../DatabaseComponents/SNFGList" +import SugarList from "../DatabaseComponents/SugarList" + +export default function DatabaseResult(props: DatabaseResultProps) { + + const [data, setData] = useState() + useEffect(() => { + if (!props.results) return + + setData(props.results) + }, []) + + return ( + <> + {data !== undefined ? +
+

Validation Report - {props.PDBCode}

+
+ + +
+ + + +
: + <>} + + ) +} \ No newline at end of file diff --git a/webserver/src/data/Constants.tsx b/webserver/src/data/Constants.tsx index 921f21de..9f3d4536 100644 --- a/webserver/src/data/Constants.tsx +++ b/webserver/src/data/Constants.tsx @@ -41,6 +41,67 @@ export const COLUMNS = [ ]; +export const DatabaseColumns = [ + { + Header: 'Chain', + accessor: 'chain', + }, + { + Header: 'SNFG', + accessor: 'SNFG', + Cell: tableProps => { + return ( +
+ ) + } + }, + { + Header: "WURCS", + accessor: 'WURCS' + } +] + +export const SugarListColumns = [ + { + Header: "Sugar ID", + accessor: "Sugar ID" + }, + { + Header: "Q", + accessor: "Q" + }, + { + Header: "Phi", + accessor: "Phi", + }, + { + Header: "Theta", + accessor: "Theta" + }, + { + Header: "RSCC", + accessor: "RSCC" + }, + { + Header: "B Factor", + accessor: "BFactor" + }, + { + Header: "Detected Type", + accessor: "Detected Type" + }, + { + Header: "mFo", + accessor: "mFo" + }, + { + Header: "Type", + accessor: "type" + } +] + export const linkage_db = { "GAL-1,4-NAG" : 'https://raw.githubusercontent.com/Dialpuri/N-glycanTorsionDatabase/main/data_json/GAL-1,4-NAG.json', "NAG-1,2-MAN" : 'https://raw.githubusercontent.com/Dialpuri/N-glycanTorsionDatabase/main/data_json/NAG-1,2-MAN.json', diff --git a/webserver/src/interfaces/types.ts b/webserver/src/interfaces/types.ts index dfe3ee6d..9735f400 100644 --- a/webserver/src/interfaces/types.ts +++ b/webserver/src/interfaces/types.ts @@ -43,6 +43,25 @@ export interface HeaderProps { failureText: string } +export interface DatabaseHeaderProps { + resetApp: boolean, + setResetApp: Dispatch>, + PDBCode: string, + setPDBCode: Dispatch>, + submit: boolean, + setSubmit: Dispatch>, + loadingText: string, + fallback: boolean, + failureText: string, + results: any, +} + +export interface DatabaseResultProps { + results: any + PDBCode: string +} + + export interface SNFGProps extends HeaderProps { filename: string } diff --git a/webserver/src/layouts/DatabaseHeader.tsx b/webserver/src/layouts/DatabaseHeader.tsx new file mode 100644 index 00000000..9eb7812f --- /dev/null +++ b/webserver/src/layouts/DatabaseHeader.tsx @@ -0,0 +1,28 @@ +import { lazy, Suspense } from 'react' + +const Upload = lazy(() => import('../components/Upload/Upload.tsx')); +const Loading = lazy(() => import('../components/Loading/Loading.tsx')); +const NavBar = lazy(() => import('./NavBar.tsx')); +const NoGlycans = lazy(() => import("../components/NoGlycans/NoGlycans.tsx")) +const DatabaseFetch = lazy(() => import("../components/DatabaseFetch/DatabaseFetch.jsx")) +const DatabaseResult = lazy(() => import("../components/DatabaseResult/DatabaseResult.jsx")) + +import {DatabaseHeaderProps} from "../interfaces/types" + +export function DatabaseHeader(props: DatabaseHeaderProps) { + + return ( +
+ +
+ {props.fallback !== true ? + }> + {!props.results ? + + : + } + + : + }
+
); +} diff --git a/webserver/src/layouts/NavBar.tsx b/webserver/src/layouts/NavBar.tsx index 671f48c1..270e1b83 100644 --- a/webserver/src/layouts/NavBar.tsx +++ b/webserver/src/layouts/NavBar.tsx @@ -1,27 +1,43 @@ import { Dispatch, SetStateAction } from "react" -import {GENERAL_CITATION, GITHUB_REPO} from "../data/Constants.tsx" +import { GENERAL_CITATION, GITHUB_REPO } from "../data/Constants.tsx" -export default function NavBar({setResetApp}: {setResetApp: Dispatch>}) { +export default function NavBar({ setResetApp }: { setResetApp: Dispatch> }) { return (
-
- Validate your carbohydrates online with - - The Swiss Army knife for carbohydrate structure validation, refinement and analysis -
-
- - - - +
+ Validate your carbohydrates online with + + The Swiss Army knife for carbohydrate structure validation, refinement and analysis +
+ +
+ + + +
-
) } - - \ No newline at end of file diff --git a/webserver/src/main.tsx b/webserver/src/main.tsx index d2d49a4a..4d61a370 100644 --- a/webserver/src/main.tsx +++ b/webserver/src/main.tsx @@ -1,10 +1,14 @@ -import React from 'react' +// import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' +import { BrowserRouter } from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')).render( - - - , + // + + + + + // , ) diff --git a/webserver/src/pages/DatabaseSection/DatabaseSection.tsx b/webserver/src/pages/DatabaseSection/DatabaseSection.tsx new file mode 100644 index 00000000..7a5aa176 --- /dev/null +++ b/webserver/src/pages/DatabaseSection/DatabaseSection.tsx @@ -0,0 +1,85 @@ +import { lazy, useEffect, useState } from "react"; +import { Information } from '../../components/Information/Information.tsx'; + +const Footer = lazy(() => import('../../layouts/Footer.tsx')); +const BorderElement = lazy(() => import('../../layouts/BorderElement.tsx')); + +import { DatabaseHeaderProps } from "../../interfaces/types" +import { DatabaseHeader } from "../../layouts/DatabaseHeader.tsx"; + +import pako from "pako" + +export default function DatabaseSection() { + + const [PDBCode, setPDBCode] = useState("") + const [submit, setSubmit] = useState(false); + const [loadingText, setLoadingText] = useState("Validating Glycans..."); + const [resetApp, setResetApp] = useState(false) + const [fallback, setFallBack] = useState(false) + const [failureText, setFailureText] = useState("") + const [results, setResults] = useState("") + const [failure, setFailure] = useState(false) + + useEffect(() => { + if (PDBCode != "") { + setLoadingText(`Fetching ${PDBCode.toUpperCase()} from the database`) + let pdb_code = PDBCode.toLowerCase() + let middlefix = pdb_code.substring(1, 3) + + let url = `https://raw.githubusercontent.com/Dialpuri/PrivateerDatabase/master/${middlefix}/${pdb_code}.json.gz` + + try { + fetch(url, { + method: "GET" + }).then(response => { + let buffer = response.arrayBuffer() + buffer.then((bytes) => { + var decompressedData = pako.inflate(bytes, { to: 'string' }); + var jsonString = decompressedData.toString('utf-8'); + var jsonObject = JSON.parse(jsonString); + setResults(jsonObject) + }).catch( e => { + setFallBack(true) + setFailureText("Cannot be found in database") + }) + }).catch(e => { + console.log(e) + }) + } catch { + console.log("not in db") + } + } + + }, [submit]) + + useEffect(() => { + setSubmit(false) + setFallBack(false) + setResetApp(false) + setPDBCode("") + setResults("") + }, [resetApp]) + + const main_props: DatabaseHeaderProps = { + resetApp: resetApp, + setResetApp: setResetApp, + PDBCode: PDBCode, + setPDBCode: setPDBCode, + submit: submit, + setSubmit: setSubmit, + loadingText: loadingText, + fallback: fallback, + failureText: failureText, + results: results, + } + + return ( + <> + + + + +
+ + ) +} \ No newline at end of file From 55155a175949d6a0583cc2521ee19af9e742589c Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 25 Nov 2023 18:16:52 +0000 Subject: [PATCH 2/3] resynced package.json --- webserver/package-lock.json | 59 +++++++++++++++++++++++++++---------- webserver/package.json | 1 + 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/webserver/package-lock.json b/webserver/package-lock.json index 8aa919a9..db13015e 100644 --- a/webserver/package-lock.json +++ b/webserver/package-lock.json @@ -11,14 +11,15 @@ "@types/jest": "^29.5.6", "@types/node": "^20.8.9", "moorhen": "file:moorhen-0.5.1.tgz", + "pako": "^2.1.0", "plotly.js": "^2.26.0", "react": "^18.2.0", + "react-collapsed": "^4.1.2", "react-dom": "^18.2.0", "react-icons": "^4.11.0", "react-inlinesvg": "^3.0.2", "react-plotly.js": "^2.6.0", "react-responsive-carousel": "^3.2.23", - "react-router-dom": "^6.14.2", "react-spinners": "^0.13.8", "react-table": "^7.8.0", "styled-components": "^6.0.6", @@ -34,6 +35,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "postcss": "^8.4.27", + "react-router-dom": "^6.20.0", "tailwindcss": "^3.3.3", "typescript": "^5.2.2", "vite": "^4.4.5", @@ -2672,11 +2674,12 @@ } }, "node_modules/@remix-run/router": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz", - "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.0.tgz", + "integrity": "sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==", + "dev": true, "engines": { - "node": ">=14" + "node": ">=14.0.0" } }, "node_modules/@rollup/plugin-virtual": { @@ -6508,6 +6511,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6967,6 +6975,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-collapsed": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-collapsed/-/react-collapsed-4.1.2.tgz", + "integrity": "sha512-vusqVnW/VbFCKJx29KNTnjJrwCbV7k3bB/FiO9/0Fj7JNoNarkU1xU7yK4FZHqPW0Q2izB7o6fYzG16zgdDNMQ==", + "dependencies": { + "tiny-warning": "^1.0.3" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -7046,29 +7066,31 @@ } }, "node_modules/react-router": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz", - "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.0.tgz", + "integrity": "sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==", + "dev": true, "dependencies": { - "@remix-run/router": "1.7.2" + "@remix-run/router": "1.13.0" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz", - "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.0.tgz", + "integrity": "sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==", + "dev": true, "dependencies": { - "@remix-run/router": "1.7.2", - "react-router": "6.14.2" + "@remix-run/router": "1.13.0", + "react-router": "6.20.0" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8", @@ -7992,6 +8014,11 @@ "xtend": "~4.0.1" } }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", diff --git a/webserver/package.json b/webserver/package.json index b4e681a1..a9b3e2b1 100644 --- a/webserver/package.json +++ b/webserver/package.json @@ -13,6 +13,7 @@ "@types/jest": "^29.5.6", "@types/node": "^20.8.9", "moorhen": "file:moorhen-0.5.1.tgz", + "pako": "^2.1.0", "plotly.js": "^2.26.0", "react": "^18.2.0", "react-collapsed": "^4.1.2", From ca57b00b6d3e414fbee6048e6f42cafbce0caa5c Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sun, 26 Nov 2023 15:42:55 +0000 Subject: [PATCH 3/3] Added beta flag --- webserver/src/components/DatabaseFetch/DatabaseFetch.jsx | 2 +- webserver/tailwind.config.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx b/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx index 471418d2..2ecbc422 100644 --- a/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx +++ b/webserver/src/components/DatabaseFetch/DatabaseFetch.jsx @@ -20,7 +20,7 @@ export default function DatabaseFetch({ PDBCode, setPDBCode, submitPressed }) {
-

Fetch from Database +

Fetch from Database - Beta