From 7610111c7e0876060100f13ce30cab543396476e Mon Sep 17 00:00:00 2001 From: John Cowen Date: Tue, 29 Jan 2019 18:26:58 +0000 Subject: [PATCH 01/17] ui: [WIP] Start splitting out service instances --- ui-v2/app/components/healthcheck-list.js | 36 +++++++ ui-v2/app/controllers/dc/services/instance.js | 17 ++++ ui-v2/app/controllers/dc/services/show.js | 57 ++++++------ ui-v2/app/initializers/search.js | 3 +- ui-v2/app/router.js | 3 + ui-v2/app/routes/dc/services/instance.js | 38 ++++++++ ui-v2/app/routes/dc/services/show.js | 2 + ui-v2/app/services/dom.js | 4 +- ui-v2/app/services/repository/intention.js | 10 ++ .../app/styles/components/form-elements.scss | 2 +- .../templates/components/healthcheck-list.hbs | 5 + .../app/templates/dc/nodes/-healthchecks.hbs | 6 +- ui-v2/app/templates/dc/nodes/-services.hbs | 2 +- .../app/templates/dc/services/-instances.hbs | 47 ++++++++++ .../app/templates/dc/services/-intentions.hbs | 0 .../app/templates/dc/services/-nodechecks.hbs | 8 ++ .../templates/dc/services/-servicechecks.hbs | 8 ++ ui-v2/app/templates/dc/services/-tags.hbs | 11 +++ .../app/templates/dc/services/-upstreams.hbs | 0 ui-v2/app/templates/dc/services/instance.hbs | 65 +++++++++++++ ui-v2/app/templates/dc/services/show.hbs | 93 +++++-------------- .../components/healthcheck-list-test.js | 34 +++++++ .../controllers/dc/services/instance-test.js | 12 +++ .../unit/routes/dc/services/instance-test.js | 11 +++ 24 files changed, 367 insertions(+), 107 deletions(-) create mode 100644 ui-v2/app/components/healthcheck-list.js create mode 100644 ui-v2/app/controllers/dc/services/instance.js create mode 100644 ui-v2/app/routes/dc/services/instance.js create mode 100644 ui-v2/app/templates/components/healthcheck-list.hbs create mode 100644 ui-v2/app/templates/dc/services/-instances.hbs create mode 100644 ui-v2/app/templates/dc/services/-intentions.hbs create mode 100644 ui-v2/app/templates/dc/services/-nodechecks.hbs create mode 100644 ui-v2/app/templates/dc/services/-servicechecks.hbs create mode 100644 ui-v2/app/templates/dc/services/-tags.hbs create mode 100644 ui-v2/app/templates/dc/services/-upstreams.hbs create mode 100644 ui-v2/app/templates/dc/services/instance.hbs create mode 100644 ui-v2/tests/integration/components/healthcheck-list-test.js create mode 100644 ui-v2/tests/unit/controllers/dc/services/instance-test.js create mode 100644 ui-v2/tests/unit/routes/dc/services/instance-test.js diff --git a/ui-v2/app/components/healthcheck-list.js b/ui-v2/app/components/healthcheck-list.js new file mode 100644 index 000000000000..092a1aadaf04 --- /dev/null +++ b/ui-v2/app/components/healthcheck-list.js @@ -0,0 +1,36 @@ +import Component from '@ember/component'; +import { get } from '@ember/object'; + +export default Component.extend({ + // TODO: Could potentially do this on attr change + actions: { + sortChecksByImportance: function(a, b) { + const statusA = get(a, 'Status'); + const statusB = get(b, 'Status'); + switch (statusA) { + case 'passing': + // a = passing + // unless b is also passing then a is less important + return statusB === 'passing' ? 0 : 1; + case 'critical': + // a = critical + // unless b is also critical then a is more important + return statusB === 'critical' ? 0 : -1; + case 'warning': + // a = warning + switch (statusB) { + // b is passing so a is more important + case 'passing': + return -1; + // b is critical so a is less important + case 'critical': + return 1; + // a and b are both warning, therefore equal + default: + return 0; + } + } + return 0; + }, + }, +}); diff --git a/ui-v2/app/controllers/dc/services/instance.js b/ui-v2/app/controllers/dc/services/instance.js new file mode 100644 index 000000000000..58dee9becfe4 --- /dev/null +++ b/ui-v2/app/controllers/dc/services/instance.js @@ -0,0 +1,17 @@ +import Controller from '@ember/controller'; +import { get, set } from '@ember/object'; + +export default Controller.extend({ + setProperties: function() { + this._super(...arguments); + // 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', 'service-checks'); + }, + actions: { + change: function(e) { + set(this, 'selectedTab', e.target.value); + }, + }, +}); diff --git a/ui-v2/app/controllers/dc/services/show.js b/ui-v2/app/controllers/dc/services/show.js index d4653888a56d..3f21a7b36bd6 100644 --- a/ui-v2/app/controllers/dc/services/show.js +++ b/ui-v2/app/controllers/dc/services/show.js @@ -1,38 +1,39 @@ import Controller from '@ember/controller'; -import { get, computed } from '@ember/object'; -import sumOfUnhealthy from 'consul-ui/utils/sumOfUnhealthy'; -import hasStatus from 'consul-ui/utils/hasStatus'; -import WithHealthFiltering from 'consul-ui/mixins/with-health-filtering'; +import { get, set, computed } from '@ember/object'; +import { inject as service } from '@ember/service'; import WithSearching from 'consul-ui/mixins/with-searching'; -export default Controller.extend(WithSearching, WithHealthFiltering, { +export default Controller.extend(WithSearching, { + dom: service('dom'), init: function() { this.searchParams = { - healthyServiceNode: 's', - unhealthyServiceNode: 's', + serviceInstance: 's', }; this._super(...arguments); }, - searchableHealthy: computed('healthy', function() { - return get(this, 'searchables.healthyServiceNode') - .add(get(this, 'healthy')) - .search(get(this, this.searchParams.healthyServiceNode)); - }), - searchableUnhealthy: computed('unhealthy', function() { - return get(this, 'searchables.unhealthyServiceNode') - .add(get(this, 'unhealthy')) - .search(get(this, this.searchParams.unhealthyServiceNode)); - }), - unhealthy: computed('filtered', function() { - return get(this, 'filtered').filter(function(item) { - return sumOfUnhealthy(item.Checks) > 0; - }); - }), - healthy: computed('filtered', function() { - return get(this, 'filtered').filter(function(item) { - return sumOfUnhealthy(item.Checks) === 0; - }); + setProperties: function() { + this._super(...arguments); + // 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', 'instances'); + }, + searchable: computed('items', function() { + return get(this, 'searchables.serviceInstance') + .add(get(this, 'items')) + .search(get(this, this.searchParams.serviceInstance)); }), - filter: function(item, { s = '', status = '' }) { - return hasStatus(get(item, 'Checks'), status); + actions: { + change: function(e) { + set(this, 'selectedTab', e.target.value); + // Ensure tabular-collections sizing is recalculated + // now it is visible in the DOM + get(this, 'dom') + .components('.tab-section input[type="radio"]:checked + div table') + .forEach(function(item) { + if (typeof item.didAppear === 'function') { + item.didAppear(); + } + }); + }, }, }); diff --git a/ui-v2/app/initializers/search.js b/ui-v2/app/initializers/search.js index 69875fdb114f..ebdd48c926f6 100644 --- a/ui-v2/app/initializers/search.js +++ b/ui-v2/app/initializers/search.js @@ -22,8 +22,7 @@ export function initialize(application) { kv: kv(filterable), healthyNode: node(filterable), unhealthyNode: node(filterable), - healthyServiceNode: serviceNode(filterable), - unhealthyServiceNode: serviceNode(filterable), + serviceInstance: serviceNode(filterable), nodeservice: nodeService(filterable), service: service(filterable), }; diff --git a/ui-v2/app/router.js b/ui-v2/app/router.js index 0a7a3bef8245..bd434eca3f94 100644 --- a/ui-v2/app/router.js +++ b/ui-v2/app/router.js @@ -18,6 +18,9 @@ export const routes = { show: { _options: { path: '/:name' }, }, + instance: { + _options: { path: '/:name/:id' }, + }, }, // Nodes represent a consul node nodes: { diff --git a/ui-v2/app/routes/dc/services/instance.js b/ui-v2/app/routes/dc/services/instance.js new file mode 100644 index 000000000000..59492478f5bf --- /dev/null +++ b/ui-v2/app/routes/dc/services/instance.js @@ -0,0 +1,38 @@ +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; +import { hash } from 'rsvp'; +import { get } from '@ember/object'; + +export default Route.extend({ + repo: service('repository/service'), + model: function(params) { + const repo = get(this, 'repo'); + // TODO: findInstanceBySlug + return hash({ + item: repo.findBySlug(params.name, this.modelFor('dc').dc.Name), + }).then(function(model) { + const i = model.item.Nodes.findIndex(function(item) { + return item.Service.ID === params.id; + }); + // console.log(model.item); + const service = model.item.Nodes[i].Service; + service.Node = model.item.Nodes[i].Node; + service.ServiceChecks = model.item.Nodes[i].Checks.filter(function(item) { + return item.ServiceID != ''; + }); + service.NodeChecks = model.item.Nodes[i].Checks.filter(function(item) { + return item.ServiceID == ''; + }); + return { + ...model, + ...{ + item: service, + }, + }; + }); + }, + setupController: function(controller, model) { + this._super(...arguments); + controller.setProperties(model); + }, +}); diff --git a/ui-v2/app/routes/dc/services/show.js b/ui-v2/app/routes/dc/services/show.js index bf5fa0d6579a..1e3be01717d2 100644 --- a/ui-v2/app/routes/dc/services/show.js +++ b/ui-v2/app/routes/dc/services/show.js @@ -5,6 +5,7 @@ import { get } from '@ember/object'; export default Route.extend({ repo: service('repository/service'), + intentionRepo: service('repository/intention'), queryParams: { s: { as: 'filter', @@ -15,6 +16,7 @@ export default Route.extend({ const repo = get(this, 'repo'); return hash({ item: repo.findBySlug(params.name, this.modelFor('dc').dc.Name), + // intentions: intentionRepo.findByService(params.name, this.modelFor('dc').dc.Name), }).then(function(model) { return { ...model, diff --git a/ui-v2/app/services/dom.js b/ui-v2/app/services/dom.js index a3bda1c8c8a2..740406cb5982 100644 --- a/ui-v2/app/services/dom.js +++ b/ui-v2/app/services/dom.js @@ -70,7 +70,9 @@ export default Service.extend({ // with traditional/standard web components you wouldn't actually need this // method as you could just get to their methods from the dom element component: function(selector, context) { - // TODO: support passing a dom element, when we need to do that + if (typeof selector !== 'string') { + return $_(selector); + } return $_(this.element(selector, context)); }, components: function(selector, context) { diff --git a/ui-v2/app/services/repository/intention.js b/ui-v2/app/services/repository/intention.js index 7df0cb8a5779..5ffcf0878f96 100644 --- a/ui-v2/app/services/repository/intention.js +++ b/ui-v2/app/services/repository/intention.js @@ -8,4 +8,14 @@ export default RepositoryService.extend({ getPrimaryKey: function() { return PRIMARY_KEY; }, + // findByService: function(slug, dc, configuration = {}) { + // const query = { + // dc: dc, + // id: slug, + // }; + // if (typeof configuration.cursor !== 'undefined') { + // query.index = configuration.cursor; + // } + // return get(this, 'store').queryRecord(this.getModelName(), query); + // } }); diff --git a/ui-v2/app/styles/components/form-elements.scss b/ui-v2/app/styles/components/form-elements.scss index 942efbb8cba9..c0bd6fa6e0a6 100644 --- a/ui-v2/app/styles/components/form-elements.scss +++ b/ui-v2/app/styles/components/form-elements.scss @@ -24,7 +24,7 @@ form table, %app-content form dl { @extend %form-row; } -%app-content [role='radiogroup'] { +%app-content form:not(.filter-bar) [role='radiogroup'] { @extend %radio-group; } %radio-group label { diff --git a/ui-v2/app/templates/components/healthcheck-list.hbs b/ui-v2/app/templates/components/healthcheck-list.hbs new file mode 100644 index 000000000000..75cdb60ce3e0 --- /dev/null +++ b/ui-v2/app/templates/components/healthcheck-list.hbs @@ -0,0 +1,5 @@ + diff --git a/ui-v2/app/templates/dc/nodes/-healthchecks.hbs b/ui-v2/app/templates/dc/nodes/-healthchecks.hbs index a956fad63133..19acae8c38e7 100644 --- a/ui-v2/app/templates/dc/nodes/-healthchecks.hbs +++ b/ui-v2/app/templates/dc/nodes/-healthchecks.hbs @@ -1,9 +1,5 @@ {{#if (gt item.Checks.length 0) }} - + {{healthcheck-list items=item.Checks}} {{else}}

This node has no health checks. diff --git a/ui-v2/app/templates/dc/nodes/-services.hbs b/ui-v2/app/templates/dc/nodes/-services.hbs index 856e51b172de..e692bb0d522e 100644 --- a/ui-v2/app/templates/dc/nodes/-services.hbs +++ b/ui-v2/app/templates/dc/nodes/-services.hbs @@ -19,7 +19,7 @@ - {{item.Service}}{{#if (not-eq item.ID item.Service) }}({{item.ID}}){{/if}} + {{item.Service}}{{#if (not-eq item.ID item.Service) }} ({{item.ID}}){{/if}} diff --git a/ui-v2/app/templates/dc/services/-instances.hbs b/ui-v2/app/templates/dc/services/-instances.hbs new file mode 100644 index 000000000000..32bbc99aec3b --- /dev/null +++ b/ui-v2/app/templates/dc/services/-instances.hbs @@ -0,0 +1,47 @@ +{{#if (gt items.length 0) }} + +

+ {{freetext-filter searchable=searchable value=s placeholder="Search"}} +
+{{/if}} + {{#changeable-set dispatcher=searchable}} + {{#block-slot 'set' as |filtered|}} + {{#tabular-collection + data-test-services + items=filtered as |item index| + }} + {{#block-slot 'header'}} + Service + Node + Address + Node Checks + Service Checks + {{/block-slot}} + {{#block-slot 'row'}} + + + + {{ or item.Service.ID item.Service.Service }} + + + + {{item.Node.Node}} + + + {{item.Service.Address}}:{{item.Service.Port}} + + + 1 + + + 1 + + {{/block-slot}} + {{/tabular-collection}} + {{/block-slot}} + {{#block-slot 'empty'}} +

+ There are no services. +

+ {{/block-slot}} + {{/changeable-set}} diff --git a/ui-v2/app/templates/dc/services/-intentions.hbs b/ui-v2/app/templates/dc/services/-intentions.hbs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ui-v2/app/templates/dc/services/-nodechecks.hbs b/ui-v2/app/templates/dc/services/-nodechecks.hbs new file mode 100644 index 000000000000..487db34fc9e9 --- /dev/null +++ b/ui-v2/app/templates/dc/services/-nodechecks.hbs @@ -0,0 +1,8 @@ +{{#if (gt item.NodeChecks.length 0) }} + {{healthcheck-list items=item.NodeChecks}} +{{else}} +

+ This instance has no node health checks. +

+{{/if}} + diff --git a/ui-v2/app/templates/dc/services/-servicechecks.hbs b/ui-v2/app/templates/dc/services/-servicechecks.hbs new file mode 100644 index 000000000000..424772e70591 --- /dev/null +++ b/ui-v2/app/templates/dc/services/-servicechecks.hbs @@ -0,0 +1,8 @@ +{{#if (gt item.ServiceChecks.length 0) }} + {{healthcheck-list items=item.ServiceChecks}} +{{else}} +

+ This instance has no service health checks. +

+{{/if}} + diff --git a/ui-v2/app/templates/dc/services/-tags.hbs b/ui-v2/app/templates/dc/services/-tags.hbs new file mode 100644 index 000000000000..603c955464d4 --- /dev/null +++ b/ui-v2/app/templates/dc/services/-tags.hbs @@ -0,0 +1,11 @@ +{{#if (gt item.Tags.length 0)}} +
+
Tags
+
+ {{#each item.Tags as |item|}} + {{item}} + {{/each}} +
+
+{{/if}} + diff --git a/ui-v2/app/templates/dc/services/-upstreams.hbs b/ui-v2/app/templates/dc/services/-upstreams.hbs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ui-v2/app/templates/dc/services/instance.hbs b/ui-v2/app/templates/dc/services/instance.hbs new file mode 100644 index 000000000000..b00f145bc5ff --- /dev/null +++ b/ui-v2/app/templates/dc/services/instance.hbs @@ -0,0 +1,65 @@ +{{#app-view class="instance show"}} + {{#block-slot 'breadcrumbs'}} +
    +
  1. All Services
  2. +
  3. Service ({{item.Service}})
  4. +
  5. Instance
  6. +
+ {{/block-slot}} + {{#block-slot 'header'}} +

+ {{ item.ID }} +{{#with (service/external-source item.Service) as |externalSource| }} + {{#with (css-var (concat '--' externalSource '-color-svg') 'none') as |bg| }} + {{#if (not-eq bg 'none') }} + Registered via {{externalSource}} + {{/if}} + {{/with}} +{{/with}} +

+
+
Service Name
+
{{item.Service}}
+
Node Name
+
{{item.Node.Node}}
+{{#if true}} +
Sidecar Proxy
+
+{{/if}} +{{#if (eq item.Kind 'connect-proxy')}} +
Dest. Service Instance
+
+
Local Service Address
+
{{item.Proxy.LocalServiceAddress}}:{{item.Proxy.LocalServicePort}}
+{{/if}} +
+ + {{tab-nav + items=(compact + (array + 'Service Checks' + 'Node Checks' +(if (eq item.Kind 'connect-proxy') 'Upstreams' '') + 'Tags' + ) + ) + selected=selectedTab + }} + {{/block-slot}} + {{#block-slot 'content'}} + {{#each + (compact + (array + (hash id=(slugify 'Service Checks') partial='dc/services/servicechecks') + (hash id=(slugify 'Node Checks') partial='dc/services/nodechecks') +(if (eq item.Kind 'connect-proxy') (hash id=(slugify 'Upstreams') partial='dc/services/upstreams') '') + (hash id=(slugify 'Tags') partial='dc/services/tags') + ) + ) as |panel| + }} + {{#tab-section id=panel.id selected=(eq (if selectedTab selectedTab '') panel.id) onchange=(action "change")}} + {{partial panel.partial}} + {{/tab-section}} + {{/each}} + {{/block-slot}} +{{/app-view}} \ No newline at end of file diff --git a/ui-v2/app/templates/dc/services/show.hbs b/ui-v2/app/templates/dc/services/show.hbs index 5a75f0055f9b..5f649e9ed2bb 100644 --- a/ui-v2/app/templates/dc/services/show.hbs +++ b/ui-v2/app/templates/dc/services/show.hbs @@ -15,76 +15,31 @@ {{/with}} {{/with}} - {{/block-slot}} - {{#block-slot 'toolbar'}} -{{#if (gt items.length 0) }} - {{catalog-filter searchable=(array searchableHealthy searchableUnhealthy) filters=healthFilters search=s status=filters.status onchange=(action 'filter')}} -{{/if}} + + {{tab-nav + items=(compact + (array + 'Instances' + 'Intentions' + 'Tags' + ) + ) + selected=selectedTab + }} {{/block-slot}} {{#block-slot 'content'}} -{{#if (gt item.Tags.length 0)}} -
-
Tags
-
- {{#each item.Tags as |item|}} - {{item}} - {{/each}} -
-
-{{/if}} -{{#if (gt unhealthy.length 0) }} -
-

Unhealthy Nodes

-
-
    - {{#changeable-set dispatcher=searchableUnhealthy}} - {{#block-slot 'set' as |unhealthy|}} - {{#each unhealthy as |item|}} - {{healthchecked-resource - tagName='li' - data-test-node=item.Node.Node - href=(href-to 'dc.nodes.show' item.Node.Node) - name=item.Node.Node - service=item.Service.ID - address=(concat (default item.Service.Address item.Node.Address) ':' item.Service.Port) - checks=item.Checks - }} - {{/each}} - {{/block-slot}} - {{#block-slot 'empty'}} -

    - There are no unhealthy nodes for that search. -

    - {{/block-slot}} - {{/changeable-set}} -
-
-
-{{/if}} -{{#if (gt healthy.length 0) }} -
-

Healthy Nodes

- {{#changeable-set dispatcher=searchableHealthy}} - {{#block-slot 'set' as |healthy|}} - {{#list-collection cellHeight=113 items=healthy as |item index|}} - {{healthchecked-resource - href=(href-to 'dc.nodes.show' item.Node.Node) - data-test-node=item.Node.Node - name=item.Node.Node - service=item.Service.ID - address=(concat (default item.Service.Address item.Node.Address) ':' item.Service.Port) - checks=item.Checks - status=item.Checks.[0].Status - }} - {{/list-collection}} - {{/block-slot}} - {{#block-slot 'empty'}} -

- There are no healthy nodes for that search. -

- {{/block-slot}} - {{/changeable-set}} -
-{{/if}} + {{#each + (compact + (array + (hash id=(slugify 'Instances') partial='dc/services/instances') + (hash id=(slugify 'Intentions') partial='dc/services/intentions') + (hash id=(slugify 'Tags') partial='dc/services/tags') + ) + ) as |panel| + }} + {{#tab-section id=panel.id selected=(eq (if selectedTab selectedTab '') panel.id) onchange=(action "change")}} + {{partial panel.partial}} + {{/tab-section}} + {{/each}} {{/block-slot}} {{/app-view}} diff --git a/ui-v2/tests/integration/components/healthcheck-list-test.js b/ui-v2/tests/integration/components/healthcheck-list-test.js new file mode 100644 index 000000000000..b0ce91215801 --- /dev/null +++ b/ui-v2/tests/integration/components/healthcheck-list-test.js @@ -0,0 +1,34 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('healthcheck-list', 'Integration | Component | healthcheck list', { + integration: true, +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{healthcheck-list}}`); + + assert.equal( + this.$() + .text() + .trim(), + '' + ); + + // Template block usage: + this.render(hbs` + {{#healthcheck-list}} + template block text + {{/healthcheck-list}} + `); + + assert.equal( + this.$() + .text() + .trim(), + 'template block text' + ); +}); diff --git a/ui-v2/tests/unit/controllers/dc/services/instance-test.js b/ui-v2/tests/unit/controllers/dc/services/instance-test.js new file mode 100644 index 000000000000..2b0693934f04 --- /dev/null +++ b/ui-v2/tests/unit/controllers/dc/services/instance-test.js @@ -0,0 +1,12 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:dc/services/instance', 'Unit | Controller | dc/services/instance', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git a/ui-v2/tests/unit/routes/dc/services/instance-test.js b/ui-v2/tests/unit/routes/dc/services/instance-test.js new file mode 100644 index 000000000000..9471a2f508d2 --- /dev/null +++ b/ui-v2/tests/unit/routes/dc/services/instance-test.js @@ -0,0 +1,11 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:dc/services/instance', 'Unit | Route | dc/services/instance', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); From aed28a7cf8b85be5734ab1050513a925dec54aad Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 31 Jan 2019 12:35:02 +0000 Subject: [PATCH 02/17] ui: Pull out the intentions tab for the moment --- ui-v2/app/routes/dc/services/show.js | 2 -- ui-v2/app/services/repository/intention.js | 10 ---------- ui-v2/app/templates/dc/services/-intentions.hbs | 0 ui-v2/app/templates/dc/services/show.hbs | 2 -- 4 files changed, 14 deletions(-) delete mode 100644 ui-v2/app/templates/dc/services/-intentions.hbs diff --git a/ui-v2/app/routes/dc/services/show.js b/ui-v2/app/routes/dc/services/show.js index 1e3be01717d2..bf5fa0d6579a 100644 --- a/ui-v2/app/routes/dc/services/show.js +++ b/ui-v2/app/routes/dc/services/show.js @@ -5,7 +5,6 @@ import { get } from '@ember/object'; export default Route.extend({ repo: service('repository/service'), - intentionRepo: service('repository/intention'), queryParams: { s: { as: 'filter', @@ -16,7 +15,6 @@ export default Route.extend({ const repo = get(this, 'repo'); return hash({ item: repo.findBySlug(params.name, this.modelFor('dc').dc.Name), - // intentions: intentionRepo.findByService(params.name, this.modelFor('dc').dc.Name), }).then(function(model) { return { ...model, diff --git a/ui-v2/app/services/repository/intention.js b/ui-v2/app/services/repository/intention.js index 5ffcf0878f96..7df0cb8a5779 100644 --- a/ui-v2/app/services/repository/intention.js +++ b/ui-v2/app/services/repository/intention.js @@ -8,14 +8,4 @@ export default RepositoryService.extend({ getPrimaryKey: function() { return PRIMARY_KEY; }, - // findByService: function(slug, dc, configuration = {}) { - // const query = { - // dc: dc, - // id: slug, - // }; - // if (typeof configuration.cursor !== 'undefined') { - // query.index = configuration.cursor; - // } - // return get(this, 'store').queryRecord(this.getModelName(), query); - // } }); diff --git a/ui-v2/app/templates/dc/services/-intentions.hbs b/ui-v2/app/templates/dc/services/-intentions.hbs deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui-v2/app/templates/dc/services/show.hbs b/ui-v2/app/templates/dc/services/show.hbs index 5f649e9ed2bb..6929d70d33b1 100644 --- a/ui-v2/app/templates/dc/services/show.hbs +++ b/ui-v2/app/templates/dc/services/show.hbs @@ -20,7 +20,6 @@ items=(compact (array 'Instances' - 'Intentions' 'Tags' ) ) @@ -32,7 +31,6 @@ (compact (array (hash id=(slugify 'Instances') partial='dc/services/instances') - (hash id=(slugify 'Intentions') partial='dc/services/intentions') (hash id=(slugify 'Tags') partial='dc/services/tags') ) ) as |panel| From 9e73e84124972826a1999eacc0fad5f4c35c55ac Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 31 Jan 2019 12:36:14 +0000 Subject: [PATCH 03/17] ui: Start finishing off the details for the service show page 1. Move healthcheck-status component to healthcheck-output 2. Create a new healthcheck-status component for showing the number of checks plus its icon 3. Create a new healthcheck-info component to group multiple statuses plus a diffferent view if there are no checks --- ui-v2/app/components/healthcheck-info.js | 14 ++++++++ ui-v2/app/components/healthcheck-output.js | 5 +++ ui-v2/app/components/healthcheck-status.js | 10 ++++-- ...ck-status.scss => healthcheck-output.scss} | 20 +++++------ .../index.scss | 0 .../layout.scss | 14 ++++---- .../skin.scss | 20 +++++------ ui-v2/app/styles/components/index.scss | 2 +- ui-v2/app/styles/core/typography.scss | 2 +- ui-v2/app/styles/variables/custom-query.scss | 4 +-- .../templates/components/healthcheck-info.hbs | 9 +++++ .../templates/components/healthcheck-list.hbs | 2 +- .../components/healthcheck-output.hbs | 25 ++++++++++++++ .../components/healthcheck-status.hbs | 27 ++------------- .../app/templates/dc/services/-instances.hbs | 12 +++++-- ui-v2/app/templates/dc/services/index.hbs | 16 +++------ ui-v2/app/utils/computed/purify.js | 20 +++++------ .../components/healthcheck-info-test.js | 34 +++++++++++++++++++ .../components/healthcheck-output-test.js | 34 +++++++++++++++++++ .../components/healthcheck-status-test.js | 18 +++++----- 20 files changed, 196 insertions(+), 92 deletions(-) create mode 100644 ui-v2/app/components/healthcheck-info.js create mode 100644 ui-v2/app/components/healthcheck-output.js rename ui-v2/app/styles/components/{healthcheck-status.scss => healthcheck-output.scss} (56%) rename ui-v2/app/styles/components/{healthcheck-status => healthcheck-output}/index.scss (100%) rename ui-v2/app/styles/components/{healthcheck-status => healthcheck-output}/layout.scss (63%) rename ui-v2/app/styles/components/{healthcheck-status => healthcheck-output}/skin.scss (60%) create mode 100644 ui-v2/app/templates/components/healthcheck-info.hbs create mode 100644 ui-v2/app/templates/components/healthcheck-output.hbs create mode 100644 ui-v2/tests/integration/components/healthcheck-info-test.js create mode 100644 ui-v2/tests/integration/components/healthcheck-output-test.js diff --git a/ui-v2/app/components/healthcheck-info.js b/ui-v2/app/components/healthcheck-info.js new file mode 100644 index 000000000000..26b8886aa92c --- /dev/null +++ b/ui-v2/app/components/healthcheck-info.js @@ -0,0 +1,14 @@ +import Component from '@ember/component'; +import { subscribe } from 'consul-ui/utils/computed/purify'; +const count = function(value) { + if (Array.isArray(value)) { + return value.length; + } + return value; +}; +export default Component.extend({ + tagName: '', + passingCount: subscribe('passing', count), + warningCount: subscribe('warning', count), + criticalCount: subscribe('critical', count), +}); diff --git a/ui-v2/app/components/healthcheck-output.js b/ui-v2/app/components/healthcheck-output.js new file mode 100644 index 000000000000..227501fc5c67 --- /dev/null +++ b/ui-v2/app/components/healthcheck-output.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + classNames: ['healthcheck-output'], +}); diff --git a/ui-v2/app/components/healthcheck-status.js b/ui-v2/app/components/healthcheck-status.js index 25a646d758c7..a8d909e48487 100644 --- a/ui-v2/app/components/healthcheck-status.js +++ b/ui-v2/app/components/healthcheck-status.js @@ -1,5 +1,11 @@ import Component from '@ember/component'; - +import { subscribe } from 'consul-ui/utils/computed/purify'; export default Component.extend({ - classNames: ['healthcheck-status'], + tagName: '', + count: subscribe('value', function(value) { + if (Array.isArray(value)) { + return value.length; + } + return value; + }), }); diff --git a/ui-v2/app/styles/components/healthcheck-status.scss b/ui-v2/app/styles/components/healthcheck-output.scss similarity index 56% rename from ui-v2/app/styles/components/healthcheck-status.scss rename to ui-v2/app/styles/components/healthcheck-output.scss index 550b2c992aa7..96216d631597 100644 --- a/ui-v2/app/styles/components/healthcheck-status.scss +++ b/ui-v2/app/styles/components/healthcheck-output.scss @@ -1,32 +1,32 @@ -@import './healthcheck-status/index'; +@import './healthcheck-output/index'; @import './icons/index'; -.healthcheck-status { - @extend %healthcheck-status; +.healthcheck-output { + @extend %healthcheck-output; } -%healthcheck-status.passing { +%healthcheck-output.passing { @extend %with-passing; } -%healthcheck-status.warning { +%healthcheck-output.warning { @extend %with-warning; } -%healthcheck-status.critical { +%healthcheck-output.critical { @extend %with-critical; } -@media #{$--lt-spacious-healthcheck-status} { - .healthcheck-status button.copy-btn { +@media #{$--lt-spacious-healthcheck-output} { + .healthcheck-output button.copy-btn { margin-top: -11px; margin-right: -18px; padding: 0; width: 20px; visibility: hidden; } - %healthcheck-status { + %healthcheck-output { padding-left: 30px; padding-top: 10px; padding-bottom: 15px; padding-right: 13px; } - %healthcheck-status::before { + %healthcheck-output::before { width: 15px !important; height: 15px !important; left: 9px; diff --git a/ui-v2/app/styles/components/healthcheck-status/index.scss b/ui-v2/app/styles/components/healthcheck-output/index.scss similarity index 100% rename from ui-v2/app/styles/components/healthcheck-status/index.scss rename to ui-v2/app/styles/components/healthcheck-output/index.scss diff --git a/ui-v2/app/styles/components/healthcheck-status/layout.scss b/ui-v2/app/styles/components/healthcheck-output/layout.scss similarity index 63% rename from ui-v2/app/styles/components/healthcheck-status/layout.scss rename to ui-v2/app/styles/components/healthcheck-output/layout.scss index ef40daf3757f..5f1a9403debb 100644 --- a/ui-v2/app/styles/components/healthcheck-status/layout.scss +++ b/ui-v2/app/styles/components/healthcheck-output/layout.scss @@ -1,4 +1,4 @@ -%healthcheck-status::before { +%healthcheck-output::before { background-size: 55%; width: 25px !important; height: 25px !important; @@ -6,25 +6,25 @@ top: 20px !important; margin-top: 0 !important; } -%healthcheck-status.warning::before { +%healthcheck-output.warning::before { background-size: 100%; } -%healthcheck-status { +%healthcheck-output { padding: 20px 24px; padding-bottom: 26px; padding-left: 57px; margin-bottom: 24px; position: relative; } -%healthcheck-status pre { +%healthcheck-output pre { padding: 12px; } -%healthcheck-status .with-feedback { +%healthcheck-output .with-feedback { float: right; } -%healthcheck-status dt { +%healthcheck-output dt { margin-bottom: 0.2em; } -%healthcheck-status dd:first-of-type { +%healthcheck-output dd:first-of-type { margin-bottom: 0.6em; } diff --git a/ui-v2/app/styles/components/healthcheck-status/skin.scss b/ui-v2/app/styles/components/healthcheck-output/skin.scss similarity index 60% rename from ui-v2/app/styles/components/healthcheck-status/skin.scss rename to ui-v2/app/styles/components/healthcheck-output/skin.scss index d0fd2cec13d4..9d26d4d66317 100644 --- a/ui-v2/app/styles/components/healthcheck-status/skin.scss +++ b/ui-v2/app/styles/components/healthcheck-output/skin.scss @@ -1,35 +1,35 @@ -%healthcheck-status { +%healthcheck-output { border-width: 1px; } -%healthcheck-status, -%healthcheck-status pre { +%healthcheck-output, +%healthcheck-output pre { border-radius: $decor-radius-100; } -%healthcheck-status dd:first-of-type { +%healthcheck-output dd:first-of-type { color: $gray-400; } -%healthcheck-status pre { +%healthcheck-output pre { background-color: $black; color: $white; } -%healthcheck-status.passing { +%healthcheck-output.passing { /* TODO: this should be a frame-gray */ // @extend %frame-green-500; color: $gray-900; border-color: $gray-200; border-style: solid; } -%healthcheck-status.warning { +%healthcheck-output.warning { @extend %frame-yellow-500; color: $gray-900; } -%healthcheck-status.critical { +%healthcheck-output.critical { @extend %frame-red-500; color: $gray-900; } -%healthcheck-status.passing::before { +%healthcheck-output.passing::before { background-color: $color-success !important; } -%healthcheck-status.critical::before { +%healthcheck-output.critical::before { background-color: $color-danger !important; } diff --git a/ui-v2/app/styles/components/index.scss b/ui-v2/app/styles/components/index.scss index f461f7bea1c8..db6110c80afa 100644 --- a/ui-v2/app/styles/components/index.scss +++ b/ui-v2/app/styles/components/index.scss @@ -16,7 +16,7 @@ @import './app-view'; @import './product'; -@import './healthcheck-status'; +@import './healthcheck-output'; @import './healthchecked-resource'; @import './freetext-filter'; @import './filter-bar'; diff --git a/ui-v2/app/styles/core/typography.scss b/ui-v2/app/styles/core/typography.scss index 2331c49c901c..c69f9bbba682 100644 --- a/ui-v2/app/styles/core/typography.scss +++ b/ui-v2/app/styles/core/typography.scss @@ -36,7 +36,7 @@ h1, h2, %header-nav, %healthchecked-resource header span, -%healthcheck-status dt, +%healthcheck-output dt, %copy-button, %app-content div > dl > dt, td a { diff --git a/ui-v2/app/styles/variables/custom-query.scss b/ui-v2/app/styles/variables/custom-query.scss index 56895ef26631..8e7160e678c3 100644 --- a/ui-v2/app/styles/variables/custom-query.scss +++ b/ui-v2/app/styles/variables/custom-query.scss @@ -26,8 +26,8 @@ $--lt-wide-footer: '(max-width: 420px)'; $--spacious-page-header: '(min-width: 850px)'; $--lt-spacious-page-header: '(max-width: 849px)'; -$--spacious-healthcheck-status: '(min-width: 421px)'; -$--lt-spacious-healthcheck-status: '(max-width: 420px)'; +$--spacious-healthcheck-output: '(min-width: 421px)'; +$--lt-spacious-healthcheck-output: '(max-width: 420px)'; $--wide-form: '(min-width: 421px)'; $--lt-wide-form: '(max-width: 420px)'; diff --git a/ui-v2/app/templates/components/healthcheck-info.hbs b/ui-v2/app/templates/components/healthcheck-info.hbs new file mode 100644 index 000000000000..594bd7a02b29 --- /dev/null +++ b/ui-v2/app/templates/components/healthcheck-info.hbs @@ -0,0 +1,9 @@ +{{#if (and (lt passingCount 1) (lt warningCount 1) (lt criticalCount 1) )}} + 0 +{{else}} +
+ {{healthcheck-status width=passingWidth name='passing' value=passingCount}} + {{healthcheck-status width=warningWidth name='warning' value=warningCount}} + {{healthcheck-status width=criticalWidth name='critical' value=criticalCount}} +
+{{/if}} diff --git a/ui-v2/app/templates/components/healthcheck-list.hbs b/ui-v2/app/templates/components/healthcheck-list.hbs index 75cdb60ce3e0..4b5774588e07 100644 --- a/ui-v2/app/templates/components/healthcheck-list.hbs +++ b/ui-v2/app/templates/components/healthcheck-list.hbs @@ -1,5 +1,5 @@
    {{#each (sort-by (action 'sortChecksByImportance') items) as |check| }} - {{healthcheck-status data-test-node-healthcheck=check.Name tagName='li' name=check.Name class=check.Status status=check.Status notes=check.Notes output=check.Output}} + {{healthcheck-output data-test-node-healthcheck=check.Name tagName='li' name=check.Name class=check.Status status=check.Status notes=check.Notes output=check.Output}} {{/each}}
diff --git a/ui-v2/app/templates/components/healthcheck-output.hbs b/ui-v2/app/templates/components/healthcheck-output.hbs new file mode 100644 index 000000000000..05a75e40a249 --- /dev/null +++ b/ui-v2/app/templates/components/healthcheck-output.hbs @@ -0,0 +1,25 @@ +{{#feedback-dialog type='inline'}} + {{#block-slot 'action' as |success error|}} + {{#copy-button success=(action success) error=(action error) clipboardText=output title='copy output to clipboard'}} + Copy Output + {{/copy-button}} + {{/block-slot}} + {{#block-slot 'success' as |transition|}} +

+ Copied IP Address! +

+ {{/block-slot}} + {{#block-slot 'error' as |transition|}} +

+ Sorry, something went wrong! +

+ {{/block-slot}} +{{/feedback-dialog}} +
+
{{name}}
+
{{notes}}
+
Output
+
+
{{output}}
+
+
\ No newline at end of file diff --git a/ui-v2/app/templates/components/healthcheck-status.hbs b/ui-v2/app/templates/components/healthcheck-status.hbs index 05a75e40a249..004f03772191 100644 --- a/ui-v2/app/templates/components/healthcheck-status.hbs +++ b/ui-v2/app/templates/components/healthcheck-status.hbs @@ -1,25 +1,2 @@ -{{#feedback-dialog type='inline'}} - {{#block-slot 'action' as |success error|}} - {{#copy-button success=(action success) error=(action error) clipboardText=output title='copy output to clipboard'}} - Copy Output - {{/copy-button}} - {{/block-slot}} - {{#block-slot 'success' as |transition|}} -

- Copied IP Address! -

- {{/block-slot}} - {{#block-slot 'error' as |transition|}} -

- Sorry, something went wrong! -

- {{/block-slot}} -{{/feedback-dialog}} -
-
{{name}}
-
{{notes}}
-
Output
-
-
{{output}}
-
-
\ No newline at end of file +
Healthchecks {{capitalize name}}
+
{{format-number count}}
\ No newline at end of file diff --git a/ui-v2/app/templates/dc/services/-instances.hbs b/ui-v2/app/templates/dc/services/-instances.hbs index 32bbc99aec3b..709b7d83ffd6 100644 --- a/ui-v2/app/templates/dc/services/-instances.hbs +++ b/ui-v2/app/templates/dc/services/-instances.hbs @@ -31,10 +31,18 @@ {{item.Service.Address}}:{{item.Service.Port}} - 1 + {{#with (reject-by 'ServiceID' '' item.Checks) as |checks|}} + {{healthcheck-info + passing=(filter-by 'Status' 'passing' checks) warning=(filter-by 'Status' 'warning' checks) critical=(filter-by 'Status' 'critical' checks) + }} + {{/with}} - 1 + {{#with (filter-by 'ServiceID' '' item.Checks) as |checks|}} + {{healthcheck-info + passing=(filter-by 'Status' 'passing' checks) warning=(filter-by 'Status' 'warning' checks) critical=(filter-by 'Status' 'critical' checks) + }} + {{/with}} {{/block-slot}} {{/tabular-collection}} diff --git a/ui-v2/app/templates/dc/services/index.hbs b/ui-v2/app/templates/dc/services/index.hbs index aee20a971833..7306ea10f314 100644 --- a/ui-v2/app/templates/dc/services/index.hbs +++ b/ui-v2/app/templates/dc/services/index.hbs @@ -35,18 +35,10 @@ - {{#if (and (lt item.ChecksPassing 1) (lt item.ChecksWarning 1) (lt item.ChecksCritical 1) )}} - 0 - {{else}} -
-
Healthchecks Passing
-
{{format-number item.ChecksPassing}}
-
Healthchecks Warning
-
{{format-number item.ChecksWarning}}
-
Healthchecks Critical
-
{{format-number item.ChecksCritical}}
-
- {{/if}} + {{healthcheck-info + passing=item.ChecksPassing warning=item.ChecksWarning critical=item.ChecksCritical + passingWidth=passingWidth warningWidth=warningWidth criticalWidth=criticalWidth + }} {{#if (gt item.Tags.length 0)}} diff --git a/ui-v2/app/utils/computed/purify.js b/ui-v2/app/utils/computed/purify.js index 3c9eba3410a5..1008ed8c4766 100644 --- a/ui-v2/app/utils/computed/purify.js +++ b/ui-v2/app/utils/computed/purify.js @@ -1,4 +1,4 @@ -import { get } from '@ember/object'; +import { get, computed } from '@ember/object'; /** * Converts a conventional non-pure Ember `computed` function into a pure one @@ -8,20 +8,18 @@ import { get } from '@ember/object'; * @param {function} filter - Optional string filter function to pre-process the names of computed properties * @returns {function} - A pure `computed` function */ - -export default function(computed, filter) { +const _success = function(value) { + return value; +}; +const purify = function(computed, filter = args => args) { return function() { let args = [...arguments]; - let success = function(value) { - return value; - }; + let success = _success; // pop the user function off the end if (typeof args[args.length - 1] === 'function') { success = args.pop(); } - if (typeof filter === 'function') { - args = filter(args); - } + args = filter(args); // this is the 'conventional' `computed` const cb = function(name) { return success.apply( @@ -39,4 +37,6 @@ export default function(computed, filter) { // concat/push the user function back on return computed(...args.concat([cb])); }; -} +}; +export const subscribe = purify(computed); +export default purify; diff --git a/ui-v2/tests/integration/components/healthcheck-info-test.js b/ui-v2/tests/integration/components/healthcheck-info-test.js new file mode 100644 index 000000000000..6267b605d056 --- /dev/null +++ b/ui-v2/tests/integration/components/healthcheck-info-test.js @@ -0,0 +1,34 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('healthcheck-info', 'Integration | Component | healthcheck info', { + integration: true, +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{healthcheck-info}}`); + + assert.equal( + this.$() + .text() + .trim(), + '' + ); + + // Template block usage: + this.render(hbs` + {{#healthcheck-info}} + template block text + {{/healthcheck-info}} + `); + + assert.equal( + this.$() + .text() + .trim(), + 'template block text' + ); +}); diff --git a/ui-v2/tests/integration/components/healthcheck-output-test.js b/ui-v2/tests/integration/components/healthcheck-output-test.js new file mode 100644 index 000000000000..b72e7412f9be --- /dev/null +++ b/ui-v2/tests/integration/components/healthcheck-output-test.js @@ -0,0 +1,34 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('healthcheck-output', 'Integration | Component | healthcheck output', { + integration: true, +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{healthcheck-output}}`); + + assert.notEqual( + this.$() + .text() + .trim() + .indexOf('Output'), + -1 + ); + + // Template block usage: + this.render(hbs` + {{#healthcheck-output}}{{/healthcheck-output}} + `); + + assert.notEqual( + this.$() + .text() + .trim() + .indexOf('Output'), + -1 + ); +}); diff --git a/ui-v2/tests/integration/components/healthcheck-status-test.js b/ui-v2/tests/integration/components/healthcheck-status-test.js index b19207e5a4cf..67cb8de5e199 100644 --- a/ui-v2/tests/integration/components/healthcheck-status-test.js +++ b/ui-v2/tests/integration/components/healthcheck-status-test.js @@ -11,24 +11,24 @@ test('it renders', function(assert) { this.render(hbs`{{healthcheck-status}}`); - assert.notEqual( + assert.equal( this.$() .text() - .trim() - .indexOf('Output'), - -1 + .trim(), + '' ); // Template block usage: this.render(hbs` - {{#healthcheck-status}}{{/healthcheck-status}} + {{#healthcheck-status}} + template block text + {{/healthcheck-status}} `); - assert.notEqual( + assert.equal( this.$() .text() - .trim() - .indexOf('Output'), - -1 + .trim(), + 'template block text' ); }); From 1e7cab031de8cf08a6d23629709998332d2cd2a2 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 31 Jan 2019 13:20:53 +0000 Subject: [PATCH 04/17] ui: Begin splitting out the CSS for healthcheck-status The used to be munged in amongst the table css file, but now we have a component just for these it makes sense that they should have a CSS 'module' also --- .../styles/components/healthcheck-status.scss | 5 +++ .../components/healthcheck-status/index.scss | 2 + .../components/healthcheck-status/layout.scss | 40 +++++++++++++++++++ .../components/healthcheck-status/skin.scss | 28 +++++++++++++ ui-v2/app/styles/components/index.scss | 1 + ui-v2/app/styles/components/table.scss | 27 ------------- ui-v2/app/styles/components/table/layout.scss | 38 ------------------ ui-v2/app/styles/routes/dc/service/index.scss | 14 +++---- 8 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 ui-v2/app/styles/components/healthcheck-status.scss create mode 100644 ui-v2/app/styles/components/healthcheck-status/index.scss create mode 100644 ui-v2/app/styles/components/healthcheck-status/layout.scss create mode 100644 ui-v2/app/styles/components/healthcheck-status/skin.scss diff --git a/ui-v2/app/styles/components/healthcheck-status.scss b/ui-v2/app/styles/components/healthcheck-status.scss new file mode 100644 index 000000000000..13edc8313e1f --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-status.scss @@ -0,0 +1,5 @@ +@import './healthcheck-status/index'; +@import './icons/index'; +.healthcheck-status { + @extend %healthcheck-status; +} diff --git a/ui-v2/app/styles/components/healthcheck-status/index.scss b/ui-v2/app/styles/components/healthcheck-status/index.scss new file mode 100644 index 000000000000..bc182521964a --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-status/index.scss @@ -0,0 +1,2 @@ +@import './skin'; +@import './layout'; diff --git a/ui-v2/app/styles/components/healthcheck-status/layout.scss b/ui-v2/app/styles/components/healthcheck-status/layout.scss new file mode 100644 index 000000000000..5244511d0f20 --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-status/layout.scss @@ -0,0 +1,40 @@ +// TODO: Why do I need to cover th and td here? +tr > * dl { + float: left; +} +%healthcheck-status { + height: 100%; +} +%healthcheck-status { + display: flex; +} +%healthcheck-status > * { + display: block; +} +%healthcheck-status dt.zero { + display: none; +} +%healthcheck-status dd.zero { + visibility: hidden; +} +%healthcheck-status dt { + text-indent: -9000px; +} +%healthcheck-status dt.warning { + overflow: visible; +} +%healthcheck-status dt.warning::before { + top: 7px; +} +%healthcheck-status dt.warning::after { + left: -2px; + top: -1px; +} +%healthcheck-status dd { + box-sizing: content-box; + margin-left: 22px; + padding-right: 10px; +} +tr dl { + @extend %healthcheck-status; +} diff --git a/ui-v2/app/styles/components/healthcheck-status/skin.scss b/ui-v2/app/styles/components/healthcheck-status/skin.scss new file mode 100644 index 000000000000..7ff5d0993187 --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-status/skin.scss @@ -0,0 +1,28 @@ +%healthcheck-status dt.passing { + @extend %with-passing; +} +%healthcheck-status dt.warning { + @extend %with-warning; +} +%healthcheck-status dt.critical { + @extend %with-critical; +} +%healthcheck-status span.zero { + @extend %with-no-healthchecks; + // TODO: Why isn't this is layout? + display: block; + text-indent: 20px; + color: $gray-400; +} +%healthcheck-status dt.passing, +%healthcheck-status dt.passing + dd { + color: $color-success; +} +%healthcheck-status dt.warning, +%healthcheck-status dt.warning + dd { + color: $color-alert; +} +%healthcheck-status dt.critical, +%healthcheck-status dt.critical + dd { + color: $color-failure; +} diff --git a/ui-v2/app/styles/components/index.scss b/ui-v2/app/styles/components/index.scss index db6110c80afa..b1f295f00dbd 100644 --- a/ui-v2/app/styles/components/index.scss +++ b/ui-v2/app/styles/components/index.scss @@ -17,6 +17,7 @@ @import './product'; @import './healthcheck-output'; +@import './healthcheck-status'; @import './healthchecked-resource'; @import './freetext-filter'; @import './filter-bar'; diff --git a/ui-v2/app/styles/components/table.scss b/ui-v2/app/styles/components/table.scss index 364c214b6532..9890f600ca48 100644 --- a/ui-v2/app/styles/components/table.scss +++ b/ui-v2/app/styles/components/table.scss @@ -3,39 +3,12 @@ td.folder { @extend %with-folder; } -td dt.passing { - @extend %with-passing; -} -td dt.warning { - @extend %with-warning; -} -td dt.critical { - @extend %with-critical; -} -td span.zero { - @extend %with-no-healthchecks; - display: block; - text-indent: 20px; - color: $gray-400; -} table:not(.sessions) tr { cursor: pointer; } table:not(.sessions) td:first-child { padding: 0; } -td dt.passing, -td dt.passing + dd { - color: $color-success; -} -td dt.warning, -td dt.warning + dd { - color: $color-alert; -} -td dt.critical, -td dt.critical + dd { - color: $color-failure; -} /* Header Tooltips/Icon*/ th { overflow: visible; diff --git a/ui-v2/app/styles/components/table/layout.scss b/ui-v2/app/styles/components/table/layout.scss index 23301b423eac..c574d10d51fc 100644 --- a/ui-v2/app/styles/components/table/layout.scss +++ b/ui-v2/app/styles/components/table/layout.scss @@ -50,44 +50,6 @@ td:not(.actions) a { overflow: hidden; } -// TODO: this isn't specific to table -// these are the node health 3 column display -tr > * dl { - float: left; -} -td dl { - height: 100%; -} -td dl { - display: flex; -} -td dl > * { - display: block; -} -td dt.zero { - display: none; -} -td dd.zero { - visibility: hidden; -} -td dt { - text-indent: -9000px; -} -td dt.warning { - overflow: visible; -} -td dt.warning::before { - top: 7px; -} -td dt.warning::after { - left: -2px; - top: -1px; -} -td dd { - box-sizing: content-box; - margin-left: 22px; - padding-right: 10px; -} /* hide actions on narrow screens, you can always click in do everything from there */ @media #{$--lt-wide-table} { tr > .actions { diff --git a/ui-v2/app/styles/routes/dc/service/index.scss b/ui-v2/app/styles/routes/dc/service/index.scss index c38a957a9ddf..ebd79757695e 100644 --- a/ui-v2/app/styles/routes/dc/service/index.scss +++ b/ui-v2/app/styles/routes/dc/service/index.scss @@ -1,11 +1,11 @@ @import '../../../components/pill/index'; -html.template-service.template-show main dl { - display: flex; - margin-bottom: 1.4em; -} -html.template-service.template-show main dt { - display: none; -} +// html.template-service.template-show main dl { +// display: flex; +// margin-bottom: 1.4em; +// } +// html.template-service.template-show main dt { +// display: none; +// } // TODO: Generalize this, also see nodes/index html.template-service.template-list td.tags span, html.template-service.template-show main dd span { From bc649a524932db21c004036d7c580b1cca63f66a Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:24:28 +0000 Subject: [PATCH 05/17] ui: Componentize tag-list --- ui-v2/app/components/tag-list.js | 6 ++++ ui-v2/app/styles/components/index.scss | 1 + ui-v2/app/styles/components/pill.scss | 3 +- ui-v2/app/styles/components/tag-list.scss | 5 +++ .../app/styles/components/tag-list/index.scss | 2 ++ .../styles/components/tag-list/layout.scss | 10 ++++++ .../app/styles/components/tag-list/skin.scss | 0 ui-v2/app/styles/routes/dc/service/index.scss | 13 ------- ui-v2/app/templates/components/tag-list.hbs | 8 +++++ ui-v2/app/templates/dc/services/-tags.hbs | 12 +------ .../integration/components/tag-list-test.js | 34 +++++++++++++++++++ 11 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 ui-v2/app/components/tag-list.js create mode 100644 ui-v2/app/styles/components/tag-list.scss create mode 100644 ui-v2/app/styles/components/tag-list/index.scss create mode 100644 ui-v2/app/styles/components/tag-list/layout.scss create mode 100644 ui-v2/app/styles/components/tag-list/skin.scss create mode 100644 ui-v2/app/templates/components/tag-list.hbs create mode 100644 ui-v2/tests/integration/components/tag-list-test.js diff --git a/ui-v2/app/components/tag-list.js b/ui-v2/app/components/tag-list.js new file mode 100644 index 000000000000..1656e4a23c18 --- /dev/null +++ b/ui-v2/app/components/tag-list.js @@ -0,0 +1,6 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: 'dl', + classNames: ['tag-list'], +}); diff --git a/ui-v2/app/styles/components/index.scss b/ui-v2/app/styles/components/index.scss index b1f295f00dbd..0012ad001042 100644 --- a/ui-v2/app/styles/components/index.scss +++ b/ui-v2/app/styles/components/index.scss @@ -16,6 +16,7 @@ @import './app-view'; @import './product'; +@import './tag-list'; @import './healthcheck-output'; @import './healthcheck-status'; @import './healthchecked-resource'; diff --git a/ui-v2/app/styles/components/pill.scss b/ui-v2/app/styles/components/pill.scss index 4d8f0673a1e2..af1809c33957 100644 --- a/ui-v2/app/styles/components/pill.scss +++ b/ui-v2/app/styles/components/pill.scss @@ -1,4 +1,5 @@ @import './pill/index'; -td strong { +td strong, +%tag-list span { @extend %pill; } diff --git a/ui-v2/app/styles/components/tag-list.scss b/ui-v2/app/styles/components/tag-list.scss new file mode 100644 index 000000000000..6bc2ea8e709d --- /dev/null +++ b/ui-v2/app/styles/components/tag-list.scss @@ -0,0 +1,5 @@ +@import './tag-list/index'; +.tag-list, +td.tags { + @extend %tag-list; +} diff --git a/ui-v2/app/styles/components/tag-list/index.scss b/ui-v2/app/styles/components/tag-list/index.scss new file mode 100644 index 000000000000..bc182521964a --- /dev/null +++ b/ui-v2/app/styles/components/tag-list/index.scss @@ -0,0 +1,2 @@ +@import './skin'; +@import './layout'; diff --git a/ui-v2/app/styles/components/tag-list/layout.scss b/ui-v2/app/styles/components/tag-list/layout.scss new file mode 100644 index 000000000000..2590f8b4c144 --- /dev/null +++ b/ui-v2/app/styles/components/tag-list/layout.scss @@ -0,0 +1,10 @@ +%tag-list dt { + display: none; +} +// TODO: Currently this is here to overwrite +// the default definition list layout used in edit pages +// ideally we'd be more specific with those to say +// only add padding to dl's in edit pages +%tag-list dd { + padding-left: 0; +} diff --git a/ui-v2/app/styles/components/tag-list/skin.scss b/ui-v2/app/styles/components/tag-list/skin.scss new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ui-v2/app/styles/routes/dc/service/index.scss b/ui-v2/app/styles/routes/dc/service/index.scss index ebd79757695e..e29aa9f66431 100644 --- a/ui-v2/app/styles/routes/dc/service/index.scss +++ b/ui-v2/app/styles/routes/dc/service/index.scss @@ -1,16 +1,3 @@ -@import '../../../components/pill/index'; -// html.template-service.template-show main dl { -// display: flex; -// margin-bottom: 1.4em; -// } -// html.template-service.template-show main dt { -// display: none; -// } -// TODO: Generalize this, also see nodes/index -html.template-service.template-list td.tags span, -html.template-service.template-show main dd span { - @extend %pill; -} html.template-node.template-show #services th:first-child, html.template-service.template-list main th:first-child { text-indent: 28px; diff --git a/ui-v2/app/templates/components/tag-list.hbs b/ui-v2/app/templates/components/tag-list.hbs new file mode 100644 index 000000000000..c51ea2a41883 --- /dev/null +++ b/ui-v2/app/templates/components/tag-list.hbs @@ -0,0 +1,8 @@ +{{#if (gt items.length 0)}} +
Tags
+
+ {{#each items as |item|}} + {{item}} + {{/each}} +
+{{/if}} diff --git a/ui-v2/app/templates/dc/services/-tags.hbs b/ui-v2/app/templates/dc/services/-tags.hbs index 603c955464d4..1c8d19065f29 100644 --- a/ui-v2/app/templates/dc/services/-tags.hbs +++ b/ui-v2/app/templates/dc/services/-tags.hbs @@ -1,11 +1 @@ -{{#if (gt item.Tags.length 0)}} -
-
Tags
-
- {{#each item.Tags as |item|}} - {{item}} - {{/each}} -
-
-{{/if}} - +{{tag-list items=item.Tags}} diff --git a/ui-v2/tests/integration/components/tag-list-test.js b/ui-v2/tests/integration/components/tag-list-test.js new file mode 100644 index 000000000000..666846367466 --- /dev/null +++ b/ui-v2/tests/integration/components/tag-list-test.js @@ -0,0 +1,34 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('tag-list', 'Integration | Component | tag list', { + integration: true, +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{tag-list}}`); + + assert.equal( + this.$() + .text() + .trim(), + '' + ); + + // Template block usage: + this.render(hbs` + {{#tag-list}} + template block text + {{/tag-list}} + `); + + assert.equal( + this.$() + .text() + .trim(), + 'template block text' + ); +}); From 60f8b14a9da605fb66c4fef5225dba02ddadc6f9 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:25:20 +0000 Subject: [PATCH 06/17] ui: Tweak tab-nav --- ui-v2/app/components/tab-nav.js | 1 + ui-v2/app/styles/components/tabs.scss | 2 +- ui-v2/app/styles/components/tabs/layout.scss | 3 +++ ui-v2/app/styles/components/tabs/skin.scss | 9 +++++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ui-v2/app/components/tab-nav.js b/ui-v2/app/components/tab-nav.js index 142b50bf4d20..db166df6415e 100644 --- a/ui-v2/app/components/tab-nav.js +++ b/ui-v2/app/components/tab-nav.js @@ -3,4 +3,5 @@ import Component from '@ember/component'; export default Component.extend({ name: 'tab', tagName: 'nav', + classNames: ['tab-nav'], }); diff --git a/ui-v2/app/styles/components/tabs.scss b/ui-v2/app/styles/components/tabs.scss index b0c08a7f8c5a..64a1b9138ef0 100644 --- a/ui-v2/app/styles/components/tabs.scss +++ b/ui-v2/app/styles/components/tabs.scss @@ -1,5 +1,5 @@ @import './tabs/index'; -main header nav:last-of-type:not(:first-of-type) { +.tab-nav { @extend %tab-nav; } .tab-section { diff --git a/ui-v2/app/styles/components/tabs/layout.scss b/ui-v2/app/styles/components/tabs/layout.scss index 9588b870ebf5..7b20b1aa1f7d 100644 --- a/ui-v2/app/styles/components/tabs/layout.scss +++ b/ui-v2/app/styles/components/tabs/layout.scss @@ -2,6 +2,9 @@ /* this keeps in-tab-section toolbars flush to the top, see Node Detail > Services */ margin-top: 0 !important; } +%tab-nav { + clear: both; +} @media #{$--horizontal-tabs} { %tab-nav ul { display: flex; diff --git a/ui-v2/app/styles/components/tabs/skin.scss b/ui-v2/app/styles/components/tabs/skin.scss index 81faad36953b..1538bcf0d853 100644 --- a/ui-v2/app/styles/components/tabs/skin.scss +++ b/ui-v2/app/styles/components/tabs/skin.scss @@ -1,3 +1,12 @@ +%tab-nav { + /* %frame-gray-something */ + border-bottom: $decor-border-100; + border-top: $decor-border-200; +} +%tab-nav { + /* %frame-gray-something */ + border-color: $gray-200; +} %tab-nav label { cursor: pointer; } From c65ec2d5886da6fe648091192353adb8887ba2bf Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:26:28 +0000 Subject: [PATCH 07/17] ui: Add upstreams listing --- .../styles/components/tabular-collection.scss | 8 ++++++- .../app/templates/dc/services/-upstreams.hbs | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ui-v2/app/styles/components/tabular-collection.scss b/ui-v2/app/styles/components/tabular-collection.scss index c9745e787f3f..9fb9bb0643f5 100644 --- a/ui-v2/app/styles/components/tabular-collection.scss +++ b/ui-v2/app/styles/components/tabular-collection.scss @@ -46,6 +46,9 @@ html.template-node.template-show #services td:first-child a span { html.template-service.template-list main table tr { @extend %services-row; } +html.template-instance.template-show #upstreams table tr { + @extend %upstreams-row; +} html.template-intention.template-list main table tr { @extend %intentions-row; } @@ -155,7 +158,7 @@ html.template-node.template-show main table.sessions tr { @extend %table-actions; } %node-services-row > * { - width: 33%; + width: calc(100% / 3); } %policies-row > * { width: calc(33% - 20px); @@ -172,3 +175,6 @@ html.template-node.template-show main table.sessions tr { %services-row > * { width: auto; } +%upstreams-row > * { + width: calc(100% / 3); +} diff --git a/ui-v2/app/templates/dc/services/-upstreams.hbs b/ui-v2/app/templates/dc/services/-upstreams.hbs index e69de29bb2d1..baee4e2f4f92 100644 --- a/ui-v2/app/templates/dc/services/-upstreams.hbs +++ b/ui-v2/app/templates/dc/services/-upstreams.hbs @@ -0,0 +1,21 @@ +{{#tabular-collection + data-test-upstreams + items=item.Proxy.Upstreams as |item index| +}} + {{#block-slot 'header'}} + Destination Name + Destination Type + Local Bind Port + {{/block-slot}} + {{#block-slot 'row'}} + + {{item.DestinationName}} + + + {{item.DestinationType}} + + + {{item.LocalBindPort}} + + {{/block-slot}} +{{/tabular-collection}} From 2959141dd9d7dd31b96c5a29c6ca3d3e145e8272 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:27:14 +0000 Subject: [PATCH 08/17] ui: Style up service instance top details --- .../styles/components/app-view/layout.scss | 9 +++++++ .../app/styles/components/app-view/skin.scss | 14 +++++++---- ui-v2/app/templates/dc/services/instance.hbs | 24 ++++++++++++------- ui-v2/app/templates/dc/services/show.hbs | 18 +++++++------- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/ui-v2/app/styles/components/app-view/layout.scss b/ui-v2/app/styles/components/app-view/layout.scss index 34827cc5bf55..f518b5d38d34 100644 --- a/ui-v2/app/styles/components/app-view/layout.scss +++ b/ui-v2/app/styles/components/app-view/layout.scss @@ -10,6 +10,15 @@ display: flex; align-items: flex-start; } +%app-view header dl { + float: left; + margin-top: 25px; + margin-right: 50px; + margin-bottom: 20px; +} +%app-view header dt { + font-weight: bold; +} /* units */ %app-view { margin-top: 50px; diff --git a/ui-v2/app/styles/components/app-view/skin.scss b/ui-v2/app/styles/components/app-view/skin.scss index e0269410ff2d..7fbf8771edde 100644 --- a/ui-v2/app/styles/components/app-view/skin.scss +++ b/ui-v2/app/styles/components/app-view/skin.scss @@ -1,10 +1,16 @@ %app-view h2, -%app-view header > div:last-of-type { - border-bottom: $decor-border-100; +%app-view header h1 { + border-bottom: $decor-border-200; } -%app-view header > div:last-of-type, +%app-view header h1, %app-view h2 { - border-color: $keyline-light; + border-color: $gray-200; +} +// We know that any sibling navs might have a top border +// by default. As its squashed up to a h1, in this +// case hide its border to avoid double border +%app-view header h1 ~ nav { + border-top: 0 !important; } %app-content div > dl > dd { color: $gray-400; diff --git a/ui-v2/app/templates/dc/services/instance.hbs b/ui-v2/app/templates/dc/services/instance.hbs index b00f145bc5ff..00385898f1a5 100644 --- a/ui-v2/app/templates/dc/services/instance.hbs +++ b/ui-v2/app/templates/dc/services/instance.hbs @@ -3,7 +3,7 @@
  1. All Services
  2. Service ({{item.Service}})
  3. -
  4. Instance
  5. +
  6. Instance
{{/block-slot}} {{#block-slot 'header'}} @@ -19,20 +19,30 @@
Service Name
-
{{item.Service}}
+
{{item.Service}}
+
+
Node Name
-
{{item.Node.Node}}
-{{#if true}} +
{{item.Node.Node}}
+
+{{#if false}} +
Sidecar Proxy
+
{{/if}} {{#if (eq item.Kind 'connect-proxy')}} +
Dest. Service Instance
-
+
{{item.Proxy.DestinationServiceID}}
+
+
Local Service Address
{{item.Proxy.LocalServiceAddress}}:{{item.Proxy.LocalServicePort}}
-{{/if}}
+{{/if}} + {{/block-slot}} + {{#block-slot 'content'}} {{tab-nav items=(compact @@ -45,8 +55,6 @@ ) selected=selectedTab }} - {{/block-slot}} - {{#block-slot 'content'}} {{#each (compact (array diff --git a/ui-v2/app/templates/dc/services/show.hbs b/ui-v2/app/templates/dc/services/show.hbs index 6929d70d33b1..bd693d9b854b 100644 --- a/ui-v2/app/templates/dc/services/show.hbs +++ b/ui-v2/app/templates/dc/services/show.hbs @@ -15,16 +15,16 @@ {{/with}} {{/with}} - - {{tab-nav - items=(compact - (array - 'Instances' - 'Tags' - ) + + {{tab-nav + items=(compact + (array + 'Instances' + 'Tags' ) - selected=selectedTab - }} + ) + selected=selectedTab + }} {{/block-slot}} {{#block-slot 'content'}} {{#each From 0702b4ee449f5a48f1d444e2b46a1be4254a39b5 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:27:53 +0000 Subject: [PATCH 09/17] ui: Tweak breadcrumb styling for current page styling --- ui-v2/app/styles/components/breadcrumbs/skin.scss | 11 ++++++++++- ui-v2/app/styles/components/icons/index.scss | 8 ++++++-- ui-v2/app/styles/core/typography.scss | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ui-v2/app/styles/components/breadcrumbs/skin.scss b/ui-v2/app/styles/components/breadcrumbs/skin.scss index 6bbe41f28847..52d3dd7849e8 100644 --- a/ui-v2/app/styles/components/breadcrumbs/skin.scss +++ b/ui-v2/app/styles/components/breadcrumbs/skin.scss @@ -1,9 +1,18 @@ -%breadcrumbs a { +%breadcrumbs li > * { @extend %with-chevron; } +%breadcrumbs li > strong::before { + background-color: $gray-300; +} +%breadcrumbs li > a::before { + background-color: rgba($color-action, 0.5); +} %breadcrumbs ol { list-style-type: none; } %breadcrumbs a { color: $color-action; } +%breadcrumbs strong { + color: $gray-400; +} diff --git a/ui-v2/app/styles/components/icons/index.scss b/ui-v2/app/styles/components/icons/index.scss index acc1eb7d6fd0..57729c30cafb 100644 --- a/ui-v2/app/styles/components/icons/index.scss +++ b/ui-v2/app/styles/components/icons/index.scss @@ -93,12 +93,16 @@ } %with-chevron::before { @extend %pseudo-icon; - background-image: url('data:image/svg+xml;charset=UTF-8,'); + mask-image: $chevron-left-svg; + mask-size: 15px 18px; + // TODO: These should go in the new %psuedo-icon + mask-repeat: no-repeat; + mask-position: center; + // width: 6px; height: 9px; left: 0; margin-top: -4px; - background-color: $color-transparent; } %with-folder::before { @extend %pseudo-icon; diff --git a/ui-v2/app/styles/core/typography.scss b/ui-v2/app/styles/core/typography.scss index c69f9bbba682..0aae116e9dff 100644 --- a/ui-v2/app/styles/core/typography.scss +++ b/ui-v2/app/styles/core/typography.scss @@ -51,7 +51,7 @@ caption { font-weight: $typo-weight-semibold !important; } th, -%breadcrumbs a, +%breadcrumbs li > *, %action-group-action, %tab-nav, %tooltip-bubble { From f7d46374a2cca9f61c87bb57549d7ddf44be0662 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:42:33 +0000 Subject: [PATCH 10/17] ui: Typo in test attribute --- ui-v2/app/templates/dc/services/-upstreams.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-v2/app/templates/dc/services/-upstreams.hbs b/ui-v2/app/templates/dc/services/-upstreams.hbs index baee4e2f4f92..2a3149d1762b 100644 --- a/ui-v2/app/templates/dc/services/-upstreams.hbs +++ b/ui-v2/app/templates/dc/services/-upstreams.hbs @@ -8,7 +8,7 @@ Local Bind Port {{/block-slot}} {{#block-slot 'row'}} - + {{item.DestinationName}} From 6bb9ebbac4b17ba2642b4441de8659f0d6bbed45 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 11:59:56 +0000 Subject: [PATCH 11/17] ui: Workaround strange ember helper bug Looking at the diff the old code produced: ``` Healthcheck Passing ``` Note the important return there. We actually want: ``` Healthcheck Passing ``` If not it affects the layout on narrow screens. --- ui-v2/app/templates/components/healthcheck-status.hbs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui-v2/app/templates/components/healthcheck-status.hbs b/ui-v2/app/templates/components/healthcheck-status.hbs index 004f03772191..ad2190903fc7 100644 --- a/ui-v2/app/templates/components/healthcheck-status.hbs +++ b/ui-v2/app/templates/components/healthcheck-status.hbs @@ -1,2 +1,3 @@ -
Healthchecks {{capitalize name}}
+{{!-- we use concat here to avoid ember adding returns between words, which causes a layout issue--}} +
{{ concat 'Healthchecks ' (capitalize 'passing') }}
{{format-number count}}
\ No newline at end of file From bd508c0511e5b57167b8653871c575f00c69a9d0 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 1 Feb 2019 15:57:39 +0000 Subject: [PATCH 12/17] ui: Various visual tweaks both HTML and CSS --- ui-v2/app/controllers/dc/services/instance.js | 2 +- .../app/styles/components/app-view/skin.scss | 20 +++++++++++++++---- ui-v2/app/styles/components/table.scss | 16 +++++++++++++++ ui-v2/app/styles/components/table/layout.scss | 4 +++- .../styles/components/tabular-collection.scss | 19 +++++++++++------- ui-v2/app/styles/core/typography.scss | 2 +- ui-v2/app/styles/routes/dc/service/index.scss | 4 ---- .../app/templates/dc/services/-instances.hbs | 8 ++++---- ui-v2/app/templates/dc/services/instance.hbs | 1 - 9 files changed, 53 insertions(+), 23 deletions(-) diff --git a/ui-v2/app/controllers/dc/services/instance.js b/ui-v2/app/controllers/dc/services/instance.js index 58dee9becfe4..a8934de52d1b 100644 --- a/ui-v2/app/controllers/dc/services/instance.js +++ b/ui-v2/app/controllers/dc/services/instance.js @@ -1,5 +1,5 @@ import Controller from '@ember/controller'; -import { get, set } from '@ember/object'; +import { set } from '@ember/object'; export default Controller.extend({ setProperties: function() { diff --git a/ui-v2/app/styles/components/app-view/skin.scss b/ui-v2/app/styles/components/app-view/skin.scss index 7fbf8771edde..a117fa1258e8 100644 --- a/ui-v2/app/styles/components/app-view/skin.scss +++ b/ui-v2/app/styles/components/app-view/skin.scss @@ -1,7 +1,17 @@ -%app-view h2, -%app-view header h1 { +%app-view h2 { border-bottom: $decor-border-200; } +@media #{$--horizontal-selects} { + %app-view header h1 { + border-bottom: $decor-border-200; + } +} +@media #{$--lt-horizontal-selects} { + %app-view header > div > div:last-child { + border-bottom: $decor-border-200; + } +} +%app-view header > div > div:last-child, %app-view header h1, %app-view h2 { border-color: $gray-200; @@ -9,8 +19,10 @@ // We know that any sibling navs might have a top border // by default. As its squashed up to a h1, in this // case hide its border to avoid double border -%app-view header h1 ~ nav { - border-top: 0 !important; +@media #{$--horizontal-selects} { + %app-view header h1 ~ nav { + border-top: 0 !important; + } } %app-content div > dl > dd { color: $gray-400; diff --git a/ui-v2/app/styles/components/table.scss b/ui-v2/app/styles/components/table.scss index 9890f600ca48..749774ad1a08 100644 --- a/ui-v2/app/styles/components/table.scss +++ b/ui-v2/app/styles/components/table.scss @@ -1,5 +1,21 @@ @import './icons/index'; @import './table/index'; + +html.template-service.template-list td:first-child a span, +html.template-node.template-show #services td:first-child a span, +html.template-service.template-show #instances td:first-child a span { + @extend %with-external-source-icon; + float: left; + margin-right: 10px; + margin-top: 2px; +} +/* This nudges the th in for the external source icons */ +html.template-node.template-show #services th:first-child, +html.template-service.template-show #instances th:first-child, +html.template-service.template-list main th:first-child { + text-indent: 28px; +} + td.folder { @extend %with-folder; } diff --git a/ui-v2/app/styles/components/table/layout.scss b/ui-v2/app/styles/components/table/layout.scss index c574d10d51fc..2706e64dc5aa 100644 --- a/ui-v2/app/styles/components/table/layout.scss +++ b/ui-v2/app/styles/components/table/layout.scss @@ -31,7 +31,7 @@ table th { padding-bottom: 0.6em; } table td, -table td a { +table td:first-child a { padding: 0.9em 0; } table th, @@ -58,6 +58,8 @@ td:not(.actions) a { } /* ideally these would be in route css files, but left here as they */ /* accomplish the same thing (hide non-essential columns for tables) */ +/* TODO: Move these to component/table.scss for the moment */ +/* Also mixed with things in component/tabular-collection.scss move those also */ @media #{$--lt-medium-table} { /* Policy > Datacenters */ html.template-policy.template-list tr > :nth-child(2) { diff --git a/ui-v2/app/styles/components/tabular-collection.scss b/ui-v2/app/styles/components/tabular-collection.scss index 9fb9bb0643f5..53d6678ef64e 100644 --- a/ui-v2/app/styles/components/tabular-collection.scss +++ b/ui-v2/app/styles/components/tabular-collection.scss @@ -35,17 +35,13 @@ table.dom-recycling { /* using: */ /* calc(<100% divided by number of non-fixed width cells> - ) */ -html.template-service.template-list td:first-child a span, -html.template-node.template-show #services td:first-child a span { - @extend %with-external-source-icon; - float: left; - margin-right: 10px; - margin-top: 2px; -} /*TODO: trs only live in tables, get rid of table */ html.template-service.template-list main table tr { @extend %services-row; } +html.template-service.template-show #instances table tr { + @extend %instances-row; +} html.template-instance.template-show #upstreams table tr { @extend %upstreams-row; } @@ -149,6 +145,12 @@ html.template-node.template-show main table.sessions tr { html.template-token.template-list main table tr td.me ~ td:nth-of-type(5) { display: none; } + html.template-service.template-show #instances tr > :nth-child(3) { + display: none; + } + %instances-row > * { + width: calc(100% / 4); + } } %kvs-row > *:first-child { @@ -175,6 +177,9 @@ html.template-node.template-show main table.sessions tr { %services-row > * { width: auto; } +%instances-row > * { + width: calc(100% / 5); +} %upstreams-row > * { width: calc(100% / 3); } diff --git a/ui-v2/app/styles/core/typography.scss b/ui-v2/app/styles/core/typography.scss index 0aae116e9dff..bc945842a88f 100644 --- a/ui-v2/app/styles/core/typography.scss +++ b/ui-v2/app/styles/core/typography.scss @@ -39,7 +39,7 @@ h2, %healthcheck-output dt, %copy-button, %app-content div > dl > dt, -td a { +td:first-child a { font-weight: $typo-weight-semibold; } %form-element > span, diff --git a/ui-v2/app/styles/routes/dc/service/index.scss b/ui-v2/app/styles/routes/dc/service/index.scss index e29aa9f66431..e69de29bb2d1 100644 --- a/ui-v2/app/styles/routes/dc/service/index.scss +++ b/ui-v2/app/styles/routes/dc/service/index.scss @@ -1,4 +0,0 @@ -html.template-node.template-show #services th:first-child, -html.template-service.template-list main th:first-child { - text-indent: 28px; -} diff --git a/ui-v2/app/templates/dc/services/-instances.hbs b/ui-v2/app/templates/dc/services/-instances.hbs index 709b7d83ffd6..2994a6f3ee08 100644 --- a/ui-v2/app/templates/dc/services/-instances.hbs +++ b/ui-v2/app/templates/dc/services/-instances.hbs @@ -11,7 +11,7 @@ items=filtered as |item index| }} {{#block-slot 'header'}} - Service + ID Node Address Node Checks @@ -19,13 +19,13 @@ {{/block-slot}} {{#block-slot 'row'}} - - + + {{ or item.Service.ID item.Service.Service }} - {{item.Node.Node}} + {{item.Node.Node}} {{item.Service.Address}}:{{item.Service.Port}} diff --git a/ui-v2/app/templates/dc/services/instance.hbs b/ui-v2/app/templates/dc/services/instance.hbs index 00385898f1a5..9cc6c2ca1e6d 100644 --- a/ui-v2/app/templates/dc/services/instance.hbs +++ b/ui-v2/app/templates/dc/services/instance.hbs @@ -43,7 +43,6 @@ {{/if}} {{/block-slot}} {{#block-slot 'content'}} - {{tab-nav items=(compact (array From 9719d018ecca8f6275530b8b6c0d756ae3ca2eaa Mon Sep 17 00:00:00 2001 From: John Cowen Date: Mon, 4 Feb 2019 13:57:52 +0000 Subject: [PATCH 13/17] ui: Add some empty messaging --- ui-v2/app/templates/dc/services/-tags.hbs | 6 ++++++ ui-v2/app/templates/dc/services/-upstreams.hbs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ui-v2/app/templates/dc/services/-tags.hbs b/ui-v2/app/templates/dc/services/-tags.hbs index 1c8d19065f29..24ddbbfc1fe5 100644 --- a/ui-v2/app/templates/dc/services/-tags.hbs +++ b/ui-v2/app/templates/dc/services/-tags.hbs @@ -1 +1,7 @@ +{{#if (gt items.Tags.length 0) }} {{tag-list items=item.Tags}} +{{else}} +

+ There are no tags. +

+{{/if}} diff --git a/ui-v2/app/templates/dc/services/-upstreams.hbs b/ui-v2/app/templates/dc/services/-upstreams.hbs index 2a3149d1762b..aa8f1a7be736 100644 --- a/ui-v2/app/templates/dc/services/-upstreams.hbs +++ b/ui-v2/app/templates/dc/services/-upstreams.hbs @@ -1,3 +1,4 @@ +{{#if (gt items.Proxy.Upstreams.length 0) }} {{#tabular-collection data-test-upstreams items=item.Proxy.Upstreams as |item index| @@ -19,3 +20,8 @@ {{/block-slot}} {{/tabular-collection}} +{{else}} +

+ There are no upstreams. +

+{{/if}} From bde111bf7ed4f9da5b2f6e398224a74e4dd86a7e Mon Sep 17 00:00:00 2001 From: John Cowen Date: Tue, 5 Feb 2019 16:22:23 +0000 Subject: [PATCH 14/17] ui: Start pulling in the related proxies --- ui-v2/app/adapters/proxy.js | 21 ++++++++++ ui-v2/app/models/proxy.js | 12 ++++++ ui-v2/app/routes/dc/services/instance.js | 29 +++++--------- ui-v2/app/serializers/proxy.js | 6 +++ ui-v2/app/services/repository/proxy.js | 33 ++++++++++++++++ ui-v2/app/services/repository/service.js | 39 ++++++++++++++----- ui-v2/app/templates/dc/services/-tags.hbs | 2 +- .../app/templates/dc/services/-upstreams.hbs | 2 +- ui-v2/app/templates/dc/services/instance.hbs | 6 +-- ui-v2/tests/unit/adapters/proxy-test.js | 12 ++++++ ui-v2/tests/unit/models/proxy-test.js | 14 +++++++ ui-v2/tests/unit/serializers/proxy-test.js | 24 ++++++++++++ 12 files changed, 166 insertions(+), 34 deletions(-) create mode 100644 ui-v2/app/adapters/proxy.js create mode 100644 ui-v2/app/models/proxy.js create mode 100644 ui-v2/app/serializers/proxy.js create mode 100644 ui-v2/app/services/repository/proxy.js create mode 100644 ui-v2/tests/unit/adapters/proxy-test.js create mode 100644 ui-v2/tests/unit/models/proxy-test.js create mode 100644 ui-v2/tests/unit/serializers/proxy-test.js diff --git a/ui-v2/app/adapters/proxy.js b/ui-v2/app/adapters/proxy.js new file mode 100644 index 000000000000..cd31c0d1531f --- /dev/null +++ b/ui-v2/app/adapters/proxy.js @@ -0,0 +1,21 @@ +import Adapter from './application'; +import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/proxy'; +import { OK as HTTP_OK } from 'consul-ui/utils/http/status'; +export default Adapter.extend({ + urlForQuery: function(query, modelName) { + if (typeof query.id === 'undefined') { + throw new Error('You must specify an id'); + } + // https://www.consul.io/api/catalog.html#list-nodes-for-connect-capable-service + return this.appendURL('catalog/connect', [query.id], this.cleanQuery(query)); + }, + handleResponse: function(status, headers, payload, requestData) { + let response = payload; + const method = requestData.method; + if (status === HTTP_OK) { + const url = this.parseURL(requestData.url); + response = this.handleBatchResponse(url, response, PRIMARY_KEY, SLUG_KEY); + } + return this._super(status, headers, response, requestData); + }, +}); diff --git a/ui-v2/app/models/proxy.js b/ui-v2/app/models/proxy.js new file mode 100644 index 000000000000..9e0858219927 --- /dev/null +++ b/ui-v2/app/models/proxy.js @@ -0,0 +1,12 @@ +import Model from 'ember-data/model'; +import attr from 'ember-data/attr'; + +export const PRIMARY_KEY = 'uid'; +export const SLUG_KEY = 'ID'; +export default Model.extend({ + [PRIMARY_KEY]: attr('string'), + [SLUG_KEY]: attr('string'), + ServiceName: attr('string'), + ServiceID: attr('string'), + ServiceProxyDestination: attr('string'), +}); diff --git a/ui-v2/app/routes/dc/services/instance.js b/ui-v2/app/routes/dc/services/instance.js index 59492478f5bf..da863ba41814 100644 --- a/ui-v2/app/routes/dc/services/instance.js +++ b/ui-v2/app/routes/dc/services/instance.js @@ -5,30 +5,21 @@ import { get } from '@ember/object'; export default Route.extend({ repo: service('repository/service'), + proxyRepo: service('repository/proxy'), model: function(params) { const repo = get(this, 'repo'); - // TODO: findInstanceBySlug + const proxyRepo = get(this, 'proxyRepo'); + const dc = this.modelFor('dc').dc.Name; return hash({ - item: repo.findBySlug(params.name, this.modelFor('dc').dc.Name), + item: repo.findInstanceBySlug(params.id, params.name, dc), }).then(function(model) { - const i = model.item.Nodes.findIndex(function(item) { - return item.Service.ID === params.id; - }); - // console.log(model.item); - const service = model.item.Nodes[i].Service; - service.Node = model.item.Nodes[i].Node; - service.ServiceChecks = model.item.Nodes[i].Checks.filter(function(item) { - return item.ServiceID != ''; - }); - service.NodeChecks = model.item.Nodes[i].Checks.filter(function(item) { - return item.ServiceID == ''; - }); - return { + return hash({ + proxy: + get(service, 'Kind') !== 'connect-proxy' + ? proxyRepo.findInstanceBySlug(params.id, params.name, dc) + : null, ...model, - ...{ - item: service, - }, - }; + }); }); }, setupController: function(controller, model) { diff --git a/ui-v2/app/serializers/proxy.js b/ui-v2/app/serializers/proxy.js new file mode 100644 index 000000000000..7c3c5c42e08c --- /dev/null +++ b/ui-v2/app/serializers/proxy.js @@ -0,0 +1,6 @@ +import Serializer from './application'; +import { PRIMARY_KEY } from 'consul-ui/models/proxy'; + +export default Serializer.extend({ + primaryKey: PRIMARY_KEY, +}); diff --git a/ui-v2/app/services/repository/proxy.js b/ui-v2/app/services/repository/proxy.js new file mode 100644 index 000000000000..ce8c055d83f1 --- /dev/null +++ b/ui-v2/app/services/repository/proxy.js @@ -0,0 +1,33 @@ +import RepositoryService from 'consul-ui/services/repository'; +import { PRIMARY_KEY } from 'consul-ui/models/proxy'; +import { get } from '@ember/object'; +const modelName = 'proxy'; +export default RepositoryService.extend({ + getModelName: function() { + return modelName; + }, + getPrimaryKey: function() { + return PRIMARY_KEY; + }, + findAllBySlug: function(slug, dc, configuration = {}) { + const query = { + id: slug, + dc: dc, + }; + if (typeof configuration.cursor !== 'undefined') { + query.index = configuration.cursor; + } + return this.get('store').query(this.getModelName(), query); + }, + findInstanceBySlug: function(id, slug, dc, configuration) { + return this.findAllBySlug(slug, dc, configuration).then(function(items) { + if (get(items, 'length') > 0) { + const instance = items.findBy('ServiceProxyDestination', id); + if (instance) { + return instance; + } + } + return; + }); + }, +}); diff --git a/ui-v2/app/services/repository/service.js b/ui-v2/app/services/repository/service.js index 5654c3a61837..2da90a3c7265 100644 --- a/ui-v2/app/services/repository/service.js +++ b/ui-v2/app/services/repository/service.js @@ -7,16 +7,35 @@ export default RepositoryService.extend({ }, findBySlug: function(slug, dc) { return this._super(...arguments).then(function(item) { - const nodes = get(item, 'Nodes'); - const service = get(nodes, 'firstObject'); - const tags = nodes - .reduce(function(prev, item) { - return prev.concat(get(item, 'Service.Tags') || []); - }, []) - .uniq(); - set(service, 'Tags', tags); - set(service, 'Nodes', nodes); - return service; + const nodes = get(item, 'Nodes'); + const service = get(nodes, 'firstObject'); + const tags = nodes + .reduce(function(prev, item) { + return prev.concat(get(item, 'Service.Tags') || []); + }, []) + .uniq(); + set(service, 'Tags', tags); + set(service, 'Nodes', nodes); + return service; + }); + }, + findInstanceBySlug: function(id, slug, dc, configuration) { + return this.findBySlug(slug, dc, configuration).then(function(item) { + const i = item.Nodes.findIndex(function(item) { + return item.Service.ID === id; }); + if (i !== -1) { + const service = item.Nodes[i].Service; + service.Node = item.Nodes[i].Node; + service.ServiceChecks = item.Nodes[i].Checks.filter(function(item) { + return item.ServiceID != ''; + }); + service.NodeChecks = item.Nodes[i].Checks.filter(function(item) { + return item.ServiceID == ''; + }); + return service; + } + // TODO: probably need to throw a 404 here? + }); }, }); diff --git a/ui-v2/app/templates/dc/services/-tags.hbs b/ui-v2/app/templates/dc/services/-tags.hbs index 24ddbbfc1fe5..c0a3a0f7830a 100644 --- a/ui-v2/app/templates/dc/services/-tags.hbs +++ b/ui-v2/app/templates/dc/services/-tags.hbs @@ -1,4 +1,4 @@ -{{#if (gt items.Tags.length 0) }} +{{#if (gt item.Tags.length 0) }} {{tag-list items=item.Tags}} {{else}}

diff --git a/ui-v2/app/templates/dc/services/-upstreams.hbs b/ui-v2/app/templates/dc/services/-upstreams.hbs index aa8f1a7be736..f4ad6fcc8139 100644 --- a/ui-v2/app/templates/dc/services/-upstreams.hbs +++ b/ui-v2/app/templates/dc/services/-upstreams.hbs @@ -1,4 +1,4 @@ -{{#if (gt items.Proxy.Upstreams.length 0) }} +{{#if (gt item.Proxy.Upstreams.length 0) }} {{#tabular-collection data-test-upstreams items=item.Proxy.Upstreams as |item index| diff --git a/ui-v2/app/templates/dc/services/instance.hbs b/ui-v2/app/templates/dc/services/instance.hbs index 9cc6c2ca1e6d..063855210426 100644 --- a/ui-v2/app/templates/dc/services/instance.hbs +++ b/ui-v2/app/templates/dc/services/instance.hbs @@ -9,7 +9,7 @@ {{#block-slot 'header'}}

{{ item.ID }} -{{#with (service/external-source item.Service) as |externalSource| }} +{{#with (service/external-source item) as |externalSource| }} {{#with (css-var (concat '--' externalSource '-color-svg') 'none') as |bg| }} {{#if (not-eq bg 'none') }} Registered via {{externalSource}} @@ -25,10 +25,10 @@
Node Name
{{item.Node.Node}}
-{{#if false}} +{{#if proxy}}
Sidecar Proxy
-
+
{{proxy.ServiceID}}
{{/if}} {{#if (eq item.Kind 'connect-proxy')}} diff --git a/ui-v2/tests/unit/adapters/proxy-test.js b/ui-v2/tests/unit/adapters/proxy-test.js new file mode 100644 index 000000000000..13859457edeb --- /dev/null +++ b/ui-v2/tests/unit/adapters/proxy-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | proxy', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let adapter = this.owner.lookup('adapter:proxy'); + assert.ok(adapter); + }); +}); diff --git a/ui-v2/tests/unit/models/proxy-test.js b/ui-v2/tests/unit/models/proxy-test.js new file mode 100644 index 000000000000..b37e80f56d29 --- /dev/null +++ b/ui-v2/tests/unit/models/proxy-test.js @@ -0,0 +1,14 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { run } from '@ember/runloop'; + +module('Unit | Model | proxy', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let store = this.owner.lookup('service:store'); + let model = run(() => store.createRecord('proxy', {})); + assert.ok(model); + }); +}); diff --git a/ui-v2/tests/unit/serializers/proxy-test.js b/ui-v2/tests/unit/serializers/proxy-test.js new file mode 100644 index 000000000000..44090cfe02d1 --- /dev/null +++ b/ui-v2/tests/unit/serializers/proxy-test.js @@ -0,0 +1,24 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { run } from '@ember/runloop'; + +module('Unit | Serializer | proxy', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let store = this.owner.lookup('service:store'); + let serializer = store.serializerFor('proxy'); + + assert.ok(serializer); + }); + + test('it serializes records', function(assert) { + let store = this.owner.lookup('service:store'); + let record = run(() => store.createRecord('proxy', {})); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); +}); From 5163a2b0e2f855859182128d837b7fd81b56c098 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 7 Feb 2019 16:51:11 +0000 Subject: [PATCH 15/17] ui: remove old tests for paths that no longer exists, pass default tests 1. This feature removes a certain amount of functionality. So we just remove the acceptence tests for this old functionality here. 2. We also do a basic amount of edits to make the default ember tests pass (these are generally 'does this thing even render' or 'can I actually instantiate this thing?' New tests will be added on top of this --- ui-v2/app/adapters/proxy.js | 1 - ui-v2/app/routes/dc/services/show.js | 1 + .../components/healthcheck-status.hbs | 2 +- .../app/templates/dc/services/-instances.hbs | 8 +++--- .../components/catalog-filter.feature | 25 ------------------- .../tests/acceptance/dc/services/show.feature | 16 ++---------- .../components/healthcheck-info-test.js | 16 ++---------- .../components/healthcheck-list-test.js | 15 ++--------- .../components/healthcheck-status-test.js | 20 +++------------ .../integration/components/tag-list-test.js | 3 +-- ui-v2/tests/pages/dc/services/show.js | 14 ++--------- .../unit/routes/dc/services/instance-test.js | 2 +- 12 files changed, 19 insertions(+), 104 deletions(-) diff --git a/ui-v2/app/adapters/proxy.js b/ui-v2/app/adapters/proxy.js index cd31c0d1531f..d4f4f41ea539 100644 --- a/ui-v2/app/adapters/proxy.js +++ b/ui-v2/app/adapters/proxy.js @@ -11,7 +11,6 @@ export default Adapter.extend({ }, handleResponse: function(status, headers, payload, requestData) { let response = payload; - const method = requestData.method; if (status === HTTP_OK) { const url = this.parseURL(requestData.url); response = this.handleBatchResponse(url, response, PRIMARY_KEY, SLUG_KEY); diff --git a/ui-v2/app/routes/dc/services/show.js b/ui-v2/app/routes/dc/services/show.js index bf5fa0d6579a..9376abdbc10a 100644 --- a/ui-v2/app/routes/dc/services/show.js +++ b/ui-v2/app/routes/dc/services/show.js @@ -19,6 +19,7 @@ export default Route.extend({ return { ...model, ...{ + // Nodes happen to be the ServiceInstances here items: model.item.Nodes, }, }; diff --git a/ui-v2/app/templates/components/healthcheck-status.hbs b/ui-v2/app/templates/components/healthcheck-status.hbs index ad2190903fc7..383f67386c56 100644 --- a/ui-v2/app/templates/components/healthcheck-status.hbs +++ b/ui-v2/app/templates/components/healthcheck-status.hbs @@ -1,3 +1,3 @@ {{!-- we use concat here to avoid ember adding returns between words, which causes a layout issue--}} -
{{ concat 'Healthchecks ' (capitalize 'passing') }}
+
{{ concat 'Healthchecks ' (capitalize name) }}
{{format-number count}}
\ No newline at end of file diff --git a/ui-v2/app/templates/dc/services/-instances.hbs b/ui-v2/app/templates/dc/services/-instances.hbs index 2994a6f3ee08..7ef34c3400e8 100644 --- a/ui-v2/app/templates/dc/services/-instances.hbs +++ b/ui-v2/app/templates/dc/services/-instances.hbs @@ -7,7 +7,7 @@ {{#changeable-set dispatcher=searchable}} {{#block-slot 'set' as |filtered|}} {{#tabular-collection - data-test-services + data-test-instances items=filtered as |item index| }} {{#block-slot 'header'}} @@ -18,16 +18,16 @@ Service Checks {{/block-slot}} {{#block-slot 'row'}} - + {{ or item.Service.ID item.Service.Service }} - + {{item.Node.Node}} - + {{item.Service.Address}}:{{item.Service.Port}} diff --git a/ui-v2/tests/acceptance/components/catalog-filter.feature b/ui-v2/tests/acceptance/components/catalog-filter.feature index ed11e247bd16..3b5dad1177ea 100644 --- a/ui-v2/tests/acceptance/components/catalog-filter.feature +++ b/ui-v2/tests/acceptance/components/catalog-filter.feature @@ -123,31 +123,6 @@ Feature: components / catalog-filter | Model | Page | Url | | service | node | /dc-1/nodes/node-0 | ------------------------------------------------- - Scenario: Filtering [Model] in [Page] - Given 1 datacenter model with the value "dc1" - And 2 [Model] models from yaml - --- - - ID: node-0 - --- - When I visit the [Page] page for yaml - --- - dc: dc1 - service: service-0 - --- - Then I fill in with yaml - --- - s: service-0-with-id - --- - And I see 1 [Model] model - Then I see id on the unhealthy like yaml - --- - - service-0-with-id - --- - Where: - ------------------------------------------------- - | Model | Page | Url | - | nodes | service | /dc-1/services/service-0 | - ------------------------------------------------- Scenario: Given 1 datacenter model with the value "dc-1" And 3 service models from yaml diff --git a/ui-v2/tests/acceptance/dc/services/show.feature b/ui-v2/tests/acceptance/dc/services/show.feature index 5fa48f0defa0..0c707f31b986 100644 --- a/ui-v2/tests/acceptance/dc/services/show.feature +++ b/ui-v2/tests/acceptance/dc/services/show.feature @@ -52,7 +52,7 @@ Feature: dc / services / show: Show Service Then I see the text "Tag1" in "[data-test-tags] span:nth-child(1)" Then I see the text "Tag2" in "[data-test-tags] span:nth-child(2)" Then I see the text "Tag3" in "[data-test-tags] span:nth-child(3)" - Scenario: Given various services the various ports on their nodes are displayed + Scenario: Given various services the various nodes on their instances are displayed Given 1 datacenter model with the value "dc1" And 3 node models And 1 service model from yaml @@ -83,21 +83,9 @@ Feature: dc / services / show: Show Service dc: dc1 service: service-0 --- - Then I see address on the healthy like yaml + Then I see address on the instances like yaml --- - "1.1.1.1:8080" - --- - Then I see address on the unhealthy like yaml - --- - "2.2.2.2:8000" - "3.3.3.3:8888" --- - Then I see id on the healthy like yaml - --- - - "passing-service-8080" - --- - Then I see id on the unhealthy like yaml - --- - - "service-8000" - - "service-8888" - --- diff --git a/ui-v2/tests/integration/components/healthcheck-info-test.js b/ui-v2/tests/integration/components/healthcheck-info-test.js index 6267b605d056..613a65065779 100644 --- a/ui-v2/tests/integration/components/healthcheck-info-test.js +++ b/ui-v2/tests/integration/components/healthcheck-info-test.js @@ -11,24 +11,12 @@ test('it renders', function(assert) { this.render(hbs`{{healthcheck-info}}`); - assert.equal( - this.$() - .text() - .trim(), - '' - ); + assert.equal(this.$('dl').length, 1); // Template block usage: this.render(hbs` {{#healthcheck-info}} - template block text {{/healthcheck-info}} `); - - assert.equal( - this.$() - .text() - .trim(), - 'template block text' - ); + assert.equal(this.$('dl').length, 1); }); diff --git a/ui-v2/tests/integration/components/healthcheck-list-test.js b/ui-v2/tests/integration/components/healthcheck-list-test.js index b0ce91215801..a85c4866de8f 100644 --- a/ui-v2/tests/integration/components/healthcheck-list-test.js +++ b/ui-v2/tests/integration/components/healthcheck-list-test.js @@ -11,24 +11,13 @@ test('it renders', function(assert) { this.render(hbs`{{healthcheck-list}}`); - assert.equal( - this.$() - .text() - .trim(), - '' - ); + assert.equal(this.$('ul').length, 1); // Template block usage: this.render(hbs` {{#healthcheck-list}} - template block text {{/healthcheck-list}} `); - assert.equal( - this.$() - .text() - .trim(), - 'template block text' - ); + assert.equal(this.$('ul').length, 1); }); diff --git a/ui-v2/tests/integration/components/healthcheck-status-test.js b/ui-v2/tests/integration/components/healthcheck-status-test.js index 67cb8de5e199..f4e9bd78ff22 100644 --- a/ui-v2/tests/integration/components/healthcheck-status-test.js +++ b/ui-v2/tests/integration/components/healthcheck-status-test.js @@ -10,25 +10,11 @@ test('it renders', function(assert) { // Handle any actions with this.on('myAction', function(val) { ... }); this.render(hbs`{{healthcheck-status}}`); - - assert.equal( - this.$() - .text() - .trim(), - '' - ); + assert.equal(this.$('dt').length, 1); // Template block usage: this.render(hbs` - {{#healthcheck-status}} - template block text - {{/healthcheck-status}} + {{#healthcheck-status}}{{/healthcheck-status}} `); - - assert.equal( - this.$() - .text() - .trim(), - 'template block text' - ); + assert.equal(this.$('dt').length, 1); }); diff --git a/ui-v2/tests/integration/components/tag-list-test.js b/ui-v2/tests/integration/components/tag-list-test.js index 666846367466..6924c8562cd3 100644 --- a/ui-v2/tests/integration/components/tag-list-test.js +++ b/ui-v2/tests/integration/components/tag-list-test.js @@ -21,7 +21,6 @@ test('it renders', function(assert) { // Template block usage: this.render(hbs` {{#tag-list}} - template block text {{/tag-list}} `); @@ -29,6 +28,6 @@ test('it renders', function(assert) { this.$() .text() .trim(), - 'template block text' + '' ); }); diff --git a/ui-v2/tests/pages/dc/services/show.js b/ui-v2/tests/pages/dc/services/show.js index f50c60c834dd..5b5fb2e3813b 100644 --- a/ui-v2/tests/pages/dc/services/show.js +++ b/ui-v2/tests/pages/dc/services/show.js @@ -2,18 +2,8 @@ export default function(visitable, attribute, collection, text, filter) { return { visit: visitable('/:dc/services/:service'), externalSource: attribute('data-test-external-source', 'h1 span'), - nodes: collection('[data-test-node]', { - name: attribute('data-test-node'), - }), - healthy: collection('[data-test-healthy] [data-test-node]', { - name: attribute('data-test-node'), - address: text('header strong'), - id: text('header em'), - }), - unhealthy: collection('[data-test-unhealthy] [data-test-node]', { - name: attribute('data-test-node'), - address: text('header strong'), - id: text('header em'), + instances: collection('#instances [data-test-tabular-row]', { + address: text('[data-test-address]'), }), filter: filter, }; diff --git a/ui-v2/tests/unit/routes/dc/services/instance-test.js b/ui-v2/tests/unit/routes/dc/services/instance-test.js index 9471a2f508d2..122dc9ee163e 100644 --- a/ui-v2/tests/unit/routes/dc/services/instance-test.js +++ b/ui-v2/tests/unit/routes/dc/services/instance-test.js @@ -2,7 +2,7 @@ import { moduleFor, test } from 'ember-qunit'; moduleFor('route:dc/services/instance', 'Unit | Route | dc/services/instance', { // Specify the other units that are required for this test. - // needs: ['controller:foo'] + needs: ['service:repository/service', 'service:repository/proxy'], }); test('it exists', function(assert) { From daa19caf719df258552cac450089b0e96d6faa81 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 8 Feb 2019 13:09:18 +0000 Subject: [PATCH 16/17] ui: Swap SVG breadcrumb chevron icon for a unicode character --- ui-v2/app/styles/components/breadcrumbs/skin.scss | 4 ++-- ui-v2/app/styles/components/icons/index.scss | 11 +++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/ui-v2/app/styles/components/breadcrumbs/skin.scss b/ui-v2/app/styles/components/breadcrumbs/skin.scss index 52d3dd7849e8..fb86355e9244 100644 --- a/ui-v2/app/styles/components/breadcrumbs/skin.scss +++ b/ui-v2/app/styles/components/breadcrumbs/skin.scss @@ -2,10 +2,10 @@ @extend %with-chevron; } %breadcrumbs li > strong::before { - background-color: $gray-300; + color: $gray-300; } %breadcrumbs li > a::before { - background-color: rgba($color-action, 0.5); + color: rgba($color-action, 0.5); } %breadcrumbs ol { list-style-type: none; diff --git a/ui-v2/app/styles/components/icons/index.scss b/ui-v2/app/styles/components/icons/index.scss index 57729c30cafb..4c61d11f3cf6 100644 --- a/ui-v2/app/styles/components/icons/index.scss +++ b/ui-v2/app/styles/components/icons/index.scss @@ -93,16 +93,11 @@ } %with-chevron::before { @extend %pseudo-icon; - mask-image: $chevron-left-svg; - mask-size: 15px 18px; - // TODO: These should go in the new %psuedo-icon - mask-repeat: no-repeat; - mask-position: center; - // + content: '❮'; width: 6px; - height: 9px; + background-color: transparent; left: 0; - margin-top: -4px; + font-size: 0.7rem; } %with-folder::before { @extend %pseudo-icon; From 39982e84cedfc15a1b6bc3ce930bcb41d1e93d53 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 21 Feb 2019 11:43:05 +0000 Subject: [PATCH 17/17] ui: fix various problems with the code 1. Remove `subscribe` and couting from healthcheck-info its not needed here at all 2. Switch back to `computed` in healthcheck-status 3. Make sure the healthcheck-info js component follows the rest of my CSS component structure instead of keeping the old healthcheck-status which is just a single icon rather than all 3 4. Fix CSS bug where the zero healthcheck icon wasn't being displayed. --- ui-v2/app/components/healthcheck-info.js | 10 ----- ui-v2/app/components/healthcheck-status.js | 5 ++- .../styles/components/healthcheck-info.scss | 12 ++++++ .../index.scss | 0 .../components/healthcheck-info/layout.scss | 32 +++++++++++++++ .../components/healthcheck-info/skin.scss | 21 ++++++++++ .../styles/components/healthcheck-status.scss | 5 --- .../components/healthcheck-status/layout.scss | 40 ------------------- .../components/healthcheck-status/skin.scss | 28 ------------- ui-v2/app/styles/components/index.scss | 2 +- .../templates/components/healthcheck-info.hbs | 8 ++-- 11 files changed, 73 insertions(+), 90 deletions(-) create mode 100644 ui-v2/app/styles/components/healthcheck-info.scss rename ui-v2/app/styles/components/{healthcheck-status => healthcheck-info}/index.scss (100%) create mode 100644 ui-v2/app/styles/components/healthcheck-info/layout.scss create mode 100644 ui-v2/app/styles/components/healthcheck-info/skin.scss delete mode 100644 ui-v2/app/styles/components/healthcheck-status.scss delete mode 100644 ui-v2/app/styles/components/healthcheck-status/layout.scss delete mode 100644 ui-v2/app/styles/components/healthcheck-status/skin.scss diff --git a/ui-v2/app/components/healthcheck-info.js b/ui-v2/app/components/healthcheck-info.js index 26b8886aa92c..abe1ccedb6d3 100644 --- a/ui-v2/app/components/healthcheck-info.js +++ b/ui-v2/app/components/healthcheck-info.js @@ -1,14 +1,4 @@ import Component from '@ember/component'; -import { subscribe } from 'consul-ui/utils/computed/purify'; -const count = function(value) { - if (Array.isArray(value)) { - return value.length; - } - return value; -}; export default Component.extend({ tagName: '', - passingCount: subscribe('passing', count), - warningCount: subscribe('warning', count), - criticalCount: subscribe('critical', count), }); diff --git a/ui-v2/app/components/healthcheck-status.js b/ui-v2/app/components/healthcheck-status.js index a8d909e48487..367cca6469f1 100644 --- a/ui-v2/app/components/healthcheck-status.js +++ b/ui-v2/app/components/healthcheck-status.js @@ -1,8 +1,9 @@ import Component from '@ember/component'; -import { subscribe } from 'consul-ui/utils/computed/purify'; +import { get, computed } from '@ember/object'; export default Component.extend({ tagName: '', - count: subscribe('value', function(value) { + count: computed('value', function() { + const value = get(this, 'value'); if (Array.isArray(value)) { return value.length; } diff --git a/ui-v2/app/styles/components/healthcheck-info.scss b/ui-v2/app/styles/components/healthcheck-info.scss new file mode 100644 index 000000000000..a249d32c4929 --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-info.scss @@ -0,0 +1,12 @@ +@import './healthcheck-info/index'; +@import './icons/index'; +tr dl { + @extend %healthcheck-info; +} +td span.zero { + @extend %with-no-healthchecks; + // TODO: Why isn't this is layout? + display: block; + text-indent: 20px; + color: $gray-400; +} diff --git a/ui-v2/app/styles/components/healthcheck-status/index.scss b/ui-v2/app/styles/components/healthcheck-info/index.scss similarity index 100% rename from ui-v2/app/styles/components/healthcheck-status/index.scss rename to ui-v2/app/styles/components/healthcheck-info/index.scss diff --git a/ui-v2/app/styles/components/healthcheck-info/layout.scss b/ui-v2/app/styles/components/healthcheck-info/layout.scss new file mode 100644 index 000000000000..0f084db303a5 --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-info/layout.scss @@ -0,0 +1,32 @@ +%healthcheck-info { + display: flex; + height: 100%; + float: left; +} +%healthcheck-info > * { + display: block; +} +%healthcheck-info dt.zero { + display: none; +} +%healthcheck-info dd.zero { + visibility: hidden; +} +%healthcheck-info dt { + text-indent: -9000px; +} +%healthcheck-info dt.warning { + overflow: visible; +} +%healthcheck-info dt.warning::before { + top: 7px; +} +%healthcheck-info dt.warning::after { + left: -2px; + top: -1px; +} +%healthcheck-info dd { + box-sizing: content-box; + margin-left: 22px; + padding-right: 10px; +} diff --git a/ui-v2/app/styles/components/healthcheck-info/skin.scss b/ui-v2/app/styles/components/healthcheck-info/skin.scss new file mode 100644 index 000000000000..9b22b05f01d7 --- /dev/null +++ b/ui-v2/app/styles/components/healthcheck-info/skin.scss @@ -0,0 +1,21 @@ +%healthcheck-info dt.passing { + @extend %with-passing; +} +%healthcheck-info dt.warning { + @extend %with-warning; +} +%healthcheck-info dt.critical { + @extend %with-critical; +} +%healthcheck-info dt.passing, +%healthcheck-info dt.passing + dd { + color: $color-success; +} +%healthcheck-info dt.warning, +%healthcheck-info dt.warning + dd { + color: $color-alert; +} +%healthcheck-info dt.critical, +%healthcheck-info dt.critical + dd { + color: $color-failure; +} diff --git a/ui-v2/app/styles/components/healthcheck-status.scss b/ui-v2/app/styles/components/healthcheck-status.scss deleted file mode 100644 index 13edc8313e1f..000000000000 --- a/ui-v2/app/styles/components/healthcheck-status.scss +++ /dev/null @@ -1,5 +0,0 @@ -@import './healthcheck-status/index'; -@import './icons/index'; -.healthcheck-status { - @extend %healthcheck-status; -} diff --git a/ui-v2/app/styles/components/healthcheck-status/layout.scss b/ui-v2/app/styles/components/healthcheck-status/layout.scss deleted file mode 100644 index 5244511d0f20..000000000000 --- a/ui-v2/app/styles/components/healthcheck-status/layout.scss +++ /dev/null @@ -1,40 +0,0 @@ -// TODO: Why do I need to cover th and td here? -tr > * dl { - float: left; -} -%healthcheck-status { - height: 100%; -} -%healthcheck-status { - display: flex; -} -%healthcheck-status > * { - display: block; -} -%healthcheck-status dt.zero { - display: none; -} -%healthcheck-status dd.zero { - visibility: hidden; -} -%healthcheck-status dt { - text-indent: -9000px; -} -%healthcheck-status dt.warning { - overflow: visible; -} -%healthcheck-status dt.warning::before { - top: 7px; -} -%healthcheck-status dt.warning::after { - left: -2px; - top: -1px; -} -%healthcheck-status dd { - box-sizing: content-box; - margin-left: 22px; - padding-right: 10px; -} -tr dl { - @extend %healthcheck-status; -} diff --git a/ui-v2/app/styles/components/healthcheck-status/skin.scss b/ui-v2/app/styles/components/healthcheck-status/skin.scss deleted file mode 100644 index 7ff5d0993187..000000000000 --- a/ui-v2/app/styles/components/healthcheck-status/skin.scss +++ /dev/null @@ -1,28 +0,0 @@ -%healthcheck-status dt.passing { - @extend %with-passing; -} -%healthcheck-status dt.warning { - @extend %with-warning; -} -%healthcheck-status dt.critical { - @extend %with-critical; -} -%healthcheck-status span.zero { - @extend %with-no-healthchecks; - // TODO: Why isn't this is layout? - display: block; - text-indent: 20px; - color: $gray-400; -} -%healthcheck-status dt.passing, -%healthcheck-status dt.passing + dd { - color: $color-success; -} -%healthcheck-status dt.warning, -%healthcheck-status dt.warning + dd { - color: $color-alert; -} -%healthcheck-status dt.critical, -%healthcheck-status dt.critical + dd { - color: $color-failure; -} diff --git a/ui-v2/app/styles/components/index.scss b/ui-v2/app/styles/components/index.scss index 0012ad001042..edfda9d16efd 100644 --- a/ui-v2/app/styles/components/index.scss +++ b/ui-v2/app/styles/components/index.scss @@ -18,7 +18,7 @@ @import './tag-list'; @import './healthcheck-output'; -@import './healthcheck-status'; +@import './healthcheck-info'; @import './healthchecked-resource'; @import './freetext-filter'; @import './filter-bar'; diff --git a/ui-v2/app/templates/components/healthcheck-info.hbs b/ui-v2/app/templates/components/healthcheck-info.hbs index 594bd7a02b29..13b62ac08c33 100644 --- a/ui-v2/app/templates/components/healthcheck-info.hbs +++ b/ui-v2/app/templates/components/healthcheck-info.hbs @@ -1,9 +1,9 @@ -{{#if (and (lt passingCount 1) (lt warningCount 1) (lt criticalCount 1) )}} +{{#if (and (lt passing 1) (lt warning 1) (lt critical 1) )}} 0 {{else}}
- {{healthcheck-status width=passingWidth name='passing' value=passingCount}} - {{healthcheck-status width=warningWidth name='warning' value=warningCount}} - {{healthcheck-status width=criticalWidth name='critical' value=criticalCount}} + {{healthcheck-status width=passingWidth name='passing' value=passing}} + {{healthcheck-status width=warningWidth name='warning' value=warning}} + {{healthcheck-status width=criticalWidth name='critical' value=critical}}
{{/if}}