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

Add domain page archival tab #770

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/views/domain-page/__fixtures__/domain-page-query-params.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { type PageQueryParamValues } from '@/hooks/use-page-query-params/use-page-query-params.types';
import type domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config';

export const mockDomainPageQueryParamsValues: PageQueryParamValues<
typeof domainPageQueryParamsConfig
> = {
export const mockDomainPageQueryParamsValues = {
adhityamamallan marked this conversation as resolved.
Show resolved Hide resolved
inputType: 'search',
search: '',
status: undefined,
Expand All @@ -15,7 +13,15 @@ export const mockDomainPageQueryParamsValues: PageQueryParamValues<
workflowId: '',
workflowType: '',
statusBasic: undefined,
};
inputTypeArchival: 'search',
searchArchival: '',
statusArchival: undefined,
timeRangeStartArchival: undefined,
timeRangeEndArchival: undefined,
sortColumnArchival: 'startTime',
sortOrderArchival: 'DESC',
queryArchival: '',
} as const satisfies PageQueryParamValues<typeof domainPageQueryParamsConfig>;

export const mockDateOverrides = {
timeRangeStart: new Date(1684800000000), // 23 May 2023 00:00
Expand Down
52 changes: 52 additions & 0 deletions src/views/domain-page/config/domain-page-query-params.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ const domainPageQueryParamsConfig: [
PageQueryParam<'workflowId', string>,
PageQueryParam<'workflowType', string>,
PageQueryParam<'statusBasic', WorkflowStatusBasicVisibility | undefined>,
// Archival inputs
PageQueryParam<'inputTypeArchival', WorkflowsHeaderInputType>,
PageQueryParam<'searchArchival', string>,
PageQueryParam<'statusArchival', WorkflowStatus | undefined>,
PageQueryParam<'timeRangeStartArchival', Date | undefined>,
PageQueryParam<'timeRangeEndArchival', Date | undefined>,
PageQueryParam<'sortColumnArchival', string>,
PageQueryParam<'sortOrderArchival', SortOrder>,
PageQueryParam<'queryArchival', string>,
] = [
{
key: 'inputType',
Expand Down Expand Up @@ -77,6 +86,49 @@ const domainPageQueryParamsConfig: [
parseValue: (value: string) =>
isWorkflowStatusBasicVisibility(value) ? value : undefined,
},
{
key: 'inputTypeArchival',
queryParamKey: 'ainput',
defaultValue: 'search',
parseValue: (value: string) => (value === 'query' ? 'query' : 'search'),
},
{
key: 'searchArchival',
queryParamKey: 'asearch',
defaultValue: '',
},
{
key: 'statusArchival',
queryParamKey: 'astatus',
parseValue: (value: string) =>
isWorkflowStatus(value) ? value : undefined,
},
{
key: 'timeRangeStartArchival',
queryParamKey: 'astart',
parseValue: parseDateQueryParam,
},
{
key: 'timeRangeEndArchival',
queryParamKey: 'aend',
parseValue: parseDateQueryParam,
},
{
key: 'sortColumnArchival',
queryParamKey: 'acolumn',
defaultValue: 'StartTime',
},
{
key: 'sortOrderArchival',
queryParamKey: 'aorder',
defaultValue: 'DESC',
parseValue: (value: string) => (value === 'ASC' ? 'ASC' : 'DESC'),
},
{
key: 'queryArchival',
queryParamKey: 'aquery',
defaultValue: '',
},
] as const;

export default domainPageQueryParamsConfig;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DomainWorkflows from '@/views/domain-workflows/domain-workflows';
import DomainWorkflowsArchival from '@/views/domain-workflows-archival/domain-workflows-archival';

import type { DomainPageTabsContentConfig } from '../domain-page-content/domain-page-content.types';
import DomainPageMetadata from '../domain-page-metadata/domain-page-metadata';
Expand All @@ -8,6 +9,7 @@ const domainPageTabsContentConfig = {
workflows: DomainWorkflows,
metadata: DomainPageMetadata,
settings: DomainPageSettings,
archival: DomainWorkflowsArchival,
} as const satisfies DomainPageTabsContentConfig;

export default domainPageTabsContentConfig;
4 changes: 4 additions & 0 deletions src/views/domain-page/config/domain-page-tabs-error.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const domainPageTabsErrorConfig: DomainPageTabsErrorConfig = {
message: 'Failed to load settings',
actions: [{ kind: 'retry', label: 'Retry' }],
}),
archival: () => ({
message: 'Failed to load archival workflows',
actions: [{ kind: 'retry', label: 'Retry' }],
}),
} as const;

export default domainPageTabsErrorConfig;
7 changes: 6 additions & 1 deletion src/views/domain-page/config/domain-page-tabs.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MdListAlt, MdSettings, MdSort } from 'react-icons/md';
import { MdArchive, MdListAlt, MdSettings, MdSort } from 'react-icons/md';

import type { DomainPageTabs } from '../domain-page-tabs/domain-page-tabs.types';

Expand All @@ -18,6 +18,11 @@ const domainPageTabsConfig = [
title: 'Settings',
artwork: MdSettings,
},
{
key: 'archival',
title: 'Archival',
artwork: MdArchive,
},
] as const satisfies DomainPageTabs;

export default domainPageTabsConfig;
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jest.mock(
workflows: (props) => <MockedTabContent {...props} tab="workflows" />,
metadata: (props) => <MockedTabContent {...props} tab="metadata" />,
settings: (props) => <MockedTabContent {...props} tab="settings" />,
archival: (props) => <MockedTabContent {...props} tab="archival" />,
}) as const satisfies DomainPageTabsContentConfig
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jest.mock(
settings: () => ({
message: 'settings error',
}),
archival: () => ({
message: 'archival error',
}),
}) as const satisfies DomainPageTabsErrorConfig
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Suspense } from 'react';

import { HttpResponse } from 'msw';

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

import { type DescribeDomainResponse } from '@/route-handlers/describe-domain/describe-domain.types';
import { mockDomainInfo } from '@/views/domain-page/__fixtures__/domain-info';

import DomainWorkflowsArchival from '../domain-workflows-archival';

jest.mock(
'../domain-workflows-archival-header/domain-workflows-archival-header',
() => jest.fn(() => <div>Mock archival header</div>)
);

describe(DomainWorkflowsArchival.name, () => {
it('renders without error and shows archival disabled page', async () => {
await setup({});

expect(await screen.findByText('Archival disabled')).toBeInTheDocument();
});

it('renders without error and shows archival content', async () => {
await setup({ isArchivalEnabled: true });

expect(await screen.findByText('Mock archival header')).toBeInTheDocument();
});

it('does not render if the initial call fails', async () => {
let renderErrorMessage;
try {
await act(async () => {
await setup({ isError: true });
});
} catch (error) {
if (error instanceof Error) {
renderErrorMessage = error.message;
}
}

expect(renderErrorMessage).toEqual('Failed to fetch domain information');
});
});

async function setup({
isArchivalEnabled,
isError,
}: {
isArchivalEnabled?: boolean;
isError?: boolean;
}) {
render(
<Suspense>
<DomainWorkflowsArchival domain="mock-domain" cluster="mock-cluster" />
</Suspense>,
{
endpointsMocks: [
{
path: '/api/domains/:domain/:cluster',
httpMethod: 'GET',
...(isError
? {
httpResolver: () => {
return HttpResponse.json(
{ message: 'Failed to fetch domain information' },
{ status: 500 }
);
},
}
: {
jsonResponse: {
...mockDomainInfo,
...(isArchivalEnabled
? {
historyArchivalStatus: 'ARCHIVAL_STATUS_ENABLED',
visibilityArchivalStatus: 'ARCHIVAL_STATUS_ENABLED',
}
: {}),
} satisfies DescribeDomainResponse,
}),
},
],
}
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createElement } from 'react';

import { type PageFilterConfig } from '@/components/page-filters/page-filters.types';
import type domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config';
import DomainWorkflowsFiltersDates from '@/views/domain-workflows/domain-workflows-filters-dates/domain-workflows-filters-dates';
import DomainWorkflowsFiltersStatus from '@/views/domain-workflows/domain-workflows-filters-status/domain-workflows-filters-status';
import { type WorkflowStatus } from '@/views/shared/workflow-status-tag/workflow-status-tag.types';

const domainWorkflowsArchivalFiltersConfig: [
PageFilterConfig<
typeof domainPageQueryParamsConfig,
{ statusArchival: WorkflowStatus | undefined }
>,
PageFilterConfig<
typeof domainPageQueryParamsConfig,
{
timeRangeStartArchival: Date | undefined;
timeRangeEndArchival: Date | undefined;
}
>,
] = [
{
id: 'status',
getValue: (v) => v,
formatValue: (v) => v,
component: ({ value, setValue }) =>
createElement(DomainWorkflowsFiltersStatus, {
value: {
status: value.statusArchival,
},
setValue: ({ status }) => {
setValue({
statusArchival: status,
});
},
}),
},
{
id: 'dates',
getValue: (v) => v,
formatValue: (v) => ({
timeRangeStartArchival: v.timeRangeStartArchival?.toISOString(),
timeRangeEndArchival: v.timeRangeEndArchival?.toISOString(),
}),
component: ({ value, setValue }) =>
createElement(DomainWorkflowsFiltersDates, {
value: {
timeRangeStart: value.timeRangeStartArchival,
timeRangeEnd: value.timeRangeEndArchival,
},
setValue: ({ timeRangeStart, timeRangeEnd }) => {
setValue({
timeRangeStartArchival: timeRangeStart,
timeRangeEndArchival: timeRangeEnd,
});
},
}),
},
] as const;

export default domainWorkflowsArchivalFiltersConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const DOMAIN_WORKFLOWS_ARCHIVAL_PAGE_SIZE = 10;

export default DOMAIN_WORKFLOWS_ARCHIVAL_PAGE_SIZE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { render, screen } from '@/test-utils/rtl';

import { mockDomainPageQueryParamsValues } from '../../../domain-page/__fixtures__/domain-page-query-params';
import DomainWorkflowsArchivalHeader from '../domain-workflows-archival-header';

jest.useFakeTimers().setSystemTime(new Date('2023-05-25'));

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

jest.mock('@/views/shared/workflows-header/workflows-header', () =>
jest.fn(() => <div>Workflows Header</div>)
);

jest.mock('@/views/shared/hooks/use-list-workflows', () =>
jest.fn(() => ({
refetch: jest.fn(),
isFetching: false,
}))
);

describe(DomainWorkflowsArchivalHeader.name, () => {
it('renders workflows header', async () => {
render(
<DomainWorkflowsArchivalHeader
domain="mock_domain"
cluster="mock_cluster"
/>
);

expect(screen.getByText('Workflows Header')).toBeInTheDocument();
});

it('pre-fills default start and end dates if not present in query params', async () => {
render(
<DomainWorkflowsArchivalHeader
domain="mock_domain"
cluster="mock_cluster"
/>
);

expect(mockSetQueryParams).toHaveBeenCalledWith({
timeRangeStartArchival: '2023-05-15T00:00:00.000Z',
timeRangeEndArchival: '2023-05-25T00:00:00.000Z',
});
});
});
Loading
Loading