-
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.
* group history events * timeline load more * Initialize Queries UI (#665) * Init commit * more commit * Add more changes * Add tests * clean up code * Init queries UI * Add unit tests * Fix unsaved merge conflict * Fix tests and merge conflicts again * update snapshot * Fix snapshot * Reorder some props in tile * resolve comments * Fix tests * Fix tests and make design responsive * Remove snapshots * Update tests for tile input * get workflow rest api * add type to decaode url param * timeline group component * add animations * lint fix --------- Co-authored-by: Adhitya Mamallan <[email protected]>
- Loading branch information
1 parent
02e913f
commit b693a19
Showing
7 changed files
with
255 additions
and
8 deletions.
There are no files selected for viewing
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
19 changes: 19 additions & 0 deletions
19
src/route-handlers/get-workflow-history/schemas/get-workflow-history-query-params-schema.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,19 @@ | ||
import { z } from 'zod'; | ||
|
||
const getWorkflowHistoryQueryParamSchema = z.object({ | ||
pageSize: z | ||
.string() | ||
.transform((val) => parseInt(val, 10)) | ||
.pipe( | ||
z.number().positive({ message: 'Page size must be a positive integer' }) | ||
), | ||
nextPage: z.string().optional(), | ||
waitForNewEvent: z | ||
.string() | ||
.toLowerCase() | ||
.transform((x) => x === 'true') | ||
.pipe(z.boolean()) | ||
.optional(), | ||
}); | ||
|
||
export default getWorkflowHistoryQueryParamSchema; |
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 |
---|---|---|
@@ -1,10 +1,10 @@ | ||
const decodeUrlParams = (params: { [k: string]: string }) => { | ||
export default function decodeUrlParams<Params extends { [k: string]: string }>( | ||
params: Params | ||
): Params { | ||
return Object.fromEntries( | ||
Object.entries(params).map(([key, value]) => [ | ||
key, | ||
decodeURIComponent(value), | ||
]) | ||
); | ||
}; | ||
|
||
export default decodeUrlParams; | ||
) as Params; // shrink object type to include only keys from params | ||
} |
100 changes: 100 additions & 0 deletions
100
...istory/workflow-history-timeline-group/__tests__/workflow-history-timeline-group.test.tsx
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,100 @@ | ||
import { render, screen } from '@/test-utils/rtl'; | ||
|
||
import { startWorkflowExecutionEvent } from '../../__fixtures__/workflow-history-single-events'; | ||
import type WorkflowHistoryEventStatusBadge from '../../workflow-history-event-status-badge/workflow-history-event-status-badge'; | ||
import type WorkflowHistoryEventsCard from '../../workflow-history-events-card/workflow-history-events-card'; | ||
import WorkflowHistoryTimelineGroup from '../workflow-history-timeline-group'; | ||
import { type styled } from '../workflow-history-timeline-group.styles'; | ||
import type { Props } from '../workflow-history-timeline-group.types'; | ||
|
||
jest.mock<typeof WorkflowHistoryEventStatusBadge>( | ||
'../../workflow-history-event-status-badge/workflow-history-event-status-badge', | ||
() => jest.fn((props) => <div>{props.status}</div>) | ||
); | ||
|
||
jest.mock<typeof WorkflowHistoryEventsCard>( | ||
'../../workflow-history-events-card/workflow-history-events-card', | ||
() => jest.fn(() => <div>Events Card</div>) | ||
); | ||
|
||
jest.mock('../workflow-history-timeline-group.styles', () => { | ||
const actual = jest.requireActual( | ||
'../workflow-history-timeline-group.styles' | ||
); | ||
return { | ||
...actual, | ||
styled: { | ||
...actual.styled, | ||
VerticalDivider: ({ $hidden }: { $hidden?: boolean }) => ( | ||
<div>Divider {$hidden ? 'hidden' : 'visible'}</div> | ||
), | ||
} satisfies typeof styled, | ||
}; | ||
}); | ||
|
||
describe('WorkflowHistoryTimelineGroup', () => { | ||
it('renders group label correctly', () => { | ||
setup({ label: 'test label' }); | ||
|
||
expect(screen.getByText('test label')).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders group status correctly', () => { | ||
setup({ status: 'CANCELED' }); | ||
|
||
expect(screen.getByText('CANCELED')).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders group timeLabel correctly', () => { | ||
setup({ timeLabel: 'Started at 19 Sep, 11:37:12 GMT+2' }); | ||
|
||
expect( | ||
screen.getByText('Started at 19 Sep, 11:37:12 GMT+2') | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders events card', () => { | ||
setup({}); | ||
|
||
expect(screen.getByText('Events Card')).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders divider when isLastEvent is false', () => { | ||
setup({ isLastEvent: false }); | ||
expect(screen.getByText('Divider visible')).toBeInTheDocument(); | ||
}); | ||
|
||
it('hides divider when isLastEvent is true', () => { | ||
setup({ isLastEvent: true }); | ||
expect(screen.getByText('Divider hidden')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
function setup({ | ||
label = 'Workflow Started', | ||
hasMissingEvents = false, | ||
eventsMetadata = [ | ||
{ | ||
label: 'Started', | ||
status: 'COMPLETED', | ||
timeMs: 1726652232190.7927, | ||
timeLabel: 'Started at 18 Sep, 11:37:12 GMT+2', | ||
}, | ||
], | ||
events = [startWorkflowExecutionEvent], | ||
status = 'COMPLETED', | ||
timeLabel = 'Started at 18 Sep, 11:37:12 GMT+2', | ||
isLastEvent = false, | ||
}: Partial<Props>) { | ||
return render( | ||
<WorkflowHistoryTimelineGroup | ||
events={events} | ||
eventsMetadata={eventsMetadata} | ||
isLastEvent={isLastEvent} | ||
label={label} | ||
timeLabel={timeLabel} | ||
hasMissingEvents={hasMissingEvents} | ||
status={status} | ||
/> | ||
); | ||
} |
50 changes: 50 additions & 0 deletions
50
...orkflow-history/workflow-history-timeline-group/workflow-history-timeline-group.styles.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,50 @@ | ||
import { styled as createStyled, type Theme } from 'baseui'; | ||
|
||
import type { | ||
StyletronCSSObject, | ||
StyletronCSSObjectOf, | ||
} from '@/hooks/use-styletron-classes'; | ||
|
||
export const styled = { | ||
VerticalDivider: createStyled<'div', { $hidden?: boolean }>( | ||
'div', | ||
({ $theme, $hidden }: { $theme: Theme; $hidden?: boolean }) => ({ | ||
...$theme.borders.border200, | ||
borderColor: $theme.colors.borderOpaque, | ||
height: $hidden ? 0 : '100%', | ||
marginLeft: $theme.sizing.scale500, | ||
transition: `height 0.2s ${$theme.animation.easeOutCurve}`, | ||
}) | ||
), | ||
}; | ||
|
||
const cssStylesObj = { | ||
groupContainer: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
}, | ||
timelineEventHeader: { | ||
display: 'flex', | ||
alignItems: 'center', | ||
gap: '16px', | ||
padding: '12px 0', | ||
}, | ||
timelineEventsLabel: (theme) => ({ | ||
...theme.typography.LabelLarge, | ||
whiteSpace: 'nowrap', | ||
textOverflow: 'ellipsis', | ||
overflow: 'hidden', | ||
}), | ||
timelineEventsTime: (theme) => ({ | ||
...theme.typography.LabelXSmall, | ||
color: theme.colors.contentTertiary, | ||
wordBreak: 'break-word', | ||
}), | ||
timelineEventCardContainer: { | ||
display: 'flex', | ||
gap: '28px', | ||
}, | ||
} satisfies StyletronCSSObject; | ||
|
||
export const cssStyles: StyletronCSSObjectOf<typeof cssStylesObj> = | ||
cssStylesObj; |
42 changes: 42 additions & 0 deletions
42
...iews/workflow-history/workflow-history-timeline-group/workflow-history-timeline-group.tsx
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,42 @@ | ||
'use client'; | ||
import React from 'react'; | ||
|
||
import useStyletronClasses from '@/hooks/use-styletron-classes'; | ||
|
||
import WorkflowHistoryEventStatusBadge from '../workflow-history-event-status-badge/workflow-history-event-status-badge'; | ||
import WorkflowHistoryEventsCard from '../workflow-history-events-card/workflow-history-events-card'; | ||
|
||
import { cssStyles, styled } from './workflow-history-timeline-group.styles'; | ||
import { type Props } from './workflow-history-timeline-group.types'; | ||
|
||
export default function WorkflowHistoryTimelineGroup({ | ||
status, | ||
label, | ||
timeLabel, | ||
events, | ||
isLastEvent, | ||
eventsMetadata, | ||
hasMissingEvents, | ||
}: Props) { | ||
const { cls } = useStyletronClasses(cssStyles); | ||
|
||
return ( | ||
<div className={cls.groupContainer}> | ||
<div className={cls.timelineEventHeader}> | ||
<WorkflowHistoryEventStatusBadge status={status} size="medium" /> | ||
<div className={cls.timelineEventsLabel}>{label}</div> | ||
<div suppressHydrationWarning className={cls.timelineEventsTime}> | ||
{timeLabel} | ||
</div> | ||
</div> | ||
<div className={cls.timelineEventCardContainer}> | ||
<styled.VerticalDivider $hidden={isLastEvent} /> | ||
<WorkflowHistoryEventsCard | ||
events={events} | ||
eventsMetadata={eventsMetadata} | ||
showEventPlaceholder={hasMissingEvents} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
13 changes: 13 additions & 0 deletions
13
...workflow-history/workflow-history-timeline-group/workflow-history-timeline-group.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,13 @@ | ||
import type { HistoryEventsGroup } from '../workflow-history.types'; | ||
|
||
export type Props = Pick< | ||
HistoryEventsGroup, | ||
| 'events' | ||
| 'eventsMetadata' | ||
| 'timeLabel' | ||
| 'label' | ||
| 'hasMissingEvents' | ||
| 'status' | ||
> & { | ||
isLastEvent: boolean; | ||
}; |