Skip to content

Commit 58fdddc

Browse files
DT-152 - batch terminate (#952)
* Add advanced visibility check for new workflows page * Fix some calendar issues, rip out bulk from old workflows page * Add filter on row for workflowId * Fix timepicker with better UI * Add button instead of divs, use outside-click on date picker * batch terminate - refactor workflows summary table not to use SelectableTable - implement BATCH terminate eg. select ALL all * Change label to Start and End * Fix Back to Workflows query logic for new filters to keep query * Clear time filter on advanced search filter clear * Remove unused imports * fix copy on toasts and confirmation modal. also make toasts primary * fix modal styling revert changes to table css (so selectable tables still can be used) * WIP * clear reason on modal close * Fix AM/PM with errors, add back cypress tests * Fix bulk actions test * Fix back to workflows query for basic * Fix cypress tests * Add isCloud check to supportsAdvancedVisibility * fix/add cy tests * Add ability to input a custom date * Capitalize ID * fix nav back to workflows retaining query change wf sort limit to 1MM format wf count numbers consistently * fix whitespace in modal content Co-authored-by: Alex Tideman <[email protected]>
1 parent 3df4687 commit 58fdddc

11 files changed

+412
-189
lines changed

Diff for: cypress/integration/workflow-bulk-actions.spec.js

+46-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="cypress" />
22

3-
describe('Bulk Termination', () => {
3+
describe('Bulk Terminate', () => {
44
it("disallows bulk actions for cluster that doesn't have elasticsearch enabled", () => {
55
cy.interceptApi();
66

@@ -12,23 +12,50 @@ describe('Bulk Termination', () => {
1212
cy.get('#workflows-table-with-bulk-actions').should('not.exist');
1313
});
1414

15-
it('allows running workflows to be terminated for cluster that does have elasticsearch enabled', () => {
16-
cy.interceptApi();
17-
cy.intercept(Cypress.env('VITE_API_HOST') + '/api/v1/cluster*', {
18-
fixture: 'cluster-with-elasticsearch.json',
19-
}).as('cluster-api-elasticsearch');
20-
21-
cy.visit('/namespaces/default/workflows');
22-
23-
cy.wait('@cluster-api-elasticsearch');
24-
cy.wait('@workflows-api');
25-
26-
cy.get('#workflows-table-with-bulk-actions').should('exist');
27-
28-
cy.get('th.selectable > label.checkbox > span.label').click();
29-
cy.get('[data-cy="bulk-terminate-button"]').click();
30-
cy.get('#bulk-terminate-reason').type('Sarah Connor');
31-
cy.get('div.modal button.destructive').click();
32-
cy.get('#batch-terminate-success-toast');
15+
describe('for cluster that does have elasticsearch enabled', () => {
16+
it('allows running workflows to be terminated by ID', () => {
17+
cy.interceptApi();
18+
cy.intercept(Cypress.env('VITE_API_HOST') + '/api/v1/cluster*', {
19+
fixture: 'cluster-with-elasticsearch.json',
20+
}).as('cluster-api-elasticsearch');
21+
22+
cy.visit('/namespaces/default/workflows');
23+
24+
cy.wait('@cluster-api-elasticsearch');
25+
cy.wait('@workflows-api');
26+
27+
cy.get('#workflows-table-with-bulk-actions').should('exist');
28+
29+
cy.get('#select-visible-workflows').click({ force: true });
30+
cy.get('[data-cy="bulk-terminate-button"]').click();
31+
cy.get('#bulk-terminate-reason').type('Sarah Connor');
32+
cy.get('div.modal button.destructive').click();
33+
cy.get('#batch-terminate-success-toast');
34+
});
35+
36+
it('allows running workflows to be terminated by a query', () => {
37+
cy.interceptApi();
38+
cy.intercept(Cypress.env('VITE_API_HOST') + '/api/v1/cluster*', {
39+
fixture: 'cluster-with-elasticsearch.json',
40+
}).as('cluster-api-elasticsearch');
41+
42+
cy.visit('/namespaces/default/workflows');
43+
44+
cy.wait('@cluster-api-elasticsearch');
45+
cy.wait('@workflows-api');
46+
47+
cy.get('#workflows-table-with-bulk-actions').should('exist');
48+
49+
cy.get('#select-visible-workflows').click({ force: true });
50+
cy.get('[data-cy="select-all-workflows"]').click();
51+
cy.get('[data-cy="bulk-terminate-button"]').click();
52+
cy.get('[data-cy="batch-action-workflows-query"]').should(
53+
'have.text',
54+
'ExecutionStatus="Running"',
55+
);
56+
cy.get('#bulk-terminate-reason').type('Sarah Connor');
57+
cy.get('div.modal button.destructive').click();
58+
cy.get('#batch-terminate-success-toast');
59+
});
3360
});
3461
});

Diff for: cypress/integration/workflow-executions-with-new-search.spec.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('Workflow Executions List With Search', () => {
3535
cy.get('#workflowType').should('have.value', 'ImportantWorkflowType');
3636

3737
cy.get('[data-cy="workflow-count"]').should(
38-
'contain',
38+
'have.text',
3939
'Results 15 of 15 workflows',
4040
);
4141
});
@@ -55,7 +55,7 @@ describe('Workflow Executions List With Search', () => {
5555
);
5656

5757
cy.get('[data-cy="workflow-count"]').should(
58-
'contain',
58+
'have.text',
5959
'Results 15 of 15 workflows',
6060
);
6161

@@ -78,7 +78,7 @@ describe('Workflow Executions List With Search', () => {
7878
'WorkflowId="002c98_Running"',
7979
);
8080
cy.get('[data-cy="workflow-count"]').should(
81-
'contain',
81+
'have.text',
8282
'Results 15 of 15 workflows',
8383
);
8484

@@ -100,7 +100,7 @@ describe('Workflow Executions List With Search', () => {
100100
'ExecutionStatus="Running"',
101101
);
102102
cy.get('[data-cy="workflow-count"]').should(
103-
'contain',
103+
'have.text',
104104
'Results 15 of 15 workflows',
105105
);
106106
});
@@ -157,7 +157,7 @@ describe('Workflow Executions List With Search', () => {
157157

158158
cy.url().should('contain', 'StartTime+BETWEEN');
159159
cy.get('[data-cy="workflow-count"]').should(
160-
'contain',
160+
'have.text',
161161
'Results 15 of 15 workflows',
162162
);
163163
});
@@ -169,7 +169,7 @@ describe('Workflow Executions List With Search', () => {
169169

170170
cy.url().should('contain', 'CloseTime+BETWEEN');
171171
cy.get('[data-cy="workflow-count"]').should(
172-
'contain',
172+
'have.text',
173173
'Results 15 of 15 workflows',
174174
);
175175
});
@@ -213,7 +213,7 @@ describe('Workflow Executions List With Search', () => {
213213
encodeURIComponent(`ExecutionStatus="Running"`),
214214
);
215215
cy.get('[data-cy="workflow-count"]').should(
216-
'contain',
216+
'have.text',
217217
'Results 15 of 15 workflows',
218218
);
219219
});

Diff for: src/lib/components/workflow/workflow-advanced-search.svelte

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import Button from '$lib/holocene/button.svelte';
1010
import { workflowFilters, workflowSorts } from '$lib/stores/filters';
1111
import { toListWorkflowFilters } from '$lib/utilities/query/to-list-workflow-filters';
12+
import { workflowsQuery } from '$lib/stores/workflows';
1213
1314
let manualSearchString = '';
1415
@@ -26,6 +27,7 @@
2627
if (!manualSearchString) {
2728
$workflowFilters = [];
2829
$workflowSorts = [];
30+
$workflowsQuery = '';
2931
} else {
3032
try {
3133
$workflowFilters = toListWorkflowFilters(manualSearchString);

Diff for: src/lib/components/workflow/workflows-summary-row-with-filters.svelte

+28-13
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
<script lang="ts">
22
import { page } from '$app/stores';
3+
import { createEventDispatcher } from 'svelte';
34
45
import { formatDate } from '$lib/utilities/format-date';
56
import { getMilliseconds } from '$lib/utilities/format-time';
6-
import {
7-
routeForEventHistory,
8-
routeForWorkflow,
9-
} from '$lib/utilities/route-for';
7+
import { routeForEventHistory } from '$lib/utilities/route-for';
108
119
import WorkflowStatus from '$lib/components/workflow-status.svelte';
1210
import FilterOrCopyButtons from '$holocene/filter-or-copy-buttons.svelte';
1311
import TableRow from '$holocene/table/table-row.svelte';
1412
import { workflowFilters, workflowSorts } from '$lib/stores/filters';
1513
import { updateQueryParamsFromFilter } from '$lib/utilities/query/to-list-workflow-filters';
16-
import SelectableTableRow from '$lib/holocene/table/selectable-table-row.svelte';
14+
import Checkbox from '$lib/holocene/checkbox.svelte';
1715
import { eventViewType } from '$lib/stores/event-view';
1816
17+
const dispatch = createEventDispatcher<{
18+
toggleWorkflow: { workflowRunId: string; checked: boolean };
19+
}>();
20+
1921
export let bulkActionsEnabled: boolean = false;
2022
export let selected: boolean = false;
2123
export let namespace: string;
2224
export let workflow: WorkflowExecution;
2325
export let timeFormat: TimeFormat | string;
26+
export let checkboxDisabled: boolean;
2427
2528
$: href = routeForEventHistory({
2629
view: $eventViewType,
@@ -54,15 +57,27 @@
5457
5558
updateQueryParamsFromFilter($page.url, $workflowFilters, $workflowSorts);
5659
};
60+
61+
const handleCheckboxChange = (event: CustomEvent<{ checked: boolean }>) => {
62+
dispatch('toggleWorkflow', {
63+
workflowRunId: workflow.runId,
64+
checked: event.detail.checked,
65+
});
66+
};
5767
</script>
5868

59-
<svelte:component
60-
this={bulkActionsEnabled ? SelectableTableRow : TableRow}
61-
item={workflow}
62-
{selected}
63-
{href}
64-
class="workflow-summary-row"
65-
>
69+
<TableRow {href} class="workflow-summary-row">
70+
{#if bulkActionsEnabled}
71+
<td on:keypress|stopPropagation on:click|stopPropagation>
72+
<div class="absolute">
73+
<Checkbox
74+
disabled={checkboxDisabled}
75+
bind:checked={selected}
76+
on:change={handleCheckboxChange}
77+
/>
78+
</div>
79+
</td>
80+
{/if}
6681
<td>
6782
<WorkflowStatus
6883
status={workflow.status}
@@ -128,7 +143,7 @@
128143
{formatDate(workflow.endTime, timeFormat)}
129144
</p>
130145
</td>
131-
</svelte:component>
146+
</TableRow>
132147

133148
<style lang="postcss">
134149
:global(.workflow-summary-row:hover) {

0 commit comments

Comments
 (0)