mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 11:15:53 +08:00
Fix dark theme styles
This commit is contained in:
parent
b15fa59cf9
commit
e7cfbc6bf7
@ -19,7 +19,6 @@
|
|||||||
"@types/react-router-dom": "5.1.6",
|
"@types/react-router-dom": "5.1.6",
|
||||||
"@types/react-syntax-highlighter": "13.5.0",
|
"@types/react-syntax-highlighter": "13.5.0",
|
||||||
"@types/recharts": "1.8.16",
|
"@types/recharts": "1.8.16",
|
||||||
"@types/styled-components": "5.1.4",
|
|
||||||
"axios": "0.20.0",
|
"axios": "0.20.0",
|
||||||
"clsx": "1.1.1",
|
"clsx": "1.1.1",
|
||||||
"lodash.uniqby": "4.7.0",
|
"lodash.uniqby": "4.7.0",
|
||||||
@ -31,7 +30,6 @@
|
|||||||
"react-scripts": "3.4.3",
|
"react-scripts": "3.4.3",
|
||||||
"react-syntax-highlighter": "15.3.0",
|
"react-syntax-highlighter": "15.3.0",
|
||||||
"recharts": "1.8.5",
|
"recharts": "1.8.5",
|
||||||
"styled-components": "5.2.0",
|
|
||||||
"typescript": "~3.7.2"
|
"typescript": "~3.7.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -2,7 +2,7 @@ import React, { useState } from "react";
|
|||||||
import { connect, ConnectedProps } from "react-redux";
|
import { connect, ConnectedProps } from "react-redux";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
|
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
|
||||||
import { makeStyles, ThemeProvider } from "@material-ui/core/styles";
|
import { makeStyles, Theme, ThemeProvider } from "@material-ui/core/styles";
|
||||||
import AppBar from "@material-ui/core/AppBar";
|
import AppBar from "@material-ui/core/AppBar";
|
||||||
import Drawer from "@material-ui/core/Drawer";
|
import Drawer from "@material-ui/core/Drawer";
|
||||||
import Toolbar from "@material-ui/core/Toolbar";
|
import Toolbar from "@material-ui/core/Toolbar";
|
||||||
@ -39,7 +39,11 @@ import PageNotFoundView from "./views/PageNotFoundView";
|
|||||||
|
|
||||||
const drawerWidth = 220;
|
const drawerWidth = 220;
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
// FIXME: For some reason, the following code does not work:
|
||||||
|
// makeStyles(theme => ({ /* use theme here */}));
|
||||||
|
// Using closure to work around this problem.
|
||||||
|
const useStyles = (theme: Theme) =>
|
||||||
|
makeStyles({
|
||||||
root: {
|
root: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
},
|
},
|
||||||
@ -66,7 +70,6 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
color: theme.palette.grey[800],
|
|
||||||
},
|
},
|
||||||
drawerPaper: {
|
drawerPaper: {
|
||||||
position: "relative",
|
position: "relative",
|
||||||
@ -105,7 +108,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
height: "100vh",
|
height: "100vh",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
background: "#ffffff",
|
background: theme.palette.background.paper,
|
||||||
},
|
},
|
||||||
contentWrapper: {
|
contentWrapper: {
|
||||||
height: "100%",
|
height: "100%",
|
||||||
@ -123,7 +126,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
borderTopRightRadius: "24px",
|
borderTopRightRadius: "24px",
|
||||||
borderBottomRightRadius: "24px",
|
borderBottomRightRadius: "24px",
|
||||||
},
|
},
|
||||||
}));
|
});
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
@ -143,10 +146,10 @@ function SlideUpTransition(props: TransitionProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function App(props: ConnectedProps<typeof connector>) {
|
function App(props: ConnectedProps<typeof connector>) {
|
||||||
const classes = useStyles();
|
const theme = makeTheme(props.isDarkTheme);
|
||||||
|
const classes = useStyles(theme)();
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const toggleDrawer = () => setOpen(!open);
|
const toggleDrawer = () => setOpen(!open);
|
||||||
const theme = makeTheme(props.isDarkTheme);
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<Router>
|
<Router>
|
||||||
@ -169,9 +172,9 @@ function App(props: ConnectedProps<typeof connector>) {
|
|||||||
<Typography
|
<Typography
|
||||||
component="h1"
|
component="h1"
|
||||||
variant="h6"
|
variant="h6"
|
||||||
color="inherit"
|
|
||||||
noWrap
|
noWrap
|
||||||
className={classes.title}
|
className={classes.title}
|
||||||
|
color="textPrimary"
|
||||||
>
|
>
|
||||||
Asynq Monitoring
|
Asynq Monitoring
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -41,11 +41,14 @@ import { ActiveTaskExtended } from "../reducers/tasksReducer";
|
|||||||
import { uuidPrefix } from "../utils";
|
import { uuidPrefix } from "../utils";
|
||||||
import { TableColumn } from "../types/table";
|
import { TableColumn } from "../types/table";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles((theme) => ({
|
||||||
table: {
|
table: {
|
||||||
minWidth: 650,
|
minWidth: 650,
|
||||||
},
|
},
|
||||||
});
|
stickyHeaderCell: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
@ -168,7 +171,10 @@ function ActiveTasksTable(props: Props & ReduxProps) {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell padding="checkbox">
|
<TableCell
|
||||||
|
padding="checkbox"
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
indeterminate={numSelected > 0 && numSelected < rowCount}
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
||||||
checked={rowCount > 0 && numSelected === rowCount}
|
checked={rowCount > 0 && numSelected === rowCount}
|
||||||
@ -179,7 +185,11 @@ function ActiveTasksTable(props: Props & ReduxProps) {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{columns.map((col) => (
|
{columns.map((col) => (
|
||||||
<TableCell key={col.key} align={col.align}>
|
<TableCell
|
||||||
|
key={col.key}
|
||||||
|
align={col.align}
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
{col.label}
|
{col.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -46,11 +46,14 @@ import { usePolling } from "../hooks";
|
|||||||
import { ArchivedTaskExtended } from "../reducers/tasksReducer";
|
import { ArchivedTaskExtended } from "../reducers/tasksReducer";
|
||||||
import { TableColumn } from "../types/table";
|
import { TableColumn } from "../types/table";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles((theme) => ({
|
||||||
table: {
|
table: {
|
||||||
minWidth: 650,
|
minWidth: 650,
|
||||||
},
|
},
|
||||||
});
|
stickyHeaderCell: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
const useRowStyles = makeStyles({
|
const useRowStyles = makeStyles({
|
||||||
root: {
|
root: {
|
||||||
@ -214,7 +217,10 @@ function ArchivedTasksTable(props: Props & ReduxProps) {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell padding="checkbox">
|
<TableCell
|
||||||
|
padding="checkbox"
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
indeterminate={numSelected > 0 && numSelected < rowCount}
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
||||||
checked={rowCount > 0 && numSelected === rowCount}
|
checked={rowCount > 0 && numSelected === rowCount}
|
||||||
@ -225,7 +231,11 @@ function ArchivedTasksTable(props: Props & ReduxProps) {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{columns.map((col) => (
|
{columns.map((col) => (
|
||||||
<TableCell key={col.key} align={col.align}>
|
<TableCell
|
||||||
|
key={col.key}
|
||||||
|
align={col.align}
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
{col.label}
|
{col.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -32,11 +32,14 @@ import { usePolling } from "../hooks";
|
|||||||
import { uuidPrefix } from "../utils";
|
import { uuidPrefix } from "../utils";
|
||||||
import { TableColumn } from "../types/table";
|
import { TableColumn } from "../types/table";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles((theme) => ({
|
||||||
table: {
|
table: {
|
||||||
minWidth: 650,
|
minWidth: 650,
|
||||||
},
|
},
|
||||||
});
|
stickyHeaderCell: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
@ -110,7 +113,11 @@ function PendingTasksTable(props: Props & ReduxProps) {
|
|||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{columns.map((col) => (
|
{columns.map((col) => (
|
||||||
<TableCell key={col.key} align={col.align}>
|
<TableCell
|
||||||
|
key={col.key}
|
||||||
|
align={col.align}
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
{col.label}
|
{col.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -27,6 +27,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
},
|
},
|
||||||
linkCell: {
|
linkCell: {
|
||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
|
color: theme.palette.text.primary,
|
||||||
},
|
},
|
||||||
footerCell: {
|
footerCell: {
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
@ -40,7 +41,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
position: "sticky",
|
position: "sticky",
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
left: 0,
|
left: 0,
|
||||||
background: theme.palette.common.white,
|
background: theme.palette.background.paper,
|
||||||
},
|
},
|
||||||
actionIconsContainer: {
|
actionIconsContainer: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -211,7 +212,10 @@ export default function QueuesOverviewTable(props: Props) {
|
|||||||
scope="row"
|
scope="row"
|
||||||
className={clsx(classes.boldCell, classes.fixedCell)}
|
className={clsx(classes.boldCell, classes.fixedCell)}
|
||||||
>
|
>
|
||||||
<Link to={queueDetailsPath(q.queue)}>
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue)}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
{q.queue}
|
{q.queue}
|
||||||
{q.paused ? " (paused)" : ""}
|
{q.paused ? " (paused)" : ""}
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -50,11 +50,14 @@ import { RetryTaskExtended } from "../reducers/tasksReducer";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { TableColumn } from "../types/table";
|
import { TableColumn } from "../types/table";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles((theme) => ({
|
||||||
table: {
|
table: {
|
||||||
minWidth: 650,
|
minWidth: 650,
|
||||||
},
|
},
|
||||||
});
|
stickyHeaderCell: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
@ -229,7 +232,10 @@ function RetryTasksTable(props: Props & ReduxProps) {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell padding="checkbox">
|
<TableCell
|
||||||
|
padding="checkbox"
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
indeterminate={numSelected > 0 && numSelected < rowCount}
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
||||||
checked={rowCount > 0 && numSelected === rowCount}
|
checked={rowCount > 0 && numSelected === rowCount}
|
||||||
@ -240,7 +246,11 @@ function RetryTasksTable(props: Props & ReduxProps) {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{columns.map((col) => (
|
{columns.map((col) => (
|
||||||
<TableCell key={col.label} align={col.align}>
|
<TableCell
|
||||||
|
key={col.label}
|
||||||
|
align={col.align}
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
{col.label}
|
{col.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -50,11 +50,14 @@ import { usePolling } from "../hooks";
|
|||||||
import { ScheduledTaskExtended } from "../reducers/tasksReducer";
|
import { ScheduledTaskExtended } from "../reducers/tasksReducer";
|
||||||
import { TableColumn } from "../types/table";
|
import { TableColumn } from "../types/table";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles((theme) => ({
|
||||||
table: {
|
table: {
|
||||||
minWidth: 650,
|
minWidth: 650,
|
||||||
},
|
},
|
||||||
});
|
stickyHeaderCell: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState) {
|
||||||
return {
|
return {
|
||||||
@ -226,7 +229,10 @@ function ScheduledTasksTable(props: Props & ReduxProps) {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell padding="checkbox">
|
<TableCell
|
||||||
|
padding="checkbox"
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
indeterminate={numSelected > 0 && numSelected < rowCount}
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
||||||
checked={rowCount > 0 && numSelected === rowCount}
|
checked={rowCount > 0 && numSelected === rowCount}
|
||||||
@ -237,7 +243,11 @@ function ScheduledTasksTable(props: Props & ReduxProps) {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{columns.map((col) => (
|
{columns.map((col) => (
|
||||||
<TableCell key={col.label} align={col.align}>
|
<TableCell
|
||||||
|
key={col.label}
|
||||||
|
align={col.align}
|
||||||
|
classes={{ stickyHeader: classes.stickyHeaderCell }}
|
||||||
|
>
|
||||||
{col.label}
|
{col.label}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
))}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles, useTheme, Theme } from "@material-ui/core/styles";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Box from "@material-ui/core/Box";
|
import Box from "@material-ui/core/Box";
|
||||||
import Collapse from "@material-ui/core/Collapse";
|
import Collapse from "@material-ui/core/Collapse";
|
||||||
@ -19,7 +19,8 @@ import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp";
|
|||||||
import Alert from "@material-ui/lab/Alert";
|
import Alert from "@material-ui/lab/Alert";
|
||||||
import AlertTitle from "@material-ui/lab/AlertTitle";
|
import AlertTitle from "@material-ui/lab/AlertTitle";
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github";
|
import syntaxHighlightStyleDark from "react-syntax-highlighter/dist/esm/styles/hljs/atom-one-dark";
|
||||||
|
import syntaxHighlightStyleLight from "react-syntax-highlighter/dist/esm/styles/hljs/atom-one-light";
|
||||||
import { ServerInfo } from "../api";
|
import { ServerInfo } from "../api";
|
||||||
import { SortDirection, SortableTableColumn } from "../types/table";
|
import { SortDirection, SortableTableColumn } from "../types/table";
|
||||||
import { timeAgo, uuidPrefix } from "../utils";
|
import { timeAgo, uuidPrefix } from "../utils";
|
||||||
@ -34,7 +35,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
position: "sticky",
|
position: "sticky",
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
left: 0,
|
left: 0,
|
||||||
background: theme.palette.common.white,
|
background: theme.palette.background.paper,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -208,10 +209,15 @@ const useRowStyles = makeStyles((theme) => ({
|
|||||||
noBorder: {
|
noBorder: {
|
||||||
border: "none",
|
border: "none",
|
||||||
},
|
},
|
||||||
|
link: {
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function Row(props: RowProps) {
|
function Row(props: RowProps) {
|
||||||
const classes = useRowStyles();
|
const classes = useRowStyles();
|
||||||
|
const theme = useTheme<Theme>();
|
||||||
|
const isDarkTheme = theme.palette.type === "dark";
|
||||||
const { server } = props;
|
const { server } = props;
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
const qnames = Object.keys(server.queue_priorities);
|
const qnames = Object.keys(server.queue_priorities);
|
||||||
@ -226,7 +232,9 @@ function Row(props: RowProps) {
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
{qnames.map((qname, idx) => (
|
{qnames.map((qname, idx) => (
|
||||||
<span key={qname}>
|
<span key={qname}>
|
||||||
<Link to={queueDetailsPath(qname)}>{qname}</Link>
|
<Link to={queueDetailsPath(qname)} className={classes.link}>
|
||||||
|
{qname}
|
||||||
|
</Link>
|
||||||
{idx === qnames.length - 1 ? "" : ", "}
|
{idx === qnames.length - 1 ? "" : ", "}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@ -276,7 +284,11 @@ function Row(props: RowProps) {
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
language="json"
|
language="json"
|
||||||
style={syntaxHighlightStyle}
|
style={
|
||||||
|
isDarkTheme
|
||||||
|
? syntaxHighlightStyleDark
|
||||||
|
: syntaxHighlightStyleLight
|
||||||
|
}
|
||||||
customStyle={{ margin: 0 }}
|
customStyle={{ margin: 0 }}
|
||||||
>
|
>
|
||||||
{JSON.stringify(worker.task.payload)}
|
{JSON.stringify(worker.task.payload)}
|
||||||
@ -308,7 +320,12 @@ function Row(props: RowProps) {
|
|||||||
{qnames.map((qname) => (
|
{qnames.map((qname) => (
|
||||||
<TableRow key={qname}>
|
<TableRow key={qname}>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Link to={queueDetailsPath(qname)}>{qname}</Link>
|
<Link
|
||||||
|
to={queueDetailsPath(qname)}
|
||||||
|
className={classes.link}
|
||||||
|
>
|
||||||
|
{qname}
|
||||||
|
</Link>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{server.queue_priorities[qname]}
|
{server.queue_priorities[qname]}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect, ConnectedProps } from "react-redux";
|
import { connect, ConnectedProps } from "react-redux";
|
||||||
import styled from "styled-components";
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import Tabs from "@material-ui/core/Tabs";
|
import Tabs from "@material-ui/core/Tabs";
|
||||||
import Tab from "@material-ui/core/Tab";
|
import Tab from "@material-ui/core/Tab";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import Paper from "@material-ui/core/Paper";
|
||||||
import ActiveTasksTable from "./ActiveTasksTable";
|
import ActiveTasksTable from "./ActiveTasksTable";
|
||||||
import PendingTasksTable from "./PendingTasksTable";
|
import PendingTasksTable from "./PendingTasksTable";
|
||||||
import ScheduledTasksTable from "./ScheduledTasksTable";
|
import ScheduledTasksTable from "./ScheduledTasksTable";
|
||||||
@ -11,8 +12,6 @@ import RetryTasksTable from "./RetryTasksTable";
|
|||||||
import ArchivedTasksTable from "./ArchivedTasksTable";
|
import ArchivedTasksTable from "./ArchivedTasksTable";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { queueDetailsPath } from "../paths";
|
import { queueDetailsPath } from "../paths";
|
||||||
import { Typography } from "@material-ui/core";
|
|
||||||
import Paper from "@material-ui/core/Paper/Paper";
|
|
||||||
import { QueueInfo } from "../reducers/queuesReducer";
|
import { QueueInfo } from "../reducers/queuesReducer";
|
||||||
import { AppState } from "../store";
|
import { AppState } from "../store";
|
||||||
|
|
||||||
@ -22,24 +21,20 @@ interface TabPanelProps {
|
|||||||
value: string; // tab panel will be shown if selected value equals to the value
|
value: string; // tab panel will be shown if selected value equals to the value
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabPanelRoot = styled.div`
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: scroll;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function TabPanel(props: TabPanelProps) {
|
function TabPanel(props: TabPanelProps) {
|
||||||
const { children, value, selected, ...other } = props;
|
const { children, value, selected, ...other } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabPanelRoot
|
<div
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
hidden={value !== selected}
|
hidden={value !== selected}
|
||||||
id={`scrollable-auto-tabpanel-${selected}`}
|
id={`scrollable-auto-tabpanel-${selected}`}
|
||||||
aria-labelledby={`scrollable-auto-tab-${selected}`}
|
aria-labelledby={`scrollable-auto-tab-${selected}`}
|
||||||
|
style={{ flex: 1, overflowY: "scroll" }}
|
||||||
{...other}
|
{...other}
|
||||||
>
|
>
|
||||||
{value === selected && children}
|
{value === selected && children}
|
||||||
</TabPanelRoot>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,67 +45,13 @@ function a11yProps(value: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const Container = styled.div`
|
const usePanelHeadingStyles = makeStyles((theme) => ({
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TaskCount = styled.div`
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 600;
|
|
||||||
margin: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Heading = styled.div`
|
|
||||||
opacity: 0.7;
|
|
||||||
font-size: 1.7rem;
|
|
||||||
font-weight: 500;
|
|
||||||
background: #f5f7f9;
|
|
||||||
padding-left: 28px;
|
|
||||||
padding-top: 28px;
|
|
||||||
padding-bottom: 28px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const PanelContainer = styled.div`
|
|
||||||
padding: 24px;
|
|
||||||
background: #ffffff;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TabsContainer = styled.div`
|
|
||||||
background: #f5f7f9;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
|
||||||
paper: {
|
paper: {
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
},
|
},
|
||||||
heading: {
|
|
||||||
padingLeft: theme.spacing(2),
|
|
||||||
},
|
|
||||||
tabsRoot: {
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
background: theme.palette.background.default,
|
|
||||||
},
|
|
||||||
tabsIndicator: {
|
|
||||||
right: "auto",
|
|
||||||
left: "0",
|
|
||||||
},
|
|
||||||
tabroot: {
|
|
||||||
width: "204px",
|
|
||||||
textAlign: "left",
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
},
|
|
||||||
tabwrapper: {
|
|
||||||
alignItems: "flex-start",
|
|
||||||
},
|
|
||||||
tabSelected: {
|
|
||||||
background: theme.palette.common.white,
|
|
||||||
boxShadow: theme.shadows[1],
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function PanelHeading(props: {
|
function PanelHeading(props: {
|
||||||
@ -119,9 +60,9 @@ function PanelHeading(props: {
|
|||||||
failed: number;
|
failed: number;
|
||||||
paused: boolean;
|
paused: boolean;
|
||||||
}) {
|
}) {
|
||||||
const classes = useStyles();
|
const classes = usePanelHeadingStyles();
|
||||||
return (
|
return (
|
||||||
<Paper className={classes.paper}>
|
<Paper variant="outlined" className={classes.paper}>
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="overline" display="block">
|
<Typography variant="overline" display="block">
|
||||||
Queue Name
|
Queue Name
|
||||||
@ -183,15 +124,66 @@ interface Props {
|
|||||||
selected: string;
|
selected: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
container: {
|
||||||
|
display: "flex",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
},
|
||||||
|
heading: {
|
||||||
|
opacity: 0.7,
|
||||||
|
fontSize: "1.7rem",
|
||||||
|
fontWeight: 500,
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
paddingLeft: "28px", // TODO: maybe use theme.spacing(3),
|
||||||
|
paddingTop: "28px",
|
||||||
|
paddingBottom: "28px",
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
tabsContainer: {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
tabsRoot: {
|
||||||
|
paddingLeft: theme.spacing(2),
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
tabsIndicator: {
|
||||||
|
right: "auto",
|
||||||
|
left: "0",
|
||||||
|
},
|
||||||
|
tabroot: {
|
||||||
|
width: "204px",
|
||||||
|
textAlign: "left",
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
},
|
||||||
|
tabwrapper: {
|
||||||
|
alignItems: "flex-start",
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
tabSelected: {
|
||||||
|
background: theme.palette.action.selected,
|
||||||
|
boxShadow: theme.shadows[1],
|
||||||
|
},
|
||||||
|
panelContainer: {
|
||||||
|
padding: "24px",
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
taskCount: {
|
||||||
|
fontSize: "2rem",
|
||||||
|
fontWeight: 600,
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
function TasksTable(props: Props & ReduxProps) {
|
function TasksTable(props: Props & ReduxProps) {
|
||||||
const { currentStats } = props;
|
const { currentStats } = props;
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<div className={classes.container}>
|
||||||
<TabsContainer>
|
<div className={classes.tabsContainer}>
|
||||||
<Heading>Tasks</Heading>
|
<div className={classes.heading}>Tasks</div>
|
||||||
<Tabs
|
<Tabs
|
||||||
value={props.selected}
|
value={props.selected}
|
||||||
onChange={(_, value: string) =>
|
onChange={(_, value: string) =>
|
||||||
@ -204,7 +196,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
<Tab
|
<Tab
|
||||||
value="active"
|
value="active"
|
||||||
label="Active"
|
label="Active"
|
||||||
icon={<TaskCount>{currentStats.active}</TaskCount>}
|
icon={
|
||||||
|
<div className={classes.taskCount}>{currentStats.active}</div>
|
||||||
|
}
|
||||||
classes={{
|
classes={{
|
||||||
root: classes.tabroot,
|
root: classes.tabroot,
|
||||||
wrapper: classes.tabwrapper,
|
wrapper: classes.tabwrapper,
|
||||||
@ -215,7 +209,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
<Tab
|
<Tab
|
||||||
value="pending"
|
value="pending"
|
||||||
label="Pending"
|
label="Pending"
|
||||||
icon={<TaskCount>{currentStats.pending}</TaskCount>}
|
icon={
|
||||||
|
<div className={classes.taskCount}>{currentStats.pending}</div>
|
||||||
|
}
|
||||||
classes={{
|
classes={{
|
||||||
root: classes.tabroot,
|
root: classes.tabroot,
|
||||||
wrapper: classes.tabwrapper,
|
wrapper: classes.tabwrapper,
|
||||||
@ -226,7 +222,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
<Tab
|
<Tab
|
||||||
value="scheduled"
|
value="scheduled"
|
||||||
label="Scheduled"
|
label="Scheduled"
|
||||||
icon={<TaskCount>{currentStats.scheduled}</TaskCount>}
|
icon={
|
||||||
|
<div className={classes.taskCount}>{currentStats.scheduled}</div>
|
||||||
|
}
|
||||||
classes={{
|
classes={{
|
||||||
root: classes.tabroot,
|
root: classes.tabroot,
|
||||||
wrapper: classes.tabwrapper,
|
wrapper: classes.tabwrapper,
|
||||||
@ -237,7 +235,7 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
<Tab
|
<Tab
|
||||||
value="retry"
|
value="retry"
|
||||||
label="Retry"
|
label="Retry"
|
||||||
icon={<TaskCount>{currentStats.retry}</TaskCount>}
|
icon={<div className={classes.taskCount}>{currentStats.retry}</div>}
|
||||||
classes={{
|
classes={{
|
||||||
root: classes.tabroot,
|
root: classes.tabroot,
|
||||||
wrapper: classes.tabwrapper,
|
wrapper: classes.tabwrapper,
|
||||||
@ -248,7 +246,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
<Tab
|
<Tab
|
||||||
value="archived"
|
value="archived"
|
||||||
label="Archived"
|
label="Archived"
|
||||||
icon={<TaskCount>{currentStats.archived}</TaskCount>}
|
icon={
|
||||||
|
<div className={classes.taskCount}>{currentStats.archived}</div>
|
||||||
|
}
|
||||||
classes={{
|
classes={{
|
||||||
root: classes.tabroot,
|
root: classes.tabroot,
|
||||||
wrapper: classes.tabwrapper,
|
wrapper: classes.tabwrapper,
|
||||||
@ -257,9 +257,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
{...a11yProps("archived")}
|
{...a11yProps("archived")}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</TabsContainer>
|
</div>
|
||||||
<TabPanel value="active" selected={props.selected}>
|
<TabPanel value="active" selected={props.selected}>
|
||||||
<PanelContainer>
|
<div className={classes.panelContainer}>
|
||||||
<PanelHeading
|
<PanelHeading
|
||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
processed={currentStats.processed}
|
processed={currentStats.processed}
|
||||||
@ -267,10 +267,10 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
paused={currentStats.paused}
|
paused={currentStats.paused}
|
||||||
/>
|
/>
|
||||||
<ActiveTasksTable queue={props.queue} />
|
<ActiveTasksTable queue={props.queue} />
|
||||||
</PanelContainer>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value="pending" selected={props.selected}>
|
<TabPanel value="pending" selected={props.selected}>
|
||||||
<PanelContainer>
|
<div className={classes.panelContainer}>
|
||||||
<PanelHeading
|
<PanelHeading
|
||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
processed={currentStats.processed}
|
processed={currentStats.processed}
|
||||||
@ -281,10 +281,10 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
totalTaskCount={currentStats.pending}
|
totalTaskCount={currentStats.pending}
|
||||||
/>
|
/>
|
||||||
</PanelContainer>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value="scheduled" selected={props.selected}>
|
<TabPanel value="scheduled" selected={props.selected}>
|
||||||
<PanelContainer>
|
<div className={classes.panelContainer}>
|
||||||
<PanelHeading
|
<PanelHeading
|
||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
processed={currentStats.processed}
|
processed={currentStats.processed}
|
||||||
@ -295,10 +295,10 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
totalTaskCount={currentStats.scheduled}
|
totalTaskCount={currentStats.scheduled}
|
||||||
/>
|
/>
|
||||||
</PanelContainer>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value="retry" selected={props.selected}>
|
<TabPanel value="retry" selected={props.selected}>
|
||||||
<PanelContainer>
|
<div className={classes.panelContainer}>
|
||||||
<PanelHeading
|
<PanelHeading
|
||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
processed={currentStats.processed}
|
processed={currentStats.processed}
|
||||||
@ -309,10 +309,10 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
totalTaskCount={currentStats.retry}
|
totalTaskCount={currentStats.retry}
|
||||||
/>
|
/>
|
||||||
</PanelContainer>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value="archived" selected={props.selected}>
|
<TabPanel value="archived" selected={props.selected}>
|
||||||
<PanelContainer>
|
<div className={classes.panelContainer}>
|
||||||
<PanelHeading
|
<PanelHeading
|
||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
processed={currentStats.processed}
|
processed={currentStats.processed}
|
||||||
@ -323,9 +323,9 @@ function TasksTable(props: Props & ReduxProps) {
|
|||||||
queue={props.queue}
|
queue={props.queue}
|
||||||
totalTaskCount={currentStats.archived}
|
totalTaskCount={currentStats.archived}
|
||||||
/>
|
/>
|
||||||
</PanelContainer>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Container>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import {POLL_INTERVAL_CHANGE, SettingsActionTypes, TOGGLE_DARK_THEME,} from '../actions/settingsActions';
|
import {
|
||||||
|
POLL_INTERVAL_CHANGE,
|
||||||
|
SettingsActionTypes,
|
||||||
|
TOGGLE_DARK_THEME,
|
||||||
|
} from "../actions/settingsActions";
|
||||||
|
|
||||||
interface SettingsState {
|
interface SettingsState {
|
||||||
pollInterval: number;
|
pollInterval: number;
|
||||||
@ -7,18 +11,21 @@ interface SettingsState {
|
|||||||
|
|
||||||
const initialState: SettingsState = {
|
const initialState: SettingsState = {
|
||||||
pollInterval: 8,
|
pollInterval: 8,
|
||||||
isDarkTheme: false,
|
isDarkTheme: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
function settingsReducer(
|
function settingsReducer(
|
||||||
state = initialState, action: SettingsActionTypes): SettingsState {
|
state = initialState,
|
||||||
|
action: SettingsActionTypes
|
||||||
|
): SettingsState {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case POLL_INTERVAL_CHANGE:
|
case POLL_INTERVAL_CHANGE:
|
||||||
return { ...state, pollInterval: action.value };
|
return { ...state, pollInterval: action.value };
|
||||||
case TOGGLE_DARK_THEME:
|
case TOGGLE_DARK_THEME:
|
||||||
return {
|
return {
|
||||||
...state, isDarkTheme: !state.isDarkTheme
|
...state,
|
||||||
}
|
isDarkTheme: !state.isDarkTheme,
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@ import CardContent from "@material-ui/core/CardContent";
|
|||||||
import Alert from "@material-ui/lab/Alert";
|
import Alert from "@material-ui/lab/Alert";
|
||||||
import AlertTitle from "@material-ui/lab/AlertTitle";
|
import AlertTitle from "@material-ui/lab/AlertTitle";
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github";
|
import syntaxHighlightStyleDark from "react-syntax-highlighter/dist/esm/styles/hljs/atom-one-dark";
|
||||||
|
import syntaxHighlightStyleLight from "react-syntax-highlighter/dist/esm/styles/hljs/atom-one-light";
|
||||||
import { getRedisInfoAsync } from "../actions/redisInfoActions";
|
import { getRedisInfoAsync } from "../actions/redisInfoActions";
|
||||||
import { usePolling } from "../hooks";
|
import { usePolling } from "../hooks";
|
||||||
import { AppState } from "../store";
|
import { AppState } from "../store";
|
||||||
@ -30,6 +31,7 @@ function mapStateToProps(state: AppState) {
|
|||||||
redisAddress: state.redis.address,
|
redisAddress: state.redis.address,
|
||||||
redisInfoRaw: state.redis.rawData,
|
redisInfoRaw: state.redis.rawData,
|
||||||
pollInterval: state.settings.pollInterval,
|
pollInterval: state.settings.pollInterval,
|
||||||
|
isDarkTheme: state.settings.isDarkTheme,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +40,13 @@ type Props = ConnectedProps<typeof connector>;
|
|||||||
|
|
||||||
function RedisInfoView(props: Props) {
|
function RedisInfoView(props: Props) {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { pollInterval, getRedisInfoAsync, redisInfo, redisInfoRaw } = props;
|
const {
|
||||||
|
pollInterval,
|
||||||
|
getRedisInfoAsync,
|
||||||
|
redisInfo,
|
||||||
|
redisInfoRaw,
|
||||||
|
isDarkTheme,
|
||||||
|
} = props;
|
||||||
|
|
||||||
usePolling(getRedisInfoAsync, pollInterval);
|
usePolling(getRedisInfoAsync, pollInterval);
|
||||||
|
|
||||||
@ -56,7 +64,9 @@ function RedisInfoView(props: Props) {
|
|||||||
{props.error === "" ? (
|
{props.error === "" ? (
|
||||||
<>
|
<>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h5">Redis Info</Typography>
|
<Typography variant="h5" color="textPrimary">
|
||||||
|
Redis Info
|
||||||
|
</Typography>
|
||||||
<Typography variant="subtitle1" color="textSecondary">
|
<Typography variant="subtitle1" color="textSecondary">
|
||||||
Connected to: {props.redisAddress}
|
Connected to: {props.redisAddress}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -153,7 +163,11 @@ function RedisInfoView(props: Props) {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
language="yaml"
|
language="yaml"
|
||||||
style={syntaxHighlightStyle}
|
style={
|
||||||
|
isDarkTheme
|
||||||
|
? syntaxHighlightStyleDark
|
||||||
|
: syntaxHighlightStyleLight
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{redisInfoRaw}
|
{redisInfoRaw}
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
|
@ -60,7 +60,9 @@ function SettingsView(props: PropsFromRedux) {
|
|||||||
<Container maxWidth="lg" className={classes.container}>
|
<Container maxWidth="lg" className={classes.container}>
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h5">Settings</Typography>
|
<Typography variant="h5" color="textPrimary">
|
||||||
|
Settings
|
||||||
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={5}>
|
<Grid item xs={5}>
|
||||||
<Paper className={classes.paper} variant="outlined">
|
<Paper className={classes.paper} variant="outlined">
|
||||||
|
Loading…
Reference in New Issue
Block a user