Skip to content

Commit

Permalink
Runs page and queries
Browse files Browse the repository at this point in the history
Admin screen for viewing the list of stored runs.
This also generates the server side run query that will be used by the
MAV system as requested in #9
  • Loading branch information
bryankennedy committed Jun 11, 2018
1 parent 2b93d55 commit 3a5c92a
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/clientRun/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"react-mousetrap": "^0.2.0",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"react-table": "^6.8.6",
"reactstrap": "^6.0.1",
"redux": "^3.7.2",
"redux-form": "^7.2.0",
Expand Down
19 changes: 19 additions & 0 deletions packages/clientRun/src/Admin/AdminPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { Fragment } from 'react';
import { Link } from 'react-router-dom';

function Admin() {
const links = [
{ path: '/admin/runs', label: 'Runs' },
];
return (
<Fragment>
<div>Admin page</div>
<ul>{links.map(link => (
<li><Link to={link.path}>{link.label}</Link></li>
))}
</ul>
</Fragment>
);
}

export default Admin;
6 changes: 5 additions & 1 deletion packages/clientRun/src/App/AppRoutes.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import StartPage from '../Start/StartPage';
import Admin from '../Admin/AdminPage';
import Home from '../Pages/Home';
import NoMatch from '../Pages/NoMatch';
import Runs from '../Runs/Runs';

function AppRoutes() {
return (
<div className="row">
<div className="col-10 offset-1">
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/start" component={StartPage} />
<Route exact path="/admin" component={Admin} />
<Route exact path="/admin/start" component={StartPage} />
<Route exact path="/admin/runs" component={Runs} />
<Route component={NoMatch} />
</Switch>
</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/clientRun/src/App/Nav/AppNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ class AppNav extends React.Component {
<Nav className="mr-auto" navbar>
{/* Anonymous user navigation */}
<NavItem>
<Link className="nav-link" to="/start">Starting line kiosk</Link>
<Link className="nav-link" to="/admin">Admin</Link>
</NavItem>
<NavItem>
<Link className="nav-link" to="/admin/start">Starting line kiosk</Link>
</NavItem>
<NavItem>
<Link className="nav-link" to="/admin/runs">Runs</Link>
</NavItem>
</Nav>
<Nav className="ml-auto" navbar>
Expand Down
4 changes: 4 additions & 0 deletions packages/clientRun/src/Runs/Runs.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.wordwrap {
white-space: pre-line !important;
word-wrap: break-word;
}
85 changes: 85 additions & 0 deletions packages/clientRun/src/Runs/Runs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
import React from 'react';
import ReactTable from 'react-table';
import moment from 'moment';
import 'react-table/react-table.css';
import './Runs.css';

const GET_RUNS = gql`
query runs($lastX: Int!) {
runs(lastX: $lastX){
id
start
end
}
}
`;

function Runs() {
const dateFormat = 'dddd, MMMM Do YYYY, h:mm:ss a';
return (
<Query
query={GET_RUNS}
variables={{ lastX: parseInt(10) }}
>
{({ loading, error, data }) => {
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<ReactTable
data={data.runs}
columns={[
{
Header: 'Run ID',
accessor: 'id',
},
{
Header: 'Start',
accessor: 'start',
className: 'wordwrap',
Cell: row => (
<div>{moment(row.row.start).format(dateFormat)}</div>
),
},
{
Header: 'End',
accessor: 'end',
className: 'wordwrap',
Cell: row => (
<div>
{
row.row.end
? moment(row.row.end).format(dateFormat)
: '-'
}
</div>
),
},
{
Header: 'Duration',
accessor: 'duration',
Cell: (row) => {
const completed = !!(row.row.start && row.row.end);
const startDate = moment(row.row.start).valueOf();
const endDate = moment(row.row.end).valueOf();
const runDuration = endDate - startDate;
return (
<div>
{completed
? <div>{runDuration}</div>
: <div>-</div>
}
</div>);
},
},
]}
/>
);
}}
</Query>
);
}

export default Runs;

13 changes: 12 additions & 1 deletion packages/clientRun/src/Start/StartPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@
import React from 'react';
import { Query } from 'react-apollo';
import { Row, Col } from 'reactstrap';
import gql from 'graphql-tag';
import OpponentSelect from './OpponentSelect';
import RunningTimerPre from './RunningTimerPre';
import Running from './Running';
import RunningTimerPost from './RunningTimerPost';
import AppState from '../App/AppState';
import GET_RACE_STATE_LOCAL from './graphql/GetRaceStateLocal.graphql';

const GET_RACE_STATE_LOCAL = gql`
query {
activeRace @client {
opponent
opponentTime
raceId
status
}
}
`;

function StartPage() {
return (
Expand Down
23 changes: 18 additions & 5 deletions packages/serverGraphQL/src/graphql/resolvers/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,42 @@ import db from '../../db/models/index';
// Queries
//------------------------------------------------------------------------------

// Load a run
// TODO: create a single run query
// TODO: create a n runs query
// Load x runs starting with the most recent
const runs = baseResolver
.createResolver((root, args) => db.run.findAll({ limit: args.lastX }));

//------------------------------------------------------------------------------
// Mutations
//------------------------------------------------------------------------------

// Keeping extraneous console statements and return helpers in the code
// while in active DB development.

// Create a run, return the ID
const runStart = baseResolver
.createResolver((root, args) => db.run.create({
opponent: args.run.opponent,
start: args.run.start,
}).then(createdRun => createdRun.id));
})
.then((createdRun) => {
console.log('Updating a run record');
return createdRun.id;
}));

// Update an existing run record with a finish time, return the ID
const runFinish = baseResolver
.createResolver((root, args) => db.run.update(
{ end: args.run.finish },
{ where: { id: args.run.id } },
));
).then((updatedRuns) => {
console.log('Updating a run record');
return updatedRuns;
}));

const RunResolver = {
Query: {
runs,
},
Mutation: {
runStart,
runFinish,
Expand Down
6 changes: 6 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9988,6 +9988,12 @@ react-router@^4.2.0:
prop-types "^15.5.4"
warning "^3.0.0"

react-table@^6.8.6:
version "6.8.6"
resolved "https://registry.yarnpkg.com/react-table/-/react-table-6.8.6.tgz#a0ad8b4839319052d5befc012603fb161e52ede3"
dependencies:
classnames "^2.2.5"

react-transition-group@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.3.1.tgz#31d611b33e143a5e0f2d94c348e026a0f3b474b6"
Expand Down

0 comments on commit 3a5c92a

Please sign in to comment.