Skip to content

Commit

Permalink
fix: use same date filter in the UI and CLI (#11840)
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Gilgur <agilgur5@gmail.com>
  • Loading branch information
agilgur5 committed Sep 20, 2023
1 parent dad5f76 commit fa116b6
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 95 deletions.
4 changes: 2 additions & 2 deletions cmd/argo/commands/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func NewDeleteCommand() *cobra.Command {
`,
Run: func(cmd *cobra.Command, args []string) {
hasFilterFlag := all || allNamespaces || flags.completed || flags.resubmitted || flags.prefix != "" ||
flags.labels != "" || flags.fields != "" || flags.finishedAfter != "" || len(flags.status) > 0
flags.labels != "" || flags.fields != "" || flags.finishedBefore != "" || len(flags.status) > 0

if len(args) == 0 && !hasFilterFlag {
cmd.HelpFunc()(cmd, args)
Expand Down Expand Up @@ -90,7 +90,7 @@ func NewDeleteCommand() *cobra.Command {
command.Flags().StringVar(&flags.prefix, "prefix", "", "Delete workflows by prefix")
command.Flags().StringVarP(&flags.labels, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
command.Flags().StringVar(&flags.fields, "field-selector", "", "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
command.Flags().StringVar(&flags.finishedAfter, "older", "", "Delete completed workflows finished before the specified duration (e.g. 10m, 3h, 1d)")
command.Flags().StringVar(&flags.finishedBefore, "older", "", "Delete completed workflows finished before the specified duration (e.g. 10m, 3h, 1d)")
command.Flags().StringSliceVar(&flags.status, "status", []string{}, "Delete by status (comma separated)")
command.Flags().Int64VarP(&flags.chunkSize, "query-chunk-size", "", 0, "Run the list query in chunks (deletes will still be executed individually)")
command.Flags().BoolVar(&dryRun, "dry-run", false, "Do not delete the workflow, only print what would happen")
Expand Down
36 changes: 18 additions & 18 deletions cmd/argo/commands/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ import (
)

type listFlags struct {
namespace string
status []string
completed bool
running bool
resubmitted bool
prefix string
output string
createdSince string
finishedAfter string
chunkSize int64
noHeaders bool
labels string
fields string
namespace string
status []string
completed bool
running bool
resubmitted bool
prefix string
output string
createdSince string
finishedBefore string
chunkSize int64
noHeaders bool
labels string
fields string
}

var (
Expand Down Expand Up @@ -82,7 +82,7 @@ func NewListCommand() *cobra.Command {
}
command.Flags().BoolVarP(&allNamespaces, "all-namespaces", "A", false, "Show workflows from all namespaces")
command.Flags().StringVar(&listArgs.prefix, "prefix", "", "Filter workflows by prefix")
command.Flags().StringVar(&listArgs.finishedAfter, "older", "", "List completed workflows finished before the specified duration (e.g. 10m, 3h, 1d)")
command.Flags().StringVar(&listArgs.finishedBefore, "older", "", "List completed workflows finished before the specified duration (e.g. 10m, 3h, 1d)")
command.Flags().StringSliceVar(&listArgs.status, "status", []string{}, "Filter by status (comma separated)")
command.Flags().BoolVar(&listArgs.completed, "completed", false, "Show completed workflows. Mutually exclusive with --running.")
command.Flags().BoolVar(&listArgs.running, "running", false, "Show running workflows. Mutually exclusive with --completed.")
Expand Down Expand Up @@ -146,10 +146,10 @@ func listWorkflows(ctx context.Context, serviceClient workflowpkg.WorkflowServic
Filter(func(wf wfv1.Workflow) bool {
return strings.HasPrefix(wf.ObjectMeta.Name, flags.prefix)
})
if flags.createdSince != "" && flags.finishedAfter != "" {
if flags.createdSince != "" && flags.finishedBefore != "" {
startTime, err := argotime.ParseSince(flags.createdSince)
errors.CheckError(err)
endTime, err := argotime.ParseSince(flags.finishedAfter)
endTime, err := argotime.ParseSince(flags.finishedBefore)
errors.CheckError(err)
workflows = workflows.Filter(wfv1.WorkflowRanBetween(*startTime, *endTime))
} else {
Expand All @@ -158,8 +158,8 @@ func listWorkflows(ctx context.Context, serviceClient workflowpkg.WorkflowServic
errors.CheckError(err)
workflows = workflows.Filter(wfv1.WorkflowCreatedAfter(*t))
}
if flags.finishedAfter != "" {
t, err := argotime.ParseSince(flags.finishedAfter)
if flags.finishedBefore != "" {
t, err := argotime.ParseSince(flags.finishedBefore)
errors.CheckError(err)
workflows = workflows.Filter(wfv1.WorkflowFinishedBefore(*t))
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func Test_listWorkflows(t *testing.T) {
}
})
t.Run("Older", func(t *testing.T) {
workflows, err := list(&metav1.ListOptions{}, listFlags{finishedAfter: "1h"})
workflows, err := list(&metav1.ListOptions{}, listFlags{finishedBefore: "1h"})
if assert.NoError(t, err) {
assert.Len(t, workflows, 1)
}
Expand Down
18 changes: 9 additions & 9 deletions ui/src/app/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ export const Utils = {
namePattern?: string;
phases?: Array<string>;
labels?: Array<string>;
minStartedAt?: Date;
maxStartedAt?: Date;
createdAfter?: Date;
finishedBefore?: Date;
pagination?: Pagination;
resourceVersion?: string;
}) {
const queryParams: string[] = [];
const fieldSelector = this.fieldSelectorParams(filter.namespace, filter.name, filter.minStartedAt, filter.maxStartedAt);
const fieldSelector = this.fieldSelectorParams(filter.namespace, filter.name, filter.createdAfter, filter.finishedBefore);
if (fieldSelector.length > 0) {
queryParams.push(`listOptions.fieldSelector=${fieldSelector}`);
}
Expand Down Expand Up @@ -162,22 +162,22 @@ export const Utils = {
return queryParams;
},

fieldSelectorParams(namespace?: string, name?: string, minStartedAt?: Date, maxStartedAt?: Date) {
fieldSelectorParams(namespace?: string, name?: string, createdAfter?: Date, finishedBefore?: Date) {
let fieldSelector = '';
if (namespace) {
fieldSelector += 'metadata.namespace=' + namespace + ',';
}
if (name) {
fieldSelector += 'metadata.name=' + name + ',';
}
if (minStartedAt) {
fieldSelector += 'spec.startedAt>' + minStartedAt.toISOString() + ',';
if (createdAfter) {
fieldSelector += 'metadata.creationTimestamp>' + createdAfter.toISOString() + ',';
}
if (maxStartedAt) {
fieldSelector += 'spec.startedAt<' + maxStartedAt.toISOString() + ',';
if (finishedBefore) {
fieldSelector += 'spec.finishedAt<' + finishedBefore.toISOString() + ',';
}
if (fieldSelector.endsWith(',')) {
fieldSelector = fieldSelector.substr(0, fieldSelector.length - 1);
fieldSelector = fieldSelector.substring(0, fieldSelector.length - 1);
}
return fieldSelector;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ interface WorkflowFilterProps {
phaseItems: WorkflowPhase[];
selectedPhases: WorkflowPhase[];
selectedLabels: string[];
minStartedAt?: Date;
maxStartedAt?: Date;
onChange: (namespace: string, selectedPhases: WorkflowPhase[], labels: string[], minStartedAt: Date, maxStartedAt: Date) => void;
createdAfter?: Date;
finishedBefore?: Date;
onChange: (namespace: string, selectedPhases: WorkflowPhase[], labels: string[], createdAfter: Date, finishedBefore: Date) => void;
}

export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
Expand All @@ -44,7 +44,7 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
<NamespaceFilter
value={this.props.namespace}
onChange={ns => {
this.props.onChange(ns, this.props.selectedPhases, this.props.selectedLabels, this.props.minStartedAt, this.props.maxStartedAt);
this.props.onChange(ns, this.props.selectedPhases, this.props.selectedLabels, this.props.createdAfter, this.props.finishedBefore);
}}
/>
</div>
Expand All @@ -55,7 +55,7 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
autocomplete={this.labelSuggestion}
tags={this.props.selectedLabels}
onChange={tags => {
this.props.onChange(this.props.namespace, this.props.selectedPhases, tags, this.props.minStartedAt, this.props.maxStartedAt);
this.props.onChange(this.props.namespace, this.props.selectedPhases, tags, this.props.createdAfter, this.props.finishedBefore);
}}
/>
</div>
Expand Down Expand Up @@ -87,21 +87,21 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
this.props.namespace,
selected.map(x => x as WorkflowPhase),
this.props.selectedLabels,
this.props.minStartedAt,
this.props.maxStartedAt
this.props.createdAfter,
this.props.finishedBefore
);
}}
items={this.getPhaseItems(this.props.workflows)}
type='phase'
/>
</div>
<div className='columns small-5 xlarge-12'>
<p className='wf-filters-container__title'>Started Time</p>
<p className='wf-filters-container__title'>Created Since</p>
<div className='wf-filters-container__content'>
<DatePicker
selected={this.props.minStartedAt}
selected={this.props.createdAfter}
onChange={date => {
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, date, this.props.maxStartedAt);
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, date, this.props.finishedBefore);
}}
placeholderText='From'
dateFormat='dd MMM yyyy'
Expand All @@ -110,16 +110,17 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
/>
<a
onClick={() => {
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, undefined, this.props.maxStartedAt);
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, undefined, this.props.finishedBefore);
}}>
<i className='fa fa-times-circle' />
</a>
</div>
<p className='wf-filters-container__title'>Finished Before</p>
<div className='wf-filters-container__content'>
<DatePicker
selected={this.props.maxStartedAt}
selected={this.props.finishedBefore}
onChange={date => {
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, this.props.minStartedAt, date);
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, this.props.createdAfter, date);
}}
placeholderText='To'
dateFormat='dd MMM yyyy'
Expand All @@ -128,7 +129,7 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
/>
<a
onClick={() => {
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, this.props.minStartedAt, undefined);
this.props.onChange(this.props.namespace, this.props.selectedPhases, this.props.selectedLabels, this.props.createdAfter, undefined);
}}>
<i className='fa fa-times-circle' />
</a>
Expand All @@ -140,7 +141,7 @@ export class WorkflowFilters extends React.Component<WorkflowFilterProps, {}> {
}

private setLabel(name: string, value: string) {
this.props.onChange(this.props.namespace, this.props.selectedPhases, [name.concat('=' + value)], this.props.minStartedAt, this.props.maxStartedAt);
this.props.onChange(this.props.namespace, this.props.selectedPhases, [name.concat('=' + value)], this.props.createdAfter, this.props.finishedBefore);
}

private getPhaseItems(workflows: models.Workflow[]) {
Expand Down

0 comments on commit fa116b6

Please sign in to comment.