Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -1,22 +1,82 @@
import { HttpResponse } from 'msw';

import { render, screen } from '@/test-utils/rtl';

import { getMockWorkflowListItem } from '@/route-handlers/list-workflows/__fixtures__/mock-workflow-list-items';
import { type ListWorkflowsResponse } from '@/route-handlers/list-workflows/list-workflows.types';

import type { Props as MSWMocksHandlersProps } from '../../../../test-utils/msw-mock-handlers/msw-mock-handlers.types';
import { mockDomainPageQueryParamsValues } from '../../../domain-page/__fixtures__/domain-page-query-params';
import DomainWorkflowsArchivalList from '../domain-workflows-archival-list';

jest.mock('@/components/error-panel/error-panel', () =>
jest.fn(({ message }: { message: string }) => <div>{message}</div>)
);

jest.mock('@/views/shared/workflows-list/workflows-list', () =>
jest.fn(() => <div>Mock workflows list</div>)
);

jest.mock('@/hooks/use-page-query-params/use-page-query-params', () =>
jest.fn(() => [mockDomainPageQueryParamsValues, jest.fn()])
);

jest.mock('@/hooks/use-config-value/use-suspense-config-value', () =>
jest.fn(() => ({ data: true }))
);

jest.mock('query-string', () => ({
stringifyUrl: jest.fn(
() => '/api/domains/mock-domain/mock-cluster/workflows'
),
}));

describe(DomainWorkflowsArchivalList.name, () => {
it('renders workflows list', () => {
render(
<DomainWorkflowsArchivalList
domain="mock-domain"
cluster="mock-cluster"
timeRangeStart="mock-time-range-start"
timeRangeEnd="mock-time-range-end"
/>
);

expect(screen.getByText('Mock workflows list')).toBeInTheDocument();
beforeEach(() => {
jest.clearAllMocks();
});

it('renders workflows list when data is loaded', async () => {
setup({});

expect(await screen.findByText('Mock workflows list')).toBeInTheDocument();
});
});

function setup({ errorCase }: { errorCase?: 'no-workflows' }) {
const mockResponse: ListWorkflowsResponse =
errorCase === 'no-workflows'
? { workflows: [], nextPage: '' }
: {
workflows: Array.from({ length: 5 }, (_, i) =>
getMockWorkflowListItem({
workflowID: `mock-wf-${i}`,
runID: `mock-run-${i}`,
workflowName: `mock-name-${i}`,
status: 'WORKFLOW_EXECUTION_CLOSE_STATUS_COMPLETED',
startTime: 1684800000000,
})
),
nextPage: '',
};

render(
<DomainWorkflowsArchivalList
domain="mock-domain"
cluster="mock-cluster"
visibleColumns={[]}
timeRangeStart="mock-time-range-start"
timeRangeEnd="mock-time-range-end"
/>,
{
endpointsMocks: [
{
path: '/api/domains/:domain/:cluster/workflows',
httpMethod: 'GET',
mockOnce: false,
httpResolver: async () => HttpResponse.json(mockResponse),
},
] as MSWMocksHandlersProps['endpointsMocks'],
}
);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,79 @@
'use client';

import ErrorPanel from '@/components/error-panel/error-panel';
import PanelSection from '@/components/panel-section/panel-section';
import SectionLoadingIndicator from '@/components/section-loading-indicator/section-loading-indicator';
import usePageQueryParams from '@/hooks/use-page-query-params/use-page-query-params';
import domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config';
import useListWorkflows from '@/views/shared/hooks/use-list-workflows';
import WorkflowsList from '@/views/shared/workflows-list/workflows-list';

import DOMAIN_WORKFLOWS_ARCHIVAL_PAGE_SIZE from '../config/domain-workflows-archival-page-size.config';
import getArchivalErrorPanelProps from '../domain-workflows-archival-table/helpers/get-archival-error-panel-props';
import useArchivalInputType from '../hooks/use-archival-input-type';

import { type Props } from './domain-workflows-archival-list.types';

export default function DomainWorkflowsArchivalList(_props: Props) {
return <WorkflowsList />;
export default function DomainWorkflowsArchivalList({
domain,
cluster,
visibleColumns,
timeRangeStart,
timeRangeEnd,
}: Props) {
const [queryParams] = usePageQueryParams(domainPageQueryParamsConfig);
const { inputType } = useArchivalInputType();

const {
workflows,
error,
isLoading,
hasNextPage,
fetchNextPage,
isFetchingNextPage,
refetch,
} = useListWorkflows({
domain,
cluster,
listType: 'archived',
pageSize: DOMAIN_WORKFLOWS_ARCHIVAL_PAGE_SIZE,
inputType,
search: queryParams.searchArchival,
statuses: queryParams.statusesArchival,
timeRangeStart,
timeRangeEnd,
sortColumn: queryParams.sortColumnArchival,
sortOrder: queryParams.sortOrderArchival,
query: queryParams.queryArchival,
});

if (isLoading) {
return <SectionLoadingIndicator />;
}

if (workflows.length === 0 && error) {
return (
<PanelSection>
<ErrorPanel
{...getArchivalErrorPanelProps({
inputType,
error,
queryString: queryParams.queryArchival,
})}
reset={refetch}
/>
</PanelSection>
);
}

return (
<WorkflowsList
workflows={workflows}
columns={visibleColumns}
error={error}
hasNextPage={hasNextPage}
fetchNextPage={fetchNextPage}
isFetchingNextPage={isFetchingNextPage}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { type WorkflowsListColumn } from '@/views/shared/workflows-list/workflows-list.types';

export type Props = {
domain: string;
cluster: string;
visibleColumns: Array<WorkflowsListColumn>;
timeRangeStart: string;
timeRangeEnd: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import getDayjsFromDateFilterValue from '@/components/date-filter/helpers/get-da
import useSuspenseConfigValue from '@/hooks/use-config-value/use-suspense-config-value';
import usePageQueryParams from '@/hooks/use-page-query-params/use-page-query-params';
import { type DomainPageTabContentProps } from '@/views/domain-page/domain-page-content/domain-page-content.types';
import useWorkflowsListColumns from '@/views/shared/workflows-list/hooks/use-workflows-list-columns';

import domainPageQueryParamsConfig from '../domain-page/config/domain-page-query-params.config';
import useSuspenseDomainDescription from '../shared/hooks/use-domain-description/use-suspense-domain-description';
Expand All @@ -24,6 +25,10 @@ export default function DomainWorkflowsArchival(

const [queryParams] = usePageQueryParams(domainPageQueryParamsConfig);

const { visibleColumns } = useWorkflowsListColumns({
cluster: props.cluster,
});

const { data: isNewWorkflowsListEnabled } = useSuspenseConfigValue(
'WORKFLOWS_LIST_ENABLED'
);
Expand Down Expand Up @@ -62,6 +67,7 @@ export default function DomainWorkflowsArchival(
<DomainWorkflowsArchivalList
domain={props.domain}
cluster={props.cluster}
visibleColumns={visibleColumns}
{...timeRangeParams}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import getDayjsFromDateFilterValue from '@/components/date-filter/helpers/get-da
import usePageQueryParams from '@/hooks/use-page-query-params/use-page-query-params';
import dayjs from '@/utils/datetime/dayjs';
import domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config';
import useWorkflowsListColumns from '@/views/shared/workflows-list/hooks/use-workflows-list-columns';

import DomainWorkflowsHeader from '../domain-workflows-header/domain-workflows-header';
import DomainWorkflowsList from '../domain-workflows-list/domain-workflows-list';
Expand All @@ -18,6 +19,8 @@ export default function DomainWorkflowsAdvanced({
}: Props) {
const [queryParams] = usePageQueryParams(domainPageQueryParamsConfig);

const { visibleColumns } = useWorkflowsListColumns({ cluster });

const timeRangeParams = useMemo(() => {
const now = dayjs();

Expand Down Expand Up @@ -47,6 +50,7 @@ export default function DomainWorkflowsAdvanced({
<DomainWorkflowsList
domain={domain}
cluster={cluster}
visibleColumns={visibleColumns}
{...timeRangeParams}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,83 @@
import { HttpResponse } from 'msw';

import { render, screen } from '@/test-utils/rtl';

import { getMockWorkflowListItem } from '@/route-handlers/list-workflows/__fixtures__/mock-workflow-list-items';
import { type ListWorkflowsResponse } from '@/route-handlers/list-workflows/list-workflows.types';

import type { Props as MSWMocksHandlersProps } from '../../../../test-utils/msw-mock-handlers/msw-mock-handlers.types';
import { mockDomainPageQueryParamsValues } from '../../../domain-page/__fixtures__/domain-page-query-params';
import DomainWorkflowsList from '../domain-workflows-list';

jest.mock('@/components/error-panel/error-panel', () =>
jest.fn(({ message }: { message: string }) => <div>{message}</div>)
);

jest.mock('@/views/shared/workflows-list/workflows-list', () =>
jest.fn(() => <div>Mock workflows list</div>)
);

jest.mock('@/hooks/use-page-query-params/use-page-query-params', () =>
jest.fn(() => [mockDomainPageQueryParamsValues, jest.fn()])
);

jest.mock('query-string', () => ({
stringifyUrl: jest.fn(
() => '/api/domains/mock-domain/mock-cluster/workflows'
),
}));

describe(DomainWorkflowsList.name, () => {
it('renders workflows list', () => {
render(
<DomainWorkflowsList
domain="mock-domain"
cluster="mock-cluster"
timeRangeEnd="mock-time-range-end"
/>
);

expect(screen.getByText('Mock workflows list')).toBeInTheDocument();
beforeEach(() => {
jest.clearAllMocks();
});

it('renders workflows list when data is loaded', async () => {
setup({});

expect(await screen.findByText('Mock workflows list')).toBeInTheDocument();
});

it('renders loading indicator while fetching', () => {
setup({ errorCase: 'no-workflows' });

expect(screen.getByRole('progressbar')).toBeInTheDocument();
});
});

function setup({ errorCase }: { errorCase?: 'no-workflows' }) {
const mockResponse: ListWorkflowsResponse =
errorCase === 'no-workflows'
? { workflows: [], nextPage: '' }
: {
workflows: Array.from({ length: 5 }, (_, i) =>
getMockWorkflowListItem({
workflowID: `mock-wf-${i}`,
runID: `mock-run-${i}`,
workflowName: `mock-name-${i}`,
status: 'WORKFLOW_EXECUTION_CLOSE_STATUS_COMPLETED',
startTime: 1684800000000,
})
),
nextPage: '',
};

render(
<DomainWorkflowsList
domain="mock-domain"
cluster="mock-cluster"
visibleColumns={[]}
timeRangeEnd="mock-time-range-end"
/>,
{
endpointsMocks: [
{
path: '/api/domains/:domain/:cluster/workflows',
httpMethod: 'GET',
mockOnce: false,
httpResolver: async () => HttpResponse.json(mockResponse),
},
] as MSWMocksHandlersProps['endpointsMocks'],
}
);
}
Loading
Loading