Skip to content

Commit db7c744

Browse files
Persist history settings based on previous use (#971)
* Access user preferences (getters & setters) via WorkflowHistoryContext, using local storage utils (last used history page view (grouped/ungrouped), event type filters) * Create wrapper component to wrap WorkflowHistory in context, and pass it to WorkflowPageTabs * Make query params for ungrouped view and history page filters optional, and handle the defaults in code instead * Disable "clearable" functionality for types filter to improve UX (otherwise, hitting "clear" would reset the filters to the default non-clear state which can be a little confusing) * Rename "Clear filters" to "Reset filters" * Reset event type filters when "Reset filters" is clicked * Add default filters to History Event Types to hide decision tasks
1 parent 285cbf2 commit db7c744

15 files changed

+669
-68
lines changed

src/components/page-filters/page-filters-fields/__tests__/page-filters-fields.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ export const mockFiltersConfig: [
6363
];
6464

6565
describe('PageFiltersFields', () => {
66-
it('should reset filters when clear filters button is pressed', async () => {
66+
it('should reset filters when reset filters button is pressed', async () => {
6767
const { mockedResetAllFilters } = setup({
6868
valuesOverrides: { paramA: 'valueA2', paramB: 'valueB2' },
6969
});
7070

71-
const clearFiltersButton = await screen.findByText('Clear filters');
71+
const clearFiltersButton = await screen.findByText('Reset filters');
7272

7373
act(() => {
7474
fireEvent.click(clearFiltersButton);

src/components/page-filters/page-filters-fields/page-filters-fields.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default function PageFiltersFields<P extends PageQueryParams>({
3535
startEnhancer={Delete}
3636
overrides={overrides.clearFiltersButton}
3737
>
38-
Clear filters
38+
Reset filters
3939
</Button>
4040
</styled.SearchFiltersContainer>
4141
);

src/views/workflow-history/__tests__/workflow-history.test.tsx

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import type workflowPageQueryParamsConfig from '@/views/workflow-page/config/wor
2323
import { completedActivityTaskEvents } from '../__fixtures__/workflow-history-activity-events';
2424
import { completedDecisionTaskEvents } from '../__fixtures__/workflow-history-decision-events';
2525
import WorkflowHistory from '../workflow-history';
26+
import { WorkflowHistoryContext } from '../workflow-history-context-provider/workflow-history-context-provider';
27+
import { type WorkflowHistoryEventFilteringType } from '../workflow-history-filters-type/workflow-history-filters-type.types';
2628

2729
jest.mock('@/hooks/use-page-query-params/use-page-query-params', () =>
2830
jest.fn(() => [{ historySelectedEventId: '1' }, jest.fn()])
@@ -110,6 +112,10 @@ jest.mock(
110112
);
111113

112114
describe('WorkflowHistory', () => {
115+
afterEach(() => {
116+
jest.restoreAllMocks();
117+
});
118+
113119
it('renders page correctly', async () => {
114120
setup({});
115121
expect(await screen.findByText('Workflow history')).toBeInTheDocument();
@@ -271,6 +277,56 @@ describe('WorkflowHistory', () => {
271277

272278
expect(screen.getByText('Workflow Actions')).toBeInTheDocument();
273279
});
280+
281+
it('should override ungrouped view preference when query param is set to true', async () => {
282+
await setup({
283+
pageQueryParamsValues: { ungroupedHistoryViewEnabled: true },
284+
ungroupedViewPreference: false,
285+
});
286+
287+
// Should show ungrouped table even though preference is false
288+
expect(await screen.findByText('Ungrouped Table')).toBeInTheDocument();
289+
expect(screen.getByText('Group')).toBeInTheDocument();
290+
});
291+
292+
it('should use preference when query param is undefined for ungrouped view', async () => {
293+
await setup({
294+
pageQueryParamsValues: { ungroupedHistoryViewEnabled: undefined },
295+
ungroupedViewPreference: true,
296+
});
297+
298+
// Should use preference (true) when query param is undefined
299+
expect(await screen.findByText('Ungrouped Table')).toBeInTheDocument();
300+
expect(screen.getByText('Group')).toBeInTheDocument();
301+
});
302+
303+
it('should override history event types preference when query param is set', async () => {
304+
const {
305+
mockSetUngroupedViewUserPreference,
306+
mockSetHistoryEventTypesUserPreference,
307+
} = await setup({
308+
pageQueryParamsValues: {
309+
historyEventTypes: ['TIMER', 'SIGNAL'],
310+
ungroupedHistoryViewEnabled: false,
311+
},
312+
historyEventTypesPreference: ['ACTIVITY', 'DECISION'],
313+
});
314+
315+
expect(mockSetUngroupedViewUserPreference).not.toHaveBeenCalled();
316+
expect(mockSetHistoryEventTypesUserPreference).not.toHaveBeenCalled();
317+
});
318+
319+
it('should use preference when history event types query param is undefined', async () => {
320+
const { mockSetHistoryEventTypesUserPreference } = await setup({
321+
pageQueryParamsValues: {
322+
historyEventTypes: undefined,
323+
ungroupedHistoryViewEnabled: false,
324+
},
325+
historyEventTypesPreference: ['TIMER', 'SIGNAL'],
326+
});
327+
328+
expect(mockSetHistoryEventTypesUserPreference).not.toHaveBeenCalled();
329+
});
274330
});
275331

276332
async function setup({
@@ -281,6 +337,8 @@ async function setup({
281337
hasNextPage,
282338
emptyEvents,
283339
withResetModal,
340+
ungroupedViewPreference,
341+
historyEventTypesPreference,
284342
}: {
285343
error?: boolean;
286344
summaryError?: boolean;
@@ -291,6 +349,8 @@ async function setup({
291349
hasNextPage?: boolean;
292350
emptyEvents?: boolean;
293351
withResetModal?: boolean;
352+
ungroupedViewPreference?: boolean;
353+
historyEventTypesPreference?: Array<WorkflowHistoryEventFilteringType>;
294354
}) {
295355
const user = userEvent.setup();
296356

@@ -304,6 +364,10 @@ async function setup({
304364
});
305365
}
306366

367+
const mockSetUngroupedViewUserPreference = jest.fn();
368+
const mockSetHistoryEventTypesUserPreference = jest.fn();
369+
const mockClearHistoryEventTypesUserPreference = jest.fn();
370+
307371
type ReqResolver = (r: GetWorkflowHistoryResponse) => void;
308372
let requestResolver: ReqResolver = () => {};
309373
let requestRejector = () => {};
@@ -313,15 +377,27 @@ async function setup({
313377

314378
const renderResult = render(
315379
<Suspense fallback={'Suspense placeholder'}>
316-
<WorkflowHistory
317-
params={{
318-
domain: 'test-domain',
319-
cluster: 'test-cluster',
320-
runId: 'test-runid',
321-
workflowId: 'test-workflowId',
322-
workflowTab: 'history',
380+
<WorkflowHistoryContext.Provider
381+
value={{
382+
ungroupedViewUserPreference: ungroupedViewPreference ?? null,
383+
setUngroupedViewUserPreference: mockSetUngroupedViewUserPreference,
384+
historyEventTypesUserPreference: historyEventTypesPreference ?? null,
385+
setHistoryEventTypesUserPreference:
386+
mockSetHistoryEventTypesUserPreference,
387+
clearHistoryEventTypesUserPreference:
388+
mockClearHistoryEventTypesUserPreference,
323389
}}
324-
/>
390+
>
391+
<WorkflowHistory
392+
params={{
393+
domain: 'test-domain',
394+
cluster: 'test-cluster',
395+
runId: 'test-runid',
396+
workflowId: 'test-workflowId',
397+
workflowTab: 'history',
398+
}}
399+
/>
400+
</WorkflowHistoryContext.Provider>
325401
</Suspense>,
326402
{
327403
endpointsMocks: [
@@ -413,5 +489,8 @@ async function setup({
413489
getRequestRejector,
414490
...renderResult,
415491
mockSetQueryParams,
492+
mockSetUngroupedViewUserPreference,
493+
mockSetHistoryEventTypesUserPreference,
494+
mockClearHistoryEventTypesUserPreference,
416495
};
417496
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { isArray } from 'lodash';
2+
import { z } from 'zod';
3+
4+
import { WORKFLOW_HISTORY_EVENT_FILTERING_TYPES } from '../workflow-history-filters-type/workflow-history-filters-type.constants';
5+
import { type WorkflowHistoryEventFilteringType } from '../workflow-history-filters-type/workflow-history-filters-type.types';
6+
import { type WorkflowHistoryUserPreferenceConfig } from '../workflow-history.types';
7+
8+
const workflowHistoryUserPreferencesConfig = {
9+
ungroupedViewEnabled: {
10+
key: 'history-ungrouped-view-enabled',
11+
schema: z
12+
.string()
13+
.refine((val) => val === 'true' || val === 'false')
14+
.transform((val) => val === 'true'),
15+
},
16+
historyEventTypes: {
17+
key: 'history-event-types',
18+
schema: z
19+
.string()
20+
.transform((arg) => {
21+
try {
22+
return JSON.parse(arg);
23+
} catch {
24+
return null;
25+
}
26+
})
27+
.refine(
28+
(val) =>
29+
isArray(val) &&
30+
val.every(
31+
(item): item is WorkflowHistoryEventFilteringType =>
32+
WORKFLOW_HISTORY_EVENT_FILTERING_TYPES.find((v) => v === item) !==
33+
undefined
34+
)
35+
),
36+
},
37+
} as const satisfies Record<string, WorkflowHistoryUserPreferenceConfig<any>>;
38+
39+
export default workflowHistoryUserPreferencesConfig;

0 commit comments

Comments
 (0)