-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
feat: show history about completed runs in each cron workflow #11790
Changes from all commits
2a11703
95e1128
8d5be3a
086bb9b
2748ce9
1d3e875
5c993a6
6732b5f
ab52986
666fc25
503be03
120d1fc
e70b3cf
69d925e
8be5e72
789e437
7c32559
a752691
8a3b7df
6679692
bb6b8e0
0341a92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,16 +2,21 @@ import {NotificationType, Page, SlidingPanel} from 'argo-ui'; | |
import * as React from 'react'; | ||
import {useContext, useEffect, useState} from 'react'; | ||
import {RouteComponentProps} from 'react-router'; | ||
import {CronWorkflow, Link} from '../../../../models'; | ||
import * as models from '../../../../models'; | ||
import {CronWorkflow, Link, Workflow} from '../../../../models'; | ||
import {uiUrl} from '../../../shared/base'; | ||
import {ErrorNotice} from '../../../shared/components/error-notice'; | ||
import {Loading} from '../../../shared/components/loading'; | ||
import {useCollectEvent} from '../../../shared/components/use-collect-event'; | ||
import {Context} from '../../../shared/context'; | ||
import {historyUrl} from '../../../shared/history'; | ||
import {Pagination, parseLimit} from '../../../shared/pagination'; | ||
import {services} from '../../../shared/services'; | ||
import {useQueryParams} from '../../../shared/use-query-params'; | ||
import * as Actions from '../../../shared/workflow-operations-map'; | ||
import {WidgetGallery} from '../../../widgets/widget-gallery'; | ||
import {allBatchActionsEnabled, WorkflowListRenderOptions} from '../../../workflows/components/workflows-list/workflows-list'; | ||
import {WorkflowsRow} from '../../../workflows/components/workflows-row/workflows-row'; | ||
import {CronWorkflowEditor} from '../cron-workflow-editor'; | ||
|
||
require('../../../workflows/components/workflow-details/workflow-details.scss'); | ||
|
@@ -25,6 +30,12 @@ export const CronWorkflowDetails = ({match, location, history}: RouteComponentPr | |
const [name] = useState(match.params.name); | ||
const [sidePanel, setSidePanel] = useState(queryParams.get('sidePanel')); | ||
const [tab, setTab] = useState(queryParams.get('tab')); | ||
const [workflows, setWorkflows] = useState<Workflow[]>([]); | ||
const [{selectedPhases, selectedLabels, paginationLimit}, setSelectedData] = useState<WorkflowListRenderOptions>(JSON.parse(localStorage.getItem('ListOptions/options'))); | ||
const [, setBatchActionDisabled] = useState<Actions.OperationDisabled>(); | ||
const [selectedWorkflows, setSelectedWorkflows] = useState(new Map<string, models.Workflow>()); | ||
const [columns, setColumns] = useState<models.Column[]>([]); | ||
const [pagination] = useState<Pagination>({offset: queryParams.get('offset'), limit: parseLimit(queryParams.get('limit') || `${paginationLimit}` || '50')}); | ||
|
||
const [cronWorkflow, setCronWorkflow] = useState<CronWorkflow>(); | ||
const [edited, setEdited] = useState(false); | ||
|
@@ -62,6 +73,16 @@ export const CronWorkflowDetails = ({match, location, history}: RouteComponentPr | |
|
||
useEffect(() => setEdited(true), [cronWorkflow]); | ||
|
||
useEffect(() => { | ||
services.workflows.list(namespace, selectedPhases, selectedLabels, pagination).then(res => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally we can filter in the request to not retrieve unnecessary workflows, although that might not be possible There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is possible (and is already done in the Workflows List filter for Cron Workflows). That is the only label that should be passed as there is otherwise no label filter here (that is similarly only in the sidebar on the Workflows List page) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also should use async/await per #11740 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can replace |
||
setWorkflows(res.items.filter(el => el.metadata.name.substring(0, el.metadata.name.lastIndexOf('-')) === name)); | ||
}); | ||
|
||
services.info.getInfo().then(info => { | ||
setColumns(info.columns); | ||
}); | ||
}, []); | ||
|
||
useCollectEvent('openedCronWorkflowDetails'); | ||
|
||
const suspendButton = | ||
|
@@ -183,6 +204,17 @@ export const CronWorkflowDetails = ({match, location, history}: RouteComponentPr | |
|
||
return items; | ||
}; | ||
const updateCurrentlySelectedAndBatchActions = (newSelectedWorkflows: Map<string, Workflow>): void => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the checkbox is unused here. No batch actions were added to this page, so it's not useable currently There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So ideally we would factor out a That being said, that requires a bit of refactoring. As a first-pass, we could just make the checkboxes no-op for now and refactor later -- that was why I commented on the function itself and not the UI elements. |
||
const actions: any = Actions.WorkflowOperationsMap; | ||
const nowDisabled: any = {...allBatchActionsEnabled}; | ||
for (const action of Object.keys(nowDisabled)) { | ||
for (const wf of Array.from(newSelectedWorkflows.values())) { | ||
nowDisabled[action] = nowDisabled[action] || actions[action].disabled(wf); | ||
} | ||
} | ||
setBatchActionDisabled(nowDisabled); | ||
setSelectedWorkflows(new Map<string, models.Workflow>(newSelectedWorkflows)); | ||
}; | ||
|
||
return ( | ||
<Page | ||
|
@@ -207,6 +239,84 @@ export const CronWorkflowDetails = ({match, location, history}: RouteComponentPr | |
<SlidingPanel isShown={!!sidePanel} onClose={() => setSidePanel(null)}> | ||
{sidePanel === 'share' && <WidgetGallery namespace={namespace} label={'workflows.argoproj.io/cron-workflow=' + name} />} | ||
</SlidingPanel> | ||
<div className='argo-table-list'> | ||
<div className='row argo-table-list__head'> | ||
<div className='columns small-1 workflows-list__status'> | ||
<input | ||
type='checkbox' | ||
className='workflows-list__status--checkbox' | ||
checked={workflows.length === selectedWorkflows.size} | ||
onClick={e => { | ||
e.stopPropagation(); | ||
}} | ||
onChange={e => { | ||
if (workflows.length === selectedWorkflows.size) { | ||
// All workflows are selected, deselect them all | ||
updateCurrentlySelectedAndBatchActions(new Map<string, models.Workflow>()); | ||
} else { | ||
// Not all workflows are selected, select them all | ||
const currentlySelected: Map<string, Workflow> = selectedWorkflows; | ||
workflows.forEach(wf => { | ||
if (!currentlySelected.has(wf.metadata.uid)) { | ||
currentlySelected.set(wf.metadata.uid, wf); | ||
} | ||
}); | ||
updateCurrentlySelectedAndBatchActions(currentlySelected); | ||
} | ||
}} | ||
/> | ||
</div> | ||
<div className='row small-11'> | ||
<div className='columns small-2'>NAME</div> | ||
<div className='columns small-1'>NAMESPACE</div> | ||
<div className='columns small-1'>STARTED</div> | ||
<div className='columns small-1'>FINISHED</div> | ||
<div className='columns small-1'>DURATION</div> | ||
<div className='columns small-1'>PROGRESS</div> | ||
<div className='columns small-2'>MESSAGE</div> | ||
<div className='columns small-1'>DETAILS</div> | ||
<div className='columns small-1'>ARCHIVED</div> | ||
{(columns || []).map(col => { | ||
return ( | ||
<div className='columns small-1' key={col.key}> | ||
{col.name} | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
{workflows.map(wf => { | ||
return ( | ||
<WorkflowsRow | ||
workflow={wf} | ||
key={wf.metadata.uid} | ||
checked={selectedWorkflows.has(wf.metadata.uid)} | ||
columns={columns} | ||
onChange={key => { | ||
const value = `${key}=${wf.metadata?.labels[key]}`; | ||
let newTags: string[] = []; | ||
if (selectedLabels.indexOf(value) === -1) { | ||
newTags = selectedLabels.concat(value); | ||
setSelectedData(prev => ({...prev, selectedLabels: newTags})); | ||
} | ||
}} | ||
select={subWf => { | ||
const wfUID = subWf.metadata.uid; | ||
if (!wfUID) { | ||
return; | ||
} | ||
const currentlySelected: Map<string, Workflow> = selectedWorkflows; | ||
if (!currentlySelected.has(wfUID)) { | ||
currentlySelected.set(wfUID, subWf); | ||
} else { | ||
currentlySelected.delete(wfUID); | ||
} | ||
updateCurrentlySelectedAndBatchActions(currentlySelected); | ||
}} | ||
/> | ||
); | ||
})} | ||
</div> | ||
</> | ||
</Page> | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are no phases or labels here. those are from the sidebar filter in the Workflows List which is not present here.
pagination does not seem to be present either. there seems to be some logic here, but no UI elements for pagination.
also the
localStorage
call would not apply here as it is specific to the Workflows list pageThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think filtering is needed right now. pagination would be nice to have, but for a first-pass MVP, I think we can leave out pagination as well.
You may have not noticed, but the main overall Cron Workflows page itself actually doesn't implement pagination yet 😅 : #10846