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 new view for workflows in basic visibility clusters #754

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
20 changes: 20 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 @@ -2,6 +2,8 @@ import { type PageQueryParam } from '@/hooks/use-page-query-params/use-page-quer
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 { type WorkflowStatusBasicVisibility } from '@/views/domain-workflows-basic/domain-workflows-basic-filters-status/domain-workflows-basic-filters-status.types';
import isWorkflowStatusBasicVisibility from '@/views/domain-workflows-basic/domain-workflows-basic-filters-status/helpers/is-workflow-status-basic-visibility';
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';

Expand All @@ -16,6 +18,10 @@ const domainPageQueryParamsConfig: [
PageQueryParam<'sortOrder', SortOrder>,
// Query input
PageQueryParam<'query', string>,
// Basic Visibility inputs
PageQueryParam<'workflowId', string>,
PageQueryParam<'workflowType', string>,
PageQueryParam<'statusBasic', WorkflowStatusBasicVisibility | undefined>,
] = [
{
key: 'inputType',
Expand Down Expand Up @@ -57,6 +63,20 @@ const domainPageQueryParamsConfig: [
key: 'query',
defaultValue: '',
},
{
key: 'workflowId',
defaultValue: '',
},
{
key: 'workflowType',
defaultValue: '',
},
{
key: 'statusBasic',
queryParamKey: 'status',
parseValue: (value: string) =>
isWorkflowStatusBasicVisibility(value) ? value : undefined,
},
] as const;

export default domainPageQueryParamsConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
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 { type DomainWorkflowsFiltersDatesValue } from '@/views/domain-workflows/domain-workflows-filters-dates/domain-workflows-filters-dates.types';

import DomainWorkflowsBasicFiltersStatus from '../domain-workflows-basic-filters-status/domain-workflows-basic-filters-status';
import { type DomainWorkflowsBasicFiltersStatusValue } from '../domain-workflows-basic-filters-status/domain-workflows-basic-filters-status.types';

const domainWorkflowsBasicFiltersConfig: [
PageFilterConfig<
typeof domainPageQueryParamsConfig,
DomainWorkflowsBasicFiltersStatusValue
>,
PageFilterConfig<
typeof domainPageQueryParamsConfig,
DomainWorkflowsFiltersDatesValue
>,
] = [
{
id: 'status',
getValue: (v) => ({ statusBasic: v.statusBasic }),
formatValue: (v) => v,
component: DomainWorkflowsBasicFiltersStatus,
},
{
id: 'dates',
getValue: (v) => ({
timeRangeStart: v.timeRangeStart,
timeRangeEnd: v.timeRangeEnd,
}),
formatValue: (v) => ({
timeRangeStart: v.timeRangeStart?.toISOString(),
timeRangeEnd: v.timeRangeEnd?.toISOString(),
}),
component: DomainWorkflowsFiltersDates,
},
] as const;

export default domainWorkflowsBasicFiltersConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const DOMAIN_WORKFLOWS_BASIC_SEARCH_DEBOUNCE_MS = 250;

export default DOMAIN_WORKFLOWS_BASIC_SEARCH_DEBOUNCE_MS;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';

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

import { mockDomainWorkflowsQueryParamsValues } from '@/views/domain-workflows/__fixtures__/domain-workflows-query-params';

import DomainWorkflowsBasicFiltersStatus from '../domain-workflows-basic-filters-status';
import { WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY } from '../domain-workflows-basic-filters-status.constants';
import { type DomainWorkflowsBasicFiltersStatusValue } from '../domain-workflows-basic-filters-status.types';

describe(DomainWorkflowsBasicFiltersStatus.name, () => {
it('renders without errors', () => {
setup({});
expect(screen.getByRole('combobox')).toBeInTheDocument();
});

it('displays all the options in the select component', () => {
setup({});
const selectFilter = screen.getByRole('combobox');
act(() => {
fireEvent.click(selectFilter);
});
Object.entries(WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY).forEach(
([_, value]) => expect(screen.getByText(value)).toBeInTheDocument()
);
});

it('calls the setQueryParams function when an option is selected', () => {
const { mockSetValue } = setup({});
const selectFilter = screen.getByRole('combobox');
act(() => {
fireEvent.click(selectFilter);
});
const runningOption = screen.getByText('Closed');
act(() => {
fireEvent.click(runningOption);
});
expect(mockSetValue).toHaveBeenCalledWith({
statusBasic: 'ALL_CLOSED',
});
});

it('calls the setQueryParams function when the filter is cleared', () => {
const { mockSetValue } = setup({
overrides: {
statusBasic: 'WORKFLOW_EXECUTION_CLOSE_STATUS_FAILED',
},
});
const clearButton = screen.getByLabelText('Clear value');
act(() => {
fireEvent.click(clearButton);
});
expect(mockSetValue).toHaveBeenCalledWith({ statusBasic: undefined });
});
});

function setup({
overrides,
}: {
overrides?: DomainWorkflowsBasicFiltersStatusValue;
}) {
const mockSetValue = jest.fn();
render(
<DomainWorkflowsBasicFiltersStatus
value={{
statusBasic: mockDomainWorkflowsQueryParamsValues.statusBasic,
...overrides,
}}
setValue={mockSetValue}
/>
);

return { mockSetValue };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { WORKFLOW_STATUS_NAMES } from '@/views/shared/workflow-status-tag/workflow-status-tag.constants';

import { type WorkflowStatusBasicVisibility } from './domain-workflows-basic-filters-status.types';

export const WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY = {
ALL_CLOSED: 'Closed',
...WORKFLOW_STATUS_NAMES,
} as const satisfies Record<WorkflowStatusBasicVisibility, string>;

export const WORKFLOW_STATUS_OPTIONS_BASIC_VISIBILITY = Object.entries(
WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY
).map(([key, value]) => ({
id: key,
label: value,
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type Theme } from 'baseui';
import type { FormControlOverrides } from 'baseui/form-control/types';
import { type StyleObject } from 'styletron-react';

export const overrides = {
selectFormControl: {
Label: {
style: ({ $theme }: { $theme: Theme }): StyleObject => ({
...$theme.typography.LabelXSmall,
}),
},
ControlContainer: {
style: (): StyleObject => ({
margin: '0px',
}),
},
} satisfies FormControlOverrides,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';
import React from 'react';

import { FormControl } from 'baseui/form-control';
import { Select, SIZE } from 'baseui/select';

import { type PageFilterComponentProps } from '@/components/page-filters/page-filters.types';
import { type WorkflowStatus } from '@/views/shared/workflow-status-tag/workflow-status-tag.types';

import { WORKFLOW_STATUS_OPTIONS_BASIC_VISIBILITY } from './domain-workflows-basic-filters-status.constants';
import { overrides } from './domain-workflows-basic-filters-status.styles';
import { type DomainWorkflowsBasicFiltersStatusValue } from './domain-workflows-basic-filters-status.types';

export default function DomainWorkflowsBasicFiltersStatus({
value,
setValue,
}: PageFilterComponentProps<DomainWorkflowsBasicFiltersStatusValue>) {
const statusOptionValue = WORKFLOW_STATUS_OPTIONS_BASIC_VISIBILITY.filter(
(option) => option.id === value.statusBasic
);

return (
<FormControl label="Status" overrides={overrides.selectFormControl}>
<Select
size={SIZE.compact}
value={statusOptionValue}
options={WORKFLOW_STATUS_OPTIONS_BASIC_VISIBILITY}
onChange={(params) =>
setValue({
statusBasic: WORKFLOW_STATUS_OPTIONS_BASIC_VISIBILITY.find(
(opt) => opt.id === params.value[0]?.id
)
? (String(params.value[0]?.id) as WorkflowStatus)
: undefined,
})
}
placeholder="Show all statuses"
/>
</FormControl>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type WorkflowStatus } from '@/views/shared/workflow-status-tag/workflow-status-tag.types';

export type WorkflowStatusBasicVisibility = WorkflowStatus | 'ALL_CLOSED';

export type DomainWorkflowsBasicFiltersStatusValue = {
statusBasic: WorkflowStatusBasicVisibility | undefined;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY } from '../../domain-workflows-basic-filters-status.constants';
import isWorkflowStatusBasicVisibility from '../is-workflow-status-basic-visibility';

describe(isWorkflowStatusBasicVisibility.name, () => {
it('should return true for valid basic visibility workflow status', () => {
Object.keys(WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY).forEach((key) => {
expect(isWorkflowStatusBasicVisibility(key)).toBe(true);
});
});

it('should return false for invalid basic visibility workflow status', () => {
expect(isWorkflowStatusBasicVisibility('InvalidStatus')).toBe(false);
expect(isWorkflowStatusBasicVisibility(123)).toBe(false);
expect(isWorkflowStatusBasicVisibility(null)).toBe(false);
expect(isWorkflowStatusBasicVisibility(undefined)).toBe(false);
expect(isWorkflowStatusBasicVisibility({})).toBe(false);
expect(isWorkflowStatusBasicVisibility([])).toBe(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY } from '../domain-workflows-basic-filters-status.constants';
import { type WorkflowStatusBasicVisibility } from '../domain-workflows-basic-filters-status.types';

export default function isWorkflowStatusBasicVisibility(
value: any
): value is WorkflowStatusBasicVisibility {
return value in WORKFLOW_STATUS_NAMES_BASIC_VISIBILITY;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { styled as createStyled, type Theme } from 'baseui';

export const styled = {
HeaderContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
marginTop: $theme.sizing.scale950,
marginBottom: $theme.sizing.scale900,
})),
InputContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: $theme.sizing.scale500,
marginBottom: $theme.sizing.scale500,
[$theme.mediaQuery.medium]: {
flexDirection: 'row',
},
})),
SearchContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
gap: $theme.sizing.scale500,
[$theme.mediaQuery.medium]: {
flexDirection: 'row',
},
})),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client';
import { useState } from 'react';

import usePageFilters from '@/components/page-filters/hooks/use-page-filters';
import PageFiltersFields from '@/components/page-filters/page-filters-fields/page-filters-fields';
import PageFiltersSearch from '@/components/page-filters/page-filters-search/page-filters-search';
import PageFiltersToggle from '@/components/page-filters/page-filters-toggle/page-filters-toggle';
import domainPageQueryParamsConfig from '@/views/domain-page/config/domain-page-query-params.config';

import domainWorkflowsBasicFiltersConfig from '../config/domain-workflows-basic-filters.config';
import DOMAIN_WORKFLOWS_BASIC_SEARCH_DEBOUNCE_MS from '../config/domain-workflows-basic-search-debounce-ms.config';

import { styled } from './domain-workflows-basic-filters.styles';

export default function DomainWorkflowsBasicFilters() {
const [areFiltersShown, setAreFiltersShown] = useState(false);

const { resetAllFilters, activeFiltersCount, queryParams, setQueryParams } =
usePageFilters({
pageFiltersConfig: domainWorkflowsBasicFiltersConfig,
pageQueryParamsConfig: domainPageQueryParamsConfig,
});

return (
<styled.HeaderContainer>
<styled.InputContainer>
<styled.SearchContainer>
<PageFiltersSearch
pageQueryParamsConfig={domainPageQueryParamsConfig}
searchQueryParamKey="workflowId"
searchPlaceholder="Workflow ID"
inputDebounceDurationMs={DOMAIN_WORKFLOWS_BASIC_SEARCH_DEBOUNCE_MS}
/>
<PageFiltersSearch
pageQueryParamsConfig={domainPageQueryParamsConfig}
searchQueryParamKey="workflowType"
searchPlaceholder="Workflow Type"
inputDebounceDurationMs={DOMAIN_WORKFLOWS_BASIC_SEARCH_DEBOUNCE_MS}
/>
<PageFiltersToggle
isActive={areFiltersShown}
onClick={() => {
setAreFiltersShown((value) => !value);
}}
activeFiltersCount={activeFiltersCount}
/>
</styled.SearchContainer>
</styled.InputContainer>
{areFiltersShown && (
<PageFiltersFields
pageFiltersConfig={domainWorkflowsBasicFiltersConfig}
resetAllFilters={resetAllFilters}
queryParams={queryParams}
setQueryParams={setQueryParams}
/>
)}
</styled.HeaderContainer>
);
}
14 changes: 14 additions & 0 deletions src/views/domain-workflows-basic/domain-workflows-basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

import { type DomainPageTabContentProps } from '@/views/domain-page/domain-page-content/domain-page-content.types';

import DomainWorkflowsBasicFilters from './domain-workflows-basic-filters/domain-workflows-basic-filters';

export default function DomainWorkflowsBasic(props: DomainPageTabContentProps) {
return (
<>
<DomainWorkflowsBasicFilters />
{/* <DomainWorkflowsBasicTable domain={props.domain} cluster={props.cluster} /> */}
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const mockDomainWorkflowsQueryParamsValues: PageQueryParamValues<
sortColumn: 'startTime',
sortOrder: 'DESC',
query: '',
workflowId: '',
workflowType: '',
statusBasic: undefined,
};

export const mockDateOverrides = {
Expand Down
Loading