Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPC-9975 Remove use-query-params #481

Merged
merged 11 commits into from
Jan 21, 2025
Prev Previous commit
Next Next commit
Replace all usages of use-query-params for new useQueryParams
Onitoxan committed Jan 9, 2025
commit 9f5606f0f67b03663cd20d753d876aa43865e92a
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import { t } from '../../../i18n';
import { LocalStorageSchema } from '../../utils/local-storage-type';
import { util } from '@unocha/hpc-core';
import { Alert } from '@mui/material';
import { Query } from '../tables/table-utils';
import type { FlowQuery, SetQuery } from '../tables/table-utils';
import { AppContext } from '../../context';
import { util as codecs, FormObjectValue } from '@unocha/hpc-data';
import validateForm from '../../utils/form-validation';
@@ -25,8 +25,8 @@ import {
} from '../../utils/fn-promises';

interface Props {
query: Query;
setQuery: (newQuery: Query) => void;
query: FlowQuery;
setQuery: SetQuery<FlowQuery>;
handleAbortController: () => void;
}
export interface FlowsFilterValues {
@@ -136,11 +136,14 @@ export const FilterFlowsTable = (props: Props) => {
if (query.filters !== encodedFilters) {
handleAbortController();
}
setQuery({
...query,
page: 0,
filters: encodedFilters,
});
setQuery(
{
...query,
page: 0,
filters: encodedFilters,
},
true
);
};
return (
<C.SearchFilter title={t.t(lang, (s) => s.components.flowsFilter.title)}>
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ import { Environment } from '../../../environments/interface';
import { decodeFilters, encodeFilters } from '../../utils/parse-filters';
import { LanguageKey, t } from '../../../i18n';
import { Dayjs } from 'dayjs';
import { Query } from '../tables/table-utils';
import type { OrganizationQuery, SetQuery } from '../tables/table-utils';
import * as io from 'io-ts';
import validateForm from '../../utils/form-validation';
import {
@@ -17,8 +17,8 @@ import {
} from '../../utils/fn-promises';
interface Props {
environment: Environment;
query: Query;
setQuery: (newQuery: Query) => void;
query: OrganizationQuery;
setQuery: SetQuery<OrganizationQuery>;
lang: LanguageKey;
}
export interface OrganizationFilterValues {
@@ -69,11 +69,14 @@ export const FilterOrganizationsTable = (props: Props) => {
) => void
) => {
formikResetForm();
setQuery({
...query,
page: 0,
filters: encodeFilters({}, ORGANIZATIONS_FILTER_INITIAL_VALUES),
});
setQuery(
{
...query,
page: 0,
filters: encodeFilters({}, ORGANIZATIONS_FILTER_INITIAL_VALUES),
},
true
);
};
return (
<C.SearchFilter
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { C } from '@unocha/hpc-ui';
import { FormObjectValue } from '@unocha/hpc-data';
import { decodeFilters, encodeFilters } from '../../utils/parse-filters';
import { t } from '../../../i18n';
import { Query } from '../tables/table-utils';
import type { FlowQuery, SetQuery } from '../tables/table-utils';
import { useContext } from 'react';
import { AppContext } from '../../context';
import {
@@ -14,8 +14,8 @@ import {
fnUsageYears,
} from '../../utils/fn-promises';
interface Props {
query: Query;
setQuery: (newQuery: Query) => void;
query: FlowQuery;
setQuery: SetQuery<FlowQuery>;
handleAbortController: () => void;
}
export interface PendingFlowsFilterValues {
7 changes: 4 additions & 3 deletions apps/hpc-ftsadmin/src/app/components/tables/flows-table.tsx
Original file line number Diff line number Diff line change
@@ -45,7 +45,8 @@ import { downloadExcel } from '../../utils/download-excel';
import DownloadIcon from '@mui/icons-material/Download';
import {
ChipDiv,
Query,
type FlowQuery,
type SetQuery,
RejectPendingFlowsButton,
RenderChipsRow,
StyledLoader,
@@ -64,8 +65,8 @@ export interface FlowsTableProps {
headers: TableHeadersProps<FlowHeaderID>[];
initialValues: FlowsFilterValues | PendingFlowsFilterValues;
rowsPerPageOption: number[];
query: Query;
setQuery: (newQuery: Query) => void;
query: FlowQuery;
setQuery: SetQuery<FlowQuery>;
abortSignal?: AbortSignal;
pending?: boolean;
}
14 changes: 5 additions & 9 deletions apps/hpc-ftsadmin/src/app/components/tables/keywords-table.tsx
Original file line number Diff line number Diff line change
@@ -37,7 +37,8 @@ import {

import {
ChipDiv,
Query,
type KeywordQuery,
type SetQuery,
StyledLoader,
TableHeaderButton,
TopRowContainer,
@@ -51,15 +52,10 @@ import { LocalStorageSchema } from '../../utils/local-storage-type';
import { Strings } from '../../../i18n/iface';
import { parseError } from '../../utils/map-functions';

export type KeywordQuery = {
orderBy: string;
orderDir: string;
tableHeaders: string;
};
export interface KeywordTableProps {
headers: TableHeadersProps<KeywordHeaderID>[];
query: KeywordQuery;
setQuery: (newQuery: KeywordQuery) => void;
setQuery: SetQuery<KeywordQuery>;
}

/**
@@ -507,7 +503,7 @@ export default function KeywordTable(props: KeywordTableProps) {
query.tableHeaders,
lang,
'keywords',
query as Query,
query,
setQuery
)}
onClick={(element) => {
@@ -517,7 +513,7 @@ export default function KeywordTable(props: KeywordTableProps) {
tableHeaders: encodeTableHeaders(
element,
'keywords',
query as Query,
query,
setQuery
),
});
Original file line number Diff line number Diff line change
@@ -41,7 +41,8 @@ import { parseUpdatedCreatedBy } from '../../utils/map-functions';
import { OrganizationFilterValues } from '../filters/filter-organization-table';
import {
ChipDiv,
Query,
type OrganizationQuery,
type SetQuery,
RenderChipsRow,
StyledLoader,
TableHeaderButton,
@@ -59,8 +60,8 @@ export interface OrganizationTableProps {
headers: TableHeadersProps<OrganizationHeaderID>[];
initialValues: OrganizationFilterValues;
rowsPerPageOption: number[];
query: Query;
setQuery: (newQuery: Query) => void;
query: OrganizationQuery;
setQuery: SetQuery<OrganizationQuery>;
}

export default function OrganizationTable(props: OrganizationTableProps) {
35 changes: 30 additions & 5 deletions apps/hpc-ftsadmin/src/app/components/tables/table-utils.tsx
Original file line number Diff line number Diff line change
@@ -7,18 +7,43 @@ import CancelRoundedIcon from '@mui/icons-material/CancelRounded';
import { C } from '@unocha/hpc-ui';
import { util } from '@unocha/hpc-core';
import { LocalStorageSchema } from '../../utils/local-storage-type';
import type {
FlowHeaderID,
KeywordHeaderID,
OrganizationHeaderID,
} from '../../utils/table-headers';
import type { NavigateOptions } from 'react-router';

export type Query = {
page: number;
rowsPerPage: number;
orderBy: string;
orderDir: string;
filters: string;
orderDir: 'ASC' | 'DESC';
tableHeaders: string;
prevPageCursor?: number;
nextPageCursor?: number;
};

export type FlowQuery = Query & {
page: number;
rowsPerPage: number;
orderBy: FlowHeaderID;
filters: string;
};

export type OrganizationQuery = Query & {
page: number;
rowsPerPage: number;
orderBy: OrganizationHeaderID;
filters: string;
};

export type KeywordQuery = Query & {
orderBy: KeywordHeaderID;
};

export type SetQuery<T extends Query> = (
newQuery: T,
flushSync?: NavigateOptions['flushSync']
) => void;

export const StyledLoader = tw(C.Loader)`
mx-auto
`;
55 changes: 13 additions & 42 deletions apps/hpc-ftsadmin/src/app/pages/flows/flows-list.tsx
Original file line number Diff line number Diff line change
@@ -3,16 +3,6 @@ import { t } from '../../../i18n';
import PageMeta from '../../components/page-meta';
import { AppContext } from '../../context';
import tw from 'twin.macro';

import {
JsonParam,
NumberParam,
StringParam,
createEnumParam,
decodeNumber,
useQueryParams,
withDefault,
} from 'use-query-params';
import {
DEFAULT_FLOW_TABLE_HEADERS,
encodeTableHeaders,
@@ -24,6 +14,8 @@ import FilterFlowsTable, {
FLOWS_FILTER_INITIAL_VALUES,
} from '../../components/filters/filter-flows-table';
import { useCallback, useEffect, useRef } from 'react';
import useQueryParams from '../../utils/useQueryParams';
import { FLOW_PARAMS_CODEC } from '../../utils/codecs';

interface Props {
className?: string;
@@ -51,44 +43,23 @@ export default (props: Props) => {
}, []);

const [query, setQuery] = useQueryParams({
page: withDefault(NumberParam, 0),
rowsPerPage: withDefault(
{
...NumberParam,
decode: (string) => {
// Prevent user requesting more than max number of rows
const number = decodeNumber(string);
return number && Math.min(number, Math.max(...rowsPerPageOptions));
},
},
50
),
orderBy: withDefault(
createEnumParam(
// Same as filter then map but this is acceptable to typescript
DEFAULT_FLOW_TABLE_HEADERS.reduce((acc, curr) => {
if (curr.sortable) {
return [...acc, curr.identifierID];
}

return acc;
}, [] as string[])
),
'flow.updatedAt'
),
orderDir: withDefault(createEnumParam(['ASC', 'DESC']), 'DESC'),
filters: withDefault(JsonParam, JSON.stringify({})),
tableHeaders: withDefault(StringParam, encodeTableHeaders([])), // Default value of table headers
prevPageCursor: withDefault(NumberParam, undefined),
nextPageCursor: withDefault(NumberParam, undefined),
codec: FLOW_PARAMS_CODEC,
initialValues: {
page: 0,
rowsPerPage: 50,
orderBy: 'flow.updatedAt',
orderDir: 'DESC',
filters: JSON.stringify({}),
tableHeaders: encodeTableHeaders([]), // Default value of table headers
},
});

const flowsTableProps: FlowsTableProps = {
headers: DEFAULT_FLOW_TABLE_HEADERS,
rowsPerPageOption: rowsPerPageOptions,
initialValues: FLOWS_FILTER_INITIAL_VALUES,
query: query,
setQuery: setQuery,
query,
setQuery,
abortSignal: abortControllerRef.current.signal,
};

54 changes: 13 additions & 41 deletions apps/hpc-ftsadmin/src/app/pages/flows/pending-flows-list.tsx
Original file line number Diff line number Diff line change
@@ -2,15 +2,6 @@ import { C, CLASSES, combineClasses } from '@unocha/hpc-ui';
import { t } from '../../../i18n';
import PageMeta from '../../components/page-meta';
import { AppContext } from '../../context';
import {
JsonParam,
NumberParam,
StringParam,
createEnumParam,
decodeNumber,
useQueryParams,
withDefault,
} from 'use-query-params';
import FilterPendingFlowsTable, {
PENDING_FLOWS_FILTER_INITIAL_VALUES,
} from '../../components/filters/filter-pending-flows-table';
@@ -23,6 +14,8 @@ import FlowsTable, {
FlowsTableProps,
} from '../../components/tables/flows-table';
import { useCallback, useEffect, useRef } from 'react';
import useQueryParams from '../../utils/useQueryParams';
import { FLOW_PARAMS_CODEC } from '../../utils/codecs';

interface Props {
className?: string;
@@ -38,36 +31,15 @@ export default (props: Props) => {
const abortControllerRef = useRef<AbortController>(new AbortController());

const [query, setQuery] = useQueryParams({
page: withDefault(NumberParam, 0),
rowsPerPage: withDefault(
{
...NumberParam,
decode: (string) => {
// Prevent user requesting more than max number of rows
const number = decodeNumber(string);
return number && Math.min(number, Math.max(...[10, 25, 50, 100]));
},
},
50
),
orderBy: withDefault(
createEnumParam(
// Same as filter then map but this is acceptable to typescript
DEFAULT_FLOW_TABLE_HEADERS.reduce((acc, curr) => {
if (curr.sortable) {
return [...acc, curr.identifierID];
}

return acc;
}, [] as string[])
),
'flow.updatedAt'
),
orderDir: withDefault(createEnumParam(['ASC', 'DESC']), 'DESC'),
filters: withDefault(JsonParam, JSON.stringify({})),
tableHeaders: withDefault(StringParam, encodeTableHeaders([])), // Default value of table headers
prevPageCursor: withDefault(NumberParam, 0),
nextPageCursor: withDefault(NumberParam, 0),
codec: FLOW_PARAMS_CODEC,
initialValues: {
page: 0,
rowsPerPage: 50,
orderBy: 'flow.updatedAt',
orderDir: 'DESC',
filters: JSON.stringify({}),
tableHeaders: encodeTableHeaders([]), // Default value of table headers
},
});

const handleAbortController = useCallback(() => {
@@ -85,8 +57,8 @@ export default (props: Props) => {
headers: DEFAULT_FLOW_TABLE_HEADERS,
initialValues: PENDING_FLOWS_FILTER_INITIAL_VALUES,
rowsPerPageOption: [10, 25, 50, 100],
query: query,
setQuery: setQuery,
query,
setQuery,
pending: true,
abortSignal: abortControllerRef.current.signal,
};
29 changes: 8 additions & 21 deletions apps/hpc-ftsadmin/src/app/pages/keywords/keyword-list.tsx
Original file line number Diff line number Diff line change
@@ -3,19 +3,15 @@ import { t } from '../../../i18n';
import PageMeta from '../../components/page-meta';
import { AppContext } from '../../context';
import tw from 'twin.macro';
import {
StringParam,
createEnumParam,
useQueryParams,
withDefault,
} from 'use-query-params';
import {
DEFAULT_KEYWORD_TABLE_HEADERS,
encodeTableHeaders,
} from '../../utils/table-headers';
import KeywordTable, {
KeywordTableProps,
} from '../../components/tables/keywords-table';
import useQueryParams from '../../utils/useQueryParams';
import { KEYWORD_PARAMS_CODEC } from '../../utils/codecs';

interface Props {
className?: string;
@@ -29,21 +25,12 @@ const LandingContainer = tw.div`
`;
export default (props: Props) => {
const [query, setQuery] = useQueryParams({
orderBy: withDefault(
createEnumParam(
// Same as filter then map but this is acceptable to typescript
DEFAULT_KEYWORD_TABLE_HEADERS.reduce((acc, curr) => {
if (curr.sortable) {
return [...acc, curr.identifierID];
}

return acc;
}, [] as string[])
),
'keyword.name'
),
orderDir: withDefault(createEnumParam(['ASC', 'DESC']), 'ASC'),
tableHeaders: withDefault(StringParam, encodeTableHeaders([], 'keywords')),
codec: KEYWORD_PARAMS_CODEC,
initialValues: {
orderBy: 'keyword.name',
orderDir: 'ASC',
tableHeaders: encodeTableHeaders([], 'keywords'),
},
});

const keywordTableProps: KeywordTableProps = {
Original file line number Diff line number Diff line change
@@ -3,15 +3,6 @@ import { t } from '../../../i18n';
import PageMeta from '../../components/page-meta';
import { AppContext, getEnv } from '../../context';
import tw from 'twin.macro';
import {
JsonParam,
NumberParam,
StringParam,
createEnumParam,
decodeNumber,
useQueryParams,
withDefault,
} from 'use-query-params';
import {
DEFAULT_ORGANIZATION_TABLE_HEADERS,
encodeTableHeaders,
@@ -22,6 +13,8 @@ import OrganizationTable, {
import FilterOrganizationsTable, {
ORGANIZATIONS_FILTER_INITIAL_VALUES,
} from '../../components/filters/filter-organization-table';
import useQueryParams from '../../utils/useQueryParams';
import { ORGANIZATION_PARAMS_CODEC } from '../../utils/codecs';

interface Props {
className?: string;
@@ -37,39 +30,15 @@ export default (props: Props) => {
const rowsPerPageOptions = [10, 25, 50, 100];

const [query, setQuery] = useQueryParams({
page: withDefault(NumberParam, 0),
rowsPerPage: withDefault(
{
...NumberParam,
decode: (string) => {
// Prevent user requesting more than max number of rows
const number = decodeNumber(string);
return number && Math.min(number, Math.max(...rowsPerPageOptions));
},
},
50
),
orderBy: withDefault(
createEnumParam(
// Same as filter then map but this is acceptable to typescript
DEFAULT_ORGANIZATION_TABLE_HEADERS.reduce((acc, curr) => {
if (curr.sortable) {
return [...acc, curr.identifierID];
}

return acc;
}, [] as string[])
),
'organization.name'
),
orderDir: withDefault(createEnumParam(['ASC', 'DESC']), 'ASC'),
filters: withDefault(JsonParam, JSON.stringify({})),
tableHeaders: withDefault(
StringParam,
encodeTableHeaders([], 'organizations')
),
prevPageCursor: withDefault(NumberParam, 0),
nextPageCursor: withDefault(NumberParam, 0),
codec: ORGANIZATION_PARAMS_CODEC,
initialValues: {
page: 0,
rowsPerPage: 50,
orderBy: 'organization.name',
orderDir: 'ASC',
filters: JSON.stringify({}),
tableHeaders: encodeTableHeaders([], 'organizations'),
},
});

const organizationTableProps: OrganizationTableProps = {
14 changes: 7 additions & 7 deletions apps/hpc-ftsadmin/src/app/utils/table-headers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageKey, t } from '../../i18n';
import { Strings } from '../../i18n/iface';
import { Query } from '../components/tables/table-utils';
import type { Query, SetQuery } from '../components/tables/table-utils';
import { FilterKeys } from './parse-filters';

/** Declare which tables there can be */
@@ -310,11 +310,11 @@ const defaultEncodeTableHeaders = (table: TableType) => {
* Encodes the query param to obtain a string suitable for the URL,
* use it alongside `decodeTableHeaders()`
*/
export const encodeTableHeaders = (
export const encodeTableHeaders = <T extends Query>(
headers: Array<HeaderType>,
table: TableType = 'flows',
query?: Query,
setQuery?: (newQuery: Query) => void
query?: T,
setQuery?: SetQuery<T>
): string => {
if (headers.length === 0) {
return defaultEncodeTableHeaders(table);
@@ -399,12 +399,12 @@ const defaultDecodeTableHeaders = (
/**
* Decodes the query param to obtain an ordered list of table headers
*/
export const decodeTableHeaders = (
export const decodeTableHeaders = <T extends Query>(
queryParam: string,
lang: LanguageKey,
table: TableType = 'flows',
query?: Query,
setQuery?: (newQuery: Query) => void
query?: T,
setQuery?: SetQuery<T>
): Array<
TableHeadersProps<FlowHeaderID | OrganizationHeaderID | KeywordHeaderID>
> => {