diff --git a/src/components/Configs/Changes/ConfigChangeHistory/index.tsx b/src/components/Configs/Changes/ConfigChangeHistory/index.tsx index 57d1d87611..653d73d13a 100644 --- a/src/components/Configs/Changes/ConfigChangeHistory/index.tsx +++ b/src/components/Configs/Changes/ConfigChangeHistory/index.tsx @@ -3,8 +3,8 @@ import { ConfigChange } from "@flanksource-ui/api/types/configs"; import GetUserAvatar from "@flanksource-ui/components/Users/GetUserAvatar"; import { PaginationOptions } from "@flanksource-ui/ui/DataTable"; import FilterByCellValue from "@flanksource-ui/ui/DataTable/FilterByCellValue"; +import useReactTableSortState from "@flanksource-ui/ui/DataTable/Hooks/useReactTableSortState"; import { DateCell } from "@flanksource-ui/ui/table"; -import { SortingState, Updater } from "@tanstack/react-table"; import { ColumnDef } from "@tanstack/table-core"; import { useState } from "react"; import { ChangeIcon } from "../../../Icon/ChangeIcon"; @@ -148,8 +148,6 @@ type ConfigChangeHistoryProps = { className?: string; tableStyle?: React.CSSProperties; pagination?: PaginationOptions; - sortBy?: SortingState; - onTableSortByChanged?: (sort: Updater) => void; }; export function ConfigChangeHistory({ @@ -158,9 +156,7 @@ export function ConfigChangeHistory({ linkConfig, className = "table-auto table-fixed", pagination, - tableStyle, - sortBy, - onTableSortByChanged = () => {} + tableStyle }: ConfigChangeHistoryProps) { const [selectedConfigChange, setSelectedConfigChange] = useState(); @@ -175,6 +171,8 @@ export function ConfigChangeHistory({ } ); + const [sortBy, onTableSortByChanged] = useReactTableSortState(); + return ( <> { - return [ - ...(params.get("sortBy") - ? [ - { - id: params.get("sortBy")!, - desc: params.get("sortOrder") === "desc" - } - ] - : []) - ]; - }, [params]); - const { data, isLoading, refetch, isRefetching, error } = useConfigInsightsQuery( { @@ -87,6 +74,8 @@ export default function ConfigInsightsList({ const totalEntries = (data as any)?.totalEntries; const pageCount = totalEntries ? Math.ceil(totalEntries / pageSize) : -1; + const [sortBy, updateSortBy] = useReactTableSortState(); + const pagination = useMemo(() => { const pagination: PaginationOptions = { setPagination: (updater) => { @@ -131,24 +120,14 @@ export default function ConfigInsightsList({ isLoading={isLoading} stickyHead pagination={pagination} - tableSortByState={sortState} hiddenColumns={columnsToHide} handleRowClick={(row) => { setClickedInsightItem(row.original); setIsInsightDetailsModalOpen(true); }} enableServerSideSorting - onTableSortByChanged={(state) => { - const getSortBy = Array.isArray(state) ? state : state(sortState); - if (getSortBy.length > 0) { - params.set("sortBy", getSortBy[0].id); - params.set("sortOrder", getSortBy[0].desc ? "desc" : "asc"); - } else { - params.delete("sortBy"); - params.delete("sortOrder"); - } - setParams(params); - }} + tableSortByState={sortBy} + onTableSortByChanged={updateSortBy} /> )} diff --git a/src/components/JobsHistory/JobsHistorySettingsPage.tsx b/src/components/JobsHistory/JobsHistorySettingsPage.tsx index e2b7da60e2..c40043e457 100644 --- a/src/components/JobsHistory/JobsHistorySettingsPage.tsx +++ b/src/components/JobsHistory/JobsHistorySettingsPage.tsx @@ -15,7 +15,7 @@ export default function JobsHistorySettingsPage() { jobHistoryDefaultDateFilter ); - const [searchParams, setSearchParams] = useSearchParams(); + const [searchParams] = useSearchParams(); const pageIndex = parseInt(searchParams.get("pageIndex") ?? "0"); const pageSize = parseInt(searchParams.get("pageSize") ?? "150"); @@ -81,19 +81,6 @@ export default function JobsHistorySettingsPage() { pageCount={pageCount} pageIndex={pageIndex} pageSize={pageSize} - sortBy={sortBy} - sortOrder={sortOrder} - onSortByChanged={(sortBy) => { - const sort = typeof sortBy === "function" ? sortBy([]) : sortBy; - if (sort.length === 0) { - searchParams.delete("sortBy"); - searchParams.delete("sortOrder"); - } else { - searchParams.set("sortBy", sort[0]?.id); - searchParams.set("sortOrder", sort[0].desc ? "desc" : "asc"); - } - setSearchParams(searchParams); - }} /> diff --git a/src/components/JobsHistory/JobsHistoryTable.tsx b/src/components/JobsHistory/JobsHistoryTable.tsx index 4260308217..4db78c0da5 100644 --- a/src/components/JobsHistory/JobsHistoryTable.tsx +++ b/src/components/JobsHistory/JobsHistoryTable.tsx @@ -1,5 +1,6 @@ import { DataTable, PaginationOptions } from "@flanksource-ui/ui/DataTable"; -import { Row, SortingState, Updater } from "@tanstack/react-table"; +import useReactTableSortState from "@flanksource-ui/ui/DataTable/Hooks/useReactTableSortState"; +import { Row } from "@tanstack/react-table"; import { useCallback, useMemo, useState } from "react"; import { useSearchParams } from "react-router-dom"; import { JobsHistoryDetails } from "./JobsHistoryDetails"; @@ -46,10 +47,7 @@ type JobsHistoryTableProps = { pageCount: number; pageIndex: number; pageSize: number; - sortBy: string; - sortOrder: string; hiddenColumns?: string[]; - onSortByChanged?: (sortByState: Updater) => void; }; export default function JobsHistoryTable({ @@ -58,22 +56,13 @@ export default function JobsHistoryTable({ pageCount, pageIndex, pageSize, - hiddenColumns = [], - sortBy, - sortOrder, - onSortByChanged = () => {} + hiddenColumns = [] }: JobsHistoryTableProps) { const [params, setParams] = useSearchParams(); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedJob, setSelectedJob] = useState(); - const tableSortByState = useMemo(() => { - return [ - { - id: sortBy, - desc: sortOrder === "desc" - } - ]; - }, [sortBy, sortOrder]); + + const [tableSortByState, onSortByChanged] = useReactTableSortState(); const pagination: PaginationOptions = useMemo(() => { return { diff --git a/src/components/SchemaResourcePage/SchemaResourceEditJobsTab.tsx b/src/components/SchemaResourcePage/SchemaResourceEditJobsTab.tsx index 115066fb9d..ae5af3f0ad 100644 --- a/src/components/SchemaResourcePage/SchemaResourceEditJobsTab.tsx +++ b/src/components/SchemaResourcePage/SchemaResourceEditJobsTab.tsx @@ -21,7 +21,7 @@ export function SchemaResourceJobsTab({ resourceId, tableName }: SchemaResourceJobsTabProps) { - const [searchParams, setSearchParams] = useSearchParams(); + const [searchParams] = useSearchParams(); const pageIndex = parseInt(searchParams.get("pageIndex") ?? "0"); const pageSize = parseInt(searchParams.get("pageSize") ?? "150"); @@ -55,19 +55,6 @@ export function SchemaResourceJobsTab({ pageIndex={pageIndex} pageSize={pageSize} hiddenColumns={["resource_id", "resource_type"]} - sortBy={sortBy} - sortOrder={sortOrder} - onSortByChanged={(sortBy) => { - const sort = typeof sortBy === "function" ? sortBy([]) : sortBy; - if (sort.length === 0) { - searchParams.delete("sortBy"); - searchParams.delete("sortOrder"); - } else { - searchParams.set("sortBy", sort[0]?.id); - searchParams.set("sortOrder", sort[0].desc ? "desc" : "asc"); - } - setSearchParams(searchParams); - }} /> )} diff --git a/src/pages/config/ConfigChangesPage.tsx b/src/pages/config/ConfigChangesPage.tsx index bbfab951dc..15e083c9d1 100644 --- a/src/pages/config/ConfigChangesPage.tsx +++ b/src/pages/config/ConfigChangesPage.tsx @@ -14,9 +14,8 @@ import { import { PaginationOptions } from "@flanksource-ui/ui/DataTable"; import { refreshButtonClickedTrigger } from "@flanksource-ui/ui/SlidingSideBar/SlidingSideBar"; import useTimeRangeParams from "@flanksource-ui/ui/TimeRangePicker/useTimeRangeParams"; -import { SortingState, Updater } from "@tanstack/react-table"; import { useAtom } from "jotai"; -import { useCallback, useMemo } from "react"; +import { useMemo } from "react"; import { useSearchParams } from "react-router-dom"; export function ConfigChangesPage() { @@ -64,20 +63,6 @@ export function ConfigChangesPage() { return Object.fromEntries(filter); }, [changeSummary, configId, createdBy, externalCreatedBy, source]); - const sortState: SortingState = useMemo( - () => [ - ...(sortBy - ? [ - { - id: sortBy, - desc: sortDirection === "desc" - } - ] - : []) - ], - [sortBy, sortDirection] - ); - const { data, isLoading, error, isRefetching, refetch } = useGetConfigsChangesQuery( { @@ -140,21 +125,6 @@ export function ConfigChangesPage() { ? error : (error as Record)?.message ?? "Something went wrong"; - const updateSortBy = useCallback( - (sort: Updater) => { - const sortBy = Array.isArray(sort) ? sort : sort(sortState); - if (sortBy.length === 0) { - params.delete("sortBy"); - params.delete("sortDirection"); - } else { - params.set("sortBy", sortBy[0]?.id); - params.set("sortDirection", sortBy[0].desc ? "desc" : "asc"); - } - setParams(params); - }, - [params, setParams, sortState] - ); - return ( <> @@ -195,8 +165,6 @@ export function ConfigChangesPage() { isLoading={isLoading} linkConfig pagination={pagination} - sortBy={sortState} - onTableSortByChanged={updateSortBy} /> )} diff --git a/src/pages/config/details/ConfigDetailsChangesPage.tsx b/src/pages/config/details/ConfigDetailsChangesPage.tsx index f3b953f97a..9bdc86751c 100644 --- a/src/pages/config/details/ConfigDetailsChangesPage.tsx +++ b/src/pages/config/details/ConfigDetailsChangesPage.tsx @@ -7,7 +7,6 @@ import { ConfigDetailsTabs } from "@flanksource-ui/components/Configs/ConfigDeta import { InfoMessage } from "@flanksource-ui/components/InfoMessage"; import { PaginationOptions } from "@flanksource-ui/ui/DataTable"; import useTimeRangeParams from "@flanksource-ui/ui/TimeRangePicker/useTimeRangeParams"; -import { SortingState } from "@tanstack/react-table"; import { useAtom } from "jotai"; import { useMemo } from "react"; import { useParams, useSearchParams } from "react-router-dom"; @@ -102,17 +101,6 @@ export function ConfigDetailsChangesPage() { return pagination; }, [page, pageSize, totalChangesPages, isLoading, params, setParams]); - const sortState: SortingState = [ - ...(sortBy - ? [ - { - id: sortBy, - desc: sortDirection === "desc" - } - ] - : []) - ]; - if (error) { const errorMessage = typeof error === "symbol" @@ -137,18 +125,6 @@ export function ConfigDetailsChangesPage() { linkConfig={!hideConfigColumn} data={changes} isLoading={isLoading} - sortBy={sortState} - onTableSortByChanged={(sort) => { - const sortBy = Array.isArray(sort) ? sort : sort(sortState); - if (sortBy.length === 0) { - params.delete("sortBy"); - params.delete("sortDirection"); - } else { - params.set("sortBy", sortBy[0]?.id); - params.set("sortDirection", sortBy[0].desc ? "desc" : "asc"); - } - setParams(params); - }} pagination={pagination} /> diff --git a/src/ui/DataTable/Hooks/useReactTableSortState.tsx b/src/ui/DataTable/Hooks/useReactTableSortState.tsx new file mode 100644 index 0000000000..f96aef0e3c --- /dev/null +++ b/src/ui/DataTable/Hooks/useReactTableSortState.tsx @@ -0,0 +1,51 @@ +import { SortingState, Updater } from "@tanstack/react-table"; +import { useCallback, useMemo } from "react"; +import { useSearchParams } from "react-router-dom"; + +/** + * + * useReactTableSortState is a custom hook that manages the sorting state of a + * react-table instance. It uses the URL search params to store the sorting + * state. It returns the sorting state and a function to update the sorting state. + * + */ +export default function useReactTableSortState( + sortByKey = "sortBy", + sortOrderKey = "sortOrder" +): [SortingState, (newSortBy: Updater) => void] { + const [searchParams, setSearchParams] = useSearchParams(); + + const sortBy = searchParams.get(sortByKey) || undefined; + const sortOrder = searchParams.get(sortOrderKey) || undefined; + + const tableSortByState = useMemo(() => { + if (!sortBy || !sortOrder) { + return []; + } + return [ + { + id: sortBy, + desc: sortOrder === "desc" + } + ] satisfies SortingState; + }, [sortBy, sortOrder]); + + console.log(tableSortByState); + + const updateSortByFn = useCallback( + (newSortBy: Updater) => { + const sort = typeof newSortBy === "function" ? newSortBy([]) : newSortBy; + if (sort.length === 0) { + searchParams.delete(sortByKey); + searchParams.delete(sortOrderKey); + } else { + searchParams.set(sortByKey, sort[0]?.id); + searchParams.set(sortOrderKey, sort[0].desc ? "desc" : "asc"); + } + setSearchParams(searchParams); + }, + [searchParams, setSearchParams, sortByKey, sortOrderKey] + ); + + return [tableSortByState, updateSortByFn]; +}