mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
Epic: Evaluation Detail Sidebar (#12370)
* chore: prettify gutter-menu * chore: add portal packages * styling: add styles sidebar and portal behavior * ui: sidebar component * ui: create and implement statechart for evals * ui: actor-relationship service and provider component * ui: d3 hierarchy computation * chore: add render-modifiers and curved arrows * ui: create evaluation actor div * fix related evaluations schema * ui: register/deregister evaluation divs * ui: handle resize behavior * bug: infinite re-render cycle * fix: conditional logic to prevent infinite render of flex resizing * ui: related evaluations schema and request param * ui: fix testing for evaluations * refact: make related-evals a proper has-many * chore: don't pauseTest * temp: debug d3 hierarchy * ui: move derived state logic into backing component class for detail * ui: deprecated related evaluations logic in statechart * ui: update evaluation models * ui: update logic to paint svg in non-viewable scroll region * ui: update styling * ui: testing for eval detail view * ui: delete detail from template directory * ui: break detail component down * ui: static data for /evaluation/:id endpoint * ui: fix styling of d3 viz * ui: add query parameter adapter for evals * ui: last minute design requests * wip: address browser updating detail view behavior * refact: handle query-state change in statechart * conditional class looking for currentEval equality (#12411) * F UI/evaluation detail sidebar rel evals (#12415) * ui: remove busy id alias from statechart * ui: edit related evaluations viz error message * ui: bug fixes on related evaluations view (#12423) * ui: remove busy id alias from statechart * ui: edit related evaluations viz error message * ui: update error state * ui: related evaluation outline styling * Related evaluation stylefile and non-link if it matches the active sidebar (#12428) * Adds tabbable and keyboard pressable evaluation table rows (#12433) * ui: fix failing eval list tests (#12437) * ui: move styling into classes (#12438) * fix test failures (#12444) * ui: move styling into classes * ui: eslint disable * ui: allocations have evaluations as async relationships * ui: fix evaluation refresh button (#12447) * ui: move styling into classes * ui: eslint disable * ui: allocations have evaluations as async relationships * ui: refresh bug * ui: final touches on sidebar (#12462) * chore: turn off template linting rules Temporarily turning off template linting because we dont have a set CSS convention and the release needs to go out ASAP. * doc: deprecate out of date comments and vars * ui: edit mirage server fetch logic * ui: style sidebar relative * Modification to mocked related evals and manually set 100% height on svg (#12460) * F UI/evaluation detail sidebar final touches (#12463) * chore: turn off template linting rules Temporarily turning off template linting because we dont have a set CSS convention and the release needs to go out ASAP. * doc: deprecate out of date comments and vars * ui: edit mirage server fetch logic * ui: style sidebar relative * ui: account for new related eval added to chain Co-authored-by: Michael Klein <michael@firstiwaslike.com> Co-authored-by: Phil Renaud <phil@riotindustries.com>
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
module.exports = {
|
||||
extends: 'recommended',
|
||||
rules: {
|
||||
'link-href-attributes': 'off',
|
||||
'no-action': 'off',
|
||||
'no-invalid-interactive': 'off',
|
||||
'no-inline-styles': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -8,4 +8,13 @@ export default class EvaluationAdapter extends ApplicationAdapter {
|
||||
result.meta = { nextToken: headers['x-nomad-nexttoken'] };
|
||||
return result;
|
||||
}
|
||||
|
||||
urlForFindRecord(_id, _modelName, snapshot) {
|
||||
const url = super.urlForFindRecord(...arguments);
|
||||
|
||||
if (snapshot.adapterOptions?.related) {
|
||||
return `${url}?related=true`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
168
ui/app/components/evaluation-sidebar/detail.hbs
Normal file
168
ui/app/components/evaluation-sidebar/detail.hbs
Normal file
@@ -0,0 +1,168 @@
|
||||
{{#let this.currentEvalDetail as |evaluation|}}
|
||||
<Portal @target="eval-detail-portal">
|
||||
<div
|
||||
data-test-eval-detail
|
||||
data-test-eval-detail-is-open={{this.isSideBarOpen}}
|
||||
class="sidebar {{if this.isSideBarOpen "open"}}"
|
||||
{{on-click-outside
|
||||
this.closeSidebar
|
||||
capture=true
|
||||
exceptSelector="tr[data-eval-row]"
|
||||
}}
|
||||
>
|
||||
{{#if this.isLoading}}
|
||||
<div data-test-eval-loading>
|
||||
<section class="section has-text-centered">
|
||||
<LoadingSpinner />
|
||||
</section>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.isError}}
|
||||
<div data-test-eval-detail-header class="error-header">
|
||||
<button
|
||||
data-test-eval-sidebar-x
|
||||
class="button is-borderless"
|
||||
type="button"
|
||||
{{on "click" this.closeSidebar}}
|
||||
>
|
||||
{{x-icon "cancel"}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="error-container">
|
||||
<div data-test-eval-error class="error-message">
|
||||
<h1 data-test-error-title class="title is-spaced">
|
||||
Not Found
|
||||
</h1>
|
||||
<p data-test-error-message class="subtitle">
|
||||
The requested evaluation could not be found. You may not be authorized to view this evaluation, it may have been garbage collected, or the ID is invalid.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.isSuccess}}
|
||||
{{! Evaluation Detail Header}}
|
||||
<div data-test-eval-detail-header class="detail-header">
|
||||
<h1 data-test-title class="title">
|
||||
{{evaluation.shortId}}
|
||||
<span class="bumper-left tag is-primary">
|
||||
{{evaluation.status}}
|
||||
</span>
|
||||
</h1>
|
||||
<button
|
||||
data-test-eval-sidebar-x
|
||||
class="button is-borderless"
|
||||
type="button"
|
||||
{{on "click" this.closeSidebar}}
|
||||
>
|
||||
{{x-icon "cancel"}}
|
||||
</button>
|
||||
</div>
|
||||
{{! Start Evaluation Stats}}
|
||||
<div class="boxed-section is-small">
|
||||
<div
|
||||
class="boxed-section-body inline-definitions"
|
||||
style="display: flex;"
|
||||
>
|
||||
<span class="label" style="width: 6.125rem;">
|
||||
Evaluation Details
|
||||
</span>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<span class="pair">
|
||||
<span class="term">
|
||||
Job
|
||||
</span>
|
||||
<LinkTo
|
||||
data-test-evaluation-job
|
||||
@model={{concat evaluation.plainJobId "@" evaluation.namespace
|
||||
}}
|
||||
@route="jobs.job"
|
||||
>
|
||||
{{evaluation.plainJobId}}
|
||||
</LinkTo>
|
||||
</span>
|
||||
<span class="pair">
|
||||
<span class="term">
|
||||
Triggered By
|
||||
</span>
|
||||
{{evaluation.triggeredBy}}
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<span class="pair">
|
||||
<span class="term">
|
||||
Priority
|
||||
</span>
|
||||
{{evaluation.priority}}
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<span class="pair">
|
||||
<span class="term">
|
||||
Created
|
||||
</span>
|
||||
{{format-month-ts evaluation.createTime}}
|
||||
</span>
|
||||
<span class="pair">
|
||||
<span class="term">
|
||||
Placement Failure
|
||||
</span>
|
||||
{{evaluation.hasPlacementFailures}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{! Placement Failures}}
|
||||
{{#if evaluation.failedTGAllocs}}
|
||||
<div class="boxed-section is-danger">
|
||||
<div class="boxed-section-head">
|
||||
Placement Failures
|
||||
</div>
|
||||
<div class="boxed-section-body">
|
||||
{{#each evaluation.failedTGAllocs as |placementFailure|}}
|
||||
<PlacementFailure @failedTGAlloc={{placementFailure}} />
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{! Related Evaluations}}
|
||||
{{#if this.descendentsMap}}
|
||||
<EvaluationSidebar::RelatedEvaluations
|
||||
@fns={{hash
|
||||
handleResize=this.handleResize
|
||||
handleEvaluationClick=@fns.handleEvaluationClick
|
||||
}}
|
||||
@data={{hash
|
||||
width=this.width
|
||||
height=this.height
|
||||
parentEvaluation=this.parentEvaluation
|
||||
descendentsMap=this.descendentsMap
|
||||
activeEvaluationID=this.currentEvalDetail.id
|
||||
}}
|
||||
/>
|
||||
{{else}}
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">
|
||||
Related Evaluations
|
||||
</div>
|
||||
<div class="boxed-section-body">
|
||||
<div data-test-eval-error class="error-message title">
|
||||
<p data-test-error-message class="subtitle">
|
||||
The related evaluations cannot be visualized. Parts of the related evaluation tree may have been garbage collected.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{! Evaluation JSON Response}}
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">
|
||||
Evaluation Response
|
||||
</div>
|
||||
<div class="boxed-section-body is-full-bleed">
|
||||
<JsonViewer @json={{evaluation}} />
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</Portal>
|
||||
{{/let}}
|
||||
78
ui/app/components/evaluation-sidebar/detail.js
Normal file
78
ui/app/components/evaluation-sidebar/detail.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import { action } from '@ember/object';
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import d3 from 'd3';
|
||||
import { matchesState } from 'ember-statecharts';
|
||||
|
||||
export default class Detail extends Component {
|
||||
get statechart() {
|
||||
return this.args.statechart;
|
||||
}
|
||||
|
||||
@matchesState({ sidebar: 'open' })
|
||||
isSideBarOpen;
|
||||
|
||||
@matchesState({ sidebar: { open: 'success' } })
|
||||
isSuccess;
|
||||
|
||||
@matchesState({ sidebar: { open: 'busy' } })
|
||||
isLoading;
|
||||
|
||||
@matchesState({ sidebar: { open: 'error' } })
|
||||
isError;
|
||||
|
||||
@tracked width = null;
|
||||
@tracked height = null;
|
||||
|
||||
@action
|
||||
handleResize({ target: { scrollWidth: width, scrollHeight: height } }) {
|
||||
if (width === this.width || height === this.height) return;
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
get currentEvalDetail() {
|
||||
return this.statechart.state.context.evaluation;
|
||||
}
|
||||
|
||||
get hierarchy() {
|
||||
try {
|
||||
const data = this.currentEvalDetail?.relatedEvals;
|
||||
|
||||
if (data) {
|
||||
return d3
|
||||
.stratify()
|
||||
.id((d) => {
|
||||
return d.id;
|
||||
})
|
||||
.parentId((d) => d.previousEval)([
|
||||
...data.toArray(),
|
||||
this.currentEvalDetail,
|
||||
]);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`\n\nRelated Evaluation Error: ${e.message}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get descendentsMap() {
|
||||
return this.hierarchy
|
||||
?.descendants()
|
||||
.map((d) => d.children)
|
||||
.compact();
|
||||
}
|
||||
|
||||
get parentEvaluation() {
|
||||
return this.hierarchy?.data;
|
||||
}
|
||||
|
||||
get error() {
|
||||
return this.statechart.state.context.error;
|
||||
}
|
||||
|
||||
@action
|
||||
closeSidebar() {
|
||||
return this.statechart.send('MODAL_CLOSE');
|
||||
}
|
||||
}
|
||||
60
ui/app/components/evaluation-sidebar/related-evaluations.hbs
Normal file
60
ui/app/components/evaluation-sidebar/related-evaluations.hbs
Normal file
@@ -0,0 +1,60 @@
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">
|
||||
Related Evaluations
|
||||
</div>
|
||||
<div class="boxed-section-body related-evaluations" data-test-eval-container>
|
||||
<div class="sidebar-content" {{on-resize @fns.handleResize}}>
|
||||
{{#if (and @data.width @data.height)}}
|
||||
<Providers::ActorsRelationships as |actors|>
|
||||
<svg
|
||||
width={{@data.width}}
|
||||
height="100%"
|
||||
style="z-index: 10; inset: 0; position: absolute; pointer-events: none"
|
||||
{{did-update actors.fns.recalcCurves @data.width}}
|
||||
>
|
||||
{{#each actors.data.relationships as |r|}}
|
||||
<path
|
||||
d={{r.d}}
|
||||
stroke="#7E8FA8"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
></path>
|
||||
<circle
|
||||
cx={{r.sx}}
|
||||
cy={{r.sy}}
|
||||
r="4"
|
||||
fill="white"
|
||||
stroke="black"
|
||||
></circle>
|
||||
<circle
|
||||
cx={{r.ex}}
|
||||
cy={{r.ey}}
|
||||
r="4"
|
||||
fill="white"
|
||||
stroke="black"
|
||||
></circle>
|
||||
{{/each}}
|
||||
</svg>
|
||||
</Providers::ActorsRelationships>
|
||||
{{/if}}
|
||||
<div>
|
||||
<EvaluationSidebar::EvaluationActor
|
||||
@eval={{@data.parentEvaluation}}
|
||||
@activeEvaluationID={{@data.activeEvaluationID}}
|
||||
@onClick={{fn @fns.handleEvaluationClick @data.parentEvaluation}}
|
||||
/>
|
||||
</div>
|
||||
{{#each @data.descendentsMap as |evals|}}
|
||||
<div class="evaluation-actors">
|
||||
{{#each evals as |eval|}}
|
||||
<EvaluationSidebar::EvaluationActor
|
||||
@eval={{eval.data}}
|
||||
@activeEvaluationID={{@data.activeEvaluationID}}
|
||||
@onClick={{fn @fns.handleEvaluationClick eval.data}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
3
ui/app/components/providers/actors-relationships.hbs
Normal file
3
ui/app/components/providers/actors-relationships.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
{{yield
|
||||
(hash fns=this.actorsRelationships.fns data=this.actorsRelationships.data)
|
||||
}}
|
||||
6
ui/app/components/providers/actors-relationships.js
Normal file
6
ui/app/components/providers/actors-relationships.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ActorsRelationships extends Component {
|
||||
@service actorsRelationships;
|
||||
}
|
||||
@@ -1,12 +1,82 @@
|
||||
import { getOwner } from '@ember/application';
|
||||
import Controller from '@ember/controller';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { schedule } from '@ember/runloop';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { useMachine } from 'ember-statecharts';
|
||||
import { use } from 'ember-usable';
|
||||
import evaluationsMachine from '../../machines/evaluations';
|
||||
|
||||
export default class EvaluationsController extends Controller {
|
||||
@service store;
|
||||
@service userSettings;
|
||||
|
||||
queryParams = ['nextToken', 'pageSize', 'status'];
|
||||
// We use statecharts here to manage complex user flows for the sidebar logic
|
||||
@use
|
||||
statechart = useMachine(evaluationsMachine).withConfig({
|
||||
services: {
|
||||
loadEvaluation: this.loadEvaluation,
|
||||
},
|
||||
actions: {
|
||||
updateEvaluationQueryParameter: this.updateEvaluationQueryParameter,
|
||||
removeCurrentEvaluationQueryParameter:
|
||||
this.removeCurrentEvaluationQueryParameter,
|
||||
},
|
||||
guards: {
|
||||
sidebarIsOpen: this._sidebarIsOpen,
|
||||
},
|
||||
});
|
||||
|
||||
queryParams = ['nextToken', 'currentEval', 'pageSize', 'status'];
|
||||
@tracked currentEval = null;
|
||||
|
||||
@action
|
||||
_sidebarIsOpen() {
|
||||
return !!this.currentEval;
|
||||
}
|
||||
|
||||
@action
|
||||
async loadEvaluation(context, { evaluation }) {
|
||||
let evaluationId;
|
||||
if (evaluation?.id) {
|
||||
evaluationId = evaluation.id;
|
||||
} else {
|
||||
evaluationId = this.currentEval;
|
||||
}
|
||||
|
||||
return this.store.findRecord('evaluation', evaluationId, {
|
||||
reload: true,
|
||||
adapterOptions: { related: true },
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async handleEvaluationClick(evaluation, e) {
|
||||
if (
|
||||
e instanceof MouseEvent ||
|
||||
(e instanceof KeyboardEvent && (e.code === 'Enter' || e.code === 'Space'))
|
||||
) {
|
||||
this.statechart.send('LOAD_EVALUATION', { evaluation });
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
notifyEvalChange([evaluation]) {
|
||||
schedule('actions', this, () => {
|
||||
this.statechart.send('CHANGE_EVAL', { evaluation });
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
updateEvaluationQueryParameter(context, { evaluation }) {
|
||||
this.currentEval = evaluation.id;
|
||||
}
|
||||
|
||||
@action
|
||||
removeCurrentEvaluationQueryParameter() {
|
||||
this.currentEval = null;
|
||||
}
|
||||
|
||||
get shouldDisableNext() {
|
||||
return !this.model.meta?.nextToken;
|
||||
@@ -52,6 +122,12 @@ export default class EvaluationsController extends Controller {
|
||||
|
||||
@action
|
||||
refresh() {
|
||||
const isDefaultParams = this.nextToken === null && this.status === null;
|
||||
if (isDefaultParams) {
|
||||
getOwner(this).lookup('route:evaluations.index').refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
this._resetTokens();
|
||||
this.status = null;
|
||||
this.pageSize = this.userSettings.pageSize;
|
||||
|
||||
124
ui/app/machines/evaluations.js
Normal file
124
ui/app/machines/evaluations.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import { assign, createMachine, send } from 'xstate';
|
||||
|
||||
// Docs on using statecharts: https://xstate.js.org/docs/packages/xstate-fsm/#api
|
||||
export default createMachine(
|
||||
{
|
||||
id: 'evaluations_ui',
|
||||
context: { evaluation: null },
|
||||
type: 'parallel',
|
||||
states: {
|
||||
table: {
|
||||
initial: 'unknown',
|
||||
on: {
|
||||
NEXT: {
|
||||
actions: ['requestNextPage', send('MODAL_CLOSE')],
|
||||
},
|
||||
PREV: {
|
||||
actions: ['requestPrevPage', send('MODAL_CLOSE')],
|
||||
},
|
||||
CHANGE_PAGES_SIZE: {
|
||||
actions: ['changePageSize', send('MODAL_CLOSE')],
|
||||
},
|
||||
MODEL_UPDATED: '#unknown',
|
||||
},
|
||||
states: {
|
||||
unknown: {
|
||||
id: 'unknown',
|
||||
always: [{ target: 'data', cond: 'hasData' }, { target: 'empty' }],
|
||||
},
|
||||
data: {},
|
||||
empty: {},
|
||||
},
|
||||
},
|
||||
sidebar: {
|
||||
initial: 'unknown',
|
||||
states: {
|
||||
unknown: {
|
||||
always: [
|
||||
{ target: 'open', cond: 'sidebarIsOpen' },
|
||||
{ target: 'close' },
|
||||
],
|
||||
},
|
||||
open: {
|
||||
initial: 'busy',
|
||||
exit: ['removeCurrentEvaluationQueryParameter'],
|
||||
states: {
|
||||
busy: {
|
||||
invoke: {
|
||||
src: 'loadEvaluation',
|
||||
onDone: 'success',
|
||||
onError: 'error',
|
||||
},
|
||||
},
|
||||
success: {
|
||||
entry: assign({
|
||||
evaluation: (context, event) => {
|
||||
return event.data;
|
||||
},
|
||||
}),
|
||||
on: {
|
||||
LOAD_EVALUATION: {
|
||||
target: 'busy',
|
||||
actions: ['updateEvaluationQueryParameter'],
|
||||
},
|
||||
},
|
||||
},
|
||||
error: {
|
||||
entry: assign({ error: (_ctx, event) => event.data }),
|
||||
on: {
|
||||
RETRY: 'busy',
|
||||
},
|
||||
},
|
||||
},
|
||||
on: {
|
||||
MODAL_CLOSE: 'close',
|
||||
CHANGE_EVAL: [{ target: 'close', cond: 'hasNoCurrentEval' }],
|
||||
},
|
||||
},
|
||||
close: {
|
||||
on: {
|
||||
LOAD_EVALUATION: {
|
||||
target: 'open',
|
||||
actions: ['updateEvaluationQueryParameter'],
|
||||
},
|
||||
CHANGE_EVAL: [
|
||||
{
|
||||
target: 'open',
|
||||
cond: 'hasCurrentEval',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
services: {
|
||||
// Overridden in the controller
|
||||
async loadEvaluations() {},
|
||||
async loadEvaluation() {},
|
||||
},
|
||||
guards: {
|
||||
sidebarIsOpen() {
|
||||
return false;
|
||||
},
|
||||
hasData() {
|
||||
return true;
|
||||
},
|
||||
hasNoCurrentEval(_ctx, { evaluation }) {
|
||||
return !evaluation;
|
||||
},
|
||||
hasCurrentEval(_ctx, { evaluation }) {
|
||||
return evaluation;
|
||||
},
|
||||
notBusy(_ctx, _event, meta) {
|
||||
return !meta.state.matches({ sidebar: { open: 'busy' } });
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
updateEvaluationQueryParameter() {},
|
||||
removeCurrentEvaluationQueryParameter() {},
|
||||
},
|
||||
}
|
||||
);
|
||||
23
ui/app/models/evaluation-stub.js
Normal file
23
ui/app/models/evaluation-stub.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import Model, { attr } from '@ember-data/model';
|
||||
import shortUUIDProperty from '../utils/properties/short-uuid';
|
||||
|
||||
export default class EvaluationStub extends Model {
|
||||
@shortUUIDProperty('id') shortId;
|
||||
@attr('number') priority;
|
||||
@attr('string') type;
|
||||
@attr('string') triggeredBy;
|
||||
@attr('string') namespace;
|
||||
@attr('string') jobId;
|
||||
@attr('string') nodeId;
|
||||
@attr('string') deploymentId;
|
||||
@attr('string') status;
|
||||
@attr('string') statusDescription;
|
||||
@attr('date') waitUntil;
|
||||
@attr('string') previousEval;
|
||||
@attr('string') nextEval;
|
||||
@attr('string') blockedEval;
|
||||
@attr('number') modifyIndex;
|
||||
@attr('date') modifyTime;
|
||||
@attr('number') createIndex;
|
||||
@attr('date') createTime;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { bool, equal } from '@ember/object/computed';
|
||||
import Model from '@ember-data/model';
|
||||
import { attr, belongsTo } from '@ember-data/model';
|
||||
import { attr, belongsTo, hasMany } from '@ember-data/model';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import shortUUIDProperty from '../utils/properties/short-uuid';
|
||||
|
||||
@@ -15,6 +15,11 @@ export default class Evaluation extends Model {
|
||||
@fragmentArray('placement-failure', { defaultValue: () => [] })
|
||||
failedTGAllocs;
|
||||
|
||||
@attr('string') previousEval;
|
||||
@attr('string') nextEval;
|
||||
@attr('string') blockedEval;
|
||||
@hasMany('evaluation-stub', { async: false }) relatedEvals;
|
||||
|
||||
@bool('failedTGAllocs.length') hasPlacementFailures;
|
||||
@equal('status', 'blocked') isBlocked;
|
||||
|
||||
|
||||
@@ -15,6 +15,37 @@ export default class Evaluation extends ApplicationSerializer {
|
||||
hash.Namespace = hash.Namespace || get(hash, 'Job.Namespace') || 'default';
|
||||
hash.JobID = JSON.stringify([hash.JobID, hash.Namespace]);
|
||||
|
||||
return super.normalize(typeHash, hash);
|
||||
const relatedEvals = hash.RelatedEvals;
|
||||
|
||||
const normalizedHash = super.normalize(typeHash, hash);
|
||||
|
||||
if (relatedEvals?.length) {
|
||||
this._handleRelatedEvalsRelationshipData(relatedEvals, normalizedHash);
|
||||
}
|
||||
|
||||
return normalizedHash;
|
||||
}
|
||||
|
||||
_handleRelatedEvalsRelationshipData(relatedEvals, normalizedHash) {
|
||||
normalizedHash.data.relationships = normalizedHash.data.relationships || {};
|
||||
|
||||
normalizedHash.data.relationships.relatedEvals = {
|
||||
data: relatedEvals.map((evaluationStub) => {
|
||||
return { id: evaluationStub.ID, type: 'evaluation-stub' };
|
||||
}),
|
||||
};
|
||||
|
||||
normalizedHash.included = normalizedHash.included || [];
|
||||
|
||||
const included = relatedEvals.reduce((acc, evaluationStub) => {
|
||||
const jsonDocument = this.normalize(
|
||||
this.store.modelFor('evaluation-stub'),
|
||||
evaluationStub
|
||||
);
|
||||
|
||||
return [...acc, jsonDocument.data];
|
||||
}, normalizedHash.included);
|
||||
|
||||
normalizedHash.included = included;
|
||||
}
|
||||
}
|
||||
|
||||
101
ui/app/services/actors-relationships.js
Normal file
101
ui/app/services/actors-relationships.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import Service from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { schedule } from '@ember/runloop';
|
||||
import { getBoxToBoxArrow } from 'curved-arrows';
|
||||
|
||||
function boxToArrow(ra, rb) {
|
||||
const bbA = ra;
|
||||
const bbB = rb;
|
||||
|
||||
const [sx, sy, c1x, c1y, c2x, c2y, ex, ey, ae, as] = getBoxToBoxArrow(
|
||||
bbA.offsetLeft,
|
||||
bbA.offsetTop,
|
||||
bbA.offsetWidth,
|
||||
bbA.offsetHeight,
|
||||
bbB.offsetLeft,
|
||||
bbB.offsetTop,
|
||||
bbB.offsetWidth,
|
||||
bbB.offsetHeight
|
||||
);
|
||||
|
||||
return {
|
||||
sx,
|
||||
sy,
|
||||
c1x,
|
||||
c1y,
|
||||
c2x,
|
||||
c2y,
|
||||
ex,
|
||||
ey,
|
||||
ae,
|
||||
as,
|
||||
};
|
||||
}
|
||||
|
||||
export default class ActorRelationshipService extends Service {
|
||||
@tracked actors = [];
|
||||
|
||||
get fns() {
|
||||
const { registerActor, deregisterActor, recalcCurves } = this;
|
||||
return { registerActor, deregisterActor, recalcCurves };
|
||||
}
|
||||
|
||||
get data() {
|
||||
const { actors, relationships } = this;
|
||||
return { actors, relationships };
|
||||
}
|
||||
|
||||
@action registerActor(actor) {
|
||||
schedule('actions', this, () => {
|
||||
this.actors = [...this.actors, actor];
|
||||
});
|
||||
}
|
||||
|
||||
@action deregisterActor(actor) {
|
||||
schedule('actions', this, () => {
|
||||
this.actors = this.actors.filter((a) => a !== actor);
|
||||
});
|
||||
}
|
||||
|
||||
get rects() {
|
||||
const { actors } = this;
|
||||
|
||||
return actors
|
||||
.filter((e) => e.previousEval)
|
||||
.map((e) => {
|
||||
const { previousEval: pid, id } = e;
|
||||
|
||||
const eRectangle = document.querySelector(`[data-eval="${id}"]`);
|
||||
const prevRectangle = document.querySelector(`[data-eval="${pid}"]`);
|
||||
|
||||
return [eRectangle, prevRectangle];
|
||||
});
|
||||
}
|
||||
|
||||
get relationships() {
|
||||
const { rects } = this;
|
||||
|
||||
return rects.map(([eRectangle, prevRectangle]) => {
|
||||
const { sx, sy, c1x, c1y, c2x, c2y, ex, ey } = boxToArrow(
|
||||
eRectangle,
|
||||
prevRectangle
|
||||
);
|
||||
|
||||
return {
|
||||
d: `M ${sx} ${sy} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${ex} ${ey}`,
|
||||
sx,
|
||||
sy,
|
||||
ex,
|
||||
ey,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
recalcCurves() {
|
||||
// retrigger the tracked getters by resetting dependent keys
|
||||
/* eslint-disable-next-line */
|
||||
this.actors = this.actors;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
@import './components/recommendation-card';
|
||||
@import './components/recommendation-row';
|
||||
@import './components/search-box';
|
||||
@import './components/sidebar';
|
||||
@import './components/simple-list';
|
||||
@import './components/status-text';
|
||||
@import './components/stepper-input';
|
||||
@@ -44,3 +45,4 @@
|
||||
@import './components/toolbar';
|
||||
@import './components/tooltip';
|
||||
@import './components/two-step-button';
|
||||
@import './components/evaluations';
|
||||
|
||||
9
ui/app/styles/components/evaluations.scss
Normal file
9
ui/app/styles/components/evaluations.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
.related-evaluation {
|
||||
margin: 24px;
|
||||
outline: 1px solid #d9dee6;
|
||||
padding: 10px;
|
||||
width: 100px;
|
||||
&.is-active {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
}
|
||||
52
ui/app/styles/components/sidebar.scss
Normal file
52
ui/app/styles/components/sidebar.scss
Normal file
@@ -0,0 +1,52 @@
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
background: #ffffff;
|
||||
width: 750px;
|
||||
padding: 24px;
|
||||
right: 0%;
|
||||
overflow-y: auto;
|
||||
bottom: 0;
|
||||
top: 112px;
|
||||
transform: translateX(100%);
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: ease;
|
||||
box-shadow: 6px 6px rgba(0, 0, 0, 0.06), 0px 12px 16px rgba(0, 0, 0, 0.2);
|
||||
z-index: 10;
|
||||
&.open {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.error-header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.related-evaluations {
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.evaluation-actors {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.actor {
|
||||
margin: 24px;
|
||||
outline: 1px solid #d9dee6;
|
||||
padding: 10px;
|
||||
width: 100px;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<Providers::ActorsRelationships as |actors|>
|
||||
<div
|
||||
class="related-evaluation
|
||||
{{if (eq @eval.id @activeEvaluationID) "is-active"}}"
|
||||
data-eval={{@eval.id}}
|
||||
...attributes
|
||||
{{did-insert (fn actors.fns.registerActor @eval)}}
|
||||
{{will-destroy (fn actors.fns.deregisterActor @eval)}}
|
||||
>
|
||||
{{#if (eq @eval.id @activeEvaluationID)}}
|
||||
<span data-test-rel-eval={{@eval.id}}>
|
||||
{{@eval.shortId}}
|
||||
</span>
|
||||
{{else}}
|
||||
<a data-test-rel-eval={{@eval.id}} {{on "click" @onClick}}>
|
||||
{{@eval.shortId}}
|
||||
</a>
|
||||
{{/if}}
|
||||
<span>
|
||||
<StatusCell @status={{@eval.status}} />
|
||||
</span>
|
||||
</div>
|
||||
</Providers::ActorsRelationships>
|
||||
@@ -1,4 +1,7 @@
|
||||
<div data-test-gutter-menu class="page-column is-left {{if this.isOpen "is-open"}}">
|
||||
<div
|
||||
data-test-gutter-menu
|
||||
class="page-column is-left {{if this.isOpen "is-open"}}"
|
||||
>
|
||||
<div class="gutter {{if this.isOpen "is-open"}}">
|
||||
<header class="collapsed-menu {{if this.isOpen "is-open"}}">
|
||||
<span
|
||||
@@ -34,13 +37,21 @@
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="jobs" @activeClass="is-active" data-test-gutter-link="jobs">
|
||||
<LinkTo
|
||||
@route="jobs"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="jobs"
|
||||
>
|
||||
Jobs
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if (can "accept recommendation")}}
|
||||
<li>
|
||||
<LinkTo @route="optimize" @activeClass="is-active" data-test-gutter-link="optimize">
|
||||
<LinkTo
|
||||
@route="optimize"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="optimize"
|
||||
>
|
||||
Optimize
|
||||
</LinkTo>
|
||||
</li>
|
||||
@@ -51,7 +62,11 @@
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="csi" @activeClass="is-active" data-test-gutter-link="storage">
|
||||
<LinkTo
|
||||
@route="csi"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="storage"
|
||||
>
|
||||
Storage
|
||||
<span class="tag is-small">
|
||||
Beta
|
||||
@@ -64,17 +79,29 @@
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="clients" @activeClass="is-active" data-test-gutter-link="clients">
|
||||
<LinkTo
|
||||
@route="clients"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="clients"
|
||||
>
|
||||
Clients
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li>
|
||||
<LinkTo @route="servers" @activeClass="is-active" data-test-gutter-link="servers">
|
||||
<LinkTo
|
||||
@route="servers"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="servers"
|
||||
>
|
||||
Servers
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li>
|
||||
<LinkTo @route="topology" @activeClass="is-active" data-test-gutter-link="topology">
|
||||
<LinkTo
|
||||
@route="topology"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="topology"
|
||||
>
|
||||
Topology
|
||||
</LinkTo>
|
||||
</li>
|
||||
@@ -84,7 +111,11 @@
|
||||
</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="evaluations" @activeClass="is-active" data-test-gutter-link="evaluations">
|
||||
<LinkTo
|
||||
@route="evaluations"
|
||||
@activeClass="is-active"
|
||||
data-test-gutter-link="evaluations"
|
||||
>
|
||||
Evaluations
|
||||
</LinkTo>
|
||||
</li>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<PageLayout>
|
||||
<PortalTarget @name="eval-detail-portal" />
|
||||
{{outlet}}
|
||||
</PageLayout>
|
||||
@@ -1,138 +1,162 @@
|
||||
{{page-title "Evaluations"}}
|
||||
{{did-update this.notifyEvalChange this.currentEval}}
|
||||
<section class="section">
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-item is-right-aligned">
|
||||
<SingleSelectDropdown
|
||||
data-test-evaluation-status-facet
|
||||
@label="Status"
|
||||
@options={{this.optionsEvaluationsStatus}}
|
||||
@selection={{this.status}}
|
||||
@onSelect={{action this.setStatus}}
|
||||
/>
|
||||
<div class="table-container">
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-item is-right-aligned">
|
||||
<SingleSelectDropdown
|
||||
data-test-evaluation-status-facet
|
||||
@label="Status"
|
||||
@options={{this.optionsEvaluationsStatus}}
|
||||
@selection={{this.status}}
|
||||
@onSelect={{action this.setStatus}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{#if @model.length}}
|
||||
<ListTable data-test-eval-table @source={{@model}} as |t|>
|
||||
<t.head>
|
||||
<th>
|
||||
Evaluation ID
|
||||
</th>
|
||||
<th>
|
||||
Resource
|
||||
</th>
|
||||
<th>
|
||||
Priority
|
||||
</th>
|
||||
<th>
|
||||
Created
|
||||
</th>
|
||||
<th>
|
||||
Triggered By
|
||||
</th>
|
||||
<th>
|
||||
Status
|
||||
</th>
|
||||
<th>
|
||||
Placement Failures
|
||||
</th>
|
||||
</t.head>
|
||||
<t.body as |row|>
|
||||
<tr
|
||||
data-test-evaluation="{{row.model.shortId}}"
|
||||
style="cursor: pointer;"
|
||||
class="{{if (eq this.currentEval row.model.id) "is-active"}}"
|
||||
tabindex="0"
|
||||
{{on "click" (fn this.handleEvaluationClick row.model)}}
|
||||
{{on "keyup" (fn this.handleEvaluationClick row.model)}}
|
||||
>
|
||||
<td data-test-id>
|
||||
{{row.model.shortId}}
|
||||
</td>
|
||||
<td data-test-id>
|
||||
{{#if row.model.hasJob}}
|
||||
<LinkTo
|
||||
data-test-evaluation-resource
|
||||
@model={{concat row.model.plainJobId "@" row.model.namespace}}
|
||||
@route="jobs.job"
|
||||
>
|
||||
{{row.model.plainJobId}}
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
<LinkTo
|
||||
data-test-evaluation-resource
|
||||
@model={{row.model.nodeId}}
|
||||
@route="clients.client"
|
||||
>
|
||||
{{row.model.shortNodeId}}
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td data-test-priority>
|
||||
{{row.model.priority}}
|
||||
</td>
|
||||
<td data-test-create-time>
|
||||
{{format-month-ts row.model.createTime}}
|
||||
</td>
|
||||
<td data-test-triggered-by>
|
||||
{{row.model.triggeredBy}}
|
||||
</td>
|
||||
<td data-test-status class="is-one-line">
|
||||
<StatusCell @status={{row.model.status}} />
|
||||
</td>
|
||||
<td data-test-blocked>
|
||||
{{#if (eq row.model.status "blocked")}}
|
||||
N/A - In Progress
|
||||
{{else if row.model.hasPlacementFailures}}
|
||||
True
|
||||
{{else}}
|
||||
False
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</t.body>
|
||||
</ListTable>
|
||||
<div class="table-foot with-padding">
|
||||
<PageSizeSelect data-test-per-page @onChange={{this.onChange}} />
|
||||
<div>
|
||||
<button
|
||||
class="button"
|
||||
data-test-eval-refresh
|
||||
type="button"
|
||||
{{on "click" this.refresh}}
|
||||
>
|
||||
{{x-icon "refresh-default" class="is-text"}}
|
||||
Refresh
|
||||
</button>
|
||||
<button
|
||||
data-test-eval-pagination-prev
|
||||
type="button"
|
||||
class="button is-text is-borderless"
|
||||
disabled={{this.shouldDisablePrev}}
|
||||
{{on "click" (fn this.onPrev this.lastToken)}}
|
||||
>
|
||||
{{x-icon "chevron-left" class="is-large"}}
|
||||
</button>
|
||||
<button
|
||||
data-test-eval-pagination-next
|
||||
type="button"
|
||||
class="button is-text is-borderless"
|
||||
disabled={{this.shouldDisableNext}}
|
||||
{{on "click" (fn this.onNext @model.meta.nextToken)}}
|
||||
>
|
||||
{{x-icon "chevron-right" class="is-large"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="boxed-section-body">
|
||||
<div class="empty-message" data-test-empty-evaluations-list>
|
||||
<h3
|
||||
class="empty-message-headline"
|
||||
data-test-empty-evalations-list-headline
|
||||
>
|
||||
No Matches
|
||||
</h3>
|
||||
<p class="empty-message-body">
|
||||
{{#if this.status}}
|
||||
<span data-test-no-eval-match>
|
||||
No evaluations match the status
|
||||
<strong>
|
||||
{{this.status}}
|
||||
</strong>
|
||||
</span>
|
||||
{{else}}
|
||||
<span data-test-no-eval>
|
||||
There are no evaluations
|
||||
</span>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if @model.length}}
|
||||
<ListTable data-test-eval-table @source={{@model}} as |t|>
|
||||
<t.head>
|
||||
<th>
|
||||
Evaluation ID
|
||||
</th>
|
||||
<th>
|
||||
Resource
|
||||
</th>
|
||||
<th>
|
||||
Priority
|
||||
</th>
|
||||
<th>
|
||||
Created
|
||||
</th>
|
||||
<th>
|
||||
Triggered By
|
||||
</th>
|
||||
<th>
|
||||
Status
|
||||
</th>
|
||||
<th>
|
||||
Placement Failures
|
||||
</th>
|
||||
</t.head>
|
||||
<t.body as |row|>
|
||||
<tr data-test-evaluation="{{row.model.shortId}}">
|
||||
<td data-test-id>
|
||||
{{row.model.shortId}}
|
||||
</td>
|
||||
<td data-test-id>
|
||||
{{#if row.model.hasJob}}
|
||||
<LinkTo
|
||||
data-test-evaluation-resource
|
||||
@model={{row.model.plainJobId}}
|
||||
@route="jobs.job"
|
||||
@query={{hash namespace=row.model.namespace}}
|
||||
>
|
||||
{{row.model.plainJobId}}
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
<LinkTo
|
||||
data-test-evaluation-resource
|
||||
@model={{row.model.nodeId}}
|
||||
@route="clients.client"
|
||||
>
|
||||
{{row.model.shortNodeId}}
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td data-test-priority>
|
||||
{{row.model.priority}}
|
||||
</td>
|
||||
<td data-test-create-time>
|
||||
{{format-month-ts row.model.createTime}}
|
||||
</td>
|
||||
<td data-test-triggered-by>
|
||||
{{row.model.triggeredBy}}
|
||||
</td>
|
||||
<td data-test-status class="is-one-line">
|
||||
<StatusCell @status={{row.model.status}} />
|
||||
</td>
|
||||
<td data-test-blocked>
|
||||
{{#if (eq row.model.status "blocked")}}
|
||||
N/A - In Progress
|
||||
{{else if row.model.hasPlacementFailures}}
|
||||
True
|
||||
{{else}}
|
||||
False
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</t.body>
|
||||
</ListTable>
|
||||
<div class="table-foot with-padding">
|
||||
<PageSizeSelect data-test-per-page @onChange={{this.onChange}} />
|
||||
<div>
|
||||
<button class="button" data-test-eval-refresh type="button" {{on "click" this.refresh}}>
|
||||
{{x-icon "refresh-default" class="is-text"}}
|
||||
Refresh
|
||||
</button>
|
||||
<button
|
||||
data-test-eval-pagination-prev
|
||||
type="button"
|
||||
class="button is-text is-borderless"
|
||||
disabled={{this.shouldDisablePrev}}
|
||||
{{on "click" (fn this.onPrev this.lastToken)}}
|
||||
>
|
||||
{{x-icon "chevron-left" class="is-large"}}
|
||||
</button>
|
||||
<button
|
||||
data-test-eval-pagination-next
|
||||
type="button"
|
||||
class="button is-text is-borderless"
|
||||
disabled={{this.shouldDisableNext}}
|
||||
{{on "click" (fn this.onNext @model.meta.nextToken)}}
|
||||
>
|
||||
{{x-icon "chevron-right" class="is-large"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="boxed-section-body">
|
||||
<div class="empty-message" data-test-empty-evaluations-list>
|
||||
<h3 class="empty-message-headline" data-test-empty-evalations-list-headline>
|
||||
No Matches
|
||||
</h3>
|
||||
<p class="empty-message-body">
|
||||
{{#if this.status}}
|
||||
<span data-test-no-eval-match>
|
||||
No evaluations match the status
|
||||
<strong>
|
||||
{{this.status}}
|
||||
</strong>
|
||||
</span>
|
||||
{{else}}
|
||||
<span data-test-no-eval>
|
||||
There are no evaluations
|
||||
</span>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<EvaluationSidebar::Detail
|
||||
@statechart={{this.statechart}}
|
||||
@fns={{hash
|
||||
closeSidebar=this.closeSidebar
|
||||
handleEvaluationClick=this.handleEvaluationClick
|
||||
}}
|
||||
/>
|
||||
</section>
|
||||
@@ -6,6 +6,7 @@ import { generateDiff } from './factories/job-version';
|
||||
import { generateTaskGroupFailures } from './factories/evaluation';
|
||||
import { copy } from 'ember-copy';
|
||||
import formatHost from 'nomad-ui/utils/format-host';
|
||||
import { generateAcceptanceTestEvalMock } from './utils';
|
||||
|
||||
export function findLeader(schema) {
|
||||
const agent = schema.agents.first();
|
||||
@@ -262,7 +263,19 @@ export default function () {
|
||||
});
|
||||
|
||||
this.get('/evaluations');
|
||||
this.get('/evaluation/:id');
|
||||
this.get(
|
||||
'/evaluation/:id',
|
||||
function ({ evaluations }, { params, queryParams }) {
|
||||
const showRelated = queryParams.related;
|
||||
|
||||
if (showRelated) {
|
||||
// we are dealing with a "related" request - return the mock
|
||||
return generateAcceptanceTestEvalMock(params.id);
|
||||
}
|
||||
|
||||
return evaluations.find(params.id);
|
||||
}
|
||||
);
|
||||
|
||||
this.get('/deployment/allocations/:id', function (schema, { params }) {
|
||||
const job = schema.jobs.find(schema.deployments.find(params.id).jobId);
|
||||
|
||||
@@ -4,9 +4,7 @@ export function provide(count, provider) {
|
||||
if (typeof count === 'function') {
|
||||
count = count();
|
||||
}
|
||||
return Array(count)
|
||||
.fill(null)
|
||||
.map(provider);
|
||||
return Array(count).fill(null).map(provider);
|
||||
}
|
||||
|
||||
export function provider() {
|
||||
@@ -26,3 +24,467 @@ export function arrToObj(prop, alias = '') {
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
export const generateAcceptanceTestEvalMock = (id) => {
|
||||
return {
|
||||
CreateIndex: 20,
|
||||
CreateTime: 1647899150314738000,
|
||||
ID: id,
|
||||
JobID: 'example',
|
||||
JobModifyIndex: 10,
|
||||
ModifyIndex: 31,
|
||||
ModifyTime: 1647899318007569000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
PreviousEval: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
|
||||
Priority: 50,
|
||||
RelatedEvals: [
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 31,
|
||||
CreateTime: 1647899318007563000,
|
||||
DeploymentID: '',
|
||||
ID: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 44,
|
||||
ModifyTime: 1647899591412413000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
NodeID: '',
|
||||
PreviousEval: id,
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 31,
|
||||
CreateTime: 1647899318007563000,
|
||||
DeploymentID: '',
|
||||
ID: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef-deux',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 44,
|
||||
ModifyTime: 1647899591412413000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
NodeID: '',
|
||||
PreviousEval: id,
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 10,
|
||||
CreateTime: 1647899129298997000,
|
||||
DeploymentID: '',
|
||||
ID: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 20,
|
||||
ModifyTime: 1647899150314745000,
|
||||
Namespace: 'default',
|
||||
NextEval: id,
|
||||
NodeID: '',
|
||||
PreviousEval: '',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'job-register',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 44,
|
||||
CreateTime: 1647899591412410000,
|
||||
DeploymentID: '',
|
||||
ID: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 53,
|
||||
ModifyTime: 1647899729480596000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
NodeID: '',
|
||||
PreviousEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 53,
|
||||
CreateTime: 1647899729480592000,
|
||||
DeploymentID: '',
|
||||
ID: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 64,
|
||||
ModifyTime: 1647899881302731000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
NodeID: '',
|
||||
PreviousEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 64,
|
||||
CreateTime: 1647899881302723000,
|
||||
DeploymentID: '',
|
||||
ID: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 81,
|
||||
ModifyTime: 1647900212725381000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
NodeID: '',
|
||||
PreviousEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 81,
|
||||
CreateTime: 1647900212725376000,
|
||||
DeploymentID: '',
|
||||
ID: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 97,
|
||||
ModifyTime: 1647900516944239000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
NodeID: '',
|
||||
PreviousEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 97,
|
||||
CreateTime: 1647900516944236000,
|
||||
DeploymentID: '',
|
||||
ID: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 114,
|
||||
ModifyTime: 1647900825385587000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
NodeID: '',
|
||||
PreviousEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 114,
|
||||
CreateTime: 1647900825385584000,
|
||||
DeploymentID: '',
|
||||
ID: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 128,
|
||||
ModifyTime: 1647900979511304000,
|
||||
Namespace: 'default',
|
||||
NextEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
NodeID: '',
|
||||
PreviousEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 128,
|
||||
CreateTime: 1647900979511301000,
|
||||
DeploymentID: '',
|
||||
ID: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 136,
|
||||
ModifyTime: 1647901211369652000,
|
||||
Namespace: 'default',
|
||||
NextEval: '1fded690-20ad-6afa-3b89-59e319dfce18',
|
||||
NodeID: '',
|
||||
PreviousEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 136,
|
||||
CreateTime: 1647901211369648000,
|
||||
DeploymentID: '',
|
||||
ID: '1fded690-20ad-6afa-3b89-59e319dfce18',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 136,
|
||||
ModifyTime: 1647901211369648000,
|
||||
Namespace: 'default',
|
||||
NextEval: '',
|
||||
NodeID: '',
|
||||
PreviousEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
Priority: 50,
|
||||
Status: 'pending',
|
||||
StatusDescription: '',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
],
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
Wait: 20000000000,
|
||||
};
|
||||
};
|
||||
|
||||
export const MOCK_EVALUATION = {
|
||||
CreateIndex: 20,
|
||||
CreateTime: 1647899150314738000,
|
||||
ID: 'fede162c-26a6-c108-178b-1c140f9f5680',
|
||||
JobID: 'example',
|
||||
JobModifyIndex: 10,
|
||||
ModifyIndex: 31,
|
||||
ModifyTime: 1647899318007569000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
PreviousEval: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
|
||||
Priority: 50,
|
||||
RelatedEvals: [
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 31,
|
||||
CreateTime: 1647899318007563000,
|
||||
DeploymentID: '',
|
||||
ID: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 44,
|
||||
ModifyTime: 1647899591412413000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
NodeID: '',
|
||||
PreviousEval: 'fede162c-26a6-c108-178b-1c140f9f5680',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 10,
|
||||
CreateTime: 1647899129298997000,
|
||||
DeploymentID: '',
|
||||
ID: 'd8a5c14f-120a-3d83-6305-90927356dd6c',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 20,
|
||||
ModifyTime: 1647899150314745000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'fede162c-26a6-c108-178b-1c140f9f5680',
|
||||
NodeID: '',
|
||||
PreviousEval: '',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'job-register',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 44,
|
||||
CreateTime: 1647899591412410000,
|
||||
DeploymentID: '',
|
||||
ID: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 53,
|
||||
ModifyTime: 1647899729480596000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
NodeID: '',
|
||||
PreviousEval: 'fd1cd898-d655-c7e4-17f6-a1a2e98b18ef',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 53,
|
||||
CreateTime: 1647899729480592000,
|
||||
DeploymentID: '',
|
||||
ID: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 64,
|
||||
ModifyTime: 1647899881302731000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
NodeID: '',
|
||||
PreviousEval: 'cac7dfa0-b79b-ee55-c86a-0ca89dffb9e1',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 64,
|
||||
CreateTime: 1647899881302723000,
|
||||
DeploymentID: '',
|
||||
ID: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 81,
|
||||
ModifyTime: 1647900212725381000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
NodeID: '',
|
||||
PreviousEval: 'e49bf53c-da6a-c869-8317-f2089682f503',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 81,
|
||||
CreateTime: 1647900212725376000,
|
||||
DeploymentID: '',
|
||||
ID: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 97,
|
||||
ModifyTime: 1647900516944239000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
NodeID: '',
|
||||
PreviousEval: 'a8d29cfc-517c-2e4c-9722-b47e84152c64',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 97,
|
||||
CreateTime: 1647900516944236000,
|
||||
DeploymentID: '',
|
||||
ID: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 114,
|
||||
ModifyTime: 1647900825385587000,
|
||||
Namespace: 'default',
|
||||
NextEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
NodeID: '',
|
||||
PreviousEval: 'b37d06e4-4eb4-b29d-3b4a-b0c7bf2528ad',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 114,
|
||||
CreateTime: 1647900825385584000,
|
||||
DeploymentID: '',
|
||||
ID: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 128,
|
||||
ModifyTime: 1647900979511304000,
|
||||
Namespace: 'default',
|
||||
NextEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
NodeID: '',
|
||||
PreviousEval: 'd7c50aa5-5bf1-5119-d7e7-0d0ae5381856',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 128,
|
||||
CreateTime: 1647900979511301000,
|
||||
DeploymentID: '',
|
||||
ID: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 136,
|
||||
ModifyTime: 1647901211369652000,
|
||||
Namespace: 'default',
|
||||
NextEval: '1fded690-20ad-6afa-3b89-59e319dfce18',
|
||||
NodeID: '',
|
||||
PreviousEval: 'ea2239aa-26d6-8874-8c56-e1600585772b',
|
||||
Priority: 50,
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
{
|
||||
BlockedEval: '',
|
||||
CreateIndex: 136,
|
||||
CreateTime: 1647901211369648000,
|
||||
DeploymentID: '',
|
||||
ID: '1fded690-20ad-6afa-3b89-59e319dfce18',
|
||||
JobID: 'example',
|
||||
ModifyIndex: 136,
|
||||
ModifyTime: 1647901211369648000,
|
||||
Namespace: 'default',
|
||||
NextEval: '',
|
||||
NodeID: '',
|
||||
PreviousEval: '25a2dd19-8d22-d1dd-280a-79860c9b8bdb',
|
||||
Priority: 50,
|
||||
Status: 'pending',
|
||||
StatusDescription: '',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
WaitUntil: null,
|
||||
},
|
||||
],
|
||||
Status: 'failed',
|
||||
StatusDescription: 'evaluation reached delivery limit (3)',
|
||||
TriggeredBy: 'failed-follow-up',
|
||||
Type: 'service',
|
||||
Wait: 20000000000,
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
|
||||
"@ember/optional-features": "2.0.0",
|
||||
"@ember/render-modifiers": "^2.0.4",
|
||||
"@ember/test-helpers": "^2.6.0",
|
||||
"@glimmer/component": "^1.0.4",
|
||||
"@glimmer/tracking": "^1.0.4",
|
||||
@@ -79,6 +80,7 @@
|
||||
"ember-cli-sri": "^2.1.1",
|
||||
"ember-cli-string-helpers": "^6.1.0",
|
||||
"ember-cli-terser": "^4.0.2",
|
||||
"ember-click-outside": "^3.0.0",
|
||||
"ember-composable-helpers": "^5.0.0",
|
||||
"ember-concurrency": "^2.2.1",
|
||||
"ember-copy": "^2.0.1",
|
||||
@@ -95,6 +97,7 @@
|
||||
"ember-modifier": "^3.1.0",
|
||||
"ember-moment": "^9.0.1",
|
||||
"ember-named-blocks-polyfill": "^0.2.4",
|
||||
"ember-on-resize-modifier": "^1.0.0",
|
||||
"ember-overridable-computed": "^1.0.0",
|
||||
"ember-page-title": "^6.2.2",
|
||||
"ember-power-select": "^4.1.7",
|
||||
@@ -104,6 +107,8 @@
|
||||
"ember-responsive": "^4.0.2",
|
||||
"ember-sinon": "^5.0.0",
|
||||
"ember-source": "~3.28.8",
|
||||
"ember-stargate": "^0.4.1",
|
||||
"ember-statecharts": "^0.13.2",
|
||||
"ember-template-lint": "^3.15.0",
|
||||
"ember-test-selectors": "^6.0.0",
|
||||
"ember-truth-helpers": "^3.0.0",
|
||||
@@ -165,6 +170,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"codemirror": "^5.56.0",
|
||||
"curved-arrows": "^0.1.0",
|
||||
"d3": "^7.3.0",
|
||||
"lru_map": "^0.4.1",
|
||||
"no-case": "^3.0.4",
|
||||
"title-case": "^3.0.3"
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { click, currentRouteName, visit } from '@ember/test-helpers';
|
||||
import {
|
||||
click,
|
||||
currentRouteName,
|
||||
currentURL,
|
||||
visit,
|
||||
waitFor,
|
||||
waitUntil,
|
||||
} from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
@@ -8,6 +15,7 @@ import {
|
||||
selectChoose,
|
||||
clickTrigger,
|
||||
} from 'ember-power-select/test-support/helpers';
|
||||
import { generateAcceptanceTestEvalMock } from '../../mirage/utils';
|
||||
|
||||
const getStandardRes = () => [
|
||||
{
|
||||
@@ -407,16 +415,17 @@ module('Acceptance | evaluations list', function (hooks) {
|
||||
module('resource linking', function () {
|
||||
test('it should generate a link to the job resource', async function (assert) {
|
||||
server.create('node');
|
||||
const job = server.create('job', { shallow: true });
|
||||
const job = server.create('job', { id: 'example', shallow: true });
|
||||
server.create('evaluation', { jobId: job.id });
|
||||
await visit('/evaluations');
|
||||
|
||||
await visit('/evaluations');
|
||||
assert
|
||||
.dom('[data-test-evaluation-resource]')
|
||||
.hasText(
|
||||
job.name,
|
||||
'It conditionally renders the correct resource name'
|
||||
);
|
||||
|
||||
await click('[data-test-evaluation-resource]');
|
||||
assert
|
||||
.dom('[data-test-job-name]')
|
||||
@@ -443,4 +452,106 @@ module('Acceptance | evaluations list', function (hooks) {
|
||||
.includesText(node.name, 'We navigate to the correct client page.');
|
||||
});
|
||||
});
|
||||
|
||||
module('evaluation detail', function () {
|
||||
test('clicking an evaluation opens the detail view', async function (assert) {
|
||||
server.get('/evaluations', getStandardRes);
|
||||
server.get('/evaluation/:id', function (_, { params }) {
|
||||
return { ...generateAcceptanceTestEvalMock(params.id), ID: params.id };
|
||||
});
|
||||
|
||||
await visit('/evaluations');
|
||||
|
||||
const evalId = '5fb1b8cd';
|
||||
await click(`[data-test-evaluation='${evalId}']`);
|
||||
|
||||
assert
|
||||
.dom('[data-test-eval-detail-is-open]')
|
||||
.exists(
|
||||
'A sidebar portal mounts to the dom after clicking an evaluation'
|
||||
);
|
||||
|
||||
assert
|
||||
.dom('[data-test-rel-eval]')
|
||||
.exists(
|
||||
{ count: 12 },
|
||||
'all related evaluations and the current evaluation are displayed'
|
||||
);
|
||||
|
||||
click(`[data-test-rel-eval='fd1cd898-d655-c7e4-17f6-a1a2e98b18ef']`);
|
||||
await waitFor('[data-test-eval-loading]');
|
||||
assert
|
||||
.dom('[data-test-eval-loading]')
|
||||
.exists(
|
||||
'transition to loading state after clicking related evaluation'
|
||||
);
|
||||
|
||||
await waitFor('[data-test-eval-detail-header]');
|
||||
|
||||
assert.equal(
|
||||
currentURL(),
|
||||
'/evaluations?currentEval=fd1cd898-d655-c7e4-17f6-a1a2e98b18ef'
|
||||
);
|
||||
assert
|
||||
.dom('[data-test-title]')
|
||||
.includesText('fd1cd898', 'New evaluation hash appears in the title');
|
||||
|
||||
await click(`[data-test-evaluation='66cb98a6']`);
|
||||
assert.equal(
|
||||
currentURL(),
|
||||
'/evaluations?currentEval=66cb98a6-7740-d5ef-37e4-fa0f8b1de44b',
|
||||
'Clicking an evaluation in the table updates the sidebar'
|
||||
);
|
||||
|
||||
click('[data-test-eval-sidebar-x]');
|
||||
|
||||
// We wait until the sidebar closes since it uses a transition of 300ms
|
||||
await waitUntil(
|
||||
() => !document.querySelector('[data-test-eval-detail-is-open]')
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
currentURL(),
|
||||
'/evaluations',
|
||||
'When the user clicks the x button the sidebar closes'
|
||||
);
|
||||
});
|
||||
|
||||
test('it should provide an error state when loading an invalid evaluation', async function (assert) {
|
||||
server.get('/evaluations', getStandardRes);
|
||||
server.get('/evaluation/:id', function () {
|
||||
return new Response(404, {}, '');
|
||||
});
|
||||
|
||||
await visit('/evaluations');
|
||||
|
||||
const evalId = '5fb1b8cd';
|
||||
await click(`[data-test-evaluation='${evalId}']`);
|
||||
|
||||
assert
|
||||
.dom('[data-test-eval-detail-is-open]')
|
||||
.exists(
|
||||
'A sidebar portal mounts to the dom after clicking an evaluation'
|
||||
);
|
||||
|
||||
assert
|
||||
.dom('[data-test-eval-error]')
|
||||
.exists(
|
||||
'all related evaluations and the current evaluation are displayed'
|
||||
);
|
||||
|
||||
click('[data-test-eval-sidebar-x]');
|
||||
|
||||
// We wait until the sidebar closes since it uses a transition of 300ms
|
||||
await waitUntil(
|
||||
() => !document.querySelector('[data-test-eval-detail-is-open]')
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
currentURL(),
|
||||
'/evaluations',
|
||||
'When the user clicks the x button the sidebar closes'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
137
ui/tests/integration/data-modeling/related-evaluations-test.js
Normal file
137
ui/tests/integration/data-modeling/related-evaluations-test.js
Normal file
@@ -0,0 +1,137 @@
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Integration | Data Modeling | related evaluations', function (hooks) {
|
||||
setupTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
test('it should a return a list of related evaluations when the related query parameter is specified', async function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
|
||||
server.get('/evaluation/:id', function (_, fakeRes) {
|
||||
assert.equal(
|
||||
fakeRes.queryParams.related,
|
||||
'true',
|
||||
'it should append the related query parameter when making the API request for related evaluations'
|
||||
);
|
||||
return {
|
||||
ID: 'tomster',
|
||||
Priority: 50,
|
||||
Type: 'service',
|
||||
TriggeredBy: 'job-register',
|
||||
JobID: 'example',
|
||||
JobModifyIndex: 52,
|
||||
NodeID: 'yes',
|
||||
NodeModifyIndex: 0,
|
||||
Status: 'complete',
|
||||
StatusDescription: '',
|
||||
Wait: 0,
|
||||
NextEval: '',
|
||||
PreviousEval: '',
|
||||
BlockedEval: '',
|
||||
FailedTGAllocs: null,
|
||||
ClassEligibility: null,
|
||||
EscapedComputedClass: false,
|
||||
AnnotatePlan: false,
|
||||
SnapshotIndex: 53,
|
||||
QueuedAllocations: {
|
||||
cache: 0,
|
||||
},
|
||||
CreateIndex: 53,
|
||||
ModifyIndex: 55,
|
||||
Related: [],
|
||||
};
|
||||
});
|
||||
await store.findRecord('evaluation', 'tomster', {
|
||||
adapterOptions: { related: true },
|
||||
});
|
||||
|
||||
server.get('/evaluation/:id', function (_, fakeRes) {
|
||||
assert.notOk(
|
||||
fakeRes.queryParams.related,
|
||||
'it should not append the related query parameter when making the API request for related evaluations'
|
||||
);
|
||||
return {
|
||||
ID: 'tomster',
|
||||
Priority: 50,
|
||||
Type: 'service',
|
||||
TriggeredBy: 'job-register',
|
||||
JobID: 'example',
|
||||
JobModifyIndex: 52,
|
||||
NodeID: 'yes',
|
||||
NodeModifyIndex: 0,
|
||||
Status: 'complete',
|
||||
StatusDescription: '',
|
||||
Wait: 0,
|
||||
NextEval: '',
|
||||
PreviousEval: '',
|
||||
BlockedEval: '',
|
||||
FailedTGAllocs: null,
|
||||
ClassEligibility: null,
|
||||
EscapedComputedClass: false,
|
||||
AnnotatePlan: false,
|
||||
SnapshotIndex: 53,
|
||||
QueuedAllocations: {
|
||||
cache: 0,
|
||||
},
|
||||
CreateIndex: 53,
|
||||
ModifyIndex: 55,
|
||||
Related: [],
|
||||
};
|
||||
});
|
||||
await store.findRecord('evaluation', 'tomster');
|
||||
});
|
||||
|
||||
test('it should store related evaluations stubs as a hasMany in the store', async function (assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
|
||||
server.get('/evaluation/:id', function () {
|
||||
return {
|
||||
ID: 'tomster',
|
||||
Priority: 50,
|
||||
Type: 'service',
|
||||
TriggeredBy: 'job-register',
|
||||
JobID: 'example',
|
||||
JobModifyIndex: 52,
|
||||
NodeID: 'yes',
|
||||
NodeModifyIndex: 0,
|
||||
Status: 'complete',
|
||||
StatusDescription: '',
|
||||
Wait: 0,
|
||||
NextEval: '',
|
||||
PreviousEval: '',
|
||||
BlockedEval: '',
|
||||
FailedTGAllocs: null,
|
||||
ClassEligibility: null,
|
||||
EscapedComputedClass: false,
|
||||
AnnotatePlan: false,
|
||||
SnapshotIndex: 53,
|
||||
QueuedAllocations: {
|
||||
cache: 0,
|
||||
},
|
||||
CreateIndex: 53,
|
||||
ModifyIndex: 55,
|
||||
RelatedEvals: [
|
||||
{ ID: 'a', StatusDescription: 'a' },
|
||||
{ ID: 'b', StatusDescription: 'b' },
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const result = await store.findRecord('evaluation', 'tomster', {
|
||||
adapterOptions: { related: true },
|
||||
});
|
||||
|
||||
assert.equal(result.relatedEvals.length, 2);
|
||||
|
||||
const mappedResult = result.relatedEvals.map((es) => es.id);
|
||||
|
||||
assert.deepEqual(
|
||||
mappedResult,
|
||||
['a', 'b'],
|
||||
'related evals data is accessible'
|
||||
);
|
||||
});
|
||||
});
|
||||
358
ui/yarn.lock
358
ui/yarn.lock
@@ -2492,7 +2492,7 @@
|
||||
mkdirp "^1.0.4"
|
||||
silent-error "^1.1.1"
|
||||
|
||||
"@ember/render-modifiers@^2.0.0":
|
||||
"@ember/render-modifiers@^2.0.0", "@ember/render-modifiers@^2.0.4":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-2.0.4.tgz#0ac7af647cb736076dbfcd54ca71e090cd329d71"
|
||||
integrity sha512-Zh/fo5VUmVzYHkHVvzWVjJ1RjFUxA2jH0zCp2+DQa80Bf3DUXauiEByxU22UkN4LFT55DBFttC0xCQSJG3WTsg==
|
||||
@@ -2542,6 +2542,14 @@
|
||||
ember-cli-version-checker "^5.1.2"
|
||||
semver "^7.3.5"
|
||||
|
||||
"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.2.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.5.0.tgz#639b8b394336a5ae26dd3e24ffc3d34d864ac5ce"
|
||||
integrity sha512-5zgwA/wTYjgn2Oo6hKRQhF/5Gnwb+hGhj/WXhZQa5yA7fRRdBV1tVMS7b7SLawZcmOhuWkyPwFdgsYtGBvDB0w==
|
||||
dependencies:
|
||||
"@embroider/shared-internals" "^1.5.0"
|
||||
semver "^7.3.5"
|
||||
|
||||
"@embroider/core@0.36.0":
|
||||
version "0.36.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/core/-/core-0.36.0.tgz#fbbd60d29c3fcbe02b4e3e63e6043a43de2b9ce3"
|
||||
@@ -2647,6 +2655,20 @@
|
||||
resolve "^1.20.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
"@embroider/macros@^1.2.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.5.0.tgz#8c67666359e7814d91cdeac2fd96c896080473b3"
|
||||
integrity sha512-QqNsWmIJ8LvwWg+YAfB+nfcRZ49hAJNTJAKt2IDpgZDKa/FYj/Mp75UWfJ1BJvB3KUq50OQCOv4TZ3ZcU9h/TQ==
|
||||
dependencies:
|
||||
"@embroider/shared-internals" "1.5.0"
|
||||
assert-never "^1.2.1"
|
||||
babel-import-util "^1.1.0"
|
||||
ember-cli-babel "^7.26.6"
|
||||
find-up "^5.0.0"
|
||||
lodash "^4.17.21"
|
||||
resolve "^1.20.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
"@embroider/shared-internals@0.40.0":
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-0.40.0.tgz#2f768c60f4f35ba5f9228f046f70324851e8bfe2"
|
||||
@@ -2699,6 +2721,19 @@
|
||||
semver "^7.3.5"
|
||||
typescript-memoize "^1.0.1"
|
||||
|
||||
"@embroider/shared-internals@1.5.0", "@embroider/shared-internals@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-1.5.0.tgz#d3883f13571be36fcdbc59c65c785db7b6d8186e"
|
||||
integrity sha512-kdR7Fh2YdzsNofJO+DJxLfrlMbW4/NNf78aMXgE21z/tg9GO5W2mKlI1DzsO2JlO5yfZdiYfqb9C9vSLJEx14A==
|
||||
dependencies:
|
||||
babel-import-util "^1.1.0"
|
||||
ember-rfc176-data "^0.3.17"
|
||||
fs-extra "^9.1.0"
|
||||
lodash "^4.17.21"
|
||||
resolve-package-path "^4.0.1"
|
||||
semver "^7.3.5"
|
||||
typescript-memoize "^1.0.1"
|
||||
|
||||
"@embroider/shared-internals@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-1.0.0.tgz#b081708ac79e4582f17ba0f3e3796e6612a8976c"
|
||||
@@ -2974,7 +3009,7 @@
|
||||
"@handlebars/parser" "^1.1.0"
|
||||
simple-html-tokenizer "^0.5.10"
|
||||
|
||||
"@glimmer/tracking@^1.0.2", "@glimmer/tracking@^1.0.4":
|
||||
"@glimmer/tracking@^1.0.0", "@glimmer/tracking@^1.0.1", "@glimmer/tracking@^1.0.2", "@glimmer/tracking@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@glimmer/tracking/-/tracking-1.0.4.tgz#f1bc1412fe5e2236d0f8d502994a8f88af1bbb21"
|
||||
integrity sha512-F+oT8I55ba2puSGIzInmVrv/8QA2PcK1VD+GWgFMhF6WC97D+uZX7BFg+a3s/2N4FVBq5KHE+QxZzgazM151Yw==
|
||||
@@ -7087,7 +7122,7 @@ commander@2.8.x:
|
||||
dependencies:
|
||||
graceful-readlink ">= 1.0.0"
|
||||
|
||||
commander@7.2.0:
|
||||
commander@7, commander@7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
|
||||
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
|
||||
@@ -7666,56 +7701,166 @@ ctype@0.5.3:
|
||||
resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f"
|
||||
integrity sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=
|
||||
|
||||
curved-arrows@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/curved-arrows/-/curved-arrows-0.1.0.tgz#824709316a856e28970c1f577803093a57475bb0"
|
||||
integrity sha512-FchrDNr8b3ijJOycRM3iT0tc7d5NJSJ5e1fPZibTv73N2yXcgIbSi858R+QfCPRbrjqSWXnR8OaUUu9w+TxTRg==
|
||||
|
||||
cyclist@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
||||
|
||||
"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.1:
|
||||
"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.1.1.tgz#7797eb53ead6b9083c75a45a681e93fc41bc468c"
|
||||
integrity sha512-33qQ+ZoZlli19IFiQx4QEpf2CBEayMRzhlisJHSCsSUbDXv6ZishqS1x7uFVClKG4Wr7rZVHvaAttoLow6GqdQ==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
d3-axis@^3.0.0:
|
||||
d3-axis@3, d3-axis@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322"
|
||||
integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==
|
||||
|
||||
"d3-color@1 - 3":
|
||||
d3-brush@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c"
|
||||
integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==
|
||||
dependencies:
|
||||
d3-dispatch "1 - 3"
|
||||
d3-drag "2 - 3"
|
||||
d3-interpolate "1 - 3"
|
||||
d3-selection "3"
|
||||
d3-transition "3"
|
||||
|
||||
d3-chord@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966"
|
||||
integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==
|
||||
dependencies:
|
||||
d3-path "1 - 3"
|
||||
|
||||
"d3-color@1 - 3", d3-color@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.0.1.tgz#03316e595955d1fcd39d9f3610ad41bb90194d0a"
|
||||
integrity sha512-6/SlHkDOBLyQSJ1j1Ghs82OIUXpKWlR0hCsw0XrLSQhuUPuCSmLQ1QPH98vpnQxMUQM2/gfAkUEWsupVpd9JGw==
|
||||
|
||||
"d3-dispatch@1 - 3":
|
||||
d3-contour@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-3.0.1.tgz#2c64255d43059599cd0dba8fe4cc3d51ccdd9bbd"
|
||||
integrity sha512-0Oc4D0KyhwhM7ZL0RMnfGycLN7hxHB8CMmwZ3+H26PWAG0ozNuYG5hXSDNgmP1SgJkQMrlG6cP20HoaSbvcJTQ==
|
||||
dependencies:
|
||||
d3-array "2 - 3"
|
||||
|
||||
d3-delaunay@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.2.tgz#7fd3717ad0eade2fc9939f4260acfb503f984e92"
|
||||
integrity sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==
|
||||
dependencies:
|
||||
delaunator "5"
|
||||
|
||||
"d3-dispatch@1 - 3", d3-dispatch@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
|
||||
integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
|
||||
|
||||
"d3-ease@1 - 3":
|
||||
"d3-drag@2 - 3", d3-drag@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
|
||||
integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
|
||||
dependencies:
|
||||
d3-dispatch "1 - 3"
|
||||
d3-selection "3"
|
||||
|
||||
"d3-dsv@1 - 3", d3-dsv@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73"
|
||||
integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==
|
||||
dependencies:
|
||||
commander "7"
|
||||
iconv-lite "0.6"
|
||||
rw "1"
|
||||
|
||||
"d3-ease@1 - 3", d3-ease@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
|
||||
integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
|
||||
|
||||
d3-fetch@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22"
|
||||
integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==
|
||||
dependencies:
|
||||
d3-dsv "1 - 3"
|
||||
|
||||
d3-force@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4"
|
||||
integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==
|
||||
dependencies:
|
||||
d3-dispatch "1 - 3"
|
||||
d3-quadtree "1 - 3"
|
||||
d3-timer "1 - 3"
|
||||
|
||||
"d3-format@1 - 3", d3-format@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.0.1.tgz#e41b81b2ab79277141ec1404aa5d05001da64084"
|
||||
integrity sha512-hdL7+HBIohpgfolhBxr1KX47VMD6+vVD/oEFrxk5yhmzV2prk99EkFKYpXuhVkFpTgHdJ6/4bYcjdLPPXV4tIA==
|
||||
|
||||
"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3":
|
||||
d3-format@3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
|
||||
integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
|
||||
|
||||
d3-geo@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.0.1.tgz#4f92362fd8685d93e3b1fae0fd97dc8980b1ed7e"
|
||||
integrity sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==
|
||||
dependencies:
|
||||
d3-array "2.5.0 - 3"
|
||||
|
||||
d3-hierarchy@3:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.1.tgz#9cbb0ffd2375137a351e6cfeed344a06d4ff4597"
|
||||
integrity sha512-LtAIu54UctRmhGKllleflmHalttH3zkfSi4NlKrTAoFKjC+AFBJohsCAdgCBYQwH0F8hIOGY89X1pPqAchlMkA==
|
||||
|
||||
"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
|
||||
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
|
||||
dependencies:
|
||||
d3-color "1 - 3"
|
||||
|
||||
"d3-path@1 - 3":
|
||||
"d3-path@1 - 3", d3-path@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e"
|
||||
integrity sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==
|
||||
|
||||
d3-scale@^4.0.2:
|
||||
d3-polygon@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398"
|
||||
integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==
|
||||
|
||||
"d3-quadtree@1 - 3", d3-quadtree@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f"
|
||||
integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==
|
||||
|
||||
d3-random@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4"
|
||||
integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==
|
||||
|
||||
d3-scale-chromatic@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a"
|
||||
integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==
|
||||
dependencies:
|
||||
d3-color "1 - 3"
|
||||
d3-interpolate "1 - 3"
|
||||
|
||||
d3-scale@4, d3-scale@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
|
||||
integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
|
||||
@@ -7726,11 +7871,18 @@ d3-scale@^4.0.2:
|
||||
d3-time "2.1.1 - 3"
|
||||
d3-time-format "2 - 4"
|
||||
|
||||
d3-selection@^3.0.0:
|
||||
"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
|
||||
integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
|
||||
|
||||
d3-shape@3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556"
|
||||
integrity sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==
|
||||
dependencies:
|
||||
d3-path "1 - 3"
|
||||
|
||||
d3-shape@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.0.1.tgz#9ccdfb28fd9b0d12f2d8aec234cd5c4a9ea27931"
|
||||
@@ -7745,19 +7897,26 @@ d3-shape@^3.0.1:
|
||||
dependencies:
|
||||
d3-time "1 - 3"
|
||||
|
||||
"d3-time@1 - 3", "d3-time@2.1.1 - 3":
|
||||
d3-time-format@4:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
|
||||
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
|
||||
dependencies:
|
||||
d3-time "1 - 3"
|
||||
|
||||
"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.0.0.tgz#65972cb98ae2d4954ef5c932e8704061335d4975"
|
||||
integrity sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==
|
||||
dependencies:
|
||||
d3-array "2 - 3"
|
||||
|
||||
"d3-timer@1 - 3":
|
||||
"d3-timer@1 - 3", d3-timer@3:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
|
||||
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
|
||||
|
||||
d3-transition@^3.0.1:
|
||||
"d3-transition@2 - 3", d3-transition@3, d3-transition@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
|
||||
integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
|
||||
@@ -7768,6 +7927,53 @@ d3-transition@^3.0.1:
|
||||
d3-interpolate "1 - 3"
|
||||
d3-timer "1 - 3"
|
||||
|
||||
d3-zoom@3:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
|
||||
integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
|
||||
dependencies:
|
||||
d3-dispatch "1 - 3"
|
||||
d3-drag "2 - 3"
|
||||
d3-interpolate "1 - 3"
|
||||
d3-selection "2 - 3"
|
||||
d3-transition "2 - 3"
|
||||
|
||||
d3@^7.3.0:
|
||||
version "7.3.0"
|
||||
resolved "https://registry.yarnpkg.com/d3/-/d3-7.3.0.tgz#f3d5a22c1f658952a6491cf50132f5267ed7a40a"
|
||||
integrity sha512-MDRLJCMK232OJQRqGljQ/gCxtB8k3/sLKFjftMjzPB3nKVUODpdW9Rb3vcq7U8Ka5YKoZkAmp++Ur6I+6iNWIw==
|
||||
dependencies:
|
||||
d3-array "3"
|
||||
d3-axis "3"
|
||||
d3-brush "3"
|
||||
d3-chord "3"
|
||||
d3-color "3"
|
||||
d3-contour "3"
|
||||
d3-delaunay "6"
|
||||
d3-dispatch "3"
|
||||
d3-drag "3"
|
||||
d3-dsv "3"
|
||||
d3-ease "3"
|
||||
d3-fetch "3"
|
||||
d3-force "3"
|
||||
d3-format "3"
|
||||
d3-geo "3"
|
||||
d3-hierarchy "3"
|
||||
d3-interpolate "3"
|
||||
d3-path "3"
|
||||
d3-polygon "3"
|
||||
d3-quadtree "3"
|
||||
d3-random "3"
|
||||
d3-scale "4"
|
||||
d3-scale-chromatic "3"
|
||||
d3-selection "3"
|
||||
d3-shape "3"
|
||||
d3-time "3"
|
||||
d3-time-format "4"
|
||||
d3-timer "3"
|
||||
d3-transition "3"
|
||||
d3-zoom "3"
|
||||
|
||||
dag-map@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/dag-map/-/dag-map-2.0.2.tgz#9714b472de82a1843de2fba9b6876938cab44c68"
|
||||
@@ -7902,6 +8108,13 @@ define-property@^2.0.2:
|
||||
is-descriptor "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
delaunator@5:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b"
|
||||
integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==
|
||||
dependencies:
|
||||
robust-predicates "^3.0.0"
|
||||
|
||||
delayed-stream@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f"
|
||||
@@ -8268,7 +8481,7 @@ ember-assign-helper@^0.3.0:
|
||||
ember-cli-babel "^7.19.0"
|
||||
ember-cli-htmlbars "^4.3.1"
|
||||
|
||||
ember-auto-import@^1.10.1, ember-auto-import@^1.11.3, ember-auto-import@^1.2.19, ember-auto-import@^2.4.0:
|
||||
ember-auto-import@^1.10.1, ember-auto-import@^1.11.3, ember-auto-import@^1.2.19, ember-auto-import@^1.6.0, ember-auto-import@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.4.0.tgz#91c4797f08315728086e35af954cb60bd23c14bc"
|
||||
integrity sha512-BwF6iTaoSmT2vJ9NEHEGRBCh2+qp+Nlaz/Q7roqNSxl5oL5iMRwenPnHhOoBPTYZvPhcV/KgXR5e+pBQ107plQ==
|
||||
@@ -8469,7 +8682,7 @@ ember-cli-htmlbars@^3.0.1:
|
||||
json-stable-stringify "^1.0.1"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
ember-cli-htmlbars@^4.0.0, ember-cli-htmlbars@^4.3.1:
|
||||
ember-cli-htmlbars@^4.0.0, ember-cli-htmlbars@^4.2.0, ember-cli-htmlbars@^4.3.1:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-4.5.0.tgz#d299e4f7eba6f30dc723ee086906cc550beb252e"
|
||||
integrity sha512-bYJpK1pqFu9AadDAGTw05g2LMNzY8xTCIqQm7dMJmKEoUpLRFbPf4SfHXrktzDh7Q5iggl6Skzf1M0bPlIxARw==
|
||||
@@ -8935,6 +9148,15 @@ ember-cli@~3.28.5:
|
||||
workerpool "^6.1.4"
|
||||
yam "^1.0.0"
|
||||
|
||||
ember-click-outside@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-click-outside/-/ember-click-outside-3.0.0.tgz#a7271345c5960b5dfe1e45a7f7245d1cf8f383dc"
|
||||
integrity sha512-X2hLE9Set/tQ9KAEUxfGzCTUgJu/g2sKG+t2ghk/EDz8zF+Y/DPtlxeyZTR6NEPsUbzu3Pqe9gWJUxwaiXC0wg==
|
||||
dependencies:
|
||||
ember-cli-babel "^7.26.6"
|
||||
ember-cli-htmlbars "^5.7.1"
|
||||
ember-modifier "^2.1.0 || ^3.0.0"
|
||||
|
||||
ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.5:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.6.tgz#603579ab2fb14be567ef944da3fc2d355f779cd8"
|
||||
@@ -9189,7 +9411,7 @@ ember-modifier-manager-polyfill@^1.2.0:
|
||||
ember-cli-version-checker "^2.1.2"
|
||||
ember-compatibility-helpers "^1.2.0"
|
||||
|
||||
ember-modifier@^3.0.0, ember-modifier@^3.1.0:
|
||||
"ember-modifier@^2.1.0 || ^3.0.0", ember-modifier@^3.0.0, ember-modifier@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-3.1.0.tgz#ba5b0941302accd787ed3dcfc8d20400b77ffc41"
|
||||
integrity sha512-G5Lj9jVFsD2sVJcRNQfaGKG1p81wT4LGfClBhCuB4TgwP1NGJKdqI+Q8BW2MptONxQt/71UjjUH0YK7Gm9eahg==
|
||||
@@ -9219,6 +9441,16 @@ ember-named-blocks-polyfill@^0.2.4:
|
||||
ember-cli-babel "^7.19.0"
|
||||
ember-cli-version-checker "^5.1.1"
|
||||
|
||||
ember-on-resize-modifier@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-on-resize-modifier/-/ember-on-resize-modifier-1.0.0.tgz#b4e12dc023b4d608d7b0f4fa0100722fb860cdd4"
|
||||
integrity sha512-awmjTV8xIZ0Qc5X+46iYL4NT3f4NahNq+3XJ3Fn7zo8D4QuMzMOM91HqvtFQBWddD8o0v7qZNzW++HXAYAPXkg==
|
||||
dependencies:
|
||||
ember-cli-babel "^7.26.6"
|
||||
ember-cli-htmlbars "^5.7.1"
|
||||
ember-modifier "^3.0.0"
|
||||
ember-resize-observer-service "^1.0.0"
|
||||
|
||||
ember-overridable-computed@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-overridable-computed/-/ember-overridable-computed-1.0.0.tgz#4fb4a5acc9ec9ed7421586a5a8b4014f5bdb04f7"
|
||||
@@ -9273,6 +9505,14 @@ ember-render-helpers@^0.2.0:
|
||||
ember-cli-babel "^7.23.0"
|
||||
ember-cli-typescript "^4.0.0"
|
||||
|
||||
ember-resize-observer-service@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-resize-observer-service/-/ember-resize-observer-service-1.0.0.tgz#6d28e33cf06ddc60e83111069c41796d6739142e"
|
||||
integrity sha512-KmKNerMJUIJgOjr/AOM+fTa3nhbLLrLLTAw2mZuHhRCF1xEivvvF3ivE9Lst2tVgwi4IgI5Q/4t6AMea/dZpAA==
|
||||
dependencies:
|
||||
ember-cli-babel "^7.26.6"
|
||||
ember-cli-htmlbars "^5.7.1"
|
||||
|
||||
ember-resolver@^8.0.3:
|
||||
version "8.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ember-resolver/-/ember-resolver-8.0.3.tgz#40f243aa58281bf195c695fe84a6b291e204690a"
|
||||
@@ -9285,6 +9525,15 @@ ember-resolver@^8.0.3:
|
||||
ember-cli-version-checker "^5.1.2"
|
||||
resolve "^1.20.0"
|
||||
|
||||
ember-resources@^4.0.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-resources/-/ember-resources-4.4.0.tgz#a3b85a0269c3523ba32a2a5ab15472c8e90a6a41"
|
||||
integrity sha512-bMk3qdD7sgG33VY3Znri6z2p/XneITuT02zgFROS9flvUE124rnW/m9ND/fySt5EOE8URhS3IZ6MImIgI1dyCg==
|
||||
dependencies:
|
||||
"@ember/test-waiters" "^3.0.0"
|
||||
"@embroider/addon-shim" "^1.2.0"
|
||||
"@embroider/macros" "^1.2.0"
|
||||
|
||||
ember-responsive@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ember-responsive/-/ember-responsive-4.0.2.tgz#271fb0e619f492493a3332d96332d3684d70cb58"
|
||||
@@ -9360,6 +9609,30 @@ ember-source@~3.28.8:
|
||||
semver "^7.3.4"
|
||||
silent-error "^1.1.1"
|
||||
|
||||
ember-stargate@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/ember-stargate/-/ember-stargate-0.4.1.tgz#04ee5595569d77d9f2882636c78aa978b874ac62"
|
||||
integrity sha512-tw+H5nC29psfIBSfsYwhYZ9BqaRf50baO3isKal3UrEELTAblkjPiA1zuls2VV9+s5cUnqU2ygwW0zKEXNi1zQ==
|
||||
dependencies:
|
||||
"@ember/render-modifiers" "^2.0.0"
|
||||
"@embroider/addon-shim" "^1.0.0"
|
||||
"@glimmer/component" "^1.0.4"
|
||||
ember-resources "^4.0.0"
|
||||
tracked-maps-and-sets "^3.0.1"
|
||||
|
||||
ember-statecharts@^0.13.2:
|
||||
version "0.13.2"
|
||||
resolved "https://registry.yarnpkg.com/ember-statecharts/-/ember-statecharts-0.13.2.tgz#dbfe00b6a8ba54da8e01af416225d7a0d12e141c"
|
||||
integrity sha512-4TJCAWIs7vwmZbfH+c9xkXUrMsGho8lcYZQaqgmVEa3A1yzal/ToJHSFqaXm07ckNHkVNoC88Byh4WnbcKKpqA==
|
||||
dependencies:
|
||||
"@glimmer/tracking" "^1.0.1"
|
||||
ember-auto-import "^1.6.0"
|
||||
ember-cli-babel "^7.22.1"
|
||||
ember-cli-htmlbars "^5.3.1"
|
||||
ember-cli-typescript "^3.1.4"
|
||||
ember-usable "https://github.com/pzuraq/ember-usable#0d03a50"
|
||||
xstate "^4.12.0"
|
||||
|
||||
ember-style-modifier@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-style-modifier/-/ember-style-modifier-0.7.0.tgz#85b3dfd7e4bc2bd546df595f2dab4fb141cf7d87"
|
||||
@@ -9423,6 +9696,14 @@ ember-text-measurer@^0.6.0:
|
||||
ember-cli-babel "^7.19.0"
|
||||
ember-cli-htmlbars "^4.3.1"
|
||||
|
||||
ember-tracked-storage-polyfill@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-tracked-storage-polyfill/-/ember-tracked-storage-polyfill-1.0.0.tgz#84d307a1e4badc5f84dca681db2cfea9bdee8a77"
|
||||
integrity sha512-eL7lZat68E6P/D7b9UoTB5bB5Oh/0aju0Z7PCMi3aTwhaydRaxloE7TGrTRYU+NdJuyNVZXeGyxFxn2frvd3TA==
|
||||
dependencies:
|
||||
ember-cli-babel "^7.26.3"
|
||||
ember-cli-htmlbars "^5.7.1"
|
||||
|
||||
"ember-truth-helpers@^2.1.0 || ^3.0.0", ember-truth-helpers@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ember-truth-helpers/-/ember-truth-helpers-3.0.0.tgz#86766bdca4ac9b86bce3d262dff2aabc4a0ea384"
|
||||
@@ -9430,6 +9711,13 @@ ember-text-measurer@^0.6.0:
|
||||
dependencies:
|
||||
ember-cli-babel "^7.22.1"
|
||||
|
||||
"ember-usable@https://github.com/pzuraq/ember-usable#0d03a50":
|
||||
version "0.0.0"
|
||||
resolved "https://github.com/pzuraq/ember-usable#0d03a500a2f49041a4ddff0bb05b077c3907ed7d"
|
||||
dependencies:
|
||||
ember-cli-babel "^7.13.0"
|
||||
ember-cli-htmlbars "^4.2.0"
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
@@ -11711,6 +11999,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@0.6:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
||||
integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
icss-utils@^4.0.0, icss-utils@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
|
||||
@@ -16085,6 +16380,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
robust-predicates@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a"
|
||||
integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==
|
||||
|
||||
rollup-pluginutils@^2.0.1, rollup-pluginutils@^2.8.1:
|
||||
version "2.8.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
|
||||
@@ -16153,6 +16453,11 @@ run-queue@^1.0.0, run-queue@^1.0.3:
|
||||
dependencies:
|
||||
aproba "^1.1.1"
|
||||
|
||||
rw@1:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=
|
||||
|
||||
rxjs@^6.4.0:
|
||||
version "6.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552"
|
||||
@@ -16201,7 +16506,7 @@ safe-regex@^1.1.0:
|
||||
dependencies:
|
||||
ret "~0.1.10"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
@@ -17661,6 +17966,16 @@ tr46@~0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
tracked-maps-and-sets@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/tracked-maps-and-sets/-/tracked-maps-and-sets-3.0.2.tgz#6ea1b9f2a367d24f2e9905b74b24437fbce76ea6"
|
||||
integrity sha512-UIRcWsX1kDOcC/Q2R58weYWlw01EnmWWBwUv3okWS+zMBvsgIfYoO6veHhuNE3hgzWCEImNp46QS5CyKnw5QUA==
|
||||
dependencies:
|
||||
"@glimmer/tracking" "^1.0.0"
|
||||
ember-cli-babel "^7.26.6"
|
||||
ember-cli-typescript "^4.2.1"
|
||||
ember-tracked-storage-polyfill "1.0.0"
|
||||
|
||||
tree-sync@^1.2.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/tree-sync/-/tree-sync-1.4.0.tgz#314598d13abaf752547d9335b8f95d9a137100d6"
|
||||
@@ -18711,6 +19026,11 @@ xmlchars@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
||||
|
||||
xstate@^4.12.0:
|
||||
version "4.30.5"
|
||||
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.30.5.tgz#c2c6753542578bf15e707b759ebb671f55849410"
|
||||
integrity sha512-iZhIoZP8Alq4qI8eN/iAYiBRLfLSbSdI29LYsgk2DUvAwMV2J9xGw6CUT2HcH+5Rp5G3XzG6ByRfRmJJ+eEuDQ==
|
||||
|
||||
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
|
||||
Reference in New Issue
Block a user