CEC-244 Remote car commands, search, sortable tables (#42)

* Add sortable table header

* Send bulk commands page
Update table page sizes
All tables are sortable

* Update site layout
Add search to update packages

* Reenable Datadog

* remove dev stuff
This commit is contained in:
John Wu
2021-05-26 15:46:46 -07:00
committed by GitHub
parent 64995ef7a6
commit 931e1521e8
29 changed files with 1886 additions and 1541 deletions

View File

@@ -8,11 +8,6 @@ exports[`File Upload Form Should render 1`] = `
<div
class="makeStyles-paper-3"
>
<h1
class="MuiTypography-root MuiTypography-h5"
>
Create Update Package
</h1>
<form
action="{onSubmit}"
class="makeStyles-form-5"
@@ -51,10 +46,10 @@ exports[`File Upload Form Should render 1`] = `
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-26 MuiOutlinedInput-notchedOutline"
class="PrivateNotchedOutline-root-31 MuiOutlinedInput-notchedOutline"
>
<legend
class="PrivateNotchedOutline-legendLabelled-28"
class="PrivateNotchedOutline-legendLabelled-33"
>
<span>
Package name
@@ -97,10 +92,10 @@ exports[`File Upload Form Should render 1`] = `
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-26 MuiOutlinedInput-notchedOutline"
class="PrivateNotchedOutline-root-31 MuiOutlinedInput-notchedOutline"
>
<legend
class="PrivateNotchedOutline-legendLabelled-28"
class="PrivateNotchedOutline-legendLabelled-33"
>
<span>
Version
@@ -143,10 +138,10 @@ exports[`File Upload Form Should render 1`] = `
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-26 MuiOutlinedInput-notchedOutline"
class="PrivateNotchedOutline-root-31 MuiOutlinedInput-notchedOutline"
>
<legend
class="PrivateNotchedOutline-legendLabelled-28"
class="PrivateNotchedOutline-legendLabelled-33"
>
<span>
Description
@@ -190,10 +185,10 @@ exports[`File Upload Form Should render 1`] = `
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-26 MuiOutlinedInput-notchedOutline"
class="PrivateNotchedOutline-root-31 MuiOutlinedInput-notchedOutline"
>
<legend
class="PrivateNotchedOutline-legendLabelled-28"
class="PrivateNotchedOutline-legendLabelled-33"
>
<span>
Release Notes URL

View File

@@ -1,5 +1,5 @@
import React, { useRef, useState } from "react";
import { Button, TextField, Typography } from "@material-ui/core";
import React, { useEffect, useRef, useState } from "react";
import { Button, TextField } from "@material-ui/core";
import { DropzoneArea } from "material-ui-dropzone";
import { useUserContext } from "../../Contexts/UserContext";
import { useStatusContext } from "../../Contexts/StatusContext";
@@ -42,13 +42,19 @@ const FileUploadZone = ({ classes, token }) => {
const MainForm = () => {
const { uploading, upload, files, cancel } = useFileUploadContext();
const { token } = useUserContext();
const { setMessage } = useStatusContext();
const { setMessage, setTitle } = useStatusContext();
const [redirect, setRedirect] = useState(null);
const classes = useStyles();
const packagenameEl = useRef(null);
const versionEl = useRef(null);
const descEl = useRef(null);
const releasenotesEl = useRef(null);
useEffect(() => {
setTitle("Create Update Package");
// eslint-disable-next-line
}, []);
const onSubmit = async (event) => {
try {
event.preventDefault();
@@ -79,9 +85,6 @@ const MainForm = () => {
return (
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Create Update Package
</Typography>
<form className={classes.form} noValidate action="{onSubmit}">
<TextField
id="packagename"

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import { Button, TextField, Typography } from "@material-ui/core";
import { Button, TextField } from "@material-ui/core";
import {
UpdatesProvider,
@@ -19,7 +19,7 @@ const MainForm = () => {
idToken: { jwtToken: token },
},
} = useUserContext();
const { setMessage } = useStatusContext();
const { setMessage, setTitle } = useStatusContext();
const [packageName, setPackageName] = useState("");
const [version, setVersion] = useState("");
const [link, setLink] = useState("");
@@ -68,10 +68,16 @@ const MainForm = () => {
}
};
useEffect(() => {
setTitle(`Edit Update Package ${id}`);
// eslint-disable-next-line
}, []);
useEffect(() => {
getData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token]);
useEffect(() => {
if (!packages || packages.length === 0) return;
var data = packages[0];
@@ -86,9 +92,6 @@ const MainForm = () => {
return (
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Edit Update Package {id}
</Typography>
<form className={classes.form} noValidate action="{onSubmit}">
<TextField
label="Create Date"

View File

@@ -6,13 +6,11 @@ import {
TableCell,
TableContainer,
TableFooter,
TableHead,
TablePagination,
TableRow,
Toolbar,
Tooltip,
Typography,
} from "@material-ui/core";
import EditIcon from "@material-ui/icons/Edit";
import SendIcon from "@material-ui/icons/Send";
import VisibilityIcon from "@material-ui/icons/Visibility";
import useStyles from "../../useStyles";
@@ -21,13 +19,42 @@ import {
useUpdatesContext,
} from "../../Contexts/UpdatesContext";
import { useUserContext } from "../../Contexts/UserContext";
import { tsLocalDateTimeString } from "../../../utils/dates";
import { useStatusContext } from "../../Contexts/StatusContext";
import { LocalDateTimeString } from "../../../utils/dates";
import { Roles, hasRole } from "../../../utils/roles";
import TableHeaderSortable from "../../Table/HeaderSortable";
import SearchField from "../../Controls/SearchField";
const tableColumns = [
{
id: "id",
label: "ID",
},
{
id: "package_name",
label: "Name",
},
{
id: "version",
label: "Version",
},
{
id: "created_at",
label: "Created",
},
{
id: "",
label: "Actions",
},
];
const UpdatePackagesList = () => {
const classes = useStyles();
const [pageSize, setPageSize] = useState(25);
const [pageIndex, setPageIndex] = useState(0);
const [orderBy, setOrderBy] = useState("id");
const [order, setOrder] = useState("desc");
const [search, setSearch] = useState("");
const { getPackages, packages, totalPackages } = useUpdatesContext();
const {
token: {
@@ -35,11 +62,25 @@ const UpdatePackagesList = () => {
},
groups,
} = useUserContext();
const { setTitle } = useStatusContext();
useEffect(() => {
getPackages({ limit: pageSize, offset: pageSize * pageIndex }, token);
setTitle("Deploy Packages");
// eslint-disable-next-line
}, [pageIndex, pageSize, token]);
}, []);
useEffect(() => {
getPackages(
{
limit: pageSize,
offset: pageSize * pageIndex,
order: `${orderBy} ${order}`,
search,
},
token
);
// eslint-disable-next-line
}, [pageIndex, pageSize, token, orderBy, order, search]);
const handleChangePageIndex = (event, newIndex) => {
setPageIndex(newIndex);
@@ -50,6 +91,23 @@ const UpdatePackagesList = () => {
setPageIndex(0);
};
const handleSort = (event, property) => {
if (property === orderBy) {
if (order === "asc") {
setOrder("desc");
} else {
setOrder("asc");
}
} else {
setOrderBy(property);
setOrder("asc");
}
};
const handleSearch = (search) => {
setSearch(search);
};
const Actions = (row) => {
let actions = [];
if (hasRole([Roles.CREATE, Roles.READ], groups)) {
@@ -65,13 +123,6 @@ const UpdatePackagesList = () => {
}
if (hasRole([Roles.CREATE], groups)) {
actions = actions.concat([
{
tip: `Edit "${row.package_name} ${row.version}"`,
link: `/update/${row.id}`,
icon: (
<EditIcon aria-label={`Edit ${row.package_name} ${row.version}`} />
),
},
{
tip: `Deploy "${row.package_name} ${row.version}"`,
link: `/carupdate-deploy/${row.id}`,
@@ -97,20 +148,18 @@ const UpdatePackagesList = () => {
return (
<div className={classes.paper} style={{ height: 700, width: "100%" }}>
<Typography component="h1" variant="h5">
Update Packages
</Typography>
<Toolbar className={classes.tableToolbar}>
<SearchField classes={classes} onSearch={handleSearch} />
</Toolbar>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">ID</TableCell>
<TableCell align="center">Name</TableCell>
<TableCell align="center">Version</TableCell>
<TableCell align="center">Created</TableCell>
<TableCell align="right">Actions</TableCell>
</TableRow>
</TableHead>
<TableHeaderSortable
classes={classes}
orderBy={orderBy}
order={order}
columnData={tableColumns}
onSortRequest={handleSort}
/>
<TableBody>
{packages.map((row) => (
<TableRow key={row.id}>
@@ -118,16 +167,16 @@ const UpdatePackagesList = () => {
<TableCell align="center">{row.package_name}</TableCell>
<TableCell align="center">{row.version}</TableCell>
<TableCell align="center">
{tsLocalDateTimeString(row.timestamp)}
{LocalDateTimeString(row.created)}
</TableCell>
<TableCell align="right">{Actions(row)}</TableCell>
<TableCell align="center">{Actions(row)}</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
rowsPerPageOptions={[5, 10, 25, 100]}
colSpan={5}
count={totalPackages}
rowsPerPage={pageSize}