Skip to content

Commit

Permalink
jobs_v2: linkify tag, strand, singleton in jobs list
Browse files Browse the repository at this point in the history
test plan:
 - click a tag, strand, or singleton in the jobs list
 - it should refilter the jobs list to show only matching jobs,
   changing the "tag" / "strand" / "singleton" selection at the
   top of the screen if needed

flag=jobs_v2
closes DE-1131

Change-Id: I9197107bb8b164afd0f49fad0b7899aa5ec7f2a8
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/289615
Tested-by: Service Cloud Jenkins <[email protected]>
Reviewed-by: Isaac Moore <[email protected]>
QA-Review: Jeremy Stanley <[email protected]>
Product-Review: Jeremy Stanley <[email protected]>
  • Loading branch information
jstanley0 committed Apr 15, 2022
1 parent 8533986 commit bdd70f9
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 9 deletions.
43 changes: 42 additions & 1 deletion ui/features/jobs_v2/react/__tests__/jobs_v2.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('JobsIndex', () => {
)
})

it('filters the job list', async () => {
it('filters the job list via the groups table', async () => {
const {getByText} = render(<JobsIndex />)
await act(async () => jest.runAllTimers())
fireEvent.click(getByText('fake_job_list_group_value'))
Expand All @@ -136,6 +136,47 @@ describe('JobsIndex', () => {
)
})

it('filters by clicking a tag in the jobs list', async () => {
const {getByRole} = render(<JobsIndex />)
await act(async () => jest.runAllTimers())
fireEvent.click(getByRole('button', {name: 'fake_job_list_tag_value'}))
expect(window.location.search).toMatch(/group_text=fake_job_list_tag_value/)
expect(doFetchApi).toHaveBeenCalledWith(
expect.objectContaining({
path: '/api/v1/jobs2/running',
params: expect.objectContaining({tag: 'fake_job_list_tag_value'})
})
)
})

it('filters by clicking a strand in the jobs list', async () => {
const {getByRole} = render(<JobsIndex />)
await act(async () => jest.runAllTimers())
fireEvent.click(getByRole('button', {name: 'fake_job_list_strand_value'}))
expect(window.location.search).toMatch(/group_type=strand/)
expect(window.location.search).toMatch(/group_text=fake_job_list_strand_value/)
expect(doFetchApi).toHaveBeenCalledWith(
expect.objectContaining({
path: '/api/v1/jobs2/running',
params: expect.objectContaining({strand: 'fake_job_list_strand_value'})
})
)
})

it('filters by clicking a singleton in the jobs list', async () => {
const {getByRole} = render(<JobsIndex />)
await act(async () => jest.runAllTimers())
fireEvent.click(getByRole('button', {name: 'fake_job_list_singleton_value'}))
expect(window.location.search).toMatch(/group_type=singleton/)
expect(window.location.search).toMatch(/group_text=fake_job_list_singleton_value/)
expect(doFetchApi).toHaveBeenCalledWith(
expect.objectContaining({
path: '/api/v1/jobs2/running',
params: expect.objectContaining({singleton: 'fake_job_list_singleton_value'})
})
)
})

it('shows job details', async () => {
const {getByText} = render(<JobsIndex />)
await act(async () => jest.runAllTimers())
Expand Down
23 changes: 15 additions & 8 deletions ui/features/jobs_v2/react/components/JobsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import SortColumnHeader from './SortColumnHeader'

const I18n = useI18nScope('jobs_v2')

function copyToClipboardTruncatedValue(value) {
function copyToClipboardTruncatedValue(value, onClick) {
const copyToClipboardAction = () => {
navigator.clipboard.writeText(value)
}
Expand All @@ -45,9 +45,11 @@ function copyToClipboardTruncatedValue(value) {
<div className="copy-button-container">
<Flex>
<Flex.Item shouldGrow shouldShrink>
<TruncateText>
<Tooltip renderTip={value}>{value}</Tooltip>
</TruncateText>
<Tooltip renderTip={value}>
<Link onClick={() => onClick(value)}>
<TruncateText>{value}</TruncateText>
</Link>
</Tooltip>
</Flex.Item>
<Flex.Item>
<div className="copy-button-container-cell">
Expand All @@ -72,6 +74,7 @@ export default function JobsTable({
sortColumn,
onClickJob,
onClickHeader,
onClickFilter,
timeZone
}) {
const renderJobRow = useCallback(
Expand All @@ -81,10 +84,14 @@ export default function JobsTable({
<Table.RowHeader>
<Link onClick={() => onClickJob(job)}>{job.id}</Link>
</Table.RowHeader>
<Table.Cell>{copyToClipboardTruncatedValue(job.tag)}</Table.Cell>
<Table.Cell>
{copyToClipboardTruncatedValue(job.strand)}
{copyToClipboardTruncatedValue(job.singleton)}
{copyToClipboardTruncatedValue(job.tag, tag => onClickFilter('tag', tag))}
</Table.Cell>
<Table.Cell>
{copyToClipboardTruncatedValue(job.strand, strand => onClickFilter('strand', strand))}
{copyToClipboardTruncatedValue(job.singleton, singleton =>
onClickFilter('singleton', singleton)
)}
</Table.Cell>
<Table.Cell>
{job.attempts} / {job.max_attempts}
Expand All @@ -96,7 +103,7 @@ export default function JobsTable({
</Table.Row>
)
},
[bucket, onClickJob, timeZone]
[bucket, onClickFilter, onClickJob, timeZone]
)

const renderColHeader = useCallback(
Expand Down
6 changes: 6 additions & 0 deletions ui/features/jobs_v2/react/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ export default function JobsIndex() {
jobDetailsRef.current?.scrollIntoView()
dispatch({type: 'SELECT_JOB', payload: job})
}}
onClickFilter={(groupType, groupText) => {
if (groupType !== state.group_type) {
dispatch({type: 'CHANGE_GROUP_TYPE', payload: groupType})
}
dispatch({type: 'CHANGE_GROUP_TEXT', payload: groupText})
}}
onClickHeader={col => dispatch({type: 'CHANGE_JOBS_ORDER', payload: col})}
timeZone={state.time_zone}
/>
Expand Down

0 comments on commit bdd70f9

Please sign in to comment.