Manager: show delete-requested jobs in the web interface

Show jobs that have been marked for deletion with a red strike-through
line in the jobs table, and show the deletion-request timestamp in the
job details.
This commit is contained in:
Sybren A. Stüvel 2023-01-08 13:52:27 +01:00
parent 067f2a439e
commit a97a4e6e67
5 changed files with 49 additions and 4 deletions

View File

@ -595,6 +595,9 @@ func jobDBtoAPI(dbJob *persistence.Job) api.Job {
ShamanCheckoutId: &dbJob.Storage.ShamanCheckoutID, ShamanCheckoutId: &dbJob.Storage.ShamanCheckoutID,
} }
} }
if dbJob.DeleteRequestedAt.Valid {
apiJob.DeleteRequestedAt = &dbJob.DeleteRequestedAt.Time
}
return apiJob return apiJob
} }

View File

@ -2,6 +2,7 @@
package api_impl package api_impl
import ( import (
"database/sql"
"net/http" "net/http"
"testing" "testing"
"time" "time"
@ -32,10 +33,23 @@ func TestQueryJobs(t *testing.T) {
}, },
} }
deletionRequestedAt := time.Now()
deletionQueuedJob := persistence.Job{
UUID: "d912ac69-de48-48ba-8028-35d82cb41451",
Name: "уходить",
JobType: "test",
Priority: 75,
Status: api.JobStatusCompleted,
DeleteRequestedAt: sql.NullTime{
Time: deletionRequestedAt,
Valid: true,
},
}
echoCtx := mf.prepareMockedRequest(nil) echoCtx := mf.prepareMockedRequest(nil)
ctx := echoCtx.Request().Context() ctx := echoCtx.Request().Context()
mf.persistence.EXPECT().QueryJobs(ctx, api.JobsQuery{}). mf.persistence.EXPECT().QueryJobs(ctx, api.JobsQuery{}).
Return([]*persistence.Job{&activeJob}, nil) Return([]*persistence.Job{&activeJob, &deletionQueuedJob}, nil)
err := mf.flamenco.QueryJobs(echoCtx) err := mf.flamenco.QueryJobs(echoCtx)
assert.NoError(t, err) assert.NoError(t, err)
@ -57,6 +71,18 @@ func TestQueryJobs(t *testing.T) {
Id: "afc47568-bd9d-4368-8016-e91d945db36d", Id: "afc47568-bd9d-4368-8016-e91d945db36d",
Status: api.JobStatusActive, Status: api.JobStatusActive,
}, },
{
SubmittedJob: api.SubmittedJob{
Name: "уходить",
Type: "test",
Priority: 75,
Settings: &api.JobSettings{},
Metadata: &api.JobMetadata{},
},
Id: "d912ac69-de48-48ba-8028-35d82cb41451",
Status: api.JobStatusCompleted,
DeleteRequestedAt: &deletionRequestedAt,
},
}, },
} }

View File

@ -620,6 +620,11 @@ button:focus,
font-weight: bold; font-weight: bold;
} }
.tabulator-row.deletion-requested * {
text-decoration: line-through red 1px;
color: var(--color-text-muted);
}
span.state-transition-arrow { span.state-transition-arrow {
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;

View File

@ -47,8 +47,14 @@
<dt class="field-created" title="Created">Created</dt> <dt class="field-created" title="Created">Created</dt>
<dd>{{ datetime.relativeTime(jobData.created) }}</dd> <dd>{{ datetime.relativeTime(jobData.created) }}</dd>
<dt class="field-updated" title="Updated">Updated</dt> <template v-if="isDeleteRequested">
<dd>{{ datetime.relativeTime(jobData.updated) }}</dd> <dt class="field-delete-requested-at" title="delete-requested-at">Delete Request</dt>
<dd>{{ datetime.relativeTime(jobData.delete_requested_at) }}</dd>
</template>
<template v-else>
<dt class="field-updated" title="Updated">Updated</dt>
<dd>{{ datetime.relativeTime(jobData.updated) }}</dd>
</template>
<dt class="field-activity" title="Activity">Activity</dt> <dt class="field-activity" title="Activity">Activity</dt>
<dd>{{ jobData.activity }}</dd> <dd>{{ jobData.activity }}</dd>
@ -119,6 +125,9 @@ export default {
hasSettings() { hasSettings() {
return this.jobData && !objectEmpty(this.settingsToDisplay); return this.jobData && !objectEmpty(this.settingsToDisplay);
}, },
isDeleteRequested() {
return this.jobData && !!this.jobData.delete_requested_at;
},
settingsToDisplay() { settingsToDisplay() {
if (!this.showAllSettings) { if (!this.showAllSettings) {
return this.simpleSettings; return this.simpleSettings;

View File

@ -76,7 +76,9 @@ export default {
rowFormatter(row) { rowFormatter(row) {
const data = row.getData(); const data = row.getData();
const isActive = (data.id === vueComponent.activeJobID); const isActive = (data.id === vueComponent.activeJobID);
row.getElement().classList.toggle("active-row", isActive); const classList = row.getElement().classList;
classList.toggle("active-row", isActive);
classList.toggle("deletion-requested", !!data.delete_requested_at);
}, },
initialSort: [ initialSort: [
{ column: "updated", dir: "desc" }, { column: "updated", dir: "desc" },