denver comp

This commit is contained in:
Evan Lanham
2022-04-02 17:13:50 -06:00
parent 0659a9736e
commit d238d52a4f
21 changed files with 241 additions and 61 deletions
+32
View File
@@ -0,0 +1,32 @@
version: "3"
services:
couchdb:
container_name: "scouting-couchdb"
restart: unless-stopped
env_file:
- .env
build:
context: ./couchdb
dockerfile: ./Dockerfile
expose:
- 5984
ports:
- "5984:5984"
environment:
- COUCHDB_HOST=couchdb
- COUCHDB_PORT=5984
- COUCHDB_USER=${COUCHDB_USER}
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
volumes:
- ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini
- ./couchdb/data:/opt/couchdb/data
# couch-ssl-proxy:
# image: fsouza/docker-ssl-proxy
# ports:
# - "5985:5985"
# environment:
# - DOMAIN=10.43.88.1
# - TARGET_PORT=5984
# - TARGET_HOST=scouting-couchdb
# - SSL_PORT:5985
+1 -30
View File
@@ -26,33 +26,4 @@ services:
# - DOMAIN=10.43.88.1
# - TARGET_PORT=8080
# - TARGET_HOST=scouting-webserver-prod
# - SSL_PORT:443
couchdb:
container_name: "scouting-couchdb"
restart: unless-stopped
env_file:
- .env
build:
context: ./couchdb
dockerfile: ./Dockerfile
expose:
- 5984
ports:
- "5984:5984"
environment:
- COUCHDB_HOST=couchdb
- COUCHDB_PORT=5984
- COUCHDB_USER=${COUCHDB_USER}
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
volumes:
- ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini
- ./couchdb/data:/opt/couchdb/data
# couch-ssl-proxy:
# image: fsouza/docker-ssl-proxy
# ports:
# - "5985:5985"
# environment:
# - DOMAIN=10.43.88.1
# - TARGET_PORT=5984
# - TARGET_HOST=scouting-couchdb
# - SSL_PORT:5985
# - SSL_PORT:443
+1 -21
View File
@@ -14,24 +14,4 @@ services:
ports:
- "3000:3000"
environment:
- CHOKIDAR_USEPOLLING=true
couchdb:
container_name: "scouting-couchdb"
restart: unless-stopped
env_file:
- .env
build:
context: ./couchdb
dockerfile: ./Dockerfile
expose:
- 5984
ports:
- "5984:5984"
environment:
- COUCHDB_HOST=couchdb
- COUCHDB_PORT=5984
- COUCHDB_USER=${COUCHDB_USER}
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
volumes:
- ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini
- ./couchdb/data:/opt/couchdb/data
- CHOKIDAR_USEPOLLING=true
+1
View File
@@ -0,0 +1 @@
docker-compose -f docker-compose.couch.yml up -d --build
+2
View File
@@ -12,6 +12,7 @@ import WelcomePage from "./Pages/WelcomePage";
import InputPage from "./Pages/InputPage";
import { createTheme, ThemeProvider } from "@mui/material";
import { ProcessedDataBucketProvider } from "./ProcessedDataBucketContext";
import NotesPage from "./Pages/NotesPage";
function App() {
const darkTheme = createTheme({
@@ -43,6 +44,7 @@ function App() {
<Route path="/" element={<WelcomePage />} />
<Route path="/Dashboard" element={<DashboardPage />} />
<Route path="/Input" element={<InputPage />} />
<Route path="/Notes" element={<NotesPage />} />
<Route path="/404" element={<NotFoundPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
+32 -1
View File
@@ -1,5 +1,5 @@
import PouchDB from "pouchdb";
import React, { useContext, useEffect, useState } from "react";
import React, { useContext, useEffect, useState, useCallback } from "react";
import { useProcessedDataBucket } from "./ProcessedDataBucketContext";
import { getProcessedDataBucket, updateProcessedDataBucket } from "./ProcessedDataBucket";
@@ -36,6 +36,33 @@ export function DbProvider({ children }) {
.on("change", (change) => {
updateProcessedDataBucket(localdb, setProcessedDataBucket);
});
// useEffect(()=>{
// updateProcessedDataBucket(localdb, setProcessedDataBucket);
// }, [setProcessedDataBucket]);
// localdb.replicate.to(remotedb, {
// retry: true,
// });
// const [localNotesdb, setLocalNotesdb] = useState(new PouchDB("denver_notes"));
// const [remoteNotesdb, setRemoteNotesdb] = useState(
// new PouchDB("http://" + window.location.hostname + ":5984/denver_notes", {
// skip_setup: true,
// auth: {
// username: "scouting",
// password: "Ridgebotics",
// },
// })
// );
// localNotesdb.replicate
// .from(remoteNotesdb, {
// live: true,
// retry: true,
// })
// .on("change", (change) => {
// // updateProcessedDataBucket(localdb, setProcessedDataBucket);
// });
// updateProcessedDataBucket(localdb, setProcessedDataBucket);
// useEffect(() => {
// setDatabaseName("denver_fr", setLocaldb, setRemotedb, setProcessedDataBucket);
@@ -98,6 +125,10 @@ export function setDatabaseName(name, setLocaldb, setRemotedb, setProcessedDataB
updateProcessedDataBucket(localdb, setProcessedDataBucket);
});
updateProcessedDataBucket(localdb, setProcessedDataBucket);
localdb.replicate.to(remotedb, {
live: true,
retry: true,
});
setLocaldb(localdb);
setRemotedb(remotedb);
}
+6 -5
View File
@@ -33,6 +33,7 @@ const InputPage = () => {
.put({
// _id: new Date().toISOString(),
_id: "match_" + values.match_number + "_team_" + values.team_number,
type: "match",
...values,
})
.then((result) => {
@@ -40,7 +41,7 @@ const InputPage = () => {
console.log(result);
console.log(localdb);
localdb.replicate.to(remotedb, {
live: true,
retry: true,
});
})
.catch((err) => {
@@ -48,7 +49,7 @@ const InputPage = () => {
alert(err);
});
// alert(JSON.stringify(values, null, 2));
// resetForm(); //Hah tobad
resetForm(); //Hah tobad
setSubmitting(false);
// }, 400);
updateProcessedDataBucket(localdb, setProcessedDataBucket);
@@ -76,7 +77,7 @@ const InputPage = () => {
lower_hub_auto: "0",
upper_hub_teleop: "0",
lower_hub_teleop: "0",
climb_level: "",
climb_level: "0",
alliance: "",
defence: "0",
disabled: false,
@@ -148,12 +149,12 @@ const InputPage = () => {
</Box>
<Box sx={{ ...panel_sx, display: "flex", flexDirection: "column" }}>
<h2>What they _______</h2>
{/* <h2>What they _______</h2>
<Box sx={{ display: "flex", flexDirection: "row", gap: 2, p: 0, m: 0 }}>
<FastField type="input" as={TextField} multiline rows={3} name="team_abilities_well" label="did well" />
<FastField type="input" as={TextField} multiline rows={3} name="team_abilities_struggle" label="struggled with" />
<FastField type="input" as={TextField} multiline rows={3} name="team_abilities_cant" label="can't do" />
</Box>
</Box> */}
<Button type="submit" disabled={isSubmitting}>
Submit
</Button>
+13
View File
@@ -0,0 +1,13 @@
.maxwidth {
display: block;
margin-left: auto;
margin-right: auto;
width: 100%;
text-align: center;
margin: auto;
max-width: fit-content;
/* max-width: 100% */
}
.smallfeild {
max-width: 25%;
}
+101
View File
@@ -0,0 +1,101 @@
import React, { useCallback } from "react";
import { useLocalDb, useRemoteDb } from "../DbContext";
import "./NotesPage.css";
import { Formik, FastField, Form, useFormikContext } from "formik";
import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material";
import { useProcessedDataBucket } from "../ProcessedDataBucketContext";
import { getProcessedDataBucket, updateProcessedDataBucket } from "../ProcessedDataBucket";
import NotesList from "../components/NotesList";
const NotesPage = () => {
let { localdb, setLocaldb } = useLocalDb();
let { remotedb, setRemotedb } = useRemoteDb();
const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
let panel_sx = {
display: "flex",
flexDirection: "column",
alignItems: { xs: "center", sm: "center" },
justifyContent: { xs: "flex-start", sm: "center" },
bgcolor: "background.paper",
p: 2,
m: 1,
gap: 2,
maxWidth: "fit-content",
borderRadius: "10px",
boxShadow: 7,
};
const onSubmit = useCallback(
(values, { setSubmitting, resetForm }) => {
// setTimeout(() => {
localdb
.put({
// _id: new Date().toISOString(),
_id: "notes_team_" + values.team_number + (new Date().toISOString()),
type: "notes",
...values,
})
.then((result) => {
alert("Notes Saved Successfully!");
console.log(result);
console.log(localdb);
localdb.replicate.to(remotedb, {
retry: true,
});
})
.catch((err) => {
console.log("Failed To Save Notes!");
alert(err);
});
// alert(JSON.stringify(values, null, 2));
resetForm(); //Hah tobad
setSubmitting(false);
// }, 400);
updateProcessedDataBucket(localdb, setProcessedDataBucket);
},
[localdb, remotedb, setProcessedDataBucket, updateProcessedDataBucket]
);
return (
<div>
<br />
<Formik
initialValues={{
team_number: "",
notes: ""
}}
validateOnChange="false"
onSubmit={onSubmit}
>
{({ values, setValues, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting }) => (
<Form>
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
{/* <Box sx={{ display: "flex", flexDirection: "row", gap: 2, p: 0, m: 0 }}> */}
{/* <Box sx={{...panel_sx, flexDirection: "column"}} fullWidth> */}
<Box sx={panel_sx} >
<FastField type="input" as={TextField} name="team_number" label="Team #" />
<FastField type="input" as={TextField} multiline rows={3} name="notes" label="Notes" />
<Button type="submit" disabled={isSubmitting}>
Submit
</Button>
</Box>
<Box sx={panel_sx} >
<NotesList/>
{/* {
processedDataBucket[] .map((item, index)=>{
return <h1 key={index}>{item}</h1>
})
} */}
</Box>
</Box>
<div />
</Form>
)}
</Formik>
</div>
);
};
export default NotesPage;
+1 -1
View File
@@ -2,7 +2,7 @@ import React from "react";
import "./WelcomePage.css";
import "../App.css";
import DbChooser from "../components/DbChooser";
import { Box } from "@mui/material";
import { Box, Button } from "@mui/material";
const WelcomePage = () => {
return (
+9 -1
View File
@@ -16,6 +16,7 @@ export function updateProcessedDataBucket(db, setProcessedDataBucket) {
teamData[doc.team_number] = {
team_number: doc.team_number,
matches_played: 0,
notes: [],
data_sets: {
upper_hub_auto: [],
lower_hub_auto: [],
@@ -40,8 +41,11 @@ export function updateProcessedDataBucket(db, setProcessedDataBucket) {
};
}
//add this game's data to the respective team data:
let thisTeamData = teamData[doc.team_number];
if (doc.type === "match")
{
console.log("MATCH: " + doc._id)
//add this game's data to the respective team data:
thisTeamData.matches_played++;
let auto_points = (parseInt(doc.taxi_auto) ? 2 : 0) + parseInt(doc.upper_hub_auto) * 4 + parseInt(doc.lower_hub_auto) * 2;
@@ -76,6 +80,10 @@ export function updateProcessedDataBucket(db, setProcessedDataBucket) {
thisTeamData.average_teleop_hub_points = thisTeamData.data_sets.teleop_hub_points.reduce(sum, 0) / thisTeamData.matches_played;
thisTeamData.average_climb_points = thisTeamData.data_sets.climb_points.reduce(sum, 0) / thisTeamData.matches_played;
thisTeamData.average_total_match_points = thisTeamData.data_sets.total_match_points.reduce(sum, 0) / thisTeamData.matches_played;
} else if (doc.type === "notes") {
console.log("NOTES: " + doc._id)
thisTeamData.notes.push(doc.notes);
}
});
setProcessedDataBucket({ teamData: teamData, matchData: matchData });
})
+11 -1
View File
@@ -1,5 +1,5 @@
import React, { useCallback } from "react";
import { Box, InputLabel, MenuItem, FormControl, Select } from "@mui/material";
import { Box, InputLabel, MenuItem, FormControl, Select, Button } from "@mui/material";
import { setDatabaseName, useLocalDb, useRemoteDb } from "../DbContext";
import { useProcessedDataBucket } from "../ProcessedDataBucketContext";
@@ -9,6 +9,13 @@ const DbChooser = (props) => {
const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
const [dbname, setDbName] = React.useState(localdb.name);
const sync = useCallback(()=>{
localdb.sync(remotedb, {
// live:true,
retry:true
});
}, [localdb, remotedb]);
const handleChange = useCallback((event) => {
console.log(event.target.value);
@@ -29,6 +36,9 @@ const DbChooser = (props) => {
<MenuItem value={"testdata"}>Test Data</MenuItem>
</Select>
</FormControl>
<Button onClick={sync}>
Force Sync
</Button>
</Box>
</div>
);
@@ -6,6 +6,7 @@ const PagesList = props => {
<ul>
<li><Link onClick={props.click} to="/Dashboard">Dashboard</Link></li>
<li><Link onClick={props.click} to="/Input">Input</Link></li>
<li><Link onClick={props.click} to="/Notes">Notes</Link></li>
</ul>
)
}
@@ -10,7 +10,7 @@ const Toolbar = props => {
<header className="toolbar">
<nav className="toolbar_navigation">
<DrawerButton click={props.drawerClickHandler} />
<div className = "toolbar_logo"><Link to="/">Ridgebotics Scouting 💙</Link></div>
<div className = "toolbar_logo"><Link to="/">Ridgebotics Scouting</Link></div>
<div className = "toolbar_spacer" />
<div className = "toolbar_items">
<PagesList />
+29
View File
@@ -0,0 +1,29 @@
import React from "react";
import { Formik, FastField, Form, useFormikContext } from "formik";
import { useProcessedDataBucket } from "../ProcessedDataBucketContext";
const NotesList = (props) => {
const { values, submitForm } = useFormikContext();
const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
if (processedDataBucket == null) {
return null;
}
// console.log(values);
if (typeof processedDataBucket.teamData[values.team_number] === "undefined") {
return null;
} else {
// let notesList = processedDataBucket.teamData[values.team_number].notes;
let notesList = processedDataBucket.teamData[values.team_number].notes;
// let notesComponents = notesList.map((item, index)=>{
return notesList.map((item, index)=>{
return <h3 key={index}>{item}</h3>
});
// return (
// // <h2>{processedDataBucket.teamData[values.team_number].Name</h2>
// {notesComponents}
// )
}
}
export default NotesList;