Manager: show worker tag in job details
Show the worker tag name (and its description in a tooltip) in the job details. When no worker tag is assigned, "All Workers" is shown in a more dimmed colour. This also renames the "Type" field to "Job Type". "Tag" and "Type" could be confused, and now they're displayed as "Worker Tag" and "Job Type". The UI in the add-on's submission interface is also updated for this, so that that also shows "Worker Tag" (instead of just "Tag").
This commit is contained in:
parent
e8438bb645
commit
df4f94c642
@ -51,7 +51,7 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel):
|
||||
)
|
||||
if not job_types.are_job_types_available():
|
||||
return
|
||||
col.prop(context.scene, "flamenco_worker_tag", text="Tag")
|
||||
col.prop(context.scene, "flamenco_worker_tag", text="Worker Tag")
|
||||
|
||||
# Job properties:
|
||||
job_col = layout.column(align=True)
|
||||
|
@ -687,7 +687,7 @@ func jobDBtoAPI(dbJob *persistence.Job) api.Job {
|
||||
apiJob.DeleteRequestedAt = &dbJob.DeleteRequestedAt.Time
|
||||
}
|
||||
if dbJob.WorkerTag != nil {
|
||||
apiJob.WorkerTag = &dbJob.WorkerTag.UUID
|
||||
apiJob.WorkerTag = workerTagDBtoAPI(dbJob.WorkerTag)
|
||||
}
|
||||
|
||||
return apiJob
|
||||
|
@ -89,6 +89,60 @@ func TestQueryJobs(t *testing.T) {
|
||||
assertResponseJSON(t, echoCtx, http.StatusOK, expectedJobs)
|
||||
}
|
||||
|
||||
func TestFetchJob(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
mf := newMockedFlamenco(mockCtrl)
|
||||
|
||||
dbJob := persistence.Job{
|
||||
UUID: "afc47568-bd9d-4368-8016-e91d945db36d",
|
||||
Name: "работа",
|
||||
JobType: "test",
|
||||
Priority: 50,
|
||||
Status: api.JobStatusActive,
|
||||
Settings: persistence.StringInterfaceMap{
|
||||
"result": "/render/frames/exploding.kittens",
|
||||
},
|
||||
Metadata: persistence.StringStringMap{
|
||||
"project": "/projects/exploding-kittens",
|
||||
},
|
||||
WorkerTag: &persistence.WorkerTag{
|
||||
UUID: "d86e1b84-5ee2-4784-a178-65963eeb484b",
|
||||
Name: "Tikkie terug Kees!",
|
||||
Description: "",
|
||||
},
|
||||
}
|
||||
|
||||
echoCtx := mf.prepareMockedRequest(nil)
|
||||
mf.persistence.EXPECT().FetchJob(gomock.Any(), dbJob.UUID).Return(&dbJob, nil)
|
||||
|
||||
require.NoError(t, mf.flamenco.FetchJob(echoCtx, dbJob.UUID))
|
||||
|
||||
expectedJob := api.Job{
|
||||
SubmittedJob: api.SubmittedJob{
|
||||
Name: "работа",
|
||||
Type: "test",
|
||||
Priority: 50,
|
||||
Settings: &api.JobSettings{AdditionalProperties: map[string]interface{}{
|
||||
"result": "/render/frames/exploding.kittens",
|
||||
}},
|
||||
Metadata: &api.JobMetadata{AdditionalProperties: map[string]string{
|
||||
"project": "/projects/exploding-kittens",
|
||||
}},
|
||||
},
|
||||
Id: "afc47568-bd9d-4368-8016-e91d945db36d",
|
||||
Status: api.JobStatusActive,
|
||||
WorkerTag: &api.WorkerTag{
|
||||
Id: ptr("d86e1b84-5ee2-4784-a178-65963eeb484b"),
|
||||
Name: "Tikkie terug Kees!",
|
||||
Description: nil, // Empty description should just be excluded from the JSON.
|
||||
},
|
||||
}
|
||||
|
||||
assertResponseJSON(t, echoCtx, http.StatusOK, expectedJob)
|
||||
}
|
||||
|
||||
func TestFetchTask(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
@ -415,6 +415,11 @@ func TestSubmitJobWithWorkerTag(t *testing.T) {
|
||||
DeleteRequestedAt: nil,
|
||||
Activity: "",
|
||||
Status: api.JobStatusQueued,
|
||||
WorkerTag: &api.WorkerTag{
|
||||
Id: ptr(workerTagUUID),
|
||||
Name: "first tag",
|
||||
Description: ptr("my first tag"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -313,8 +313,11 @@ func (f *Flamenco) FetchWorkerTag(e echo.Context, tagUUID string) error {
|
||||
logger.Error().Err(err).Msg("fetching worker tag")
|
||||
return sendAPIError(e, http.StatusInternalServerError, "error fetching worker tag: %v", err)
|
||||
}
|
||||
if tag == nil {
|
||||
panic("Could fetch a worker tag without error, but then the returned tag was still nil")
|
||||
}
|
||||
|
||||
return e.JSON(http.StatusOK, workerTagDBtoAPI(*tag))
|
||||
return e.JSON(http.StatusOK, workerTagDBtoAPI(tag))
|
||||
}
|
||||
|
||||
func (f *Flamenco) UpdateWorkerTag(e echo.Context, tagUUID string) error {
|
||||
@ -387,8 +390,8 @@ func (f *Flamenco) FetchWorkerTags(e echo.Context) error {
|
||||
|
||||
apiTags := []api.WorkerTag{}
|
||||
for _, dbTag := range dbTags {
|
||||
apiTag := workerTagDBtoAPI(*dbTag)
|
||||
apiTags = append(apiTags, apiTag)
|
||||
apiTag := workerTagDBtoAPI(dbTag)
|
||||
apiTags = append(apiTags, *apiTag)
|
||||
}
|
||||
|
||||
tagList := api.WorkerTagList{
|
||||
@ -443,7 +446,7 @@ func (f *Flamenco) CreateWorkerTag(e echo.Context) error {
|
||||
sioUpdate := eventbus.NewWorkerTagUpdate(&dbTag)
|
||||
f.broadcaster.BroadcastNewWorkerTag(sioUpdate)
|
||||
|
||||
return e.JSON(http.StatusOK, workerTagDBtoAPI(dbTag))
|
||||
return e.JSON(http.StatusOK, workerTagDBtoAPI(&dbTag))
|
||||
}
|
||||
|
||||
func workerSummary(w persistence.Worker) api.WorkerSummary {
|
||||
@ -479,7 +482,7 @@ func workerDBtoAPI(w persistence.Worker) api.Worker {
|
||||
if len(w.Tags) > 0 {
|
||||
tags := []api.WorkerTag{}
|
||||
for i := range w.Tags {
|
||||
tags = append(tags, workerTagDBtoAPI(*w.Tags[i]))
|
||||
tags = append(tags, *workerTagDBtoAPI(w.Tags[i]))
|
||||
}
|
||||
apiWorker.Tags = &tags
|
||||
}
|
||||
@ -487,7 +490,11 @@ func workerDBtoAPI(w persistence.Worker) api.Worker {
|
||||
return apiWorker
|
||||
}
|
||||
|
||||
func workerTagDBtoAPI(wc persistence.WorkerTag) api.WorkerTag {
|
||||
func workerTagDBtoAPI(wc *persistence.WorkerTag) *api.WorkerTag {
|
||||
if wc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
uuid := wc.UUID // Take a copy for safety.
|
||||
|
||||
apiTag := api.WorkerTag{
|
||||
@ -497,5 +504,5 @@ func workerTagDBtoAPI(wc persistence.WorkerTag) api.WorkerTag {
|
||||
if len(wc.Description) > 0 {
|
||||
apiTag.Description = &wc.Description
|
||||
}
|
||||
return apiTag
|
||||
return &apiTag
|
||||
}
|
||||
|
@ -359,6 +359,18 @@ func (db *DB) FetchJob(ctx context.Context, jobUUID string) (*Job, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sqlcJob.WorkerTagID.Valid {
|
||||
workerTag, err := fetchWorkerTagByID(db.gormDB, uint(sqlcJob.WorkerTagID.Int64))
|
||||
switch {
|
||||
case errors.Is(err, sql.ErrNoRows):
|
||||
return nil, ErrWorkerTagNotFound
|
||||
case err != nil:
|
||||
return nil, workerTagError(err, "fetching worker tag of job")
|
||||
}
|
||||
gormJob.WorkerTag = workerTag
|
||||
}
|
||||
|
||||
return &gormJob, nil
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,38 @@ func TestStoreAuthoredJobWithShamanCheckoutID(t *testing.T) {
|
||||
assert.Equal(t, job.Storage.ShamanCheckoutID, fetchedJob.Storage.ShamanCheckoutID)
|
||||
}
|
||||
|
||||
func TestStoreAuthoredJobWithWorkerTag(t *testing.T) {
|
||||
ctx, cancel, db := persistenceTestFixtures(1 * time.Second)
|
||||
defer cancel()
|
||||
|
||||
workerTagUUID := "daa811ac-6861-4004-8748-7700aebc244c"
|
||||
require.NoError(t, db.CreateWorkerTag(ctx, &WorkerTag{
|
||||
UUID: workerTagUUID,
|
||||
Name: "🐈",
|
||||
Description: "Mrieuw",
|
||||
}))
|
||||
workerTag, err := db.FetchWorkerTag(ctx, workerTagUUID)
|
||||
require.NoError(t, err)
|
||||
|
||||
job := createTestAuthoredJobWithTasks()
|
||||
job.WorkerTagUUID = workerTagUUID
|
||||
|
||||
err = db.StoreAuthoredJob(ctx, job)
|
||||
require.NoError(t, err)
|
||||
|
||||
fetchedJob, err := db.FetchJob(ctx, job.JobID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, fetchedJob)
|
||||
|
||||
require.NotNil(t, fetchedJob.WorkerTagID)
|
||||
assert.Equal(t, *fetchedJob.WorkerTagID, workerTag.ID)
|
||||
|
||||
require.NotNil(t, fetchedJob.WorkerTag)
|
||||
assert.Equal(t, fetchedJob.WorkerTag.Name, workerTag.Name)
|
||||
assert.Equal(t, fetchedJob.WorkerTag.Description, workerTag.Description)
|
||||
assert.Equal(t, fetchedJob.WorkerTag.UUID, workerTagUUID)
|
||||
}
|
||||
|
||||
func TestFetchTaskJobUUID(t *testing.T) {
|
||||
ctx, cancel, db := persistenceTestFixtures(1 * time.Second)
|
||||
defer cancel()
|
||||
|
@ -53,6 +53,16 @@ func fetchWorkerTag(gormDB *gorm.DB, uuid string) (*WorkerTag, error) {
|
||||
return &w, nil
|
||||
}
|
||||
|
||||
// fetchWorkerTagByID fetches the worker tag using the given database instance.
|
||||
func fetchWorkerTagByID(gormDB *gorm.DB, id uint) (*WorkerTag, error) {
|
||||
w := WorkerTag{}
|
||||
tx := gormDB.First(&w, "id = ?", id)
|
||||
if tx.Error != nil {
|
||||
return nil, workerTagError(tx.Error, "fetching worker tag")
|
||||
}
|
||||
return &w, nil
|
||||
}
|
||||
|
||||
func (db *DB) SaveWorkerTag(ctx context.Context, tag *WorkerTag) error {
|
||||
if err := db.gormDB.WithContext(ctx).Save(tag).Error; err != nil {
|
||||
return workerTagError(err, "saving worker tag")
|
||||
|
@ -52,9 +52,15 @@
|
||||
{{ jobData.status }}
|
||||
</dd>
|
||||
|
||||
<dt class="field-type" title="Type">Type</dt>
|
||||
<dt class="field-type" title="Job Type">Job Type</dt>
|
||||
<dd>{{ jobType ? jobType.label : jobData.type }}</dd>
|
||||
|
||||
<dt class="field-worker-tag" title="Worker Tag">Worker Tag</dt>
|
||||
<dd v-if="jobData.worker_tag" :title="jobData.worker_tag.description">
|
||||
{{ jobData.worker_tag.name }}
|
||||
</dd>
|
||||
<dd v-else class="no-worker-tag">All Workers</dd>
|
||||
|
||||
<dt class="field-priority" title="Priority">Priority</dt>
|
||||
<dd>
|
||||
<PopoverEditableJobPriority :jobId="jobData.id" :priority="jobData.priority" />
|
||||
@ -289,4 +295,8 @@ export default {
|
||||
color: var(--indicator-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd.no-worker-tag {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user