feat: UI cleanup and short GUIDs
This commit is contained in:
27
package-lock.json
generated
27
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "game-logger",
|
"name": "game-logger",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "game-logger",
|
"name": "game-logger",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ts-rest/core": "^3.51.0",
|
"@ts-rest/core": "^3.51.0",
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.1.2",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
|
"jotai": "^2.11.0",
|
||||||
"material-react-table": "^3.1.0",
|
"material-react-table": "^3.1.0",
|
||||||
"openapi3-ts": "^4.4.0",
|
"openapi3-ts": "^4.4.0",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
@@ -3577,6 +3578,28 @@
|
|||||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/jotai": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-zKfoBBD1uDw3rljwHkt0fWuja1B76R7CjznuBO+mSX6jpsO1EBeWNRKpeaQho9yPI/pvCv4recGfgOXGxwPZvQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": ">=17.0.0",
|
||||||
|
"react": ">=17.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.1.2",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
|
"jotai": "^2.11.0",
|
||||||
"material-react-table": "^3.1.0",
|
"material-react-table": "^3.1.0",
|
||||||
"openapi3-ts": "^4.4.0",
|
"openapi3-ts": "^4.4.0",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import {
|
|||||||
AppBar,
|
AppBar,
|
||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
Container,
|
Container,
|
||||||
|
FormControlLabel,
|
||||||
Link,
|
Link,
|
||||||
Stack,
|
Stack,
|
||||||
|
Switch,
|
||||||
Toolbar,
|
Toolbar,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
@@ -15,11 +17,23 @@ import {
|
|||||||
} from "react-router";
|
} from "react-router";
|
||||||
import "./theme";
|
import "./theme";
|
||||||
import { serverRoot } from "./client";
|
import { serverRoot } from "./client";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { shortGuidsAtom } from "./configuration";
|
||||||
|
import { ChangeEvent, useCallback } from "react";
|
||||||
|
|
||||||
export function Root() {
|
export function Root() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
||||||
|
const [shortGuids, setShortGuids] = useAtom(shortGuidsAtom);
|
||||||
|
|
||||||
|
const handleShortGuidsOnChange = useCallback(
|
||||||
|
(e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setShortGuids(e.target.checked);
|
||||||
|
},
|
||||||
|
[setShortGuids]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container maxWidth="lg">
|
<Container maxWidth="lg">
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
@@ -28,6 +42,17 @@ export function Root() {
|
|||||||
<Typography variant="h6" component="h1" sx={{ flexGrow: 1 }}>
|
<Typography variant="h6" component="h1" sx={{ flexGrow: 1 }}>
|
||||||
Game Logger
|
Game Logger
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={shortGuids}
|
||||||
|
onChange={handleShortGuidsOnChange}
|
||||||
|
aria-label="short guids switch"
|
||||||
|
color="secondary"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={"Use short GUIDs"}
|
||||||
|
/>
|
||||||
<Link
|
<Link
|
||||||
variant="appbar"
|
variant="appbar"
|
||||||
href={serverRoot + "/swagger-ui"}
|
href={serverRoot + "/swagger-ui"}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import { GetSessionsResponse } from "../common/contract";
|
|||||||
import { format, formatDuration, interval, intervalToDuration } from "date-fns";
|
import { format, formatDuration, interval, intervalToDuration } from "date-fns";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
|
import { Typography } from "@mui/material";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { shortGuidsAtom } from "./configuration";
|
||||||
|
import { formatGuid } from "./guid";
|
||||||
|
|
||||||
export function Sessions() {
|
export function Sessions() {
|
||||||
const [paginationState, setPaginationState] = useState<MRT_PaginationState>({
|
const [paginationState, setPaginationState] = useState<MRT_PaginationState>({
|
||||||
@@ -73,27 +77,54 @@ function SessionsTable({
|
|||||||
isRefetching: boolean;
|
isRefetching: boolean;
|
||||||
columnFilters: MRT_ColumnFiltersState;
|
columnFilters: MRT_ColumnFiltersState;
|
||||||
}) {
|
}) {
|
||||||
|
const [shortGuids] = useAtom(shortGuidsAtom);
|
||||||
|
|
||||||
const columns = useMemo<MRT_ColumnDef<GetSessionsResponse["sessions"][0]>[]>(
|
const columns = useMemo<MRT_ColumnDef<GetSessionsResponse["sessions"][0]>[]>(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
accessorKey: "save_id",
|
accessorKey: "save_id",
|
||||||
header: "Save ID",
|
header: "Save ID",
|
||||||
|
grow: false,
|
||||||
|
Cell: ({
|
||||||
|
row: {
|
||||||
|
original: { save_id },
|
||||||
|
},
|
||||||
|
}) => <Typography variant="body2">{formatGuid(save_id, shortGuids)}</Typography>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "id",
|
accessorKey: "id",
|
||||||
header: "ID",
|
header: "ID",
|
||||||
|
grow: true,
|
||||||
|
Cell: ({
|
||||||
|
row: {
|
||||||
|
original: { id },
|
||||||
|
},
|
||||||
|
}) => <Typography variant="body2">{formatGuid(id, shortGuids)}</Typography>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "game_name",
|
accessorKey: "game_name",
|
||||||
header: "Game Name",
|
header: "Game Name",
|
||||||
|
grow: false,
|
||||||
|
Cell: ({
|
||||||
|
row: {
|
||||||
|
original: { game_name },
|
||||||
|
},
|
||||||
|
}) => <Typography variant="body1">{game_name}</Typography>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "version",
|
accessorKey: "version",
|
||||||
header: "Version",
|
header: "Version",
|
||||||
|
grow: false,
|
||||||
|
Cell: ({
|
||||||
|
row: {
|
||||||
|
original: { version },
|
||||||
|
},
|
||||||
|
}) => <Typography variant="body2">{version}</Typography>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "time",
|
accessorKey: "time",
|
||||||
header: "Time",
|
header: "Time",
|
||||||
|
grow: true,
|
||||||
Cell: ({ row }) => {
|
Cell: ({ row }) => {
|
||||||
const rangeInterval = interval(
|
const rangeInterval = interval(
|
||||||
row.original.start_time,
|
row.original.start_time,
|
||||||
@@ -104,19 +135,23 @@ function SessionsTable({
|
|||||||
const formattedDuration = formatDuration(duration);
|
const formattedDuration = formatDuration(duration);
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{formattedStartTime}
|
<Typography variant="body2">{formattedStartTime}</Typography>
|
||||||
<br />({formattedDuration || "very quick"})
|
<Typography variant="body2" color="textSecondary">
|
||||||
|
{formattedDuration || "very quick"}, {row.original.num_events}{" "}
|
||||||
|
events
|
||||||
|
</Typography>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[]
|
[shortGuids]
|
||||||
);
|
);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const table = useMaterialReactTable({
|
const table = useMaterialReactTable({
|
||||||
|
layoutMode: "grid",
|
||||||
data: sessions,
|
data: sessions,
|
||||||
columns,
|
columns,
|
||||||
muiTableBodyRowProps: ({ row }) => ({
|
muiTableBodyRowProps: ({ row }) => ({
|
||||||
|
|||||||
3
src/client/configuration.ts
Normal file
3
src/client/configuration.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import {atom} from "jotai";
|
||||||
|
|
||||||
|
export const shortGuidsAtom = atom(true);
|
||||||
7
src/client/guid.ts
Normal file
7
src/client/guid.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function formatGuid(guid: string, shortGuid: boolean) {
|
||||||
|
if (shortGuid) {
|
||||||
|
return guid.substring(0, 4) + "-" + guid.substring(guid.length - 4);
|
||||||
|
} else {
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,17 +7,15 @@ declare module "@mui/material/Typography" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const x: LinkPropsVariantOverrides;
|
|
||||||
|
|
||||||
// A custom theme for this app
|
// A custom theme for this app
|
||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
cssVariables: true,
|
cssVariables: true,
|
||||||
palette: {
|
palette: {
|
||||||
primary: {
|
primary: {
|
||||||
main: "#556cd6",
|
main: "#735DA5",
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: "#19857b",
|
main: "#D3C5E5",
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
main: red.A400,
|
main: red.A400,
|
||||||
|
|||||||
Reference in New Issue
Block a user