diff --git a/client/src/app/Constants.ts b/client/src/app/Constants.ts index 422963935c..f672a0faaf 100644 --- a/client/src/app/Constants.ts +++ b/client/src/app/Constants.ts @@ -242,4 +242,5 @@ export enum TableURLParamKeyPrefix { issuesAffectedFiles = "if", issuesRemainingIncidents = "ii", dependencyApplications = "da", + archetypes = "ar", } diff --git a/client/src/app/hooks/table-controls/useLocalTableControlState.ts b/client/src/app/hooks/table-controls/useLocalTableControlState.ts index 9f3f7062d9..3dd671b58a 100644 --- a/client/src/app/hooks/table-controls/useLocalTableControlState.ts +++ b/client/src/app/hooks/table-controls/useLocalTableControlState.ts @@ -1,13 +1,23 @@ import { useSelectionState } from "@migtools/lib-ui"; -import { getLocalFilterDerivedState, useFilterState } from "./filtering"; -import { useSortState, getLocalSortDerivedState } from "./sorting"; +import { + getLocalFilterDerivedState, + useFilterState, + useFilterUrlParams, +} from "./filtering"; +import { + useSortState, + getLocalSortDerivedState, + useSortUrlParams, +} from "./sorting"; import { getLocalPaginationDerivedState, usePaginationState, + usePaginationUrlParams, } from "./pagination"; -import { useExpansionState } from "./expansion"; -import { useActiveRowState } from "./active-row"; +import { useExpansionState, useExpansionUrlParams } from "./expansion"; +import { useActiveRowState, useActiveRowUrlParams } from "./active-row"; import { + IExtraArgsForURLParamHooks, IUseLocalTableControlStateArgs, IUseTableControlPropsArgs, } from "./types"; @@ -15,7 +25,7 @@ import { export const useLocalTableControlState = < TItem, TColumnKey extends string, - TSortableColumnKey extends TColumnKey + TSortableColumnKey extends TColumnKey, >( args: IUseLocalTableControlStateArgs ): IUseTableControlPropsArgs => { @@ -77,3 +87,75 @@ export const useLocalTableControlState = < currentPageItems: hasPagination ? currentPageItems : sortedItems, }; }; + +// TODO refactor useUrlParams so it can be used conditionally (e.g. useStateOrUrlParams) so we don't have to duplicate all this. +// this would mean all use[Feature]UrlParams hooks could be consolidated into use[Feature]State with a boolean option for whether to use URL params. + +export const useLocalTableControlUrlParams = < + TItem, + TColumnKey extends string, + TSortableColumnKey extends TColumnKey, + TURLParamKeyPrefix extends string = string, +>( + args: IUseLocalTableControlStateArgs & + IExtraArgsForURLParamHooks +): IUseTableControlPropsArgs => { + const { + items, + filterCategories = [], + sortableColumns = [], + getSortValues, + initialSort = null, + hasPagination = true, + initialItemsPerPage = 10, + idProperty, + initialSelected, + isItemSelectable, + } = args; + + const filterState = useFilterUrlParams(args); + const { filteredItems } = getLocalFilterDerivedState({ + items, + filterCategories, + filterState, + }); + + const selectionState = useSelectionState({ + items: filteredItems, + isEqual: (a, b) => a[idProperty] === b[idProperty], + initialSelected, + isItemSelectable, + }); + + const sortState = useSortUrlParams({ ...args, sortableColumns, initialSort }); + const { sortedItems } = getLocalSortDerivedState({ + sortState, + items: filteredItems, + getSortValues, + }); + + const paginationState = usePaginationUrlParams({ + ...args, + initialItemsPerPage, + }); + const { currentPageItems } = getLocalPaginationDerivedState({ + paginationState, + items: sortedItems, + }); + + const expansionState = useExpansionUrlParams(args); + + const activeRowState = useActiveRowUrlParams(args); + + return { + ...args, + filterState, + expansionState, + selectionState, + sortState, + paginationState, + activeRowState, + totalItemCount: items.length, + currentPageItems: hasPagination ? currentPageItems : sortedItems, + }; +}; diff --git a/client/src/app/hooks/table-controls/useLocalTableControls.ts b/client/src/app/hooks/table-controls/useLocalTableControls.ts index b20714a8cc..4e5efc6762 100644 --- a/client/src/app/hooks/table-controls/useLocalTableControls.ts +++ b/client/src/app/hooks/table-controls/useLocalTableControls.ts @@ -1,11 +1,27 @@ -import { useLocalTableControlState } from "./useLocalTableControlState"; +import { + useLocalTableControlState, + useLocalTableControlUrlParams, +} from "./useLocalTableControlState"; import { useTableControlProps } from "./useTableControlProps"; -import { IUseLocalTableControlStateArgs } from "./types"; +import { + IExtraArgsForURLParamHooks, + IUseLocalTableControlStateArgs, +} from "./types"; export const useLocalTableControls = < TItem, TColumnKey extends string, - TSortableColumnKey extends TColumnKey + TSortableColumnKey extends TColumnKey, >( args: IUseLocalTableControlStateArgs ) => useTableControlProps(useLocalTableControlState(args)); + +export const useLocalTableControlsWithUrlParams = < + TItem, + TColumnKey extends string, + TSortableColumnKey extends TColumnKey, + TURLParamKeyPrefix extends string = string, +>( + args: IUseLocalTableControlStateArgs & + IExtraArgsForURLParamHooks +) => useTableControlProps(useLocalTableControlUrlParams(args)); diff --git a/client/src/app/hooks/table-controls/useTableControlUrlParams.ts b/client/src/app/hooks/table-controls/useTableControlUrlParams.ts index 4e15c40fc4..7f8db39a73 100644 --- a/client/src/app/hooks/table-controls/useTableControlUrlParams.ts +++ b/client/src/app/hooks/table-controls/useTableControlUrlParams.ts @@ -10,7 +10,7 @@ export const useTableControlUrlParams = < TColumnKey extends string, TSortableColumnKey extends TColumnKey, TFilterCategoryKey extends string = string, - TURLParamKeyPrefix extends string = string + TURLParamKeyPrefix extends string = string, >( args: ITableControlCommonArgs< TItem, diff --git a/client/src/app/pages/archetypes/archetypes-page.tsx b/client/src/app/pages/archetypes/archetypes-page.tsx index 60fad8847d..09cea4db16 100644 --- a/client/src/app/pages/archetypes/archetypes-page.tsx +++ b/client/src/app/pages/archetypes/archetypes-page.tsx @@ -39,7 +39,7 @@ import { TableHeaderContentWithControls, TableRowContentWithControls, } from "@app/components/TableControls"; -import { useLocalTableControls } from "@app/hooks/table-controls"; +import { useLocalTableControlsWithUrlParams } from "@app/hooks/table-controls"; import { useDeleteArchetypeMutation, useFetchArchetypes, @@ -57,6 +57,7 @@ import { formatPath, getAxiosErrorMessage } from "@app/utils/utils"; import { AxiosError } from "axios"; import { Paths } from "@app/Paths"; import { SimplePagination } from "@app/components/SimplePagination"; +import { TableURLParamKeyPrefix } from "@app/Constants"; const Archetypes: React.FC = () => { const { t } = useTranslation(); @@ -96,7 +97,8 @@ const Archetypes: React.FC = () => { onError ); - const tableControls = useLocalTableControls({ + const tableControls = useLocalTableControlsWithUrlParams({ + urlParamKeyPrefix: TableURLParamKeyPrefix.archetypes, idProperty: "id", items: archetypes, isLoading: isFetching,