diff --git a/ui-v2/app/controllers/dc/nodes/show.js b/ui-v2/app/controllers/dc/nodes/show.js index f90de09113..3dc82775e6 100644 --- a/ui-v2/app/controllers/dc/nodes/show.js +++ b/ui-v2/app/controllers/dc/nodes/show.js @@ -1,9 +1,14 @@ import Controller from '@ember/controller'; import { inject as service } from '@ember/service'; import { get, set, computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; import WithSearching from 'consul-ui/mixins/with-searching'; -export default Controller.extend(WithSearching, { +import WithEventSource, { listen } from 'consul-ui/mixins/with-event-source'; + +export default Controller.extend(WithEventSource, WithSearching, { dom: service('dom'), + notify: service('flashMessages'), + items: alias('item.Services'), queryParams: { s: { as: 'filter', @@ -16,6 +21,21 @@ export default Controller.extend(WithSearching, { }; this._super(...arguments); }, + item: listen('item').catch(function(e) { + if (e.target.readyState === 1) { + // OPEN + if (get(e, 'error.errors.firstObject.status') === '404') { + get(this, 'notify').add({ + destroyOnClick: false, + sticky: true, + type: 'warning', + action: 'update', + }); + get(this, 'tomography').close(); + get(this, 'sessions').close(); + } + } + }), searchable: computed('items', function() { return get(this, 'searchables.nodeservice') .add(get(this, 'items')) @@ -28,7 +48,7 @@ export default Controller.extend(WithSearching, { // This method is called immediately after `Route::setupController`, and done here rather than there // as this is a variable used purely for view level things, if the view was different we might not // need this variable - set(this, 'selectedTab', get(this.item, 'Checks.length') > 0 ? 'health-checks' : 'services'); + set(this, 'selectedTab', get(this, 'item.Checks.length') > 0 ? 'health-checks' : 'services'); }, actions: { change: function(e) { diff --git a/ui-v2/app/controllers/dc/services/instance.js b/ui-v2/app/controllers/dc/services/instance.js index a8934de52d..37847bb519 100644 --- a/ui-v2/app/controllers/dc/services/instance.js +++ b/ui-v2/app/controllers/dc/services/instance.js @@ -1,7 +1,10 @@ import Controller from '@ember/controller'; -import { set } from '@ember/object'; +import { get, set } from '@ember/object'; +import { inject as service } from '@ember/service'; +import WithEventSource, { listen } from 'consul-ui/mixins/with-event-source'; -export default Controller.extend({ +export default Controller.extend(WithEventSource, { + notify: service('flashMessages'), setProperties: function() { this._super(...arguments); // This method is called immediately after `Route::setupController`, and done here rather than there @@ -9,6 +12,19 @@ export default Controller.extend({ // need this variable set(this, 'selectedTab', 'service-checks'); }, + item: listen('item').catch(function(e) { + if (e.target.readyState === 1) { + // OPEN + if (get(e, 'error.errors.firstObject.status') === '404') { + get(this, 'notify').add({ + destroyOnClick: false, + sticky: true, + type: 'warning', + action: 'update', + }); + } + } + }), actions: { change: function(e) { set(this, 'selectedTab', e.target.value); diff --git a/ui-v2/app/instance-initializers/event-source.js b/ui-v2/app/instance-initializers/event-source.js index 01265dfec5..d2a707ee10 100644 --- a/ui-v2/app/instance-initializers/event-source.js +++ b/ui-v2/app/instance-initializers/event-source.js @@ -5,7 +5,7 @@ export function initialize(container) { if (config[enabled] || window.localStorage.getItem(enabled) !== null) { return; } - ['node', 'service'] + ['node', 'coordinate', 'session', 'service', 'proxy'] .map(function(item) { // create repositories that return a promise resolving to an EventSource return { @@ -20,7 +20,7 @@ export function initialize(container) { }) .concat([ // These are the routes where we overwrite the 'default' - // repo service. Default repos are repos that return a promise resovlving to + // repo service. Default repos are repos that return a promise resolving to // an ember-data record or recordset { route: 'dc/nodes/index', @@ -28,6 +28,14 @@ export function initialize(container) { repo: 'repository/node/event-source', }, }, + { + route: 'dc/nodes/show', + services: { + repo: 'repository/node/event-source', + coordinateRepo: 'repository/coordinate/event-source', + sessionRepo: 'repository/session/event-source', + }, + }, { route: 'dc/services/index', services: { @@ -40,6 +48,13 @@ export function initialize(container) { repo: 'repository/service/event-source', }, }, + { + route: 'dc/services/instance', + services: { + repo: 'repository/service/event-source', + proxyRepo: 'repository/proxy/event-source', + }, + }, ]) .forEach(function(definition) { if (typeof definition.extend !== 'undefined') { diff --git a/ui-v2/app/models/node.js b/ui-v2/app/models/node.js index cbe4272a58..be33ca7cf6 100644 --- a/ui-v2/app/models/node.js +++ b/ui-v2/app/models/node.js @@ -21,6 +21,7 @@ export default Model.extend({ Datacenter: attr('string'), Segment: attr(), Coord: attr(), + meta: attr(), hasStatus: function(status) { return hasStatus(get(this, 'Checks'), status); }, diff --git a/ui-v2/app/routes/dc/nodes/show.js b/ui-v2/app/routes/dc/nodes/show.js index 0449afc2df..ad7bf3b029 100644 --- a/ui-v2/app/routes/dc/nodes/show.js +++ b/ui-v2/app/routes/dc/nodes/show.js @@ -1,17 +1,14 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; import { hash } from 'rsvp'; -import { get, set } from '@ember/object'; +import { get } from '@ember/object'; -import distance from 'consul-ui/utils/distance'; -import tomographyFactory from 'consul-ui/utils/tomography'; import WithBlockingActions from 'consul-ui/mixins/with-blocking-actions'; -const tomography = tomographyFactory(distance); - export default Route.extend(WithBlockingActions, { repo: service('repository/node'), sessionRepo: service('repository/session'), + coordinateRepo: service('repository/coordinate'), queryParams: { s: { as: 'filter', @@ -20,24 +17,11 @@ export default Route.extend(WithBlockingActions, { }, model: function(params) { const dc = this.modelFor('dc').dc.Name; - const repo = get(this, 'repo'); - const sessionRepo = get(this, 'sessionRepo'); + const name = params.name; return hash({ - item: repo.findBySlug(params.name, dc), - }).then(function(model) { - // TODO: Consider loading this after initial page load - const coordinates = get(model.item, 'Coordinates'); - return hash({ - ...model, - ...{ - tomography: - get(coordinates, 'length') > 1 - ? tomography(params.name, coordinates.map(item => get(item, 'data'))) - : null, - items: get(model.item, 'Services'), - sessions: sessionRepo.findByNode(get(model.item, 'Node'), dc), - }, - }); + item: get(this, 'repo').findBySlug(name, dc), + tomography: get(this, 'coordinateRepo').findAllByNode(name, dc), + sessions: get(this, 'sessionRepo').findByNode(name, dc), }); }, setupController: function(controller, model) { @@ -52,7 +36,9 @@ export default Route.extend(WithBlockingActions, { const node = get(item, 'Node'); return repo.remove(item).then(() => { return repo.findByNode(node, dc).then(function(sessions) { - set(controller, 'sessions', sessions); + controller.setProperties({ + sessions: sessions, + }); }); }); }, 'delete'); diff --git a/ui-v2/app/routes/dc/services/instance.js b/ui-v2/app/routes/dc/services/instance.js index b4d0f1c5b9..2fb9eb30fd 100644 --- a/ui-v2/app/routes/dc/services/instance.js +++ b/ui-v2/app/routes/dc/services/instance.js @@ -13,6 +13,9 @@ export default Route.extend({ return hash({ item: repo.findInstanceBySlug(params.id, params.name, dc), }).then(function(model) { + // this will not be run in a blocking loop, but this is ok as + // its highly unlikely that a service will suddenly change to being a + // connect-proxy or vice versa so leave as is for now return hash({ proxy: get(model.item, 'Kind') === 'connect-proxy' diff --git a/ui-v2/app/services/repository/coordinate.js b/ui-v2/app/services/repository/coordinate.js index f6f5c1d8e6..75b3f2f1f7 100644 --- a/ui-v2/app/services/repository/coordinate.js +++ b/ui-v2/app/services/repository/coordinate.js @@ -1,8 +1,23 @@ +import { get } from '@ember/object'; import RepositoryService from 'consul-ui/services/repository'; +import tomographyFactory from 'consul-ui/utils/tomography'; +import distance from 'consul-ui/utils/distance'; +const tomography = tomographyFactory(distance); + const modelName = 'coordinate'; export default RepositoryService.extend({ getModelName: function() { return modelName; }, + findAllByNode: function(node, dc, configuration) { + return this.findAllByDatacenter(dc, configuration).then(function(coordinates) { + let results = {}; + if (get(coordinates, 'length') > 1) { + results = tomography(node, coordinates.map(item => get(item, 'data'))); + } + results.meta = get(coordinates, 'meta'); + return results; + }); + }, }); diff --git a/ui-v2/app/services/repository/node.js b/ui-v2/app/services/repository/node.js index 0d7eb57344..eec4f211d3 100644 --- a/ui-v2/app/services/repository/node.js +++ b/ui-v2/app/services/repository/node.js @@ -1,20 +1,9 @@ import RepositoryService from 'consul-ui/services/repository'; import { inject as service } from '@ember/service'; -import { get } from '@ember/object'; const modelName = 'node'; export default RepositoryService.extend({ coordinates: service('repository/coordinate'), getModelName: function() { return modelName; }, - findBySlug: function(slug, dc) { - return this._super(...arguments).then(node => { - return get(this, 'coordinates') - .findAllByDatacenter(dc) - .then(function(res) { - node.Coordinates = res; - return node; - }); - }); - }, }); diff --git a/ui-v2/app/services/repository/proxy.js b/ui-v2/app/services/repository/proxy.js index 41f1207b4e..6daeee8c54 100644 --- a/ui-v2/app/services/repository/proxy.js +++ b/ui-v2/app/services/repository/proxy.js @@ -1,6 +1,6 @@ import RepositoryService from 'consul-ui/services/repository'; import { PRIMARY_KEY } from 'consul-ui/models/proxy'; -import { get } from '@ember/object'; +import { get, set } from '@ember/object'; const modelName = 'proxy'; export default RepositoryService.extend({ getModelName: function() { @@ -21,17 +21,20 @@ export default RepositoryService.extend({ }, findInstanceBySlug: function(id, slug, dc, configuration) { return this.findAllBySlug(slug, dc, configuration).then(function(items) { + let res = {}; if (get(items, 'length') > 0) { let instance = items.findBy('ServiceProxy.DestinationServiceID', id); if (instance) { - return instance; - } - instance = items.findBy('ServiceProxy.DestinationServiceName', slug); - if (instance) { - return instance; + res = instance; + } else { + instance = items.findBy('ServiceProxy.DestinationServiceName', slug); + if (instance) { + res = instance; + } } } - return; + set(res, 'meta', get(items, 'meta')); + return res; }); }, }); diff --git a/ui-v2/app/services/repository/service.js b/ui-v2/app/services/repository/service.js index 3e42c84f56..472c6ae670 100644 --- a/ui-v2/app/services/repository/service.js +++ b/ui-v2/app/services/repository/service.js @@ -46,6 +46,7 @@ export default RepositoryService.extend({ service.NodeChecks = item.Nodes[i].Checks.filter(function(item) { return item.ServiceID == ''; }); + set(service, 'meta', get(item, 'meta')); return service; } // TODO: Add an store.error("404", "message") or similar diff --git a/ui-v2/app/templates/dc/nodes/-notifications.hbs b/ui-v2/app/templates/dc/nodes/-notifications.hbs index 70f90530b4..cbc36249f0 100644 --- a/ui-v2/app/templates/dc/nodes/-notifications.hbs +++ b/ui-v2/app/templates/dc/nodes/-notifications.hbs @@ -4,5 +4,9 @@ {{else}} There was an error invalidating the session. {{/if}} +{{else if (eq type 'update')}} + {{#if (eq status 'warning') }} + This node no longer exists in the catalog. + {{else}} + {{/if}} {{/if}} - diff --git a/ui-v2/app/templates/dc/nodes/show.hbs b/ui-v2/app/templates/dc/nodes/show.hbs index 10a12fc576..3a4d135ffe 100644 --- a/ui-v2/app/templates/dc/nodes/show.hbs +++ b/ui-v2/app/templates/dc/nodes/show.hbs @@ -18,7 +18,7 @@ (array 'Health Checks' 'Services' - (if tomography 'Round Trip Time' '') + (if tomography.distances 'Round Trip Time' '') 'Lock Sessions' ) ) @@ -48,10 +48,10 @@ {{#each (compact (array - (hash id=(slugify 'Health Checks') partial='dc/nodes/healthchecks') - (hash id=(slugify 'Services') partial='dc/nodes/services') - (if tomography (hash id=(slugify 'Round Trip Time') partial='dc/nodes/rtt') '') - (hash id=(slugify 'Lock Sessions') partial='dc/nodes/sessions') + (hash id=(slugify 'Health Checks') partial='dc/nodes/healthchecks') + (hash id=(slugify 'Services') partial='dc/nodes/services') + (if tomography.distances (hash id=(slugify 'Round Trip Time') partial='dc/nodes/rtt') '') + (hash id=(slugify 'Lock Sessions') partial='dc/nodes/sessions') ) ) as |panel| }} diff --git a/ui-v2/app/templates/dc/services/instance.hbs b/ui-v2/app/templates/dc/services/instance.hbs index 76a0b95d26..b5aae2b9ea 100644 --- a/ui-v2/app/templates/dc/services/instance.hbs +++ b/ui-v2/app/templates/dc/services/instance.hbs @@ -1,4 +1,7 @@ {{#app-view class="instance show"}} + {{#block-slot 'notification' as |status type|}} + {{partial 'dc/services/notifications'}} + {{/block-slot}} {{#block-slot 'breadcrumbs'}}