-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* expand all toggle * update EventCollapseState to EventExpansionState
- Loading branch information
1 parent
662a7f1
commit e76050b
Showing
13 changed files
with
459 additions
and
61 deletions.
There are no files selected for viewing
126 changes: 126 additions & 0 deletions
126
src/views/workflow-history/hooks/__tests__/use-event-expansion-toggle.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import { renderHook, act } from '@/test-utils/rtl'; | ||
|
||
import useEventExpansionToggle from '../use-event-expansion-toggle'; | ||
|
||
describe('useEventExpansionToggle', () => { | ||
const mockVisibleEvents = [ | ||
{ eventId: '1' }, | ||
{ eventId: '2' }, | ||
{ eventId: '3' }, | ||
]; | ||
|
||
it('should initialize with provided initialState as true (all events expanded)', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: true, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
expect(result.current.expandedEvents).toBe(true); | ||
}); | ||
|
||
it('should initialize with provided initialState as an object with specific events expanded', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: { '1': true, '2': false }, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
expect(result.current.expandedEvents).toEqual({ '1': true, '2': false }); | ||
}); | ||
|
||
it('should toggle all events expansion state', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: { '1': true, '2': false }, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
act(() => { | ||
result.current.toggleIsExpandAllEvents(); | ||
}); | ||
expect(result.current.expandedEvents).toBe(true); | ||
|
||
act(() => { | ||
result.current.toggleIsExpandAllEvents(); | ||
}); | ||
expect(result.current.expandedEvents).toEqual({}); | ||
}); | ||
|
||
it('should expand a specific event when toggled', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: {}, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
act(() => { | ||
result.current.toggleIsEventExpanded('1'); | ||
}); | ||
expect(result.current.expandedEvents).toEqual({ '1': true }); | ||
}); | ||
|
||
it('should collapse a specific event when toggled if already expanded', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: { '1': true }, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
act(() => { | ||
result.current.toggleIsEventExpanded('1'); | ||
}); | ||
expect(result.current.expandedEvents).toEqual({}); | ||
}); | ||
|
||
it('should collapse only the toggled event when all events are expanded', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: true, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
act(() => { | ||
result.current.toggleIsEventExpanded('1'); | ||
}); | ||
|
||
expect(result.current.expandedEvents).toEqual({ | ||
'2': true, | ||
'3': true, | ||
}); | ||
}); | ||
|
||
it('should expand all events when each event has been individually expanded', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: {}, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
act(() => { | ||
result.current.toggleIsEventExpanded('1'); | ||
result.current.toggleIsEventExpanded('2'); | ||
result.current.toggleIsEventExpanded('3'); | ||
}); | ||
|
||
expect(result.current.expandedEvents).toBe(true); | ||
}); | ||
|
||
it('should check if an event is expanded using getIsEventExpanded', () => { | ||
const { result } = renderHook(() => | ||
useEventExpansionToggle({ | ||
initialState: { '1': true, '2': false }, | ||
visibleEvents: mockVisibleEvents, | ||
}) | ||
); | ||
|
||
expect(result.current.getIsEventExpanded('1')).toBe(true); | ||
expect(result.current.getIsEventExpanded('2')).toBe(false); | ||
expect(result.current.getIsEventExpanded('3')).toBe(false); | ||
}); | ||
}); |
88 changes: 88 additions & 0 deletions
88
src/views/workflow-history/hooks/use-event-expansion-toggle.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { useCallback, useState } from 'react'; | ||
|
||
import omit from 'lodash/omit'; | ||
|
||
import { type HistoryEvent } from '@/__generated__/proto-ts/uber/cadence/api/v1/HistoryEvent'; | ||
|
||
import { | ||
type EventExpansionState, | ||
type GetIsEventExpanded, | ||
type ToggleIsEventExpanded, | ||
type ToggleIsExpandAllEvents, | ||
} from './use-event-expansion-toggle.types'; | ||
|
||
export default function useEventExpansionToggle({ | ||
initialState = {}, | ||
visibleEvents, | ||
}: { | ||
initialState?: EventExpansionState; | ||
visibleEvents: Pick<HistoryEvent, 'eventId'>[]; | ||
}) { | ||
const [expandedEvents, setExpandedEvents] = | ||
useState<EventExpansionState>(initialState); | ||
|
||
const isExpandAllEvents = expandedEvents === true; | ||
const toggleIsExpandAllEvents = useCallback<ToggleIsExpandAllEvents>(() => { | ||
setExpandedEvents((prev) => { | ||
if (prev === true) { | ||
return {}; | ||
} | ||
|
||
return true; | ||
}); | ||
}, []); | ||
|
||
const getIsEventExpanded = useCallback<GetIsEventExpanded>( | ||
(eventId: string) => { | ||
if (expandedEvents === true) { | ||
return true; | ||
} | ||
|
||
return Boolean(expandedEvents[eventId]); | ||
}, | ||
[expandedEvents] | ||
); | ||
|
||
const toggleIsEventExpanded = useCallback<ToggleIsEventExpanded>( | ||
(eventId: string) => { | ||
setExpandedEvents((prev) => { | ||
let newState: Record<string, boolean>; | ||
if (prev === true) { | ||
const retainedExpansion = visibleEvents.reduce( | ||
(result, { eventId }) => { | ||
result[eventId] = true; | ||
return result; | ||
}, | ||
{} as Record<string, boolean> | ||
); | ||
newState = omit(retainedExpansion, eventId); | ||
} else { | ||
if (prev[eventId] === true) { | ||
newState = omit(prev, eventId); | ||
} else { | ||
newState = { | ||
...prev, | ||
[eventId]: true, | ||
}; | ||
} | ||
} | ||
if (visibleEvents.every(({ eventId }) => newState[eventId])) { | ||
return true; | ||
} | ||
return newState; | ||
}); | ||
}, | ||
[visibleEvents] | ||
); | ||
|
||
return { | ||
expandedEvents, | ||
setExpandedEvents, | ||
|
||
isExpandAllEvents, | ||
toggleIsExpandAllEvents, | ||
|
||
getIsEventExpanded, | ||
toggleIsEventExpanded, | ||
}; | ||
} |
9 changes: 9 additions & 0 deletions
9
src/views/workflow-history/hooks/use-event-expansion-toggle.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export type EventExpansionState = Record<string, boolean> | true; | ||
|
||
export type ToggleIsExpandAllEvents = () => void; | ||
|
||
export type GetIsEventExpanded = (eventId: string) => boolean; | ||
|
||
export type OnEventExpandToggle = (eventId: string) => void; | ||
|
||
export type ToggleIsEventExpanded = (eventId: string) => void; |
Oops, something went wrong.