Skip to content

Commit

Permalink
Merge pull request #80 from cryptoeng/frontend_enhancements
Browse files Browse the repository at this point in the history
Frontend enhancements
  • Loading branch information
dingens authored Jun 17, 2020
2 parents 49b3048 + a1a9731 commit 3e6114b
Show file tree
Hide file tree
Showing 17 changed files with 1,760 additions and 1,108 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
working-directory: tools/validation
run: npm install
- name: Create PQDB SQLite-File
run: node tools/validation/validate.js pqdb-frontend/public/pqdb.sqlite pqdb-frontend/src/tables.svg
run: node tools/validation/validate.js frontend/public/pqdb.sqlite frontend/src/tables.svg
- name: Install Frontend Dependencies and Build
working-directory: pqdb-frontend
working-directory: frontend
run: |
yarn install
yarn build
Expand All @@ -28,5 +28,5 @@ jobs:
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages
FOLDER: pqdb-frontend/build
FOLDER: frontend/build
SINGLE_COMMIT: true
3 changes: 3 additions & 0 deletions pqdb-frontend/.gitignore → frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

/public/pqdb.sqlite
/src/tables.svg
File renamed without changes.
12 changes: 12 additions & 0 deletions frontend/config-overrides.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const CopyPlugin = require('copy-webpack-plugin');

module.exports = function override(config, env) {
config.plugins.push(new CopyPlugin({
patterns: [
// This wasm file will be fetched dynamically when we initialize sql.js
// It is important that we do not change its name, and that it is in the same folder as the js
{ from: 'node_modules/sql.js/dist/sql-wasm.wasm', to: 'static/js/' },
]
}));
return config;
}
9 changes: 6 additions & 3 deletions pqdb-frontend/package.json → frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
"private": true,
"homepage": ".",
"dependencies": {
"@material-ui/core": "^4.9.14",
"@material-ui/core": "4.10.2",
"@material-ui/icons": "^4.9.1",
"csv-stringify": "^5.5.0",
"query-string": "6.13.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-image-lightbox": "^5.1.1",
"react-image-magnifiers": "^1.3.2",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"sql.js": "^1.2.2"
},
"devDependencies": {
"copy-webpack-plugin": "^5.1.1",
"copy-webpack-plugin": "6.0.2",
"react-app-rewired": "^2.1.5"
},
"scripts": {
Expand Down
Binary file added frontend/public/favicon.ico
Binary file not shown.
File renamed without changes.
153 changes: 153 additions & 0 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import React from 'react';
import {
CssBaseline, Grid, Box, Paper, List, ListItem, ListItemText,
IconButton, Drawer, CircularProgress, Container, Tooltip
} from '@material-ui/core';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import {
Menu as MenuIcon, BrightnessHigh as LightIcon, Brightness4 as DarkIcon
} from '@material-ui/icons';
import initSqlJs from "sql.js";
import { CustomSQLQuery, Welcome } from './components/views';
import { Route, Switch, Redirect } from 'react-router-dom';

import logo from './pqdb.svg';


function getTheme(type) {
return createMuiTheme({
palette: {
type: type
},
});
}

const pathname = (key) => '/' + key;

// Add new views here
const views = {
"": {
name: "Welcome Page",
description: "Contains info about this website.",
view: Welcome
},
"raw_sql": {
name: "Custom SQL Query",
description: "Enter a custom database query and display the result in a table.",
view: CustomSQLQuery
}
};

const Progress = (props) => <Box display='flex' justifyContent="center"><CircularProgress /></Box>;

const DrawerList = (props) =>
<List>
{
Object.keys(views).map(key =>
<ListItem key={key} button onClick={() => props.onClick(key)}>
<ListItemText primary={views[key].name} secondary={views[key].description} />
</ListItem>
)
}
</List>;

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
themeId: "light",
db: null,
drawerOpen: false
};
}

componentDidMount() {
// sql.js needs to fetch its wasm file, so we cannot immediately instantiate the database
// without any configuration, initSqlJs will fetch the wasm files directly from the same path as the js
// see ../config-overrides.js
initSqlJs()
.then(SQL => this.loadDatabase(SQL))
.catch(err => this.setState({ error: err }));
}

componentWillUnmount() {
this.state.db.close();
}


loadDatabase(SQL) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'pqdb.sqlite', true);
xhr.responseType = 'arraybuffer';

xhr.onload = e => {
var uInt8Array = new Uint8Array(xhr.response);
this.setState({ db: new SQL.Database(uInt8Array) });
};
xhr.send();
}

switchView(view) {
const history = this.props.history;
history.push({
pathname: pathname(view)
});
this.setState({ drawerOpen: false });
}

toggleTheme() {
this.setState({ themeId: (this.state.themeId === 'light') ? 'dark' : 'light' });
}

render() {
return (
<ThemeProvider theme={getTheme(this.state.themeId)}>
<CssBaseline />
<Box p={2}>
<Grid container direction="column" spacing={2}>
<Grid item>
<Box display='flex' justifyContent="center">
<img src={logo} width="500em" height="192.5em" alt="Logo" />
</Box>
</Grid>
{
(this.state.db != null) ?
<Grid container item>
<Switch>
{
Object.keys(views).map(key =>
<Route key={key} exact path={pathname(key)} render={(props) =>
React.createElement(views[key].view, { key: key + "?" + this.props.history.location.search, db: this.state.db, ...props })} />
)
}
<Route render={(props) => <Redirect to='/' />} />
</Switch>
</Grid> : <Progress />
}
<Grid item>
<Container maxWidth="md">
<Paper>
<Box p={1} display='flex' alignItems="center" justifyContent="center">
<Tooltip title={"Switch to " + ((this.state.themeId === 'light') ? 'dark' : 'light') + " theme"}>
<IconButton onClick={() => this.toggleTheme()}>
{(this.state.themeId === 'light') ? <DarkIcon /> : <LightIcon />}
</IconButton>
</Tooltip>
</Box>
</Paper>
</Container>
</Grid>
</Grid>
<IconButton style={{ position: "absolute", top: 0, left: 0 }} onClick={() => this.setState({ drawerOpen: true })}>
<MenuIcon />
</IconButton>
</Box>
<Drawer anchor="left" open={this.state.drawerOpen} onClose={() => this.setState({ drawerOpen: false })}>
<DrawerList onClick={(view) => this.switchView(view)} />
</Drawer>
</ThemeProvider>
);
}
}

export default App;
Loading

0 comments on commit 3e6114b

Please sign in to comment.