Skip to content

Commit f7571bf

Browse files
committed
Added modal for editing job status
1 parent b289971 commit f7571bf

File tree

3 files changed

+93
-11
lines changed

3 files changed

+93
-11
lines changed

playwright.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default defineConfig({
3838

3939
webServer: [
4040
{
41-
command: './tests/start-test-server.sh 1.4.0a9',
41+
command: './tests/start-test-server.sh 1.4.0a10',
4242
port: 8000,
4343
waitForPort: true,
4444
stdout: 'pipe',

src/lib/components/jobs/JobsList.svelte

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
/** @type {('project'|'workflow'|'user_email')[]} */
1616
export let columnsToHide = [];
1717
/** @type {boolean} */
18-
export let showFilters = true;
19-
/** @type {boolean} */
20-
export let hideCancelJobButton = false;
18+
export let admin = false;
2119
2220
/** @type {JobInfoModal} */
2321
let jobInfoModal;
@@ -148,7 +146,7 @@
148146
{#if tableHandler}
149147
<div class="d-flex justify-content-end align-items-center my-3">
150148
<div>
151-
{#if showFilters}
149+
{#if !admin}
152150
<button
153151
class="btn btn-warning"
154152
on:click={() => {
@@ -169,7 +167,7 @@
169167
<div id="jobUpdatesError" />
170168
<table class="table jobs-table">
171169
<colgroup>
172-
<col width="90" />
170+
<col width="100" />
173171
<col width="110" />
174172
<col width="100" />
175173
<col width="100" />
@@ -203,7 +201,7 @@
203201
<Th handler={tableHandler} key="user_email" label="User" />
204202
{/if}
205203
</tr>
206-
{#if showFilters}
204+
{#if !admin}
207205
<tr>
208206
<th>
209207
<select class="form-control" bind:value={statusFilter}>
@@ -271,7 +269,12 @@
271269
{#each $rows as row}
272270
<tr class="align-middle">
273271
<td>
274-
<StatusBadge status={row.status} />
272+
<span>
273+
<StatusBadge status={row.status} />
274+
{#if admin}
275+
<slot name="edit-status" {row} />
276+
{/if}
277+
</span>
275278
</td>
276279
<td>
277280
<button
@@ -300,7 +303,7 @@
300303
</a>
301304
{/if}
302305
{/if}
303-
{#if row.status === 'running' && !hideCancelJobButton}
306+
{#if row.status === 'running' && !admin}
304307
<button class="btn btn-danger" on:click={() => handleJobCancel(row)}>
305308
<i class="bi-x-circle" /> Cancel
306309
</button>

src/routes/admin/jobs/+page.svelte

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script>
22
import { page } from '$app/stores';
3-
import { displayStandardErrorAlert } from '$lib/common/errors';
3+
import { AlertError, displayStandardErrorAlert } from '$lib/common/errors';
4+
import Modal from '$lib/components/common/Modal.svelte';
45
import JobsList from '$lib/components/jobs/JobsList.svelte';
56
67
let searched = false;
@@ -48,6 +49,10 @@
4849
}
4950
}
5051
jobs = jobs.map((j) => {
52+
if (j.status === 'failed') {
53+
// The admin has manually updated the job status while the AJAX call was in progress
54+
return j;
55+
}
5156
const updatedJob = updatedJobs.find((uj) => uj.id === j.id);
5257
return updatedJob ?? j;
5358
});
@@ -218,6 +223,49 @@
218223
downloader.setAttribute('download', filename);
219224
downloader.click();
220225
}
226+
227+
/** @type {Modal} */
228+
let statusModal;
229+
/** @type {import('$lib/types').ApplyWorkflow|undefined} */
230+
let jobInEditing;
231+
232+
/**
233+
* @param {import('$lib/types').ApplyWorkflow} row
234+
*/
235+
function openEditStatusModal(row) {
236+
jobInEditing = row;
237+
statusModal.show();
238+
}
239+
240+
let updatingStatus = false;
241+
242+
async function updateJobStatus() {
243+
statusModal.confirmAndHide(async () => {
244+
updatingStatus = true;
245+
try {
246+
const jobId = /** @type {import('$lib/types').ApplyWorkflow} */ (jobInEditing).id;
247+
248+
const headers = new Headers();
249+
headers.append('Content-Type', 'application/json');
250+
251+
const response = await fetch(`/api/admin/job/${jobId}`, {
252+
method: 'PATCH',
253+
credentials: 'include',
254+
headers,
255+
body: JSON.stringify({ status: 'failed' })
256+
});
257+
258+
if (!response.ok) {
259+
throw new AlertError(await response.json());
260+
}
261+
262+
jobs = jobs.map((j) => (j.id === jobId ? { ...j, status: 'failed' } : j));
263+
jobsListComponent.setJobs(jobs);
264+
} finally {
265+
updatingStatus = false;
266+
}
267+
});
268+
}
221269
</script>
222270
223271
<div class="container">
@@ -367,16 +415,47 @@
367415
<div id="searchError" class="mt-3" />
368416
369417
<div class:d-none={!searched}>
370-
<JobsList {jobUpdater} bind:this={jobsListComponent} showFilters={false} hideCancelJobButton={true}>
418+
<JobsList {jobUpdater} bind:this={jobsListComponent} admin={true}>
371419
<svelte:fragment slot="buttons">
372420
<button class="btn btn-outline-secondary" on:click={downloadCSV}>
373421
<i class="bi-download" /> Download CSV
374422
</button>
375423
</svelte:fragment>
424+
<svelte:fragment slot="edit-status" let:row>
425+
{#if row.status !== 'failed'}
426+
&nbsp;
427+
<button class="btn btn-link p-0" on:click={() => openEditStatusModal(row)}>
428+
<i class="bi bi-pencil" />
429+
</button>
430+
{/if}
431+
</svelte:fragment>
376432
</JobsList>
377433
</div>
378434
</div>
379435
436+
<Modal id="editJobStatusModal" bind:this={statusModal} centered={true} size="md">
437+
<svelte:fragment slot="header">
438+
{#if jobInEditing}
439+
<h1 class="h5 modal-title flex-grow-1">Editing job #{jobInEditing.id}</h1>
440+
{/if}
441+
</svelte:fragment>
442+
<svelte:fragment slot="body">
443+
<div id="errorAlert-editJobStatusModal" />
444+
<div class="alert alert-warning">
445+
<i class="bi bi-exclamation-triangle" />
446+
<strong>Warning</strong>: this operation will not cancel job execution but only modify its
447+
status in the database
448+
</div>
449+
<div class="d-flex justify-content-center">
450+
<button class="btn btn-danger" on:click={updateJobStatus} disabled={updatingStatus}>
451+
Set status to failed
452+
</button>
453+
&nbsp;
454+
<button class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
455+
</div>
456+
</svelte:fragment>
457+
</Modal>
458+
380459
<style>
381460
input[type='date'] {
382461
min-width: 190px;

0 commit comments

Comments
 (0)