Skip to content

Commit

Permalink
Upgrade Material UI to v5 (#35)
Browse files Browse the repository at this point in the history
* source code changes for mui v5

* updated deps

* bring node version in sync w/ local + lts

* npm audit fix --force

* experiment: update to tab navigation

* fix nav on mobile/ small screens

* replace href based nav w/ single page app

* avoid repeating title from nav bar, use all avail horizontal space for file list

* moved version display to settings, fixed formatting

* update action versions to address deprecation warnings

* updated arm exec w/ latest frontend code

Co-authored-by: Ingo Jaeckel <[email protected]>
  • Loading branch information
ingojaeckel and Ingo Jaeckel authored Dec 26, 2022
1 parent e0c44c9 commit fc5100b
Show file tree
Hide file tree
Showing 12 changed files with 30,786 additions and 11,536 deletions.
11 changes: 4 additions & 7 deletions .github/workflows/go-arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Set up npm
uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
node-version: '18'
- name: Build frontend
run: cd frontend && npm install && npm run build && cd ../
- name: Set up Go
uses: actions/setup-go@v1
- uses: actions/setup-go@v3
with:
go-version: 1.16
id: go
Expand Down
11 changes: 4 additions & 7 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Set up npm
uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
node-version: '18'
- name: Build frontend
run: cd frontend && npm install && npm run build && cd ../
- name: Set up Go
uses: actions/setup-go@v1
- uses: actions/setup-go@v3
with:
go-version: 1.16
id: go
Expand Down
Binary file modified bin/arm/go-raspberry-pi-timelapse
Binary file not shown.
42,069 changes: 30,686 additions & 11,383 deletions frontend/package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"private": true,
"homepage": "/static/frontend/build",
"dependencies": {
"@material-ui/core": "^4.11.3",
"@material-ui/data-grid": "^4.0.0-alpha.20",
"@material-ui/icons": "^4.11.2",
"@mui/icons-material": "^5.10.16",
"@mui/material": "^5.10.16",
"@mui/styles": "^5.10.16",
"@mui/x-data-grid": "^5.17.14",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
Expand All @@ -20,7 +21,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.0",
"react-scripts": "^5.0.1",
"source-map-explorer": "^2.5.2",
"typescript": "^3.9.9"
},
Expand Down
120 changes: 56 additions & 64 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,72 @@
import React from 'react';
import { createBrowserHistory } from "history";
import { NavLink, Router } from 'react-router-dom';
import Grid from '@material-ui/core/Grid';
import HomeIcon from '@material-ui/icons/Home';
import SettingsIcon from '@material-ui/icons/Settings';
import TimelineIcon from '@material-ui/icons/Timeline';
import DescriptionIcon from '@material-ui/icons/Description';
import { Container, List, Avatar, ListItemAvatar, ListItem, CssBaseline } from '@material-ui/core';
import Switcher from './Switch';
import axios from 'axios';
import { PhotoCamera } from '@material-ui/icons';
import { Box, Container, CssBaseline, Grid, Tab, Tabs, Typography } from '@mui/material';
import { Home, PhotoCamera, Timeline, Settings, Description } from '@mui/icons-material'
import PhotoComponent from './components/PhotoComponent';
import MonitoringComponent from './components/MonitoringComponent';
import SetupComponent from './components/SetupComponent';
import PreviewComponent from './components/PreviewComponent';
import LogComponent from './components/LogComponent';

// Register default request interceptors
axios.interceptors.request.use(request => {
console.log('Starting Request', JSON.stringify(request, null, 2))
return request
})

const customHistory = createBrowserHistory();
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}

function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;

return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}

function App() {
const [value, setValue] = React.useState(0);
const handleChange = (_event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
return (
<Router history={customHistory}>
<React.Fragment>
<CssBaseline />
<Container fixed>
<Grid container spacing={0}>
<Grid item xs={2} alignItems="center">
<List disablePadding>
<ListItem to={`${process.env.PUBLIC_URL}/`} component={NavLink} disableGutters>
<ListItemAvatar>
<Avatar>
<HomeIcon />
</Avatar>
</ListItemAvatar>
</ListItem>
<ListItem to={`${process.env.PUBLIC_URL}/preview`} component={NavLink} disableGutters>
<ListItemAvatar>
<Avatar>
<PhotoCamera />
</Avatar>
</ListItemAvatar>
</ListItem>
<ListItem to={`${process.env.PUBLIC_URL}/monitoring`} component={NavLink} disableGutters>
<ListItemAvatar>
<Avatar>
<TimelineIcon />
</Avatar>
</ListItemAvatar>
</ListItem>
<ListItem to={`${process.env.PUBLIC_URL}/settings`} component={NavLink} disableGutters>
<ListItemAvatar>
<Avatar>
<SettingsIcon />
</Avatar>
</ListItemAvatar>
</ListItem>
<ListItem to={`${process.env.PUBLIC_URL}/logs`} component={NavLink} disableGutters>
<ListItemAvatar>
<Avatar>
<DescriptionIcon />
</Avatar>
</ListItemAvatar>
</ListItem>
</List>
</Grid>
<Grid item xs={10}>
<Switcher />
</Grid>
<Grid item xs={12}>
<div className="footer">version: <a href={"https://github.com/ingojaeckel/go-raspberry-pi-timelapse/commit/" + process.env.REACT_APP_GIT_SHA}>{process.env.REACT_APP_GIT_SHA}</a></div>
</Grid>
<React.Fragment>
<CssBaseline />
<Container>
<Grid container spacing={0}>
<Grid item xs={12}>
<Tabs value={value} onChange={handleChange} variant="scrollable" scrollButtons allowScrollButtonsMobile aria-label="scrollable icon label tabs">
<Tab label="home" icon={<Home />} />
<Tab label="preview" icon={<PhotoCamera />} />
<Tab label="monitoring" icon={<Timeline />} />
<Tab label="settings" icon={<Settings />} />
<Tab label="logs" icon={<Description />} />
</Tabs>
<TabPanel value={value} index={0}><PhotoComponent /></TabPanel>
<TabPanel value={value} index={1}><PreviewComponent /></TabPanel>
<TabPanel value={value} index={2}><MonitoringComponent /></TabPanel>
<TabPanel value={value} index={3}><SetupComponent /></TabPanel>
<TabPanel value={value} index={4}><LogComponent /></TabPanel>
</Grid>
</Container>
</React.Fragment>
</Router>
</Grid>
</Container>
</React.Fragment>
);
}

Expand Down
29 changes: 0 additions & 29 deletions frontend/src/Switch.tsx

This file was deleted.

3 changes: 1 addition & 2 deletions frontend/src/components/LogComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Button, ButtonGroup } from '@mui/material';
import { LogResponse } from '../models/response'
import { Typography, Button, ButtonGroup } from '@material-ui/core';
import { BaseUrl } from '../conf/config'

export default function LogComponent() {
Expand All @@ -22,7 +22,6 @@ export default function LogComponent() {

return (
<React.Fragment>
<Typography variant="h4" component="h4">Logs</Typography>
<ButtonGroup color="primary" aria-label="outlined primary button group">
<Button onClick={() => getLogs()}>Refresh</Button>
</ButtonGroup>
Expand Down
28 changes: 11 additions & 17 deletions frontend/src/components/MonitoringComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { BaseUrl } from '../conf/config'
import { MonitoringResponse } from '../models/response'
import { Typography } from '@material-ui/core';

export default function MonitoringComponent() {
const [state, setState] = useState<MonitoringResponse>({
Expand All @@ -24,21 +23,16 @@ export default function MonitoringComponent() {
}, []);

return (
<div>
<div>
<Typography variant="h4" component="h4">Monitoring</Typography>
</div>
<ul>
<li>Current Time: <br/><pre>{state.Time}</pre></li>
<li>Uptime: <br /><pre>{state.Uptime}</pre></li>
<li>Free Disk Space: <br/><pre>{state.FreeDiskSpace}</pre></li>
<li>Temperature:
<ul>
<li>GPU: <br/><pre>{state.GpuTemperature}</pre></li>
<li>CPU: <br/><pre>{state.CpuTemperature}</pre></li>
</ul>
</li>
</ul>
</div>
<ul>
<li>Current Time: <br/><pre>{state.Time}</pre></li>
<li>Uptime: <br /><pre>{state.Uptime}</pre></li>
<li>Free Disk Space: <br/><pre>{state.FreeDiskSpace}</pre></li>
<li>Temperature:
<ul>
<li>GPU: <br/><pre>{state.GpuTemperature}</pre></li>
<li>CPU: <br/><pre>{state.CpuTemperature}</pre></li>
</ul>
</li>
</ul>
);
}
29 changes: 12 additions & 17 deletions frontend/src/components/PhotoComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Typography, Button, ButtonGroup } from '@material-ui/core';
import { DataGrid, ColDef, RowData, RowId, SelectionModelChangeParams, CellParams } from '@material-ui/data-grid';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import { PhotosResponse } from '../models/response';
import { DataGrid, GridColDef, GridRowData, GridRowId, GridCellParams, GridSelectionModel, GridCallbackDetails } from '@mui/x-data-grid';
import { Button, ButtonGroup, Dialog, DialogActions, DialogContent, DialogContentText } from '@mui/material';
import { BaseUrl } from '../conf/config'
import { PhotosResponse } from '../models/response';

export interface PhotosRowData {
ShowDeletionDialog: boolean,
Photos: RowData[],
Selected: RowId[],
Photos: GridRowData[], // TODO replace with GridRowModel
Selected: GridRowId[],
SelectedFilesParameter: string,
}

const columns: ColDef[] = [
{ field: 'fileName', headerName: 'Name', width: 300, renderCell: (p: CellParams) => (<a href={BaseUrl + "/file/" + p.value}>{p.value}</a> ) },
const columns: GridColDef[] = [
{ field: 'fileName', headerName: 'Name', width: 300, renderCell: (p: GridCellParams) => (<a href={BaseUrl + "/file/" + p.value}>{p.value}</a> ) },
{ field: 'fileCreateTime', headerName: 'Created At', width: 300 },
{ field: 'fileSizeBytes', headerName: 'Size', width: 100 },
];
Expand All @@ -37,7 +33,7 @@ const getPhotos = () => {
.then(resp => {
// After receiving a response, map the PhotosResponse to RowData[] which can be displayed in the data grid.
if (resp.data) {
var rows: RowData[] = [];
var rows: GridRowData[] = [];

for (var i=0; i<resp.data.Photos.length; i++) {
let photo = resp.data.Photos[i];
Expand All @@ -63,11 +59,11 @@ const getPhotos = () => {
getPhotos()
}, []);

const handleSelectionModelChanged = (params: SelectionModelChangeParams) => {
console.log("selection changed: ", params);
const handleSelectionModelChanged = (selectionModel: GridSelectionModel, details: GridCallbackDetails) => {
console.log("selection changed: ", selectionModel, details);

var link = "";
params.selectionModel.forEach(selected => {
selectionModel.forEach(selected => {
let selectedPhoto = state.Photos.find(e => e.id === selected);
if (selectedPhoto) {
let selectedPhotoFilename = selectedPhoto.fileName;
Expand All @@ -78,7 +74,7 @@ const getPhotos = () => {
setState({
ShowDeletionDialog: false,
Photos: state.Photos,
Selected: params.selectionModel,
Selected: selectionModel,
SelectedFilesParameter: link,
});
};
Expand Down Expand Up @@ -118,7 +114,6 @@ const getPhotos = () => {

return (
<React.Fragment>
<Typography variant="h4" component="h4">Photos</Typography>
<ButtonGroup color="primary" aria-label="outlined primary button group">
<Button onClick={handleRefreshClicked}>Refresh</Button>
<Button onClick={deletePhotosClicked}>Delete selected ({state.Selected.length})</Button>
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/components/PreviewComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react';
import { Typography } from '@material-ui/core';
import { BaseUrl } from '../conf/config';

export default function PhotosComponent() {
return (
<React.Fragment>
<Typography variant="h4" component="h4">Photo preview</Typography>
<div><img src={BaseUrl+"/capture"} alt="preview" /></div>
<div>
Tips for fine-tuning the camera position, focus, etc:
Expand Down
Loading

0 comments on commit fc5100b

Please sign in to comment.