Skip to content

Commit

Permalink
Merge pull request #23 from harmonydata/staging
Browse files Browse the repository at this point in the history
Releasing Staging Branch
  • Loading branch information
ronnyTodgers authored May 31, 2024
2 parents ff3998f + 55f6a45 commit a835905
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 44 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ REACT_APP_API_EXAMPLES=$REACT_APP_API_URL/text/examples
REACT_APP_API_PARSE=$REACT_APP_API_URL/text/parse
REACT_APP_API_MATCH=$REACT_APP_API_URL/text/match
REACT_APP_API_VERSION=$REACT_APP_API_URL/info/version
REACT_APP_API_MODELS=$REACT_APP_API_URL/info/list-models
REACT_APP_ABSOLUTE_URL_PREFIX=https://harmonydata.github.io
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ REACT_APP_API_EXAMPLES=$REACT_APP_API_URL/text/examples
REACT_APP_API_PARSE=$REACT_APP_API_URL/text/parse
REACT_APP_API_MATCH=$REACT_APP_API_URL/text/match
REACT_APP_API_VERSION=$REACT_APP_API_URL/info/version
REACT_APP_API_MODELS=$REACT_APP_API_URL/info/list-models
REACT_APP_ABSOLUTE_URL_PREFIX=https://harmonydata.github.io
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ You can access Harmony in your browser at `http://localhost:3000/app#/`.

## How to run this front end and connect to localhost API

[Watch a video tutorial on how to run the Harmony front end locally and connect to Harmony API on localhost](https://youtu.be/1xp3Uh6dptg?si=g2CkXGEJCtevgdzY)

Run the [Harmony API](https://github.com/harmonydata/harmonyapi) app in Python.

Open `.env` and change `REACT_APP_API_URL` to `http://localhost:8000` and change `REACT_APP_ABSOLUTE_URL_PREFIX` to `http://localhost:8000/app` (so that the front end knows that it's running on localhost and that it should connect to a localhost API)
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"mui-nested-menu": "^3.2.1",
"nth-check": ">=2.1.1",
"pdfjs-dist": "^4.0.269",
"react": "^18.2.0",
"react": "^18.3.1",
"react-card-flip": "^1.2.0",
"react-circular-progressbar": "^2.1.0",
"react-cookie-consent": "^8.0.1",
"react-dom": "^18.2.0",
"react-dom": "^18.3.1",
"react-drag-drop-files": "^2.3.10",
"react-ga4": "^2.1.0",
"react-pdf": "^7.6.0",
Expand Down
98 changes: 87 additions & 11 deletions src/components/AppBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
Menu,
Container,
Divider,
FormControl,
InputLabel,
OutlinedInput,
ListItemText,
} from "@mui/material";
import { Logout, JoinInner } from "@mui/icons-material/";
import { useAuth } from "../contexts/AuthContext";
Expand All @@ -28,6 +32,7 @@ const SettingsIcons = {
function HarmonyAppBar() {
const [anchorUser, setAnchorUser] = React.useState(null);
const [apiVersion, setApiVersion] = React.useState(null);
const [allModels, setAllModels] = React.useState();
const [error, setError] = React.useState(null);
const {
currentUser,
Expand All @@ -36,7 +41,7 @@ function HarmonyAppBar() {
signInWithGitHub,
signInWithTwitter,
} = useAuth();
const { getVersion } = useData();
const { getVersion, getModels, currentModel, setCurrentModel } = useData();

React.useEffect(() => {
getVersion()
Expand All @@ -46,6 +51,24 @@ function HarmonyAppBar() {
.catch((e) => setError("ERROR: API unreachable"));
}, [getVersion]);

React.useEffect(() => {
getModels()
.then((models) => {
setAllModels(models);
})
.catch((e) => setError("ERROR: API unreachable"));
}, [getModels]);

const handleModelSelect = (event) => {
const model = event.target.value;
if (
model.framework !== currentModel.framework ||
model.model !== currentModel.model
) {
setCurrentModel(model);
}
};

const handleOpenUserMenu = (event) => {
setAnchorUser(event.currentTarget);
};
Expand Down Expand Up @@ -80,15 +103,27 @@ function HarmonyAppBar() {
>
<Container sx={{ maxWidth: "100%!important" }}>
<Toolbar disableGutters>
<Box sx={{ flexGrow: 1, textAlign: "right", paddingRight: 2 }}>
{apiVersion && (
<Typography>Harmony API version: {apiVersion}</Typography>
)}
{error && (
<Typography sx={{ color: "red", fontWeight: 900 }}>
{error}
</Typography>
)}
<Box
sx={{
flexGrow: 1,

textAlign: "right",
paddingRight: 2,
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyItems: "flex-end",
}}
>
{error && (
<Typography sx={{ color: "red", fontWeight: 900 }}>
{error}
</Typography>
)}
</Box>
</Box>

<Box sx={{ flexGrow: 0 }}>
Expand All @@ -105,7 +140,7 @@ function HarmonyAppBar() {
</Avatar>
</Tooltip>
<Menu
sx={{ mt: "45px" }}
sx={{ mt: "45px", maxWidth: "50%" }}
id="menu-appbar"
anchorEl={anchorUser}
anchorOrigin={{
Expand Down Expand Up @@ -134,6 +169,41 @@ function HarmonyAppBar() {
<MenuItem value={"PT"}>Portuguese</MenuItem>
</Select>
</MenuItem>
<MenuItem key="model">
<FormControl sx={{ margin: "auto" }}>
<InputLabel id="models">Model</InputLabel>
<Select
size="small"
labelId="models"
id="modelcombo"
value={currentModel}
onChange={handleModelSelect}
input={
<OutlinedInput
sx={{ overflow: "hidden" }}
label="Model"
/>
}
renderValue={(selected) =>
selected.framework + " (" + selected.model + ")"
}
>
{allModels &&
allModels.map(
(model) =>
model.available && (
<MenuItem key={model.model} value={model}>
<ListItemText
primary={
model.framework + " (" + model.model + ")"
}
/>
</MenuItem>
)
)}
</Select>
</FormControl>
</MenuItem>
<Divider />

{settings.map((setting) => (
Expand Down Expand Up @@ -189,6 +259,12 @@ function HarmonyAppBar() {
</Typography>
</MenuItem>
)}
<Divider />
{apiVersion && (
<Typography sx={{ mx: 1 }}>
Harmony API version: {apiVersion}
</Typography>
)}
</Menu>
</Box>
</Toolbar>
Expand Down
19 changes: 19 additions & 0 deletions src/components/GoogleDriveImport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import { Box, Button } from "@mui/material";

function GoogleDriveImport({ filesReceiver, sx }) {
return (
<Box sx={sx}>
<Button variant="contained" size="large" sx={{ mx: "auto" }}>
<img
style={{ height: "2rem", marginRight: 10 }}
src={require("../img/google-drive.png")}
alt="Google Drive"
/>
Import Forms, Sheets or Documents from Google Drive
</Button>
</Box>
);
}

export default GoogleDriveImport;
33 changes: 15 additions & 18 deletions src/components/ThemeToggle.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,36 @@
import React from 'react';
import { IconButton, Box } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import Brightness4Icon from '@mui/icons-material/Brightness4';
import Brightness7Icon from '@mui/icons-material/Brightness7';
import { ColorModeContext } from "../contexts/ColorModeContext"
import React from "react";
import { IconButton, Box } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import Brightness4Icon from "@mui/icons-material/Brightness4";
import Brightness7Icon from "@mui/icons-material/Brightness7";
import { ColorModeContext } from "../contexts/ColorModeContext";

export default function ThemeToggle() {
const theme = useTheme();
const colorMode = React.useContext(ColorModeContext);

return (
<Box
onClick={colorMode.toggleColorMode}
sx={{
display: 'flex',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
bgcolor: 'background.default',
display: "flex",
width: "100%",
alignItems: "center",
justifyContent: "center",
bgcolor: "background.default",
color: theme.palette.text.primary,
borderRadius: 1,
p: 0,
}}
>
{theme.palette.mode} mode
<IconButton
sx={{ ml: 1 }}
onClick={colorMode.toggleColorMode}
color="inherit"
>
{theme.palette.mode === 'dark' ? (
<IconButton sx={{ ml: 1 }} color="inherit">
{theme.palette.mode === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
</Box>
);
}
}
54 changes: 44 additions & 10 deletions src/components/Upload.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useRef, memo, useMemo, useCallback } from "react";
import DragDrop from "./DragDrop";
import GoogleDriveImport from "./GoogleDriveImport";
import { useData } from "../contexts/DataContext";
import {
Box,
Expand Down Expand Up @@ -29,6 +30,7 @@ import { simplifyApi } from "../utilities/simplifyApi";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import pdfTableExtractor from "../utilities/pdf-table-extractor";
import { useAuth } from "../contexts/AuthContext";

export default function Upload({
appFileInfos,
Expand All @@ -37,6 +39,7 @@ export default function Upload({
existingInstruments,
ReactGA,
}) {
const { currentUser } = useAuth();
const [loading, setLoading] = useState(false);
const [parseError, setParseError] = useState(false);
const [matchError, setMatchError] = useState(false);
Expand All @@ -56,11 +59,22 @@ export default function Upload({
return dirty.current ? localFileInfos.current || [] : appFileInfos || [];
}, [appFileInfos]);

const setFileInfos = useCallback((fi) => {
console.log("setting local FI " + JSON.stringify(fi));
dirty.current = dirty.current + 1;
localFileInfos.current = fi;
}, []);
const setFileInfos = useCallback(
(fi, forceExpanded) => {
console.log("setting local FI " + JSON.stringify(fi));
dirty.current = dirty.current + 1;
localFileInfos.current = fi;
if (forceExpanded) {
setExpanded(forceExpanded);
} else if (
fi.length &&
!(expanded && fi.map((i) => i.instrument_id).includes(expanded))
) {
setExpanded(fi[0].instrument_id);
}
},
[expanded, setExpanded]
);

const syncFileInfos = useCallback(() => {
console.log("syncing fileinfo");
Expand Down Expand Up @@ -222,18 +236,18 @@ export default function Upload({
const after = fileInfos.findIndex(
(f) => f.instrument_id === after_instrument_id
);
const instrument_id = "ManuallyCreated" + String(new Date().getTime());
const newFileInfos = fileInfos
.slice(0, after + 1)
.concat([
{
instrument_id: String(new Date().getTime()),
instrument_id: instrument_id,
instrument_name: "",
questions: [{ question_no: "", question_text: "" }],
},
])
.concat(fileInfos.slice(after + 1));
console.log(newFileInfos);
setFileInfos(newFileInfos);
setFileInfos(newFileInfos, instrument_id);
syncFileInfos();
};

Expand Down Expand Up @@ -375,7 +389,7 @@ export default function Upload({
key={instrument_id}
expanded={expanded === instrument_id}
onChange={(e, ex) => {
setExpanded(ex ? instrument_id : false);
if (ex) setExpanded(instrument_id);
syncFileInfos();
}}
>
Expand All @@ -399,6 +413,16 @@ export default function Upload({
}}
>
<TextField
error={
fi.questions.reduce((a, q) => (a = a + q.question_text), "")
.length === 0
}
helperText={
fi.questions.reduce((a, q) => (a = a + q.question_text), "")
.length === 0
? "You must add questions before this will be harmonised"
: false
}
variant="standard"
sx={{
pointerEvents: "auto",
Expand Down Expand Up @@ -500,7 +524,17 @@ export default function Upload({
setState={setMatchError}
/>

<DragDrop filesReceiver={filesReceiver} sx={{ margin: "2rem" }} />
<DragDrop filesReceiver={filesReceiver} sx={{ mt: "2rem" }} />
{currentUser &&
currentUser.providerData &&
currentUser.providerData
.map((p) => p.providerId)
.includes("google.com") && (
<GoogleDriveImport
filesReceiver={filesReceiver}
sx={{ display: "flex", width: "100%", mt: "1rem" }}
/>
)}
<Stack
direction={"row"}
spacing={1}
Expand Down
Loading

0 comments on commit a835905

Please sign in to comment.