open-nomad/ui/app/templates/jobs/job/task-group.hbs
Jai 49b7e78275
refact: add namespace to nested detail pages (#15261)
* refact: add namespace to job breadcrumb

* refact: edit markup for correctness

* styling: add child span style

* chore: undo prev commits after design exploration

* ui: add namespace to alloc details

* ui: add namespace to task details

* ui: add namespace to taskgroup
2022-11-23 11:36:47 -05:00

355 lines
11 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<Breadcrumb @crumb={{this.breadcrumb}} />
{{page-title "Task group " this.model.name " - Job " this.model.job.name}}
<div class="tabs is-subnav">
<ul>
<li>
<LinkTo
@route="jobs.job.task-group"
@models={{array this.model.job this.model}}
@activeClass="is-active"
>
Overview
</LinkTo>
</li>
</ul>
</div>
<section class="section">
<h1 class="title with-flex">
<span>
{{this.model.name}}
</span>
<div>
<Exec::OpenButton @job={{this.model.job}} @taskGroup={{this.model}} />
{{#if this.model.scaling}}
<StepperInput
data-test-task-group-count-stepper
aria-label={{this.tooltipText}}
@min={{this.model.scaling.min}}
@max={{this.model.scaling.max}}
@value={{this.model.count}}
@class="is-primary is-small"
@disabled={{or
this.model.job.runningDeployment
(cannot "scale job" namespace=this.model.job.namespace.name)
}}
@onChange={{action "scaleTaskGroup"}}
>
Count
</StepperInput>
{{/if}}
</div>
</h1>
<div class="boxed-section is-small">
<div class="boxed-section-body inline-definitions">
<span class="label">
Task Group Details
</span>
<span class="pair" data-test-task-group-tasks>
<span class="term">
# Tasks
</span>
{{this.model.tasks.length}}
</span>
<span class="pair" data-test-task-group-cpu>
<span class="term">
Reserved CPU
</span>
{{format-scheduled-hertz this.model.reservedCPU}}
</span>
<span class="pair" data-test-task-group-mem>
<span class="term">
Reserved Memory
</span>
{{format-scheduled-bytes this.model.reservedMemory start="MiB"}}
{{#if (gt this.model.reservedMemoryMax this.model.reservedMemory)}}
({{format-scheduled-bytes this.model.reservedMemoryMax start="MiB"}}Max)
{{/if}}
</span>
<span class="pair" data-test-task-group-disk>
<span class="term">
Reserved Disk
</span>
{{format-scheduled-bytes this.model.reservedEphemeralDisk start="MiB"}}
</span>
<span class="pair">
<span class="term">
Namespace
</span>
{{this.model.job.namespace.name}}
</span>
{{#if this.model.scaling}}
<span class="pair" data-test-task-group-min>
<span class="term">
Count Range
</span>
{{this.model.scaling.min}}
to
{{this.model.scaling.max}}
</span>
<span class="pair" data-test-task-group-max>
<span class="term">
Scaling Policy?
</span>
{{if this.model.scaling.policy "Yes" "No"}}
</span>
{{/if}}
{{#if (and (can "list variables") this.model.pathLinkedVariable)}}
<span class="pair" data-test-task-group-stat="variables">
<LinkTo @route="variables.variable" @model={{this.model.pathLinkedVariable.id}}>Variables</LinkTo>
</span>
{{/if}}
</div>
</div>
<div class="boxed-section">
<div class="boxed-section-head">
<div>
Allocation Status
<span class="badge is-white">
{{this.allocations.length}}
</span>
</div>
</div>
<div class="boxed-section-body">
<AllocationStatusBar
@allocationContainer={{this.model.summary}}
@class="split-view" as |chart|
>
<ol class="legend">
{{#each chart.data as |datum index|}}
<li
class="{{datum.className}}
{{if (eq datum.label chart.activeDatum.label) "is-active"}}
{{if (eq datum.value 0) "is-empty"}}"
>
<JobPage::Parts::SummaryLegendItem @datum={{datum}} @index={{index}} />
</li>
{{/each}}
</ol>
</AllocationStatusBar>
</div>
</div>
<div class="boxed-section">
<div class="boxed-section-head">
Allocations
<div class="pull-right is-subsection">
<MultiSelectDropdown
data-test-allocation-status-facet
@label="Status"
@options={{this.optionsAllocationStatus}}
@selection={{this.selectionStatus}}
@onSelect={{action this.setFacetQueryParam "qpStatus"}}
/>
<MultiSelectDropdown
data-test-allocation-client-facet
@label="Client"
@options={{this.optionsClients}}
@selection={{this.selectionClient}}
@onSelect={{action this.setFacetQueryParam "qpClient"}}
/>
<SearchBox
@searchTerm={{mut this.searchTerm}}
@placeholder="Search allocations..."
@onChange={{action this.resetPagination}}
@class="is-padded"
@inputClass="is-compact"
/>
<span class="is-padded is-one-line">
<Toggle
@isActive={{this.showSubTasks}}
@onToggle={{this.toggleShowSubTasks}}
title="Show tasks of allocations"
>
Show Tasks
</Toggle>
</span>
</div>
</div>
<div class="boxed-section-body is-full-bleed">
{{#if this.sortedAllocations}}
<ListPagination
@source={{this.sortedAllocations}}
@size={{this.pageSize}}
@page={{this.currentPage}}
@class="allocations" as |p|
>
<ListTable
@source={{p.list}}
@sortProperty={{this.sortProperty}}
@sortDescending={{this.sortDescending}}
@class="with-foot {{if this.showSubTasks "with-collapsed-borders"}}" as |t|
>
<t.head>
<th class="is-narrow"></th>
<t.sort-by @prop="shortId">
ID
</t.sort-by>
<t.sort-by @prop="createIndex" @title="Create Index">
Created
</t.sort-by>
<t.sort-by @prop="modifyIndex" @title="Modify Index">
Modified
</t.sort-by>
<t.sort-by @prop="statusIndex">
Status
</t.sort-by>
<t.sort-by @prop="jobVersion">
Version
</t.sort-by>
<t.sort-by @prop="node.shortId">
Client
</t.sort-by>
<th>
Volume
</th>
<th>
CPU
</th>
<th>
Memory
</th>
</t.head>
<t.body @key="model.id" as |row|>
<AllocationRow
{{keyboard-shortcut
enumerated=true
action=(action "gotoAllocation" row.model)
}}
@data-test-allocation={{row.model.id}}
@allocation={{row.model}}
@context="taskGroup"
@onClick={{action "gotoAllocation" row.model}}
/>
{{#if this.showSubTasks}}
{{#each row.model.states as |task|}}
<TaskSubRow @namespan="8" @taskState={{task}} @active={{eq this.activeTask (concat task.allocation.id "-" task.name)}} @onSetActiveTask={{action 'setActiveTaskQueryParam'}} />
{{/each}}
{{/if}}
</t.body>
</ListTable>
<div class="table-foot">
<PageSizeSelect @onChange={{action this.resetPagination}} />
<nav class="pagination">
<div class="pagination-numbers">
{{p.startsAt}}
{{p.endsAt}}
of
{{this.sortedAllocations.length}}
</div>
<p.prev @class="pagination-previous">
{{x-icon "chevron-left"}}
</p.prev>
<p.next @class="pagination-next">
{{x-icon "chevron-right"}}
</p.next>
<ul class="pagination-list"></ul>
</nav>
</div>
</ListPagination>
{{else if this.allocations.length}}
<div class="boxed-section-body">
<div class="empty-message" data-test-empty-allocations-list>
<h3 class="empty-message-headline" data-test-empty-allocations-list-headline>
No Matches
</h3>
<p class="empty-message-body">
No allocations match the term
<strong>
{{this.searchTerm}}
</strong>
</p>
</div>
</div>
{{else}}
<div class="boxed-section-body">
<div class="empty-message" data-test-empty-allocations-list>
<h3 class="empty-message-headline" data-test-empty-allocations-list-headline>
No Allocations
</h3>
<p class="empty-message-body">
No allocations have been placed.
</p>
</div>
</div>
{{/if}}
</div>
</div>
<LifecycleChart @tasks={{this.model.tasks}} />
{{#if this.model.scaleState.isVisible}}
{{#if this.shouldShowScaleEventTimeline}}
<div data-test-scaling-timeline class="boxed-section">
<div class="boxed-section-head is-hollow">
Scaling Timeline
</div>
<div class="boxed-section-body">
<ScaleEventsChart @events={{this.sortedScaleEvents}} />
</div>
</div>
{{/if}}
<div data-test-scaling-events class="boxed-section">
<div class="boxed-section-head">
Recent Scaling Events
</div>
<div class="boxed-section-body">
<ScaleEventsAccordion @events={{this.sortedScaleEvents}} />
</div>
</div>
{{/if}}
{{#if this.model.volumes.length}}
<div data-test-volumes class="boxed-section">
<div class="boxed-section-head">
Volume Requirements
</div>
<div class="boxed-section-body is-full-bleed">
<ListTable @source={{this.model.volumes}} as |t|>
<t.head>
<th>
Name
</th>
<th>
Type
</th>
<th>
Source
</th>
<th>
Permissions
</th>
</t.head>
<t.body as |row|>
<tr data-test-volume>
<td data-test-volume-name>
{{#if row.model.isCSI}}
{{!-- if volume is per_alloc=true, there's no one specific volume. So, link to the volumes index with an active query --}}
{{#if row.model.perAlloc}}
<LinkTo @route="csi.volumes.index" @query={{hash search=row.model.source}}>{{row.model.name}}</LinkTo>
{{else}}
<LinkTo
@route="csi.volumes.volume"
@model={{concat row.model.source "@" row.model.namespace.id}}
>
{{row.model.name}}
</LinkTo>
{{/if}}
{{else}}
{{row.model.name}}
{{/if}}
</td>
<td data-test-volume-type>
{{row.model.type}}
</td>
<td data-test-volume-source>
{{row.model.source}}
</td>
<td data-test-volume-permissions>
{{if row.model.readOnly "Read" "Read/Write"}}
</td>
</tr>
</t.body>
</ListTable>
</div>
</div>
{{/if}}
</section>