mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
[ui] Adds meta k/v tables to Task Group and Task pages (#24594)
* Experimenting with a generic meta job-part component * Taskstate.task gets me every time * continue-on-error false test * continue-on-error back in, but explicit success check after exam * Testfixes for new meta structure on tasks and groups * Clean up test and dev code
This commit is contained in:
3
.changelog/24594.txt
Normal file
3
.changelog/24594.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
ui: Adds metadata tables to Task Group and Task pages
|
||||
```
|
||||
@@ -62,13 +62,13 @@ export default class TaskGroup extends Fragment {
|
||||
|
||||
@fragment('group-scaling') scaling;
|
||||
|
||||
@attr() meta;
|
||||
@fragment('structured-attributes') meta;
|
||||
|
||||
@computed('job.meta.raw', 'meta')
|
||||
@computed('job.meta.raw', 'meta.raw')
|
||||
get mergedMeta() {
|
||||
return {
|
||||
...this.job.get('meta.raw'),
|
||||
...this.meta,
|
||||
...this.get('meta.raw'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,15 +21,15 @@ export default class Task extends Fragment {
|
||||
@fragmentArray('action', { defaultValue: () => [] })
|
||||
actions;
|
||||
|
||||
@attr() meta;
|
||||
@fragment('structured-attributes') meta;
|
||||
|
||||
@fragment('task-schedule') schedule;
|
||||
|
||||
@computed('taskGroup.mergedMeta', 'meta')
|
||||
@computed('meta.raw', 'taskGroup.mergedMeta')
|
||||
get mergedMeta() {
|
||||
return {
|
||||
...this.taskGroup.mergedMeta,
|
||||
...this.meta,
|
||||
...this.meta?.raw,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -287,4 +287,9 @@
|
||||
</ListTable>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.model.task.meta}}
|
||||
<JobPage::Parts::Meta
|
||||
@meta={{this.model.task.meta}}
|
||||
/>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
PlacementFailures=(component "job-page/parts/placement-failures" job=@job)
|
||||
TaskGroups=(component "job-page/parts/task-groups" job=@job)
|
||||
RecentAllocations=(component "job-page/parts/recent-allocations" job=@job activeTask=@activeTask setActiveTaskQueryParam=@setActiveTaskQueryParam)
|
||||
Meta=(component "job-page/parts/meta" job=@job)
|
||||
Meta=(component "job-page/parts/meta" meta=@job.meta)
|
||||
DasRecommendations=(component
|
||||
"job-page/parts/das-recommendations" job=@job
|
||||
)
|
||||
@@ -35,4 +35,4 @@
|
||||
|
||||
)
|
||||
)
|
||||
}}
|
||||
}}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
{{#if @job.meta.structured}}
|
||||
{{#if @meta.structured}}
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">
|
||||
Meta
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="boxed-section-body is-full-bleed">
|
||||
<AttributesTable
|
||||
data-test-meta
|
||||
@attributePairs={{@job.meta.structured.root}}
|
||||
@attributePairs={{@meta.structured.root}}
|
||||
@class="attributes-table" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
</t.head>
|
||||
<t.body @key="model.id" as |row|>
|
||||
<AllocationRow
|
||||
{{keyboard-shortcut
|
||||
{{keyboard-shortcut
|
||||
enumerated=true
|
||||
action=(action "gotoAllocation" row.model)
|
||||
}}
|
||||
@@ -360,4 +360,10 @@
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.model.meta}}
|
||||
<JobPage::Parts::Meta
|
||||
@meta={{this.model.meta}}
|
||||
/>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
@@ -57,6 +57,9 @@ export default Factory.extend({
|
||||
// When true, the group will simulate a "scheduled" block's paused state
|
||||
withPausedTasks: false,
|
||||
|
||||
// When true, the tasks will have metadata
|
||||
withTaskMeta: false,
|
||||
|
||||
afterCreate(group, server) {
|
||||
let taskIds = [];
|
||||
let volumes = Object.keys(group.volumes);
|
||||
@@ -114,6 +117,7 @@ export default Factory.extend({
|
||||
})),
|
||||
createRecommendations: group.createRecommendations,
|
||||
withSchedule: group.withPausedTasks,
|
||||
withMeta: group.withTaskMeta,
|
||||
});
|
||||
});
|
||||
taskIds = tasks.mapBy('id');
|
||||
|
||||
@@ -26,6 +26,8 @@ export default Factory.extend({
|
||||
// Set in the TaskGroup factory
|
||||
volumeMounts: [],
|
||||
|
||||
meta: null,
|
||||
|
||||
JobID: '',
|
||||
|
||||
name: (id) => `task-${dasherize(faker.hacker.noun())}-${id}`,
|
||||
@@ -128,5 +130,9 @@ export default Factory.extend({
|
||||
});
|
||||
task.update({ schedule: schedule });
|
||||
}
|
||||
|
||||
if (task.withMeta) {
|
||||
task.update({ meta: { raw: { foo: 'bar' } } });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -12,7 +12,6 @@ import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
|
||||
import Task from 'nomad-ui/tests/pages/allocations/task/detail';
|
||||
import Layout from 'nomad-ui/tests/pages/layout';
|
||||
import moment from 'moment';
|
||||
|
||||
let allocation;
|
||||
let task;
|
||||
|
||||
@@ -213,6 +212,28 @@ module('Acceptance | task detail', function (hooks) {
|
||||
});
|
||||
});
|
||||
|
||||
test('when a task group has metadata, the metadata table is shown', async function (assert) {
|
||||
const job = server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
const taskGroup = server.create('task-group', {
|
||||
job,
|
||||
name: 'scaling',
|
||||
count: 1,
|
||||
withTaskMeta: true,
|
||||
});
|
||||
job.update({ taskGroupIds: [taskGroup.id] });
|
||||
allocation = server.db.allocations[1];
|
||||
server.db.taskStates.update(
|
||||
{ allocationId: allocation.id },
|
||||
{ state: 'running' }
|
||||
);
|
||||
const jobTask = taskGroup.tasks.models[0];
|
||||
task = jobTask;
|
||||
await Task.visit({ id: allocation.id, name: task.name });
|
||||
assert.ok(Task.hasMeta);
|
||||
});
|
||||
|
||||
test('each recent event should list the time, type, and description of the event', async function (assert) {
|
||||
const event = server.db.taskEvents.where({ taskStateId: task.id })[0];
|
||||
const recentEvent = Task.events.objectAt(Task.events.length - 1);
|
||||
|
||||
@@ -453,6 +453,19 @@ module('Acceptance | task group detail', function (hooks) {
|
||||
assert.notOk(TaskGroup.hasVolumes);
|
||||
});
|
||||
|
||||
test('when the task group has metadata, the metadata table is shown', async function (assert) {
|
||||
job = server.create('job', {
|
||||
meta: { raw: { a: 'b' } },
|
||||
});
|
||||
taskGroup = server.create('task-group', {
|
||||
job,
|
||||
meta: { raw: { foo: 'bar' } },
|
||||
});
|
||||
await TaskGroup.visit({ id: job.id, name: taskGroup.name });
|
||||
|
||||
assert.ok(TaskGroup.hasMeta);
|
||||
});
|
||||
|
||||
test('each row in the volumes table lists information about the volume', async function (assert) {
|
||||
await TaskGroup.visit({ id: job.id, name: taskGroup.name });
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@ export default create({
|
||||
clientSource: text('[data-test-volume-client-source]'),
|
||||
}),
|
||||
|
||||
hasMeta: isPresent('[data-test-meta]'),
|
||||
|
||||
events: collection('[data-test-task-event]', {
|
||||
time: text('[data-test-task-event-time]'),
|
||||
type: text('[data-test-task-event-type]'),
|
||||
|
||||
@@ -54,6 +54,8 @@ export default create({
|
||||
permissions: text('[data-test-volume-permissions]'),
|
||||
}),
|
||||
|
||||
hasMeta: isPresent('[data-test-meta]'),
|
||||
|
||||
hasScaleEvents: isPresent('[data-test-scale-events]'),
|
||||
scaleEvents: collection(
|
||||
'[data-test-scale-events] [data-test-accordion-head]',
|
||||
|
||||
@@ -76,24 +76,22 @@ module('Unit | Model | task-group', function (hooks) {
|
||||
const jobWithMeta = run(() =>
|
||||
store.createRecord('job', {
|
||||
name: 'example-with-meta',
|
||||
meta: store.createFragment('structured-attributes', {
|
||||
raw: { a: 'b' },
|
||||
}),
|
||||
meta: { raw: { a: 'b' } },
|
||||
taskGroups: [
|
||||
{
|
||||
name: 'one',
|
||||
meta: { c: 'd' },
|
||||
meta: { raw: { c: 'd' } },
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
},
|
||||
{
|
||||
name: 'three',
|
||||
meta: null,
|
||||
meta: { raw: null },
|
||||
},
|
||||
{
|
||||
name: 'four',
|
||||
meta: {},
|
||||
meta: { raw: {} },
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -114,18 +112,18 @@ module('Unit | Model | task-group', function (hooks) {
|
||||
taskGroups: [
|
||||
{
|
||||
name: 'one',
|
||||
meta: { c: 'd' },
|
||||
meta: { raw: { c: 'd' } },
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
},
|
||||
{
|
||||
name: 'three',
|
||||
meta: null,
|
||||
meta: { raw: null },
|
||||
},
|
||||
{
|
||||
name: 'four',
|
||||
meta: {},
|
||||
meta: { raw: {} },
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -20,22 +20,22 @@ module('Unit | Model | task', function (hooks) {
|
||||
taskGroups: [
|
||||
{
|
||||
name: 'one',
|
||||
meta: { a: 'b' },
|
||||
meta: { raw: { a: 'b' } },
|
||||
tasks: [
|
||||
{
|
||||
name: 'task-one',
|
||||
meta: { c: 'd' },
|
||||
meta: { raw: { c: 'd' } },
|
||||
},
|
||||
{
|
||||
name: 'task-two',
|
||||
},
|
||||
{
|
||||
name: 'task-three',
|
||||
meta: null,
|
||||
meta: { raw: null },
|
||||
},
|
||||
{
|
||||
name: 'task-four',
|
||||
meta: {},
|
||||
meta: { raw: {} },
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -44,18 +44,18 @@ module('Unit | Model | task', function (hooks) {
|
||||
tasks: [
|
||||
{
|
||||
name: 'task-one',
|
||||
meta: { c: 'd' },
|
||||
meta: { raw: { c: 'd' } },
|
||||
},
|
||||
{
|
||||
name: 'task-two',
|
||||
},
|
||||
{
|
||||
name: 'task-three',
|
||||
meta: null,
|
||||
meta: { raw: null },
|
||||
},
|
||||
{
|
||||
name: 'task-four',
|
||||
meta: {},
|
||||
meta: { raw: {} },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user