Skip to content

Commit

Permalink
refactor(web): reorganize log page
Browse files Browse the repository at this point in the history
- Split up table and route
- Renamed "logs" to "log"
- Added "Not Found" indication
  • Loading branch information
LordTermor committed Jun 26, 2024
1 parent 69fbb69 commit 6dd3bac
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 135 deletions.
122 changes: 122 additions & 0 deletions web/src/components/LogTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2024 Artem Grinev <agrinev@manjaro.org>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/

import React from "react";
import { Table } from "react-daisyui";
import {
useReactTable,
flexRender,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
SortingState,
createColumnHelper
} from "@tanstack/react-table";
import SectionLabel from "../components/SectionLabel";

interface LogTableProps {
entries: LogEntry[];
sorting: SortingState;
setSorting: React.Dispatch<React.SetStateAction<SortingState>>;
}

const LogTable = ({ entries, sorting, setSorting }: LogTableProps) => {
const columnHelper = createColumnHelper<LogEntry>();

const columns = [
columnHelper.accessor("type", {
header: "Type"
}),
columnHelper.accessor("package.name", {
header: "Name"
}),

columnHelper.accessor("package.poolEntries", {
header: "Version",
cell: (context) => {
const value = context.getValue();
const preferredLocation =
context?.row?.original?.package?.preferredLocation;

if (value && preferredLocation && value[preferredLocation]) {
return value[preferredLocation].version;
} else {
return "Unknown Version";
}
}
}),

columnHelper.accessor("package.section", {
header: "Section",
cell: (context) => <SectionLabel section={context.getValue()} />
}),

columnHelper.accessor((entry) => entry.time, {
header: "Time",
enableSorting: true,
sortingFn: "datetime"
})
];

const table = useReactTable<LogEntry>({
columns,
data: entries,
state: {
sorting
},
manualPagination: true,
sortDescFirst: true,
enableSorting: true,
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
initialState: {}
});

return (
<Table size="xs" zebra={true} className="w-full">
<Table.Head>
{table
.getHeaderGroups()
.flatMap((headerGroup) =>
headerGroup.headers.map((header) => (
<span key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</span>
))
)}
</Table.Head>

<Table.Body>
{table.getRowModel().rows.map((row) => {
return (
<Table.Row key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<span key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</span>
);
})}
</Table.Row>
);
})}
</Table.Body>
</Table>
);
};

export default LogTable;
2 changes: 1 addition & 1 deletion web/src/components/RootDrawerLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function RootDrawerLayout() {
() => [
{ route: "/", name: "Packages", icon: faFolderTree },
{ route: "/compare", name: "Compare", icon: faCodeCompare },
{ route: "/logs", name: "Logs", icon: faListCheck },
{ route: "/log", name: "Log", icon: faListCheck },
{ route: "/admin", name: "Admin", icon: faToolbox }
],
[]
Expand Down
13 changes: 9 additions & 4 deletions web/src/hooks/BxtHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ export const useSections = (): [Section[], IUpdateSections] => {
return [sections, updateSections];
};

export const usePackageLogs = (): [LogEntry[], () => void] => {
const [entries, setEntries] = useState<LogEntry[]>([]);
export const usePackageLogs = (): [LogEntry[] | null, () => void, boolean] => {
const [entries, setEntries] = useState<LogEntry[] | null>(null);
const [isLoading, setIsLoading] = useState(false);

const updateEntries = useCallback(async () => {
setIsLoading(true);
try {
const result = await axios.get(`/api/logs/packages`);

Expand All @@ -40,10 +42,13 @@ export const usePackageLogs = (): [LogEntry[], () => void] => {
return value;
});
setEntries(entries);
} catch (error) {}
} catch (error) {
setEntries(null);
}
setIsLoading(false);
}, [setEntries]);

return [entries, updateEntries];
return [entries, updateEntries, isLoading];
};

export interface IGetCompareResults {
Expand Down
2 changes: 1 addition & 1 deletion web/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const AppRoot = (props: any) => {
element: <Main />
},
{
path: "logs",
path: "log",
element: <Log />
},
{
Expand Down
173 changes: 44 additions & 129 deletions web/src/routes/log.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,145 +4,60 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/
import React, { useEffect, useState } from "react";
import { Table, Loading } from "react-daisyui";
import React from "react";
import { Loading, Card } from "react-daisyui";
import { usePackageLogs } from "../hooks/BxtHooks";
import {
useReactTable,
createColumnHelper,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
flexRender,
SortingState
} from "@tanstack/react-table";
import SectionLabel from "../components/SectionLabel";

const dateCompare = (a: LogEntry, b: LogEntry) => {
if (a.time < b.time) {
return -1;
}
if (a.time > b.time) {
return 1;
}
return 0;
};
import { SortingState } from "@tanstack/react-table";
import LogTable from "../components/LogTable";
import { faBan } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

export default function Log(props: any) {
const [entries, updateEntries] = usePackageLogs();
const [isLoading, setIsLoading] = useState(false);
const [entries, updateEntries, isLoading] = usePackageLogs();
const [sorting, setSorting] = React.useState<SortingState>([
{ id: "Time", desc: true }
]);

useEffect(() => {
setIsLoading(false);
}, [entries]);

useEffect(() => {
updateEntries();
setIsLoading(true);
}, []);

const columnHelper = createColumnHelper<LogEntry>();

const columns = [
columnHelper.accessor("type", {
header: "Type"
}),
columnHelper.accessor("package.name", {
header: "Name"
}),

columnHelper.accessor("package.poolEntries", {
header: "Version",
cell: (context) => {
const value = context.getValue();
const preferredLocation =
context?.row?.original?.package?.preferredLocation;

if (value && preferredLocation && value[preferredLocation]) {
return value[preferredLocation].version;
} else {
return "Unknown Version";
}
}
}),

columnHelper.accessor("package.section", {
header: "Section",
cell: (context) => <SectionLabel section={context.getValue()} />
}),

columnHelper.accessor((entry) => entry.time, {
header: "Time",
enableSorting: true,
sortingFn: "datetime"
})
];

const table = useReactTable<LogEntry>({
columns,
data: entries,
state: {
sorting
},
manualPagination: true,
sortDescFirst: true,
enableSorting: true,
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
initialState: {}
});

return (
<div className="flex flex-col w-full h-full overflow-x-auto">
{isLoading ? (
const renderContent = () => {
if (isLoading) {
return (
<div className="grow flex w-full justify-center content-center">
<Loading variant="bars" className="w-20" />
</div>
) : (
<Table size="xs" zebra={true} className="w-full" {...props}>
<Table.Head>
{table
.getHeaderGroups()
.flatMap((headerGroup) =>
headerGroup.headers.map((header) => (
<span key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef
.header,
header.getContext()
)}
</span>
))
)}
</Table.Head>
);
}

if (!entries) {
return (
<div className="overflow-y-auto flex h-full w-full justify-center items-center">
<Card
className="m-auto bg-base-100 shadow-sm"
compact={true}
>
<Card.Body>
<Card.Title>
<FontAwesomeIcon icon={faBan} />
Not found
</Card.Title>
No events was found. It may happen because there
were no actions yet or the database is corrupted.
</Card.Body>
</Card>
</div>
);
}

return (
<LogTable
entries={entries!}
sorting={sorting}
setSorting={setSorting}
/>
);
};

<Table.Body>
{table.getRowModel().rows.map((row) => {
return (
<Table.Row key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<span key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</span>
);
})}
</Table.Row>
);
})}
</Table.Body>
</Table>
)}
return (
<div className="flex flex-col w-full h-full overflow-x-auto bg-base-200">
{renderContent()}
</div>
);
}

0 comments on commit 6dd3bac

Please sign in to comment.