Skip to content

Commit

Permalink
feat: update settings table to use mantine-react-table
Browse files Browse the repository at this point in the history
This provides more features and better performance than the previous
implementation. This also includes a new pagination hook that can be
used in other tables.

Fixes #2080
  • Loading branch information
mainawycliffe authored and moshloop committed Jul 28, 2024
1 parent 0f32b90 commit b07f0c4
Show file tree
Hide file tree
Showing 23 changed files with 1,077 additions and 531 deletions.
455 changes: 436 additions & 19 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"ansi-to-html": "^0.7.2",
"axios": "^1.6.2",
"casbin.js": "^0.5.0",
"clsx": "^1.1.1",
"clsx": "^2.1.1",
"d3-hierarchy": "^3.1.2",
"d3-shape": "^3.1.0",
"dayjs": "^1.10.7",
Expand All @@ -59,6 +59,7 @@
"jotai-location": "^0.5.2",
"jsonpath-plus": "^7.0.0",
"lodash": "^4.17.21",
"mantine-react-table": "^1.3.4",
"monaco-editor": "0.48.0",
"monaco-themes": "0.4.4",
"monaco-yaml": "5.1.1",
Expand Down
8 changes: 2 additions & 6 deletions src/components/Agents/AgentPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { tables } from "@flanksource-ui/context/UserAccessContext/permissions";
import useReactTablePaginationState from "@flanksource-ui/ui/DataTable/Hooks/useReactTablePaginationState";
import { SearchLayout } from "@flanksource-ui/ui/Layout/SearchLayout";
import { useState } from "react";
import { useAgentsListQuery } from "../../api/query-hooks/useAgentsQuery";
import { User } from "../../api/types/users";
import { BreadcrumbNav, BreadcrumbRoot } from "../../ui/BreadcrumbNav";
Expand Down Expand Up @@ -36,10 +36,7 @@ export type AgentSummary = Agent & {
};

export default function AgentsPage() {
const [{ pageIndex, pageSize }, setPageState] = useState({
pageIndex: 0,
pageSize: 150
});
const { pageIndex, pageSize } = useReactTablePaginationState();

const { data, isLoading, refetch, isRefetching } = useAgentsListQuery(
{
Expand Down Expand Up @@ -88,7 +85,6 @@ export default function AgentsPage() {
pageCount={pageCount}
pageIndex={pageIndex}
pageSize={pageSize}
setPageState={setPageState}
refresh={refetch}
/>
</div>
Expand Down
20 changes: 4 additions & 16 deletions src/components/Agents/List/AgentsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { DataTable } from "@flanksource-ui/ui/DataTable";
import useReactTableSortState from "@flanksource-ui/ui/DataTable/Hooks/useReactTableSortState";
import MRTDataTable from "@flanksource-ui/ui/MRTDataTable/MRTDataTable";
import { useMemo } from "react";
import { useSearchParams } from "react-router-dom";
import AgentForm from "../Add/AddAgentForm";
Expand All @@ -12,42 +11,31 @@ type AgentsTableProps = {
pageCount: number;
pageIndex: number;
pageSize: number;
setPageState?: (state: { pageIndex: number; pageSize: number }) => void;
hiddenColumns?: string[];
refresh?: () => void;
};

export default function AgentsTable({
agents,
isLoading,
hiddenColumns = [],
refresh = () => {}
}: AgentsTableProps) {
const [searchParams, setSearchParams] = useSearchParams();

const agentId = searchParams.get("id") ?? undefined;

const [sortState, onSortByChanged] = useReactTableSortState();

const columns = useMemo(() => agentsTableColumns, []);

return (
<>
<DataTable
<MRTDataTable
data={agents}
columns={columns}
isLoading={isLoading}
handleRowClick={(agent) => {
searchParams.set("id", agent.original.id!);
onRowClick={(agent) => {
searchParams.set("id", agent.id!);
setSearchParams(searchParams);
}}
stickyHead
hiddenColumns={hiddenColumns}
tableSortByState={sortState}
onTableSortByChanged={onSortByChanged}
enableServerSideSorting
/>

{agentId && (
<AgentForm
isOpen={!!agentId}
Expand Down
16 changes: 8 additions & 8 deletions src/components/Agents/List/AgentsTableColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { User } from "@flanksource-ui/api/types/users";
import { Avatar } from "@flanksource-ui/ui/Avatar";
import { DateCell } from "@flanksource-ui/ui/DataTable/Cells/DateCells";
import { ColumnDef } from "@tanstack/react-table";
import { MRTDateCell } from "@flanksource-ui/ui/MRTDataTable/Cells/MRTDateCells";
import clsx from "clsx";
import dayjs from "dayjs";
import { MRT_ColumnDef } from "mantine-react-table";
import { FaDotCircle } from "react-icons/fa";
import { AgentSummary } from "../AgentPage";

export const agentsTableColumns: ColumnDef<AgentSummary>[] = [
export const agentsTableColumns: MRT_ColumnDef<AgentSummary>[] = [
{
header: "Name",
accessorKey: "name",
Expand All @@ -34,7 +34,7 @@ export const agentsTableColumns: ColumnDef<AgentSummary>[] = [
header: "Status",
accessorKey: "status",
enableSorting: true,
cell: ({ row }) => {
Cell: ({ row }) => {
const lastSeen = row.original.last_seen;
if (!lastSeen) {
return null;
Expand All @@ -60,25 +60,25 @@ export const agentsTableColumns: ColumnDef<AgentSummary>[] = [
header: "Last Pushed",
enableSorting: true,
accessorKey: "last_received",
cell: DateCell
Cell: MRTDateCell
},
{
header: "Created At",
enableSorting: true,
accessorKey: "created_at",
cell: DateCell
Cell: MRTDateCell
},
{
header: "Updated At",
accessorKey: "updated_at",
enableSorting: true,
cell: DateCell
Cell: MRTDateCell
},
{
header: "Created By",
minSize: 80,
accessorKey: "created_by",
cell: ({ row }) => {
Cell: ({ row }) => {
const createdBy = row?.getValue<User>("created_by");
return <Avatar user={createdBy} />;
}
Expand Down
40 changes: 18 additions & 22 deletions src/components/Connections/ConnectionsList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Avatar } from "@flanksource-ui/ui/Avatar";
import { DataTable } from "@flanksource-ui/ui/DataTable";
import { DateCell } from "@flanksource-ui/ui/DataTable/Cells/DateCells";
import { CellContext, ColumnDef } from "@tanstack/table-core";
import MRTAvatarCell from "@flanksource-ui/ui/MRTDataTable/Cells/MRTAvataCell";
import { MRTDateCell } from "@flanksource-ui/ui/MRTDataTable/Cells/MRTDateCells";
import { MRTCellProps } from "@flanksource-ui/ui/MRTDataTable/MRTCellProps";
import MRTDataTable from "@flanksource-ui/ui/MRTDataTable/MRTDataTable";
import clsx from "clsx";
import { MRT_ColumnDef } from "mantine-react-table";
import { Icon } from "../../ui/Icons/Icon";
import { Connection } from "./ConnectionFormModal";

Expand All @@ -12,24 +13,23 @@ type ConnectionListProps = {
onRowClick?: (data: Connection) => void;
} & Omit<React.HTMLProps<HTMLDivElement>, "data">;

const NameCell = ({ row, getValue }: CellContext<Connection, any>) => {
const NameCell = ({
row,
renderedCellValue: getValue
}: MRTCellProps<Connection>) => {
return (
<div className="flex flex-row items-center space-x-2">
<Icon name={row.original.type} className="h-auto w-6" />
<div>{getValue()}</div>
<div>{getValue}</div>
</div>
);
};

const AvatarCell = ({ getValue }: CellContext<Connection, any>) => {
return <Avatar user={getValue()} circular />;
};

const columns: ColumnDef<Connection>[] = [
const columns: MRT_ColumnDef<Connection>[] = [
{
header: "Name",
accessorKey: "name",
cell: NameCell,
Cell: NameCell,
minSize: 150,
enableResizing: true
},
Expand All @@ -48,20 +48,20 @@ const columns: ColumnDef<Connection>[] = [
{
header: "Created By",
accessorKey: "created_by",
cell: AvatarCell,
Cell: MRTAvatarCell,
maxSize: 50
},
{
header: "Created",
accessorKey: "created_at",
cell: DateCell,
Cell: MRTDateCell,
sortingFn: "datetime",
maxSize: 50
},
{
header: "Updated",
accessorKey: "updated_at",
cell: DateCell,
Cell: MRTDateCell,
sortingFn: "datetime",
maxSize: 50
}
Expand All @@ -71,20 +71,16 @@ export function ConnectionList({
data,
isLoading,
className,
onRowClick,
onRowClick = () => {},
...rest
}: ConnectionListProps) {
return (
<div className={clsx(className)} {...rest}>
<DataTable
stickyHead
<MRTDataTable
columns={columns}
data={data}
tableStyle={{ borderSpacing: "0" }}
isLoading={isLoading}
preferencesKey="connections-list"
savePreferences={false}
handleRowClick={(row) => onRowClick?.(row.original)}
onRowClick={(row) => onRowClick(row)}
/>
</div>
);
Expand Down
38 changes: 7 additions & 31 deletions src/components/Integrations/IntegrationsList.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,27 @@
import { SchemaResourceWithJobStatus } from "@flanksource-ui/api/schemaResources";
import { DataTable, PaginationOptions } from "@flanksource-ui/ui/DataTable";
import { PaginationState, Updater } from "@tanstack/react-table";
import { useMemo } from "react";
import MRTDataTable from "@flanksource-ui/ui/MRTDataTable/MRTDataTable";
import { integrationsTableColumns } from "./Table/IntegrationsTableColumns";

type IntegrationsListProps = {
data: SchemaResourceWithJobStatus[];
onRowClick: (row: SchemaResourceWithJobStatus) => void;
pageCount: number;
pageIndex: number;
pageSize: number;
isLoading: boolean;
setPageState?: (state: Updater<PaginationState>) => void;
isLoading?: boolean;
pageCount?: number;
};

export default function IntegrationsList({
data,
onRowClick,
pageCount,
pageIndex,
pageSize,
isLoading = false,
setPageState = () => {}
pageCount
}: IntegrationsListProps) {
const pagination = useMemo(() => {
return {
setPagination: (state) => {
setPageState(state);
},
pageIndex,
pageSize,
pageCount,
remote: true,
enable: true,
loading: isLoading
} satisfies PaginationOptions;
}, [setPageState, pageIndex, pageSize, pageCount, isLoading]);

return (
<DataTable
<MRTDataTable
data={data}
handleRowClick={(row) => onRowClick(row.original)}
onRowClick={onRowClick}
columns={integrationsTableColumns}
pagination={pagination}
isLoading={isLoading}
groupBy={["integration_type"]}
expandAllRows
manualPageCount={pageCount}
/>
);
}
14 changes: 4 additions & 10 deletions src/components/Integrations/IntegrationsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getIntegrationsWithJobStatus } from "@flanksource-ui/api/schemaResources";
import { tables } from "@flanksource-ui/context/UserAccessContext/permissions";
import useReactTablePaginationState from "@flanksource-ui/ui/DataTable/Hooks/useReactTablePaginationState";
import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { BreadcrumbNav, BreadcrumbRoot } from "../../ui/BreadcrumbNav";
import { Head } from "../../ui/Head";
Expand All @@ -13,10 +13,7 @@ import IntegrationsList from "./IntegrationsList";
export default function IntegrationsPage() {
const navigate = useNavigate();

const [{ pageIndex, pageSize }, setPageState] = useState({
pageIndex: 0,
pageSize: 150
});
const { pageIndex, pageSize } = useReactTablePaginationState();

const { data, refetch, isLoading, isRefetching } = useQuery({
queryKey: ["integrations", { pageIndex, pageSize }],
Expand Down Expand Up @@ -60,19 +57,16 @@ export default function IntegrationsPage() {
loading={isLoading || isRefetching}
>
<div className="flex h-full w-full flex-1 flex-col p-6 pb-0">
<div className="mx-auto flex flex-col">
<div className="mx-auto flex w-full flex-1 flex-col">
<IntegrationsList
data={integrations ?? []}
onRowClick={(row) => {
navigate(
`/settings/integrations/${row.integration_type}/${row.id}`
);
}}
isLoading={isLoading || isRefetching}
isLoading={isLoading}
pageCount={pageCount}
pageIndex={pageIndex}
pageSize={pageSize}
setPageState={setPageState}
/>
</div>
</div>
Expand Down
Loading

0 comments on commit b07f0c4

Please sign in to comment.