From ccca673569de160ec1b44fdf789529e814af8030 Mon Sep 17 00:00:00 2001 From: Adhitya Mamallan Date: Thu, 21 Nov 2024 17:57:36 +0100 Subject: [PATCH] Add "inputType" and "query" to query params (#737) Add query params inputType and query, and update components --- .../list-workflows/list-workflows.ts | 19 +++--- .../list-workflows-query-params-schema.ts | 2 + .../config/domain-page-query-params.config.ts | 17 +++++- .../domain-workflows-query-params.ts | 2 + .../domain-workflows-page-size.config.ts | 3 + .../config/domain-workflows-table.config.ts | 4 +- .../domain-workflows-header.types.ts | 4 ++ .../domain-workflows-table.constants.ts | 1 - .../domain-workflows-table.tsx | 58 +++++-------------- .../domain-workflows.types.ts | 7 +++ .../hooks/use-list-workflows.ts | 57 ++++++++++++++++++ 11 files changed, 117 insertions(+), 57 deletions(-) create mode 100644 src/views/domain-workflows/config/domain-workflows-page-size.config.ts create mode 100644 src/views/domain-workflows/domain-workflows-header/domain-workflows-header.types.ts delete mode 100644 src/views/domain-workflows/domain-workflows-table/domain-workflows-table.constants.ts create mode 100644 src/views/domain-workflows/domain-workflows.types.ts create mode 100644 src/views/domain-workflows/hooks/use-list-workflows.ts diff --git a/src/route-handlers/list-workflows/list-workflows.ts b/src/route-handlers/list-workflows/list-workflows.ts index f3d97e4d6..6bc76e604 100644 --- a/src/route-handlers/list-workflows/list-workflows.ts +++ b/src/route-handlers/list-workflows/list-workflows.ts @@ -41,14 +41,17 @@ export async function listWorkflows( domain: decodedParams.domain, pageSize: queryParams.pageSize, nextPageToken: queryParams.nextPage, - query: getListWorkflowExecutionsQuery({ - search: queryParams.search, - workflowStatus: queryParams.status, - sortColumn: queryParams.sortColumn, - sortOrder: queryParams.sortOrder, - timeRangeStart: queryParams.timeRangeStart, - timeRangeEnd: queryParams.timeRangeEnd, - }), + query: + queryParams.inputType === 'query' + ? queryParams.query + : getListWorkflowExecutionsQuery({ + search: queryParams.search, + workflowStatus: queryParams.status, + sortColumn: queryParams.sortColumn, + sortOrder: queryParams.sortOrder, + timeRangeStart: queryParams.timeRangeStart, + timeRangeEnd: queryParams.timeRangeEnd, + }), }); const response: ListWorkflowsResponse = { diff --git a/src/route-handlers/list-workflows/schemas/list-workflows-query-params-schema.ts b/src/route-handlers/list-workflows/schemas/list-workflows-query-params-schema.ts index 3ecc9a856..8a2d5160a 100644 --- a/src/route-handlers/list-workflows/schemas/list-workflows-query-params-schema.ts +++ b/src/route-handlers/list-workflows/schemas/list-workflows-query-params-schema.ts @@ -12,7 +12,9 @@ const listWorkflowsQueryParamSchema = z.object({ .pipe( z.number().positive({ message: 'Page size must be a positive integer' }) ), + inputType: z.enum(['search', 'query']), search: z.string().optional(), + query: z.string().optional(), status: z .custom(isWorkflowStatus, { message: 'Invalid workflow status', diff --git a/src/views/domain-page/config/domain-page-query-params.config.ts b/src/views/domain-page/config/domain-page-query-params.config.ts index ef407c411..abb27a548 100644 --- a/src/views/domain-page/config/domain-page-query-params.config.ts +++ b/src/views/domain-page/config/domain-page-query-params.config.ts @@ -1,19 +1,28 @@ import { type PageQueryParam } from '@/hooks/use-page-query-params/use-page-query-params.types'; import parseDateQueryParam from '@/utils/datetime/parse-date-query-param'; import { type SortOrder } from '@/utils/sort-by'; +import { type DomainWorkflowsHeaderInputType } from '@/views/domain-workflows/domain-workflows-header/domain-workflows-header.types'; import isWorkflowStatus from '@/views/shared/workflow-status-tag/helpers/is-workflow-status'; import { type WorkflowStatus } from '@/views/shared/workflow-status-tag/workflow-status-tag.types'; const domainPageQueryParamsConfig: [ - // Workflows + PageQueryParam<'inputType', DomainWorkflowsHeaderInputType>, + // Search input PageQueryParam<'search', string>, PageQueryParam<'status', WorkflowStatus | undefined>, PageQueryParam<'timeRangeStart', Date | undefined>, PageQueryParam<'timeRangeEnd', Date | undefined>, PageQueryParam<'sortColumn', string>, PageQueryParam<'sortOrder', SortOrder>, - // Task Lists + // Query input + PageQueryParam<'query', string>, ] = [ + { + key: 'inputType', + queryParamKey: 'input', + defaultValue: 'search', + parseValue: (value: string) => (value === 'query' ? 'query' : 'search'), + }, { key: 'search', defaultValue: '', @@ -44,6 +53,10 @@ const domainPageQueryParamsConfig: [ defaultValue: 'DESC', parseValue: (value: string) => (value === 'ASC' ? 'ASC' : 'DESC'), }, + { + key: 'query', + defaultValue: '', + }, ] as const; export default domainPageQueryParamsConfig; diff --git a/src/views/domain-workflows/__fixtures__/domain-workflows-query-params.ts b/src/views/domain-workflows/__fixtures__/domain-workflows-query-params.ts index d241512fb..e127bd0ad 100644 --- a/src/views/domain-workflows/__fixtures__/domain-workflows-query-params.ts +++ b/src/views/domain-workflows/__fixtures__/domain-workflows-query-params.ts @@ -4,12 +4,14 @@ import type domainPageQueryParamsConfig from '@/views/domain-page/config/domain- export const mockDomainWorkflowsQueryParamsValues: PageQueryParamValues< typeof domainPageQueryParamsConfig > = { + inputType: 'search', search: '', status: undefined, timeRangeStart: undefined, timeRangeEnd: undefined, sortColumn: 'startTime', sortOrder: 'DESC', + query: '', }; export const mockDateOverrides = { diff --git a/src/views/domain-workflows/config/domain-workflows-page-size.config.ts b/src/views/domain-workflows/config/domain-workflows-page-size.config.ts new file mode 100644 index 000000000..8a7d6af84 --- /dev/null +++ b/src/views/domain-workflows/config/domain-workflows-page-size.config.ts @@ -0,0 +1,3 @@ +const DOMAIN_WORKFLOWS_PAGE_SIZE = 10; + +export default DOMAIN_WORKFLOWS_PAGE_SIZE; diff --git a/src/views/domain-workflows/config/domain-workflows-table.config.ts b/src/views/domain-workflows/config/domain-workflows-table.config.ts index 21ad31db3..5392d67b5 100644 --- a/src/views/domain-workflows/config/domain-workflows-table.config.ts +++ b/src/views/domain-workflows/config/domain-workflows-table.config.ts @@ -6,7 +6,7 @@ import { type TableColumn } from '@/components/table/table.types'; import { type DomainWorkflow } from '@/views/domain-page/domain-page.types'; import WorkflowStatusTag from '@/views/shared/workflow-status-tag/workflow-status-tag'; -const domainWorkflowsTableConfig: Array> = [ +const domainWorkflowsTableConfig = [ { name: 'Workflow ID', id: 'WorkflowID', @@ -55,6 +55,6 @@ const domainWorkflowsTableConfig: Array> = [ width: '12.5%', sortable: true, }, -]; +] as const satisfies Array>; export default domainWorkflowsTableConfig; diff --git a/src/views/domain-workflows/domain-workflows-header/domain-workflows-header.types.ts b/src/views/domain-workflows/domain-workflows-header/domain-workflows-header.types.ts new file mode 100644 index 000000000..1caec1506 --- /dev/null +++ b/src/views/domain-workflows/domain-workflows-header/domain-workflows-header.types.ts @@ -0,0 +1,4 @@ +import { type ListWorkflowsRequestQueryParams } from '@/route-handlers/list-workflows/list-workflows.types'; + +export type DomainWorkflowsHeaderInputType = + ListWorkflowsRequestQueryParams['inputType']; diff --git a/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.constants.ts b/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.constants.ts deleted file mode 100644 index 718f14d0f..000000000 --- a/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const PAGE_SIZE = 10; diff --git a/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.tsx b/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.tsx index 3ac33ecea..7da0e6956 100644 --- a/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.tsx +++ b/src/views/domain-workflows/domain-workflows-table/domain-workflows-table.tsx @@ -1,76 +1,46 @@ 'use client'; -import React, { useMemo } from 'react'; - -import { useInfiniteQuery } from '@tanstack/react-query'; -import queryString from 'query-string'; +import React from 'react'; import ErrorPanel from '@/components/error-panel/error-panel'; import SectionLoadingIndicator from '@/components/section-loading-indicator/section-loading-indicator'; import Table from '@/components/table/table'; import usePageQueryParams from '@/hooks/use-page-query-params/use-page-query-params'; -import { - type ListWorkflowsResponse, - type ListWorkflowsRequestQueryParams, -} from '@/route-handlers/list-workflows/list-workflows.types'; -import request from '@/utils/request'; import domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config'; import domainWorkflowsTableConfig from '../config/domain-workflows-table.config'; import DomainWorkflowsTableEndMessage from '../domain-workflows-table-end-message/domain-workflows-table-end-message'; import getNextSortOrder from '../helpers/get-next-sort-order'; +import useListWorkflows from '../hooks/use-list-workflows'; -import { PAGE_SIZE } from './domain-workflows-table.constants'; import { styled } from './domain-workflows-table.styles'; import { type Props } from './domain-workflows-table.types'; import getWorkflowsErrorPanelProps from './helpers/get-workflows-error-panel-props'; -export default function DomainWorkflowsTable(props: Props) { +export default function DomainWorkflowsTable({ domain, cluster }: Props) { const [queryParams, setQueryParams] = usePageQueryParams( domainPageQueryParamsConfig ); - const requestQueryParams: ListWorkflowsRequestQueryParams = { - pageSize: PAGE_SIZE.toString(), - search: queryParams.search, - status: queryParams.status, - sortColumn: queryParams.sortColumn, - sortOrder: queryParams.sortOrder, - timeRangeStart: queryParams.timeRangeStart?.toISOString(), - timeRangeEnd: queryParams.timeRangeEnd?.toISOString(), - }; - const { - data, + workflows, error, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage, refetch, - } = useInfiniteQuery({ - queryKey: ['listWorkflows', { ...props, ...requestQueryParams }], - queryFn: async ({ pageParam }) => - request( - queryString.stringifyUrl({ - url: `/api/domains/${props.domain}/${props.cluster}/workflows`, - query: { - ...requestQueryParams, - nextPage: pageParam as string, - }, - }) - ).then((res) => res.json()), - initialPageParam: undefined, - getNextPageParam: (lastPage) => { - if (!lastPage.nextPage) return undefined; - return lastPage.nextPage; - }, + } = useListWorkflows({ + domain, + cluster, + inputType: queryParams.inputType, + search: queryParams.search, + status: queryParams.status, + sortColumn: queryParams.sortColumn, + sortOrder: queryParams.sortOrder, + timeRangeStart: queryParams.timeRangeStart?.toISOString(), + timeRangeEnd: queryParams.timeRangeEnd?.toISOString(), }); - const workflows = useMemo(() => { - if (!data) return []; - return data.pages.flatMap((page) => page.workflows ?? []); - }, [data]); - if (isLoading) { return ; } diff --git a/src/views/domain-workflows/domain-workflows.types.ts b/src/views/domain-workflows/domain-workflows.types.ts new file mode 100644 index 000000000..055124e9e --- /dev/null +++ b/src/views/domain-workflows/domain-workflows.types.ts @@ -0,0 +1,7 @@ +import { + type RouteParams as ListWorkflowsRouteParams, + type ListWorkflowsRequestQueryParams, +} from '@/route-handlers/list-workflows/list-workflows.types'; + +export type UseListWorkflowsParams = ListWorkflowsRouteParams & + Omit & { pageSize?: number }; diff --git a/src/views/domain-workflows/hooks/use-list-workflows.ts b/src/views/domain-workflows/hooks/use-list-workflows.ts new file mode 100644 index 000000000..7f942a7bc --- /dev/null +++ b/src/views/domain-workflows/hooks/use-list-workflows.ts @@ -0,0 +1,57 @@ +'use client'; +import { useMemo } from 'react'; + +import { useInfiniteQuery } from '@tanstack/react-query'; +import queryString from 'query-string'; + +import { + type ListWorkflowsResponse, + type ListWorkflowsRequestQueryParams, +} from '@/route-handlers/list-workflows/list-workflows.types'; +import request from '@/utils/request'; +import { type RequestError } from '@/utils/request/request-error'; + +import DOMAIN_WORKFLOWS_PAGE_SIZE from '../config/domain-workflows-page-size.config'; +import { type UseListWorkflowsParams } from '../domain-workflows.types'; + +export default function useListWorkflows({ + domain, + cluster, + pageSize = DOMAIN_WORKFLOWS_PAGE_SIZE, + ...requestQueryParams +}: UseListWorkflowsParams) { + const queryResult = useInfiniteQuery({ + queryKey: [ + 'listWorkflows', + { domain, cluster, ...requestQueryParams, pageSize }, + ], + queryFn: async ({ pageParam }) => + request( + queryString.stringifyUrl({ + url: `/api/domains/${domain}/${cluster}/workflows`, + query: { + ...requestQueryParams, + pageSize: pageSize.toString(), + nextPage: pageParam as string, + } as const satisfies ListWorkflowsRequestQueryParams, + }) + ).then((res) => res.json()), + initialPageParam: undefined, + getNextPageParam: (lastPage) => { + if (!lastPage.nextPage) return undefined; + return lastPage.nextPage; + }, + retry: false, + refetchOnWindowFocus: (query) => query.state.status !== 'error', + }); + + const workflows = useMemo(() => { + if (!queryResult.data) return []; + return queryResult.data.pages.flatMap((page) => page.workflows ?? []); + }, [queryResult.data]); + + return { + workflows, + ...queryResult, + }; +}