mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 02:15:43 +03:00
Add Ember ESLint plugin (#8134)
This is extracted from #8094, where I have run into some snags. Since these ESLint fixes aren’t actually connected to the Ember 3.16 update but involve changes to many files, we might as well address them separately. Where possible I fixed the problems but in cases where a fix seemed too involved, I added per-line or -file exceptions.
This commit is contained in:
6
.circleci/config.yml
generated
6
.circleci/config.yml
generated
@@ -708,13 +708,13 @@ jobs:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-deps-{{ checksum "ui/yarn.lock" }}
|
||||
- v1-deps-
|
||||
- v2-deps-{{ checksum "ui/yarn.lock" }}
|
||||
- v2-deps-
|
||||
- run:
|
||||
command: cd ui && yarn install
|
||||
name: yarn install
|
||||
- save_cache:
|
||||
key: v1-deps-{{ checksum "ui/yarn.lock" }}
|
||||
key: v2-deps-{{ checksum "ui/yarn.lock" }}
|
||||
paths:
|
||||
- ./ui/node_modules
|
||||
- run:
|
||||
|
||||
@@ -7,13 +7,13 @@ steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-deps-{{ checksum "ui/yarn.lock" }}
|
||||
- v1-deps-
|
||||
- v2-deps-{{ checksum "ui/yarn.lock" }}
|
||||
- v2-deps-
|
||||
- run:
|
||||
name: yarn install
|
||||
command: cd ui && yarn install
|
||||
- save_cache:
|
||||
key: v1-deps-{{ checksum "ui/yarn.lock" }}
|
||||
key: v2-deps-{{ checksum "ui/yarn.lock" }}
|
||||
paths:
|
||||
- ./ui/node_modules
|
||||
- run:
|
||||
|
||||
@@ -7,12 +7,18 @@ module.exports = {
|
||||
browser: true,
|
||||
es6: true,
|
||||
},
|
||||
extends: 'eslint:recommended',
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:ember/recommended',
|
||||
],
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: [
|
||||
'ember'
|
||||
],
|
||||
rules: {
|
||||
indent: ['error', 2, { SwitchCase: 1 }],
|
||||
'linebreak-style': ['error', 'unix'],
|
||||
|
||||
@@ -24,6 +24,8 @@ export default RESTAdapter.extend({
|
||||
'X-Nomad-Token': token,
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
handleResponse(status, headers, payload) {
|
||||
|
||||
@@ -3,9 +3,9 @@ import addToPath from 'nomad-ui/utils/add-to-path';
|
||||
import WithNamespaceIDs from 'nomad-ui/mixins/with-namespace-ids';
|
||||
|
||||
export default Watchable.extend(WithNamespaceIDs, {
|
||||
relationshipFallbackLinks: {
|
||||
relationshipFallbackLinks: Object.freeze({
|
||||
summary: '/summary',
|
||||
},
|
||||
}),
|
||||
|
||||
fetchRawDefinition(job) {
|
||||
const url = this.urlForFindRecord(job.get('id'), 'job');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Watchable from './watchable';
|
||||
|
||||
export default Watchable.extend({
|
||||
queryParamsToAttrs: {
|
||||
queryParamsToAttrs: Object.freeze({
|
||||
type: 'type',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -2,8 +2,8 @@ import Watchable from './watchable';
|
||||
import WithNamespaceIDs from 'nomad-ui/mixins/with-namespace-ids';
|
||||
|
||||
export default Watchable.extend(WithNamespaceIDs, {
|
||||
queryParamsToAttrs: {
|
||||
queryParamsToAttrs: Object.freeze({
|
||||
type: 'type',
|
||||
plugin_id: 'plugin.id',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -24,6 +24,8 @@ export default Component.extend({
|
||||
if (metric === 'cpu' || metric === 'memory') {
|
||||
return this[this.metric];
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
formattedStat: computed('metric', 'stat.used', function() {
|
||||
@@ -32,13 +34,9 @@ export default Component.extend({
|
||||
return this.stat.used;
|
||||
}),
|
||||
|
||||
formattedReserved: computed(
|
||||
'metric',
|
||||
'statsTracker.reservedMemory',
|
||||
'statsTracker.reservedCPU',
|
||||
function() {
|
||||
if (this.metric === 'memory') return `${this.statsTracker.reservedMemory} MiB`;
|
||||
if (this.metric === 'cpu') return `${this.statsTracker.reservedCPU} MHz`;
|
||||
}
|
||||
),
|
||||
formattedReserved: computed('metric', 'statsTracker.{reservedMemory,reservedCPU}', function() {
|
||||
if (this.metric === 'memory') return `${this.statsTracker.reservedMemory} MiB`;
|
||||
if (this.metric === 'cpu') return `${this.statsTracker.reservedCPU} MHz`;
|
||||
return;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-observers */
|
||||
import Component from '@ember/component';
|
||||
import { computed, observer, set } from '@ember/object';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
@@ -27,14 +27,16 @@ export default Component.extend({
|
||||
durationIsCustom: equal('selectedDurationQuickOption.value', 'custom'),
|
||||
customDuration: '',
|
||||
|
||||
durationQuickOptions: computed(() => [
|
||||
{ label: '1 Hour', value: '1h' },
|
||||
{ label: '4 Hours', value: '4h' },
|
||||
{ label: '8 Hours', value: '8h' },
|
||||
{ label: '12 Hours', value: '12h' },
|
||||
{ label: '1 Day', value: '1d' },
|
||||
{ label: 'Custom', value: 'custom' },
|
||||
]),
|
||||
durationQuickOptions: computed(function() {
|
||||
return [
|
||||
{ label: '1 Hour', value: '1h' },
|
||||
{ label: '4 Hours', value: '4h' },
|
||||
{ label: '8 Hours', value: '8h' },
|
||||
{ label: '12 Hours', value: '12h' },
|
||||
{ label: '1 Day', value: '1d' },
|
||||
{ label: 'Custom', value: 'custom' },
|
||||
];
|
||||
}),
|
||||
|
||||
deadline: computed(
|
||||
'deadlineEnabled',
|
||||
|
||||
@@ -19,6 +19,8 @@ export default Component.extend({
|
||||
if (this.model.allocation) {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
type: computed('taskState', function() {
|
||||
@@ -53,5 +55,4 @@ export default Component.extend({
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
});
|
||||
|
||||
@@ -64,19 +64,15 @@ export default Component.extend({
|
||||
} else if (this.mode === 'head' || this.mode === 'tail') {
|
||||
return 'readat';
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
fileUrl: computed(
|
||||
'allocation.id',
|
||||
'allocation.node.httpAddr',
|
||||
'fetchMode',
|
||||
'useServer',
|
||||
function() {
|
||||
const address = this.get('allocation.node.httpAddr');
|
||||
const url = `/v1/client/fs/${this.fetchMode}/${this.allocation.id}`;
|
||||
return this.useServer ? url : `//${address}${url}`;
|
||||
}
|
||||
),
|
||||
fileUrl: computed('allocation.{id,node.httpAddr}', 'fetchMode', 'useServer', function() {
|
||||
const address = this.get('allocation.node.httpAddr');
|
||||
const url = `/v1/client/fs/${this.fetchMode}/${this.allocation.id}`;
|
||||
return this.useServer ? url : `//${address}${url}`;
|
||||
}),
|
||||
|
||||
fileParams: computed('taskState.name', 'file', 'mode', function() {
|
||||
// The Log class handles encoding query params
|
||||
|
||||
@@ -8,11 +8,15 @@ export default Component.extend({
|
||||
if (this.taskState && this.taskState.state === 'running') {
|
||||
return 'is-active';
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
finishedClass: computed('taskState.finishedAt', function() {
|
||||
if (this.taskState && this.taskState.finishedAt) {
|
||||
return 'is-finished';
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-observers */
|
||||
import Component from '@ember/component';
|
||||
import { computed, observer } from '@ember/object';
|
||||
import { computed as overridable } from 'ember-overridable-computed';
|
||||
|
||||
@@ -25,6 +25,7 @@ export default Component.extend({
|
||||
};
|
||||
});
|
||||
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('stateCache', decoratedSource);
|
||||
return decoratedSource;
|
||||
}),
|
||||
|
||||
@@ -29,12 +29,14 @@ export default Component.extend({
|
||||
didReceiveAttrs() {
|
||||
const dropdown = this.dropdown;
|
||||
if (this.isOpen && dropdown) {
|
||||
run.scheduleOnce('afterRender', () => {
|
||||
dropdown.actions.reposition();
|
||||
});
|
||||
run.scheduleOnce('afterRender', this, this.repositionDropdown);
|
||||
}
|
||||
},
|
||||
|
||||
repositionDropdown() {
|
||||
this.dropdown.actions.reposition();
|
||||
},
|
||||
|
||||
actions: {
|
||||
toggle({ key }) {
|
||||
const newSelection = this.selection.slice();
|
||||
|
||||
@@ -12,7 +12,7 @@ const FOCUSABLE = [
|
||||
].join(', ');
|
||||
|
||||
export default Component.extend({
|
||||
classnames: ['popover'],
|
||||
classNames: ['popover'],
|
||||
|
||||
triggerClass: '',
|
||||
isOpen: false,
|
||||
@@ -31,12 +31,14 @@ export default Component.extend({
|
||||
didReceiveAttrs() {
|
||||
const dropdown = this.dropdown;
|
||||
if (this.isOpen && dropdown) {
|
||||
run.scheduleOnce('afterRender', () => {
|
||||
dropdown.actions.reposition();
|
||||
});
|
||||
run.scheduleOnce('afterRender', this, this.repositionDropdown);
|
||||
}
|
||||
},
|
||||
|
||||
repositionDropdown() {
|
||||
this.dropdown.actions.reposition();
|
||||
},
|
||||
|
||||
actions: {
|
||||
openOnArrowDown(dropdown, e) {
|
||||
if (!this.isOpen && e.keyCode === ARROW_DOWN) {
|
||||
|
||||
@@ -17,23 +17,25 @@ export default Component.extend(WindowResizable, {
|
||||
return;
|
||||
}
|
||||
|
||||
run.scheduleOnce('actions', () => {
|
||||
switch (this.mode) {
|
||||
case 'head':
|
||||
this.head.perform();
|
||||
break;
|
||||
case 'tail':
|
||||
this.tail.perform();
|
||||
break;
|
||||
case 'streaming':
|
||||
if (this.isStreaming) {
|
||||
this.stream.perform();
|
||||
} else {
|
||||
this.logger.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
run.scheduleOnce('actions', this, this.performTask);
|
||||
},
|
||||
|
||||
performTask() {
|
||||
switch (this.mode) {
|
||||
case 'head':
|
||||
this.head.perform();
|
||||
break;
|
||||
case 'tail':
|
||||
this.tail.perform();
|
||||
break;
|
||||
case 'streaming':
|
||||
if (this.isStreaming) {
|
||||
this.stream.perform();
|
||||
} else {
|
||||
this.logger.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
@@ -54,17 +56,16 @@ export default Component.extend(WindowResizable, {
|
||||
|
||||
head: task(function*() {
|
||||
yield this.get('logger.gotoHead').perform();
|
||||
run.scheduleOnce('afterRender', () => {
|
||||
this.element.scrollTop = 0;
|
||||
});
|
||||
run.scheduleOnce('afterRender', this, this.scrollToTop);
|
||||
}),
|
||||
|
||||
scrollToTop() {
|
||||
this.element.scrollTop = 0;
|
||||
},
|
||||
|
||||
tail: task(function*() {
|
||||
yield this.get('logger.gotoTail').perform();
|
||||
run.scheduleOnce('afterRender', () => {
|
||||
const cliWindow = this.element;
|
||||
cliWindow.scrollTop = cliWindow.scrollHeight;
|
||||
});
|
||||
run.scheduleOnce('afterRender', this, this.synchronizeScrollPosition, [true]);
|
||||
}),
|
||||
|
||||
synchronizeScrollPosition(force = false) {
|
||||
@@ -78,7 +79,7 @@ export default Component.extend(WindowResizable, {
|
||||
stream: task(function*() {
|
||||
// Force the scroll position to the bottom of the window when starting streaming
|
||||
this.logger.one('tick', () => {
|
||||
run.scheduleOnce('afterRender', () => this.synchronizeScrollPosition(true));
|
||||
run.scheduleOnce('afterRender', this, this.synchronizeScrollPosition, [true]);
|
||||
});
|
||||
|
||||
// Follow the log if the scroll position is near the bottom of the cli window
|
||||
@@ -89,7 +90,7 @@ export default Component.extend(WindowResizable, {
|
||||
}),
|
||||
|
||||
scheduleScrollSynchronization() {
|
||||
run.scheduleOnce('afterRender', () => this.synchronizeScrollPosition());
|
||||
run.scheduleOnce('afterRender', this, this.synchronizeScrollPosition);
|
||||
},
|
||||
|
||||
willDestroy() {
|
||||
|
||||
@@ -28,7 +28,7 @@ export default Component.extend({
|
||||
|
||||
mode: 'stdout',
|
||||
|
||||
logUrl: computed('allocation.id', 'allocation.node.httpAddr', 'useServer', function() {
|
||||
logUrl: computed('allocation.{id,node.httpAddr}', 'useServer', function() {
|
||||
const address = this.get('allocation.node.httpAddr');
|
||||
const allocation = this.get('allocation.id');
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@ export default Component.extend({
|
||||
// Internal state
|
||||
statsError: false,
|
||||
|
||||
enablePolling: computed(() => !Ember.testing),
|
||||
enablePolling: computed(function() {
|
||||
return !Ember.testing;
|
||||
}),
|
||||
|
||||
// Since all tasks for an allocation share the same tracker, use the registry
|
||||
stats: computed('task', 'task.isRunning', function() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-observers */
|
||||
import Controller from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed, observer } from '@ember/object';
|
||||
|
||||
@@ -15,7 +15,7 @@ export default Controller.extend({
|
||||
}),
|
||||
|
||||
network: alias('model.resources.networks.firstObject'),
|
||||
ports: computed('network.reservedPorts.[]', 'network.dynamicPorts.[]', function() {
|
||||
ports: computed('network.{reservedPorts.[],dynamicPorts.[]}', function() {
|
||||
return (this.get('network.reservedPorts') || [])
|
||||
.map(port => ({
|
||||
name: port.Label,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-observers */
|
||||
import { inject as service } from '@ember/service';
|
||||
import Controller from '@ember/controller';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-observers */
|
||||
import { alias } from '@ember/object/computed';
|
||||
import Controller from '@ember/controller';
|
||||
import { computed, observer } from '@ember/object';
|
||||
@@ -24,7 +25,9 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
sortProperty: 'modifyIndex',
|
||||
sortDescending: true,
|
||||
|
||||
searchProps: computed(() => ['shortId', 'name']),
|
||||
searchProps: computed(function() {
|
||||
return ['shortId', 'name'];
|
||||
}),
|
||||
|
||||
onlyPreemptions: false,
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-incorrect-calls-with-inline-anonymous-functions */
|
||||
import { alias, readOnly } from '@ember/object/computed';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Controller, { inject as controller } from '@ember/controller';
|
||||
@@ -35,7 +36,9 @@ export default Controller.extend(
|
||||
sortProperty: 'modifyIndex',
|
||||
sortDescending: true,
|
||||
|
||||
searchProps: computed(() => ['id', 'name', 'datacenter']),
|
||||
searchProps: computed(function() {
|
||||
return ['id', 'name', 'datacenter'];
|
||||
}),
|
||||
|
||||
qpClass: '',
|
||||
qpState: '',
|
||||
@@ -54,25 +57,29 @@ export default Controller.extend(
|
||||
|
||||
// Remove any invalid node classes from the query param/selection
|
||||
scheduleOnce('actions', () => {
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('qpClass', serialize(intersection(classes, this.selectionClass)));
|
||||
});
|
||||
|
||||
return classes.sort().map(dc => ({ key: dc, label: dc }));
|
||||
}),
|
||||
|
||||
optionsState: computed(() => [
|
||||
{ key: 'initializing', label: 'Initializing' },
|
||||
{ key: 'ready', label: 'Ready' },
|
||||
{ key: 'down', label: 'Down' },
|
||||
{ key: 'ineligible', label: 'Ineligible' },
|
||||
{ key: 'draining', label: 'Draining' },
|
||||
]),
|
||||
optionsState: computed(function() {
|
||||
return [
|
||||
{ key: 'initializing', label: 'Initializing' },
|
||||
{ key: 'ready', label: 'Ready' },
|
||||
{ key: 'down', label: 'Down' },
|
||||
{ key: 'ineligible', label: 'Ineligible' },
|
||||
{ key: 'draining', label: 'Draining' },
|
||||
];
|
||||
}),
|
||||
|
||||
optionsDatacenter: computed('nodes.[]', function() {
|
||||
const datacenters = Array.from(new Set(this.nodes.mapBy('datacenter'))).compact();
|
||||
|
||||
// Remove any invalid datacenters from the query param/selection
|
||||
scheduleOnce('actions', () => {
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('qpDatacenter', serialize(intersection(datacenters, this.selectionDatacenter)));
|
||||
});
|
||||
|
||||
@@ -86,6 +93,7 @@ export default Controller.extend(
|
||||
const volumes = Array.from(new Set(allVolumes.mapBy('name')));
|
||||
|
||||
scheduleOnce('actions', () => {
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('qpVolume', serialize(intersection(volumes, this.selectionVolume)));
|
||||
});
|
||||
|
||||
|
||||
@@ -30,8 +30,12 @@ export default Controller.extend(
|
||||
currentPage: 1,
|
||||
pageSize: readOnly('userSettings.pageSize'),
|
||||
|
||||
searchProps: computed(() => ['id']),
|
||||
fuzzySearchProps: computed(() => ['id']),
|
||||
searchProps: computed(function() {
|
||||
return ['id'];
|
||||
}),
|
||||
fuzzySearchProps: computed(function() {
|
||||
return ['id'];
|
||||
}),
|
||||
|
||||
sortProperty: 'id',
|
||||
sortDescending: false,
|
||||
|
||||
@@ -29,24 +29,21 @@ export default Controller.extend(SortableFactory(['updateTime', 'healthy']), {
|
||||
selectionType: selection('qpType'),
|
||||
selectionHealth: selection('qpHealth'),
|
||||
|
||||
optionsType: computed(() => [
|
||||
{ key: 'controller', label: 'Controller' },
|
||||
{ key: 'node', label: 'Node' },
|
||||
]),
|
||||
optionsType: computed(function() {
|
||||
return [{ key: 'controller', label: 'Controller' }, { key: 'node', label: 'Node' }];
|
||||
}),
|
||||
|
||||
optionsHealth: computed(() => [
|
||||
{ key: 'true', label: 'Healthy' },
|
||||
{ key: 'false', label: 'Unhealthy' },
|
||||
]),
|
||||
optionsHealth: computed(function() {
|
||||
return [{ key: 'true', label: 'Healthy' }, { key: 'false', label: 'Unhealthy' }];
|
||||
}),
|
||||
|
||||
combinedAllocations: computed('model.controllers.[]', 'model.nodes.[]', function() {
|
||||
combinedAllocations: computed('model.{controllers.[],nodes.[]}', function() {
|
||||
return this.model.controllers.toArray().concat(this.model.nodes.toArray());
|
||||
}),
|
||||
|
||||
filteredAllocations: computed(
|
||||
'combinedAllocations.[]',
|
||||
'model.controllers.[]',
|
||||
'model.nodes.[]',
|
||||
'model.{controllers.[],nodes.[]}',
|
||||
'selectionType',
|
||||
'selectionHealth',
|
||||
function() {
|
||||
|
||||
@@ -35,14 +35,18 @@ export default Controller.extend(
|
||||
sortProperty: 'id',
|
||||
sortDescending: false,
|
||||
|
||||
searchProps: computed(() => ['name']),
|
||||
fuzzySearchProps: computed(() => ['name']),
|
||||
searchProps: computed(function() {
|
||||
return ['name'];
|
||||
}),
|
||||
fuzzySearchProps: computed(function() {
|
||||
return ['name'];
|
||||
}),
|
||||
fuzzySearchEnabled: true,
|
||||
|
||||
/**
|
||||
Visible volumes are those that match the selected namespace
|
||||
*/
|
||||
visibleVolumes: computed('model.[]', 'model.@each.parent', function() {
|
||||
visibleVolumes: computed('model.{[],@each.parent}', function() {
|
||||
if (!this.model) return [];
|
||||
|
||||
// Namespace related properties are ommitted from the dependent keys
|
||||
|
||||
@@ -43,14 +43,12 @@ export default Controller.extend({
|
||||
allocations: alias('model.allocations'),
|
||||
|
||||
taskState: computed(
|
||||
'allocations.[]',
|
||||
'allocations.{[],@each.isActive}',
|
||||
'allocationShortId',
|
||||
'allocations.@each.isActive',
|
||||
'taskName',
|
||||
'taskGroupName',
|
||||
'allocation',
|
||||
'allocation.states.@each.name',
|
||||
'allocation.states.@each.isRunning',
|
||||
'allocation.states.@each.{name,isRunning}',
|
||||
function() {
|
||||
if (!this.allocations) {
|
||||
return false;
|
||||
@@ -72,6 +70,8 @@ export default Controller.extend({
|
||||
if (allocation) {
|
||||
return allocation.states.find(state => state.name === this.taskName);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
),
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/no-incorrect-calls-with-inline-anonymous-functions */
|
||||
import { inject as service } from '@ember/service';
|
||||
import { alias, readOnly } from '@ember/object/computed';
|
||||
import Controller, { inject as controller } from '@ember/controller';
|
||||
@@ -32,8 +33,12 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
sortProperty: 'modifyIndex',
|
||||
sortDescending: true,
|
||||
|
||||
searchProps: computed(() => ['id', 'name']),
|
||||
fuzzySearchProps: computed(() => ['name']),
|
||||
searchProps: computed(function() {
|
||||
return ['id', 'name'];
|
||||
}),
|
||||
fuzzySearchProps: computed(function() {
|
||||
return ['name'];
|
||||
}),
|
||||
fuzzySearchEnabled: true,
|
||||
|
||||
qpType: '',
|
||||
@@ -46,19 +51,23 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
selectionDatacenter: selection('qpDatacenter'),
|
||||
selectionPrefix: selection('qpPrefix'),
|
||||
|
||||
optionsType: computed(() => [
|
||||
{ key: 'batch', label: 'Batch' },
|
||||
{ key: 'parameterized', label: 'Parameterized' },
|
||||
{ key: 'periodic', label: 'Periodic' },
|
||||
{ key: 'service', label: 'Service' },
|
||||
{ key: 'system', label: 'System' },
|
||||
]),
|
||||
optionsType: computed(function() {
|
||||
return [
|
||||
{ key: 'batch', label: 'Batch' },
|
||||
{ key: 'parameterized', label: 'Parameterized' },
|
||||
{ key: 'periodic', label: 'Periodic' },
|
||||
{ key: 'service', label: 'Service' },
|
||||
{ key: 'system', label: 'System' },
|
||||
];
|
||||
}),
|
||||
|
||||
optionsStatus: computed(() => [
|
||||
{ key: 'pending', label: 'Pending' },
|
||||
{ key: 'running', label: 'Running' },
|
||||
{ key: 'dead', label: 'Dead' },
|
||||
]),
|
||||
optionsStatus: computed(function() {
|
||||
return [
|
||||
{ key: 'pending', label: 'Pending' },
|
||||
{ key: 'running', label: 'Running' },
|
||||
{ key: 'dead', label: 'Dead' },
|
||||
];
|
||||
}),
|
||||
|
||||
optionsDatacenter: computed('visibleJobs.[]', function() {
|
||||
const flatten = (acc, val) => acc.concat(val);
|
||||
@@ -67,6 +76,7 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
// Remove any invalid datacenters from the query param/selection
|
||||
const availableDatacenters = Array.from(allDatacenters).compact();
|
||||
scheduleOnce('actions', () => {
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set(
|
||||
'qpDatacenter',
|
||||
serialize(intersection(availableDatacenters, this.selectionDatacenter))
|
||||
@@ -103,6 +113,7 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
// Remove any invalid prefixes from the query param/selection
|
||||
const availablePrefixes = prefixes.mapBy('prefix');
|
||||
scheduleOnce('actions', () => {
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('qpPrefix', serialize(intersection(availablePrefixes, this.selectionPrefix)));
|
||||
});
|
||||
|
||||
@@ -117,7 +128,7 @@ export default Controller.extend(Sortable, Searchable, {
|
||||
Visible jobs are those that match the selected namespace and aren't children
|
||||
of periodic or parameterized jobs.
|
||||
*/
|
||||
visibleJobs: computed('model.[]', 'model.@each.parent', function() {
|
||||
visibleJobs: computed('model.{[],@each.parent}', function() {
|
||||
// Namespace related properties are ommitted from the dependent keys
|
||||
// due to a prop invalidation bug caused by region switching.
|
||||
const hasNamespaces = this.get('system.namespaces.length');
|
||||
|
||||
@@ -21,7 +21,9 @@ export default Controller.extend(Sortable, Searchable, WithNamespaceResetting, {
|
||||
|
||||
job: alias('model'),
|
||||
|
||||
searchProps: computed(() => ['shortId', 'name', 'taskGroupName']),
|
||||
searchProps: computed(function() {
|
||||
return ['shortId', 'name', 'taskGroupName'];
|
||||
}),
|
||||
|
||||
allocations: computed('model.allocations.[]', function() {
|
||||
return this.get('model.allocations') || [];
|
||||
|
||||
@@ -22,7 +22,9 @@ export default Controller.extend(Sortable, Searchable, WithNamespaceResetting, {
|
||||
sortProperty: 'modifyIndex',
|
||||
sortDescending: true,
|
||||
|
||||
searchProps: computed(() => ['shortId', 'name']),
|
||||
searchProps: computed(function() {
|
||||
return ['shortId', 'name'];
|
||||
}),
|
||||
|
||||
allocations: computed('model.allocations.[]', function() {
|
||||
return this.get('model.allocations') || [];
|
||||
|
||||
@@ -22,9 +22,12 @@ import Fuse from 'fuse.js';
|
||||
Properties provided:
|
||||
- listSearched: a subset of listToSearch of items that meet the search criteria
|
||||
*/
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
searchTerm: '',
|
||||
listToSearch: computed(() => []),
|
||||
listToSearch: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
|
||||
searchProps: null,
|
||||
exactMatchSearchProps: reads('searchProps'),
|
||||
@@ -83,11 +86,7 @@ export default Mixin.create({
|
||||
|
||||
if (this.exactMatchEnabled) {
|
||||
results.push(
|
||||
...exactMatchSearch(
|
||||
searchTerm,
|
||||
this.listToSearch,
|
||||
this.exactMatchSearchProps
|
||||
)
|
||||
...exactMatchSearch(searchTerm, this.listToSearch, this.exactMatchSearchProps)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -96,9 +95,7 @@ export default Mixin.create({
|
||||
}
|
||||
|
||||
if (this.regexEnabled) {
|
||||
results.push(
|
||||
...regexSearch(searchTerm, this.listToSearch, this.regexSearchProps)
|
||||
);
|
||||
results.push(...regexSearch(searchTerm, this.listToSearch, this.regexSearchProps));
|
||||
}
|
||||
|
||||
return results.uniq();
|
||||
|
||||
@@ -21,11 +21,14 @@ import { warn } from '@ember/debug';
|
||||
export default function sortableFactory(properties, fromSortableMixin) {
|
||||
const eachProperties = properties.map(property => `listToSort.@each.${property}`);
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
return Mixin.create({
|
||||
// Override in mixin consumer
|
||||
sortProperty: null,
|
||||
sortDescending: true,
|
||||
listToSort: computed(() => []),
|
||||
listToSort: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
|
||||
_sortableFactoryWarningPrinted: false,
|
||||
|
||||
@@ -44,6 +47,7 @@ export default function sortableFactory(properties, fromSortableMixin) {
|
||||
}
|
||||
|
||||
warn(message, properties.length > 0, { id: 'nomad.no-sortable-properties' });
|
||||
// eslint-disable-next-line ember/no-side-effects
|
||||
this.set('_sortableFactoryWarningPrinted', true);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,21 @@ import { run } from '@ember/runloop';
|
||||
import { assert } from '@ember/debug';
|
||||
import { on } from '@ember/object/evented';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
windowResizeHandler() {
|
||||
assert('windowResizeHandler needs to be overridden in the Component', false);
|
||||
},
|
||||
|
||||
setupWindowResize: on('didInsertElement', function() {
|
||||
run.scheduleOnce('afterRender', this, () => {
|
||||
this.set('_windowResizeHandler', this.windowResizeHandler.bind(this));
|
||||
window.addEventListener('resize', this._windowResizeHandler);
|
||||
});
|
||||
run.scheduleOnce('afterRender', this, this.addResizeListener);
|
||||
}),
|
||||
|
||||
addResizeListener() {
|
||||
this.set('_windowResizeHandler', this.windowResizeHandler.bind(this));
|
||||
window.addEventListener('resize', this._windowResizeHandler);
|
||||
},
|
||||
|
||||
removeWindowResize: on('willDestroyElement', function() {
|
||||
window.removeEventListener('resize', this._windowResizeHandler);
|
||||
}),
|
||||
|
||||
@@ -3,6 +3,7 @@ import Mixin from '@ember/object/mixin';
|
||||
import { assert } from '@ember/debug';
|
||||
import { on } from '@ember/object/evented';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
visibilityHandler() {
|
||||
assert('visibilityHandler needs to be overridden in the Component', false);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
setupController(controller) {
|
||||
if (this.isForbidden) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Mixin from '@ember/object/mixin';
|
||||
import notifyError from 'nomad-ui/utils/notify-error';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
model() {
|
||||
return this._super(...arguments).catch(notifyError(this));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { inject as service } from '@ember/service';
|
||||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
system: service(),
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { inject as controller } from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
system: service(),
|
||||
jobsController: controller('jobs'),
|
||||
|
||||
@@ -3,6 +3,7 @@ import Mixin from '@ember/object/mixin';
|
||||
import { assert } from '@ember/debug';
|
||||
import { on } from '@ember/object/evented';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
visibilityHandler() {
|
||||
assert('visibilityHandler needs to be overridden in the Route', false);
|
||||
|
||||
@@ -3,8 +3,11 @@ import { computed } from '@ember/object';
|
||||
import { assert } from '@ember/debug';
|
||||
import WithVisibilityDetection from './with-route-visibility-detection';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create(WithVisibilityDetection, {
|
||||
watchers: computed(() => []),
|
||||
watchers: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
|
||||
cancelAllWatchers() {
|
||||
this.watchers.forEach(watcher => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { alias, equal, or, and } from '@ember/object/computed';
|
||||
import { alias, equal, or, and, mapBy } from '@ember/object/computed';
|
||||
import { computed } from '@ember/object';
|
||||
import Model from 'ember-data/model';
|
||||
import attr from 'ember-data/attr';
|
||||
@@ -61,8 +61,7 @@ export default Model.extend({
|
||||
'type',
|
||||
'periodic',
|
||||
'parameterized',
|
||||
'parent.periodic',
|
||||
'parent.parameterized',
|
||||
'parent.{periodic,parameterized}',
|
||||
function() {
|
||||
const type = this.type;
|
||||
|
||||
@@ -131,9 +130,11 @@ export default Model.extend({
|
||||
.uniq();
|
||||
}),
|
||||
|
||||
allocationsUnhealthyDrivers: mapBy('allocations', 'unhealthyDrivers'),
|
||||
|
||||
// Getting all unhealthy drivers for a job can be incredibly expensive if the job
|
||||
// has many allocations. This can lead to making an API request for many nodes.
|
||||
unhealthyDrivers: computed('allocations.@each.unhealthyDrivers.[]', function() {
|
||||
unhealthyDrivers: computed('allocationsUnhealthyDrivers.[]', function() {
|
||||
return this.allocations
|
||||
.mapBy('unhealthyDrivers')
|
||||
.reduce((all, drivers) => {
|
||||
@@ -149,7 +150,7 @@ export default Model.extend({
|
||||
|
||||
hasPlacementFailures: and('latestFailureEvaluation', 'hasBlockedEvaluation'),
|
||||
|
||||
latestEvaluation: computed('evaluations.@each.modifyIndex', 'evaluations.isPending', function() {
|
||||
latestEvaluation: computed('evaluations.{@each.modifyIndex,isPending}', function() {
|
||||
const evaluations = this.evaluations;
|
||||
if (!evaluations || evaluations.get('isPending')) {
|
||||
return null;
|
||||
@@ -157,21 +158,19 @@ export default Model.extend({
|
||||
return evaluations.sortBy('modifyIndex').get('lastObject');
|
||||
}),
|
||||
|
||||
latestFailureEvaluation: computed(
|
||||
'evaluations.@each.modifyIndex',
|
||||
'evaluations.isPending',
|
||||
function() {
|
||||
const evaluations = this.evaluations;
|
||||
if (!evaluations || evaluations.get('isPending')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const failureEvaluations = evaluations.filterBy('hasPlacementFailures');
|
||||
if (failureEvaluations) {
|
||||
return failureEvaluations.sortBy('modifyIndex').get('lastObject');
|
||||
}
|
||||
latestFailureEvaluation: computed('evaluations.{@each.modifyIndex,isPending}', function() {
|
||||
const evaluations = this.evaluations;
|
||||
if (!evaluations || evaluations.get('isPending')) {
|
||||
return null;
|
||||
}
|
||||
),
|
||||
|
||||
const failureEvaluations = evaluations.filterBy('hasPlacementFailures');
|
||||
if (failureEvaluations) {
|
||||
return failureEvaluations.sortBy('modifyIndex').get('lastObject');
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
supportsDeployments: equal('type', 'service'),
|
||||
|
||||
@@ -180,6 +179,7 @@ export default Model.extend({
|
||||
runningDeployment: computed('latestDeployment', 'latestDeployment.isRunning', function() {
|
||||
const latest = this.latestDeployment;
|
||||
if (latest.get('isRunning')) return latest;
|
||||
return;
|
||||
}),
|
||||
|
||||
fetchRawDefinition() {
|
||||
|
||||
@@ -62,6 +62,8 @@ export default Model.extend({
|
||||
if (allocation) {
|
||||
return allocation.modifyTime;
|
||||
}
|
||||
|
||||
return;
|
||||
}),
|
||||
|
||||
drivers: fragmentArray('node-driver'),
|
||||
|
||||
@@ -8,12 +8,12 @@ export default Route.extend(WithForbiddenState, {
|
||||
store: service(),
|
||||
system: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Clients',
|
||||
args: ['clients.index'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
beforeModel() {
|
||||
return this.get('system.leader');
|
||||
|
||||
@@ -6,12 +6,12 @@ import notifyForbidden from 'nomad-ui/utils/notify-forbidden';
|
||||
export default Route.extend(WithForbiddenState, {
|
||||
store: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Storage',
|
||||
args: ['csi.index'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
model() {
|
||||
return this.store.query('plugin', { type: 'csi' }).catch(notifyForbidden(this));
|
||||
|
||||
@@ -7,12 +7,12 @@ export default Route.extend(WithForbiddenState, {
|
||||
system: service(),
|
||||
store: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Storage',
|
||||
args: ['csi.index'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
queryParams: {
|
||||
volumeNamespace: {
|
||||
|
||||
@@ -7,12 +7,12 @@ export default Route.extend(WithForbiddenState, {
|
||||
system: service(),
|
||||
store: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Jobs',
|
||||
args: ['jobs.index'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
queryParams: {
|
||||
jobNamespace: {
|
||||
|
||||
@@ -6,12 +6,12 @@ export default Route.extend({
|
||||
store: service(),
|
||||
system: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Run',
|
||||
args: ['jobs.run'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
beforeModel() {
|
||||
if (this.can.cannot('run job')) {
|
||||
|
||||
@@ -8,12 +8,12 @@ export default Route.extend(WithForbiddenState, {
|
||||
store: service(),
|
||||
system: service(),
|
||||
|
||||
breadcrumbs: [
|
||||
breadcrumbs: Object.freeze([
|
||||
{
|
||||
label: 'Servers',
|
||||
args: ['servers.index'],
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
beforeModel() {
|
||||
return this.get('system.leader');
|
||||
|
||||
@@ -6,7 +6,7 @@ export default ApplicationSerializer.extend({
|
||||
externalId: 'ExternalID',
|
||||
},
|
||||
|
||||
embeddedRelationships: ['writeAllocations', 'readAllocations'],
|
||||
embeddedRelationships: Object.freeze(['writeAllocations', 'readAllocations']),
|
||||
|
||||
// Volumes treat Allocations as embedded records. Ember has an
|
||||
// EmbeddedRecords mixin, but it assumes an application is using
|
||||
|
||||
@@ -9,7 +9,7 @@ export default Service.extend({
|
||||
// currentRouteName has all information necessary to compute breadcrumbs,
|
||||
// but it doesn't change when a transition to the same route with a different
|
||||
// model occurs.
|
||||
breadcrumbs: computed('router.currentURL', 'router.currentRouteName', function() {
|
||||
breadcrumbs: computed('router.{currentURL,currentRouteName}', function() {
|
||||
const owner = getOwner(this);
|
||||
const allRoutes = (this.get('router.currentRouteName') || '')
|
||||
.split('.')
|
||||
|
||||
@@ -28,7 +28,9 @@ export default Service.extend({
|
||||
// A read-only way of getting a reference to the registry.
|
||||
// Since this could be overwritten by a bad actor, it isn't
|
||||
// used in getTracker
|
||||
registryRef: computed(() => registry),
|
||||
registryRef: computed(function() {
|
||||
return registry;
|
||||
}),
|
||||
|
||||
getTracker(resource) {
|
||||
if (!resource) return;
|
||||
|
||||
@@ -59,6 +59,7 @@ export default Service.extend({
|
||||
set(key, value) {
|
||||
if (value == null) {
|
||||
window.localStorage.removeItem('nomadActiveRegion');
|
||||
return;
|
||||
} else {
|
||||
// All localStorage values are strings. Stringify first so
|
||||
// the return value is consistent with what is persisted.
|
||||
@@ -110,6 +111,7 @@ export default Service.extend({
|
||||
set(key, value) {
|
||||
if (value == null) {
|
||||
window.localStorage.removeItem('nomadActiveNamespace');
|
||||
return;
|
||||
} else if (typeof value === 'string') {
|
||||
window.localStorage.nomadActiveNamespace = value;
|
||||
return this.namespaces.findBy('id', value);
|
||||
|
||||
@@ -43,6 +43,7 @@ export default Service.extend({
|
||||
|
||||
selfToken: computed('secret', 'fetchSelfToken.lastSuccessful.value', function() {
|
||||
if (this.secret) return this.get('fetchSelfToken.lastSuccessful.value');
|
||||
return;
|
||||
}),
|
||||
|
||||
fetchSelfTokenPolicies: task(function*() {
|
||||
|
||||
@@ -6,7 +6,9 @@ import Service from '@ember/service';
|
||||
let list = {};
|
||||
|
||||
export default Service.extend({
|
||||
_list: computed(() => copy(list, true)),
|
||||
_list: computed(function() {
|
||||
return copy(list, true);
|
||||
}),
|
||||
|
||||
list: readOnly('_list'),
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import queryString from 'query-string';
|
||||
|
||||
const MAX_OUTPUT_LENGTH = 50000;
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
url: '',
|
||||
params: overridable(() => ({})),
|
||||
|
||||
@@ -4,6 +4,7 @@ import { assert } from '@ember/debug';
|
||||
import { task, timeout } from 'ember-concurrency';
|
||||
import jsonWithDefault from 'nomad-ui/utils/json-with-default';
|
||||
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
export default Mixin.create({
|
||||
url: '',
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ import { fetchFailure } from './log';
|
||||
export default EmberObject.extend(AbstractLogger, {
|
||||
reader: null,
|
||||
|
||||
additionalParams: computed(() => ({
|
||||
follow: true,
|
||||
})),
|
||||
additionalParams: computed(function() {
|
||||
return {
|
||||
follow: true,
|
||||
};
|
||||
}),
|
||||
|
||||
start() {
|
||||
return this.poll.perform();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import Ember from 'ember';
|
||||
import fetch from 'fetch';
|
||||
import config from '../config/environment';
|
||||
|
||||
@@ -9,6 +8,6 @@ const mirageEnabled =
|
||||
config['ember-cli-mirage'] &&
|
||||
config['ember-cli-mirage'].enabled !== false;
|
||||
|
||||
const fetchToUse = Ember.testing || mirageEnabled ? fetch : window.fetch || fetch;
|
||||
const fetchToUse = mirageEnabled ? fetch : window.fetch || fetch;
|
||||
|
||||
export default fetchToUse;
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
"ember-test-selectors": "^2.1.0",
|
||||
"ember-truth-helpers": "^2.0.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-ember": "^6.2.0",
|
||||
"eslint-plugin-node": "^9.0.1",
|
||||
"faker": "^4.1.0",
|
||||
"flat": "^4.0.0",
|
||||
|
||||
@@ -111,7 +111,7 @@ export let LiveUpdating = () => {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
|
||||
distributionBarDataRotating: computed('timerTicks', () => {
|
||||
distributionBarDataRotating: computed('timerTicks', function() {
|
||||
return [
|
||||
{ label: 'one', value: Math.round(Math.random() * 50) },
|
||||
{ label: 'two', value: Math.round(Math.random() * 50) },
|
||||
|
||||
@@ -92,6 +92,8 @@ export let LiveData = () => {
|
||||
context: {
|
||||
controller: EmberObject.extend({
|
||||
startTimer: on('init', function() {
|
||||
this.lineChartLive = [];
|
||||
|
||||
this.set(
|
||||
'timer',
|
||||
setInterval(() => {
|
||||
@@ -110,8 +112,6 @@ export let LiveData = () => {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
|
||||
lineChartLive: [],
|
||||
|
||||
secondsFormat() {
|
||||
return date => moment(date).format('HH:mm:ss');
|
||||
},
|
||||
|
||||
@@ -102,11 +102,11 @@ export let HighLowComparison = () => {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
|
||||
metricsHigh: computed(() => {
|
||||
metricsHigh: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
|
||||
metricsLow: computed(() => {
|
||||
metricsLow: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ export let SortableColumns = () => {
|
||||
})
|
||||
),
|
||||
|
||||
sortedShortList: computed('controller.sortProperty', 'controller.sortDescending', function() {
|
||||
sortedShortList: computed('controller.{sortProperty,sortDescending}', function() {
|
||||
let sorted = productMetadata.sortBy(this.get('controller.sortProperty') || 'name');
|
||||
return this.get('controller.sortDescending') ? sorted.reverse() : sorted;
|
||||
}),
|
||||
@@ -278,7 +278,7 @@ export let MultiRow = () => {
|
||||
})
|
||||
),
|
||||
|
||||
sortedShortList: computed('controller.sortProperty', 'controller.sortDescending', function() {
|
||||
sortedShortList: computed('controller.{sortProperty,sortDescending}', function() {
|
||||
let sorted = productMetadata.sortBy(this.get('controller.sortProperty') || 'name');
|
||||
return this.get('controller.sortDescending') ? sorted.reverse() : sorted;
|
||||
}),
|
||||
|
||||
@@ -11,7 +11,10 @@ module('Integration | Component | app breadcrumbs', function(hooks) {
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
const mockBreadcrumbs = Service.extend({
|
||||
breadcrumbs: [],
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.breadcrumbs = [];
|
||||
},
|
||||
});
|
||||
|
||||
this.owner.register('service:breadcrumbs', mockBreadcrumbs);
|
||||
|
||||
@@ -31,8 +31,12 @@ module('Integration | Component | primary metric', function(hooks) {
|
||||
yield trackerSignalPauseSpy();
|
||||
}),
|
||||
|
||||
cpu: computed(() => []),
|
||||
memory: computed(() => []),
|
||||
cpu: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
memory: computed(function() {
|
||||
return [];
|
||||
}),
|
||||
});
|
||||
|
||||
const mockStatsTrackersRegistry = Service.extend({
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import Service from '@ember/service';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import Service from '@ember/service';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import Service from '@ember/service';
|
||||
|
||||
@@ -9,9 +9,12 @@ module('Unit | Mixin | Searchable', function(hooks) {
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
this.subject = function() {
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
const SearchableObject = EmberObject.extend(Searchable, {
|
||||
source: null,
|
||||
searchProps: computed(() => ['id', 'name']),
|
||||
searchProps: computed(function() {
|
||||
return ['id', 'name'];
|
||||
}),
|
||||
listToSearch: alias('source'),
|
||||
});
|
||||
|
||||
@@ -193,9 +196,12 @@ module('Unit | Mixin | Searchable (with pagination)', function(hooks) {
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
this.subject = function() {
|
||||
// eslint-disable-next-line ember/no-new-mixins
|
||||
const SearchablePaginatedObject = EmberObject.extend(Searchable, {
|
||||
source: null,
|
||||
searchProps: computed(() => ['id', 'name']),
|
||||
searchProps: computed(function() {
|
||||
return ['id', 'name'];
|
||||
}),
|
||||
listToSearch: alias('source'),
|
||||
currentPage: 1,
|
||||
});
|
||||
|
||||
@@ -10,11 +10,11 @@ import { settled } from '@ember/test-helpers';
|
||||
let startSpy, stopSpy, initSpy, fetchSpy;
|
||||
|
||||
const MockStreamer = EmberObject.extend({
|
||||
poll: {
|
||||
isRunning: false,
|
||||
},
|
||||
|
||||
init() {
|
||||
this.poll = {
|
||||
isRunning: false,
|
||||
};
|
||||
|
||||
initSpy(...arguments);
|
||||
},
|
||||
|
||||
|
||||
26
ui/yarn.lock
26
ui/yarn.lock
@@ -1279,6 +1279,11 @@
|
||||
ember-cli-typescript "^2.0.2"
|
||||
inflection "1.12.0"
|
||||
|
||||
"@ember-data/rfc395-data@^0.0.4":
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ember-data/rfc395-data/-/rfc395-data-0.0.4.tgz#ecb86efdf5d7733a76ff14ea651a1b0ed1f8a843"
|
||||
integrity sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ==
|
||||
|
||||
"@ember-data/serializer@3.12.4":
|
||||
version "3.12.4"
|
||||
resolved "https://registry.yarnpkg.com/@ember-data/serializer/-/serializer-3.12.4.tgz#e3ae7143f0cd736722daa3a640e11dc07c8aef5a"
|
||||
@@ -7427,6 +7432,11 @@ ember-responsive@^3.0.4:
|
||||
dependencies:
|
||||
ember-cli-babel "^6.6.0"
|
||||
|
||||
ember-rfc176-data@^0.3.11:
|
||||
version "0.3.13"
|
||||
resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.13.tgz#ed1712a26e65fec703655f35410414aa1982cf3b"
|
||||
integrity sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ==
|
||||
|
||||
ember-rfc176-data@^0.3.12, ember-rfc176-data@^0.3.9:
|
||||
version "0.3.12"
|
||||
resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.12.tgz#90d82878e69e2ac9a5438e8ce14d12c6031c5bd2"
|
||||
@@ -7714,6 +7724,15 @@ escodegen@^1.11.0:
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-plugin-ember@^6.2.0:
|
||||
version "6.10.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-ember/-/eslint-plugin-ember-6.10.1.tgz#ca7a5cc28b91a247c31b1686421a66281467f238"
|
||||
integrity sha512-RZI0+UoR4xeD6UE3KQCUwbN2nZOIIPaFCCXqBIRXDr0rFuwvknAHqYtDPJVZicvTzNHa4TEZvAKqfbE8t7SztQ==
|
||||
dependencies:
|
||||
"@ember-data/rfc395-data" "^0.0.4"
|
||||
ember-rfc176-data "^0.3.11"
|
||||
snake-case "^2.1.0"
|
||||
|
||||
eslint-plugin-es@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998"
|
||||
@@ -13960,6 +13979,13 @@ slice-ansi@^2.1.0:
|
||||
astral-regex "^1.0.0"
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
|
||||
snake-case@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
|
||||
integrity sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=
|
||||
dependencies:
|
||||
no-case "^2.2.0"
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
|
||||
Reference in New Issue
Block a user