github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/controllers/jobs/job/task-group.js (about) 1 /* eslint-disable ember/no-incorrect-calls-with-inline-anonymous-functions */ 2 import { inject as service } from '@ember/service'; 3 import { alias, readOnly } from '@ember/object/computed'; 4 import Controller from '@ember/controller'; 5 import { action, computed, get } from '@ember/object'; 6 import { scheduleOnce } from '@ember/runloop'; 7 import intersection from 'lodash.intersection'; 8 import Sortable from 'nomad-ui/mixins/sortable'; 9 import Searchable from 'nomad-ui/mixins/searchable'; 10 import WithNamespaceResetting from 'nomad-ui/mixins/with-namespace-resetting'; 11 import { 12 serialize, 13 deserializedQueryParam as selection, 14 } from 'nomad-ui/utils/qp-serialize'; 15 import classic from 'ember-classic-decorator'; 16 import localStorageProperty from 'nomad-ui/utils/properties/local-storage'; 17 18 @classic 19 export default class TaskGroupController extends Controller.extend( 20 Sortable, 21 Searchable, 22 WithNamespaceResetting 23 ) { 24 @service userSettings; 25 @service can; 26 27 queryParams = [ 28 { 29 currentPage: 'page', 30 }, 31 { 32 searchTerm: 'search', 33 }, 34 { 35 sortProperty: 'sort', 36 }, 37 { 38 sortDescending: 'desc', 39 }, 40 { 41 qpStatus: 'status', 42 }, 43 { 44 qpClient: 'client', 45 }, 46 'activeTask', 47 ]; 48 49 currentPage = 1; 50 @readOnly('userSettings.pageSize') pageSize; 51 52 qpStatus = ''; 53 qpClient = ''; 54 sortProperty = 'modifyIndex'; 55 sortDescending = true; 56 activeTask = null; 57 58 @computed 59 get searchProps() { 60 return ['shortId', 'name']; 61 } 62 63 @localStorageProperty('nomadShowSubTasks', true) showSubTasks; 64 65 @action 66 toggleShowSubTasks(e) { 67 e.preventDefault(); 68 this.set('showSubTasks', !this.get('showSubTasks')); 69 } 70 71 @computed('model.allocations.[]') 72 get allocations() { 73 return this.get('model.allocations') || []; 74 } 75 76 @computed('allocations.[]', 'selectionStatus', 'selectionClient') 77 get filteredAllocations() { 78 const { selectionStatus, selectionClient } = this; 79 80 return this.allocations.filter((alloc) => { 81 if ( 82 selectionStatus.length && 83 !selectionStatus.includes(alloc.clientStatus) 84 ) { 85 return false; 86 } 87 if ( 88 selectionClient.length && 89 !selectionClient.includes(alloc.get('node.shortId')) 90 ) { 91 return false; 92 } 93 94 return true; 95 }); 96 } 97 98 @alias('filteredAllocations') listToSort; 99 @alias('listSorted') listToSearch; 100 @alias('listSearched') sortedAllocations; 101 102 @selection('qpStatus') selectionStatus; 103 @selection('qpClient') selectionClient; 104 105 @computed('model.scaleState.events.@each.time', function () { 106 const events = get(this, 'model.scaleState.events'); 107 if (events) { 108 return events.sortBy('time').reverse(); 109 } 110 return []; 111 }) 112 sortedScaleEvents; 113 114 @computed('sortedScaleEvents.@each.hasCount', function () { 115 const countEventsCount = this.sortedScaleEvents.filterBy('hasCount').length; 116 return ( 117 countEventsCount > 1 && 118 countEventsCount >= this.sortedScaleEvents.length / 2 119 ); 120 }) 121 shouldShowScaleEventTimeline; 122 123 @computed('model.job.{namespace,runningDeployment}') 124 get tooltipText() { 125 if ( 126 this.can.cannot('scale job', null, { 127 namespace: this.model.job.namespace.get('name'), 128 }) 129 ) 130 return "You aren't allowed to scale task groups"; 131 if (this.model.job.runningDeployment) 132 return 'You cannot scale task groups during a deployment'; 133 return undefined; 134 } 135 136 @action 137 gotoAllocation(allocation) { 138 this.transitionToRoute('allocations.allocation', allocation); 139 } 140 141 @action 142 scaleTaskGroup(count) { 143 return this.model.scale(count); 144 } 145 146 get optionsAllocationStatus() { 147 return [ 148 { key: 'pending', label: 'Pending' }, 149 { key: 'running', label: 'Running' }, 150 { key: 'complete', label: 'Complete' }, 151 { key: 'failed', label: 'Failed' }, 152 { key: 'lost', label: 'Lost' }, 153 { key: 'unknown', label: 'Unknown' }, 154 ]; 155 } 156 157 @computed('model.allocations.[]', 'selectionClient') 158 get optionsClients() { 159 const clients = Array.from( 160 new Set(this.model.allocations.mapBy('node.shortId')) 161 ).compact(); 162 163 // Update query param when the list of clients changes. 164 scheduleOnce('actions', () => { 165 // eslint-disable-next-line ember/no-side-effects 166 this.set( 167 'qpClient', 168 serialize(intersection(clients, this.selectionClient)) 169 ); 170 }); 171 172 return clients.sort().map((dc) => ({ key: dc, label: dc })); 173 } 174 175 setFacetQueryParam(queryParam, selection) { 176 this.set(queryParam, serialize(selection)); 177 } 178 179 get taskGroup() { 180 return this.model; 181 } 182 183 get breadcrumb() { 184 const { job, name } = this.taskGroup; 185 return { 186 title: 'Task Group', 187 label: name, 188 args: ['jobs.job.task-group', job, name], 189 }; 190 } 191 192 @action 193 setActiveTaskQueryParam(task) { 194 if (task) { 195 this.set('activeTask', `${task.allocation.id}-${task.name}`); 196 } else { 197 this.set('activeTask', null); 198 } 199 } 200 }