mirror of https://github.com/hashicorp/consul
ui: Redesign - Service Detail Page (#7655)
* Create ConsulServiceInstanceList with styling and test * Implement ConsulServiceInstanceList to Service Detail page * Implement ConsulExternalSource to Services Show page header * Update services/show page object * Update the styling of CompositeRow * Refactor ConsulServiceList component and styling * Update ConsulExternalSource to say 'Registered via...' * Upgrade consul-api-double to patch 2.14.1 * Fix up tests to not use Kind in service models * Update ListCollection with clickFirstAnchor action * Add $typo-size-450 to typography base variablespull/7857/head
parent
8e9fca9be6
commit
51db157fab
|
@ -1,17 +1,19 @@
|
||||||
{{#let (if _externalSource _externalSource (service/external-source item)) as |externalSource|}}
|
{{#if item}}
|
||||||
{{#if externalSource}}
|
{{#let (if _externalSource _externalSource (service/external-source item)) as |externalSource|}}
|
||||||
{{#if (has-block)}}
|
{{#if externalSource}}
|
||||||
{{yield
|
{{#if (has-block)}}
|
||||||
(component 'consul-external-source' item=item _externalSource=externalSource)
|
{{yield
|
||||||
}}
|
(component 'consul-external-source' item=item _externalSource=externalSource)
|
||||||
{{else}}
|
}}
|
||||||
<span data-test-external-source={{externalSource}} class="consul-external-source source-{{externalSource}}">
|
{{else}}
|
||||||
{{#if (eq externalSource 'aws')}}
|
<span data-test-external-source={{externalSource}} class="consul-external-source source-{{externalSource}}">
|
||||||
<span>Synced from {{uppercase externalSource}}</span>
|
{{#if (eq externalSource 'aws')}}
|
||||||
{{else}}
|
<span>Registered via {{uppercase externalSource}}</span>
|
||||||
<span>Synced from {{capitalize externalSource}}</span>
|
{{else}}
|
||||||
{{/if}}
|
<span>Registered via {{capitalize externalSource}}</span>
|
||||||
</span>
|
{{/if}}
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/let}}
|
||||||
{{/let}}
|
{{/if}}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
{{yield}}
|
||||||
|
{{#if (gt items.length 0)}}
|
||||||
|
<ListCollection @cellHeight={{73}} @items={{items}} class="consul-service-instance-list" as |item index|>
|
||||||
|
<a href={{href-to routeName item.Service.Service item.Node.Node (or item.Service.ID item.Service.Service)}}>
|
||||||
|
{{item.Service.ID}}
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
<ConsulExternalSource @item={{item.Service}} as |ExternalSource|>
|
||||||
|
<li>
|
||||||
|
<ExternalSource />
|
||||||
|
</li>
|
||||||
|
</ConsulExternalSource>
|
||||||
|
{{#with (reject-by 'ServiceID' '' item.Checks) as |checks|}}
|
||||||
|
<li class={{service/instance-checks checks}}>
|
||||||
|
{{checks.length}} service checks
|
||||||
|
</li>
|
||||||
|
{{/with}}
|
||||||
|
{{#with (filter-by 'ServiceID' '' item.Checks) as |checks|}}
|
||||||
|
<li class={{service/instance-checks checks}}>
|
||||||
|
{{checks.length}} node checks
|
||||||
|
</li>
|
||||||
|
{{/with}}
|
||||||
|
{{#if (get proxies item.Service.ID)}}
|
||||||
|
<li class="proxy">
|
||||||
|
connected with proxy
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (gt item.Node.Node.length 0)}}
|
||||||
|
<li class="node">
|
||||||
|
<a href={{href-to 'dc.nodes.show' item.Node.Node}}>{{item.Node.Node}}</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
<li class="address" data-test-address>
|
||||||
|
{{#if (not-eq item.Service.Address '')}}
|
||||||
|
{{item.Service.Address}}:{{item.Service.Port}}
|
||||||
|
{{else}}
|
||||||
|
{{item.Node.Address}}:{{item.Service.Port}}
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
{{#if (gt item.Service.Tags.length 0)}}
|
||||||
|
<li>
|
||||||
|
<TagList @items={{item.Service.Tags}}/>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</ListCollection>
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from '@ember/component';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
tagName: '',
|
||||||
|
});
|
|
@ -1,14 +1,30 @@
|
||||||
{{yield}}
|
{{yield}}
|
||||||
{{#if (gt items.length 0)}}
|
{{#if (gt items.length 0)}}
|
||||||
<ListCollection @cellHeight={{73}} @items={{items}} class="consul-service-list" as |item index|>
|
<ListCollection @cellHeight={{73}} @items={{items}} class="consul-service-list" as |item index|>
|
||||||
<a href={{href-to routeName item.Name}}>
|
<a href={{href-to routeName item.Name}} class={{service/health-checks item}}>
|
||||||
<span class={{service/health-checks item}}></span>
|
{{item.Name}}
|
||||||
<span>
|
|
||||||
{{item.Name}}
|
|
||||||
</span>
|
|
||||||
<YieldSlot @name="metadata" @params={{block-params item}}>
|
|
||||||
{{yield}}
|
|
||||||
</YieldSlot>
|
|
||||||
</a>
|
</a>
|
||||||
|
<ul>
|
||||||
|
<ConsulExternalSource @item={{item}} as |ExternalSource|>
|
||||||
|
<li>
|
||||||
|
<ExternalSource />
|
||||||
|
</li>
|
||||||
|
</ConsulExternalSource>
|
||||||
|
{{#if (not-eq item.InstanceCount 0)}}
|
||||||
|
<li>
|
||||||
|
{{format-number item.InstanceCount}} {{pluralize item.InstanceCount 'Instance' without-count=true}}
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (get proxies item.Name)}}
|
||||||
|
<li class="proxy">
|
||||||
|
connected with proxy
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (gt items.Tags.length 0)}}
|
||||||
|
<li>
|
||||||
|
<TagList @items={{item.Tags}}/>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
</ListCollection>
|
</ListCollection>
|
||||||
{{/if}}
|
{{/if}}
|
|
@ -1,6 +1,5 @@
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import Slotted from 'block-slots';
|
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<EmberNativeScrollable @tagName="ul" @content-size={{_contentSize}} @scroll-left={{_scrollLeft}} @scroll-top={{_scrollTop}} @scrollChange={{action "scrollChange"}} @clientSizeChange={{action "clientSizeChange"}}>
|
<EmberNativeScrollable @tagName="ul" @content-size={{_contentSize}} @scroll-left={{_scrollLeft}} @scroll-top={{_scrollTop}} @scrollChange={{action "scrollChange"}} @clientSizeChange={{action "clientSizeChange"}}>
|
||||||
<li></li>
|
<li></li>
|
||||||
{{~#each _cells as |cell|~}}
|
{{~#each _cells as |cell|~}}
|
||||||
<li style={{{cell.style}}}>{{yield cell.item cell.index }}</li>
|
<li onclick={{action 'click'}} style={{{cell.style}}}>{{yield cell.item cell.index }}</li>
|
||||||
{{~/each~}}
|
{{~/each~}}
|
||||||
</EmberNativeScrollable>
|
</EmberNativeScrollable>
|
|
@ -45,4 +45,9 @@ export default Component.extend(WithResizing, {
|
||||||
this.updateScrollPosition();
|
this.updateScrollPosition();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
actions: {
|
||||||
|
click: function(e) {
|
||||||
|
return this.dom.clickFirstAnchor(e, 'li');
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,19 +21,19 @@ export default Controller.extend(WithEventSource, WithSearching, {
|
||||||
}),
|
}),
|
||||||
services: computed('items.[]', function() {
|
services: computed('items.[]', function() {
|
||||||
return this.items.filter(function(item) {
|
return this.items.filter(function(item) {
|
||||||
return item.Kind === 'consul';
|
return typeof item.Kind === 'undefined';
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
proxies: computed('items.[]', function() {
|
proxies: computed('items.[]', function() {
|
||||||
return this.items.filter(function(item) {
|
|
||||||
return item.Kind === 'connect-proxy';
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
withProxies: computed('proxies', function() {
|
|
||||||
const proxies = {};
|
const proxies = {};
|
||||||
this.proxies.forEach(item => {
|
this.items
|
||||||
proxies[item.Name.replace('-proxy', '')] = true;
|
.filter(function(item) {
|
||||||
});
|
return item.Kind === 'connect-proxy';
|
||||||
|
})
|
||||||
|
.forEach(item => {
|
||||||
|
proxies[item.Name.replace('-proxy', '')] = true;
|
||||||
|
});
|
||||||
|
|
||||||
return proxies;
|
return proxies;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { get, computed } from '@ember/object';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import WithSearching from 'consul-ui/mixins/with-searching';
|
import WithSearching from 'consul-ui/mixins/with-searching';
|
||||||
|
|
||||||
export default Controller.extend(WithSearching, {
|
export default Controller.extend(WithSearching, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
items: alias('item.Nodes'),
|
items: alias('item.Nodes'),
|
||||||
|
@ -23,4 +24,12 @@ export default Controller.extend(WithSearching, {
|
||||||
.add(this.items)
|
.add(this.items)
|
||||||
.search(get(this, this.searchParams.serviceInstance));
|
.search(get(this, this.searchParams.serviceInstance));
|
||||||
}),
|
}),
|
||||||
|
keyedProxies: computed('proxies.[]', function() {
|
||||||
|
const proxies = {};
|
||||||
|
this.proxies.forEach(item => {
|
||||||
|
proxies[item.ServiceProxy.DestinationServiceID] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return proxies;
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { helper } from '@ember/component/helper';
|
||||||
|
|
||||||
|
export function healthChecks([items], hash) {
|
||||||
|
let ChecksCritical = 0;
|
||||||
|
let ChecksWarning = 0;
|
||||||
|
let ChecksPassing = 0;
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
switch (item.Status) {
|
||||||
|
case 'critical':
|
||||||
|
ChecksCritical += 1;
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
ChecksWarning += 1;
|
||||||
|
break;
|
||||||
|
case 'passing':
|
||||||
|
ChecksPassing += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case ChecksCritical !== 0:
|
||||||
|
return 'critical';
|
||||||
|
case ChecksWarning !== 0:
|
||||||
|
return 'warning';
|
||||||
|
case ChecksPassing !== 0:
|
||||||
|
return 'passing';
|
||||||
|
default:
|
||||||
|
return 'empty';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default helper(healthChecks);
|
|
@ -7,6 +7,7 @@ export default Route.extend({
|
||||||
repo: service('repository/service'),
|
repo: service('repository/service'),
|
||||||
intentionRepo: service('repository/intention'),
|
intentionRepo: service('repository/intention'),
|
||||||
chainRepo: service('repository/discovery-chain'),
|
chainRepo: service('repository/discovery-chain'),
|
||||||
|
proxyRepo: service('repository/proxy'),
|
||||||
settings: service('settings'),
|
settings: service('settings'),
|
||||||
model: function(params, transition = {}) {
|
model: function(params, transition = {}) {
|
||||||
const dc = this.modelFor('dc').dc.Name;
|
const dc = this.modelFor('dc').dc.Name;
|
||||||
|
@ -16,12 +17,11 @@ export default Route.extend({
|
||||||
intentions: this.intentionRepo.findByService(params.name, dc, nspace),
|
intentions: this.intentionRepo.findByService(params.name, dc, nspace),
|
||||||
urls: this.settings.findBySlug('urls'),
|
urls: this.settings.findBySlug('urls'),
|
||||||
dc: dc,
|
dc: dc,
|
||||||
nspace: nspace,
|
|
||||||
}).then(model => {
|
}).then(model => {
|
||||||
return hash({
|
return ['connect-proxy', 'mesh-gateway'].includes(get(model, 'item.Service.Kind'))
|
||||||
chain: ['connect-proxy', 'mesh-gateway'].includes(get(model, 'item.Service.Kind'))
|
? model
|
||||||
? null
|
: hash({
|
||||||
: this.chainRepo.findBySlug(params.name, dc, nspace).catch(function(e) {
|
chain: this.chainRepo.findBySlug(params.name, dc, nspace).catch(function(e) {
|
||||||
const code = get(e, 'errors.firstObject.status');
|
const code = get(e, 'errors.firstObject.status');
|
||||||
// Currently we are specifically catching a 500, but we return null
|
// Currently we are specifically catching a 500, but we return null
|
||||||
// by default, so null for all errors.
|
// by default, so null for all errors.
|
||||||
|
@ -38,8 +38,9 @@ export default Route.extend({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
...model,
|
proxies: this.proxyRepo.findAllBySlug(params.name, dc, nspace),
|
||||||
});
|
...model,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setupController: function(controller, model) {
|
setupController: function(controller, model) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ $typo-size-100: 3.5rem;
|
||||||
$typo-size-200: 1.8rem;
|
$typo-size-200: 1.8rem;
|
||||||
$typo-size-300: 1.3rem;
|
$typo-size-300: 1.3rem;
|
||||||
$typo-size-400: 1.2rem;
|
$typo-size-400: 1.2rem;
|
||||||
|
$typo-size-450: 1.125rem;
|
||||||
$typo-size-500: 1rem;
|
$typo-size-500: 1rem;
|
||||||
$typo-size-600: 0.875rem;
|
$typo-size-600: 0.875rem;
|
||||||
$typo-size-700: 0.8125rem;
|
$typo-size-700: 0.8125rem;
|
||||||
|
|
|
@ -115,4 +115,11 @@ main {
|
||||||
#toolbar-toggle:checked + * {
|
#toolbar-toggle:checked + * {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
html.template-service.template-show #toolbar-toggle + * {
|
||||||
|
display: block;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
html.template-service.template-show .actions {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
%app-view-header dt {
|
%app-view-header dt {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
%app-view-header .title-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
%app-view-header .title-bar > h1 {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
%app-view-header .title-bar > span {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
/* units */
|
/* units */
|
||||||
%app-view {
|
%app-view {
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
@import './layout';
|
@import './layout';
|
||||||
@import './skin';
|
@import './skin';
|
||||||
%composite-row a:hover,
|
%composite-row:hover,
|
||||||
%composite-row a:focus,
|
%composite-row:focus,
|
||||||
%composite-row a:active {
|
%composite-row:active {
|
||||||
@extend %composite-row-intent;
|
@extend %composite-row-intent;
|
||||||
}
|
}
|
||||||
%composite-row > a > span {
|
%composite-row > a {
|
||||||
@extend %composite-row-header;
|
@extend %composite-row-header;
|
||||||
}
|
}
|
||||||
%composite-row > a > ul {
|
%composite-row > ul {
|
||||||
@extend %composite-row-detail;
|
@extend %composite-row-detail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
%composite-row a {
|
%composite-row {
|
||||||
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
@ -19,3 +20,6 @@
|
||||||
%composite-row-detail > li:not(:first-child) {
|
%composite-row-detail > li:not(:first-child) {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
%composite-row-detail .node::before {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
%composite-row {
|
%composite-row {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
|
||||||
%composite-row a {
|
|
||||||
border-top-color: $gray-200;
|
border-top-color: $gray-200;
|
||||||
border-bottom-color: $gray-200;
|
border-bottom-color: transparent;
|
||||||
border-right-color: transparent;
|
border-right-color: transparent;
|
||||||
border-left-color: transparent;
|
border-left-color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -17,3 +15,41 @@
|
||||||
%composite-row-detail {
|
%composite-row-detail {
|
||||||
color: $gray-500;
|
color: $gray-500;
|
||||||
}
|
}
|
||||||
|
%composite-row:last-child {
|
||||||
|
border-bottom-color: $gray-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Health Checks
|
||||||
|
%composite-row .passing::before {
|
||||||
|
@extend %with-check-circle-fill-color-mask, %as-pseudo;
|
||||||
|
background-color: $green-500;
|
||||||
|
}
|
||||||
|
%composite-row .warning::before {
|
||||||
|
@extend %with-alert-triangle-color-mask, %as-pseudo;
|
||||||
|
background-color: $orange-500;
|
||||||
|
}
|
||||||
|
%composite-row .critical::before {
|
||||||
|
@extend %with-cancel-square-fill-color-mask, %as-pseudo;
|
||||||
|
background-color: $red-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metadata
|
||||||
|
%composite-row .node a {
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
%composite-row .node a:hover {
|
||||||
|
color: $color-action;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
%composite-row .node::before {
|
||||||
|
@extend %with-git-commit-mask, %as-pseudo;
|
||||||
|
background-color: $gray-500;
|
||||||
|
}
|
||||||
|
%composite-row .address::before {
|
||||||
|
@extend %with-public-default-mask, %as-pseudo;
|
||||||
|
background-color: $gray-500;
|
||||||
|
}
|
||||||
|
%composite-row .proxy::before {
|
||||||
|
@extend %with-swap-horizontal-mask, %as-pseudo;
|
||||||
|
background-color: $gray-500;
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
.consul-external-source {
|
.consul-external-source {
|
||||||
background-color: $gray-100;
|
background-color: $gray-100;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
height: 16px;
|
|
||||||
line-height: 12px;
|
|
||||||
margin-top: 3px;
|
|
||||||
border-radius: $decor-radius-100;
|
border-radius: $decor-radius-100;
|
||||||
|
height: 18px;
|
||||||
|
line-height: 0.7rem;
|
||||||
}
|
}
|
||||||
.consul-external-source > span {
|
.consul-external-source > span {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -1px;
|
color: $gray-500;
|
||||||
}
|
}
|
||||||
.consul-external-source::before {
|
.consul-external-source::before {
|
||||||
font-size: 0.7em;
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
.consul-service-instance-list > ul {
|
||||||
|
@extend %consul-service-instance-list;
|
||||||
|
}
|
||||||
|
%consul-service-instance-list > li:not(:first-child) {
|
||||||
|
@extend %consul-service-instance-row;
|
||||||
|
}
|
||||||
|
%consul-service-instance-row {
|
||||||
|
@extend %composite-row;
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
@import './consul-service-list/index';
|
|
||||||
|
|
||||||
.consul-service-list > ul {
|
.consul-service-list > ul {
|
||||||
@extend %consul-service-list;
|
@extend %consul-service-list;
|
||||||
}
|
}
|
||||||
|
@ -9,3 +7,6 @@
|
||||||
%consul-service-row {
|
%consul-service-row {
|
||||||
@extend %composite-row;
|
@extend %composite-row;
|
||||||
}
|
}
|
||||||
|
%consul-service-row > ul {
|
||||||
|
margin-left: 26px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
@import './layout';
|
|
||||||
@import './skin';
|
|
|
@ -1,16 +0,0 @@
|
||||||
%consul-service-row > a > span:first-child {
|
|
||||||
margin-right: 4px;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
%consul-service-row > a > span:nth-child(3) {
|
|
||||||
margin-left: 4px;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
%consul-service-row > a > ul {
|
|
||||||
margin-left: 26px;
|
|
||||||
}
|
|
||||||
%consul-service-row .proxy::before {
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
%consul-service-row > a > span:nth-child(2) {
|
|
||||||
font-size: 1.125rem;
|
|
||||||
font-weight: $typo-weight-medium;
|
|
||||||
}
|
|
||||||
%consul-service-row > a > span:first-child,
|
|
||||||
%consul-service-row > a > span:nth-child(3) {
|
|
||||||
@extend %as-pseudo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Health Checks
|
|
||||||
%consul-service-row .empty {
|
|
||||||
@extend %with-minus-square-fill-mask;
|
|
||||||
background-color: #7c8797;
|
|
||||||
}
|
|
||||||
%consul-service-row .passing {
|
|
||||||
@extend %with-check-circle-fill-mask;
|
|
||||||
background-color: $green-500;
|
|
||||||
}
|
|
||||||
%consul-service-row .warning {
|
|
||||||
@extend %with-alert-triangle-mask;
|
|
||||||
background-color: $orange-500;
|
|
||||||
}
|
|
||||||
%consul-service-row .critical {
|
|
||||||
@extend %with-cancel-square-fill-mask;
|
|
||||||
background-color: $red-500;
|
|
||||||
}
|
|
||||||
%consul-service-row .proxy::before {
|
|
||||||
@extend %with-git-commit-mask, %as-pseudo;
|
|
||||||
background-color: $gray-500;
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
%filter-bar {
|
%filter-bar {
|
||||||
padding: 14px;
|
padding: 4px;
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
|
margin-bottom: 8px !important;
|
||||||
}
|
}
|
||||||
@media #{$--horizontal-filters} {
|
@media #{$--horizontal-filters} {
|
||||||
%filter-bar {
|
%filter-bar {
|
||||||
|
@ -19,6 +20,6 @@
|
||||||
}
|
}
|
||||||
@media #{$--lt-horizontal-filters} {
|
@media #{$--lt-horizontal-filters} {
|
||||||
%filter-bar > *:first-child {
|
%filter-bar > *:first-child {
|
||||||
margin-bottom: 12px;
|
margin: 2px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
@import './list-collection';
|
@import './list-collection';
|
||||||
@import './grid-collection';
|
@import './grid-collection';
|
||||||
@import './consul-service-list';
|
@import './consul-service-list';
|
||||||
|
@import './consul-service-instance-list';
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,13 @@ pre code,
|
||||||
}
|
}
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
/* composite row */
|
||||||
|
%composite-row-header {
|
||||||
|
font-size: $typo-size-450;
|
||||||
|
font-weight: $typo-weight-medium;
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
|
||||||
/* TODO: We have nothing else with a 500 */
|
/* TODO: We have nothing else with a 500 */
|
||||||
/* either make this the biggest %p or don't use it */
|
/* either make this the biggest %p or don't use it */
|
||||||
%app-view h1 em {
|
%app-view h1 em {
|
||||||
|
|
|
@ -14,21 +14,7 @@
|
||||||
<BlockSlot @name="content">
|
<BlockSlot @name="content">
|
||||||
<ChangeableSet @dispatcher={{searchable}}>
|
<ChangeableSet @dispatcher={{searchable}}>
|
||||||
<BlockSlot @name="set" as |filtered|>
|
<BlockSlot @name="set" as |filtered|>
|
||||||
<ConsulServiceList @routeName="dc.services.show" @items={{filtered}}>
|
<ConsulServiceList @routeName="dc.services.show" @items={{filtered}} @proxies={{proxies}}/> </BlockSlot>
|
||||||
<BlockSlot @name="metadata" as |item|>
|
|
||||||
<ul>
|
|
||||||
<ConsulExternalSource @item={{item}} as |ExternalSource|>
|
|
||||||
<li>
|
|
||||||
<ExternalSource />
|
|
||||||
</li>
|
|
||||||
</ConsulExternalSource>
|
|
||||||
<li>{{format-number item.InstanceCount}} {{pluralize item.InstanceCount 'Instance' without-count=true}}</li>
|
|
||||||
{{#if (get withProxies item.Name)}}<li class="proxy">connected with proxy</li>{{/if}}
|
|
||||||
<li><TagList @items={{item.Tags}}/></li>
|
|
||||||
</ul>
|
|
||||||
</BlockSlot>
|
|
||||||
</ConsulServiceList>
|
|
||||||
</BlockSlot>
|
|
||||||
<BlockSlot @name="empty">
|
<BlockSlot @name="empty">
|
||||||
<p>
|
<p>
|
||||||
There are no services.
|
There are no services.
|
||||||
|
|
|
@ -10,29 +10,21 @@
|
||||||
</ol>
|
</ol>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h1>
|
<div class="title-bar">
|
||||||
{{item.Service.Service}}
|
<h1>
|
||||||
{{#let (service/external-source item.Service) as |externalSource| }}
|
{{item.Service.Service}}
|
||||||
{{#if externalSource }}
|
</h1>
|
||||||
<span data-test-external-source={{externalSource}} style={{concat 'background-image: var(--' externalSource '-icon)'}} data-tooltip="Registered via {{externalSource}}">Registered via {{externalSource}}</span>
|
<ConsulExternalSource @item={{item.Service}} />
|
||||||
{{/if}}
|
</div>
|
||||||
{{/let}}
|
<TabNav @items={{
|
||||||
{{#if (eq item.Service.Kind 'connect-proxy')}}
|
compact
|
||||||
<span class="kind-proxy">Proxy</span>
|
(array
|
||||||
{{else if (eq item.Service.Kind 'mesh-gateway')}}
|
(hash label="Instances" href=(href-to "dc.services.show.instances") selected=(is-href "dc.services.show.instances"))
|
||||||
<span class="kind-proxy">Mesh Gateway</span>
|
(hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions"))
|
||||||
{{/if}}
|
|
||||||
</h1>
|
|
||||||
<label for="toolbar-toggle"></label>
|
|
||||||
<TabNav @items={{
|
|
||||||
compact
|
|
||||||
(array
|
|
||||||
(hash label="Instances" href=(href-to "dc.services.show.instances") selected=(is-href "dc.services.show.instances"))
|
|
||||||
(hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions"))
|
|
||||||
(if (not-eq chain) (hash label="Routing" href=(href-to "dc.services.show.routing") selected=(is-href "dc.services.show.routing")) '')
|
(if (not-eq chain) (hash label="Routing" href=(href-to "dc.services.show.routing") selected=(is-href "dc.services.show.routing")) '')
|
||||||
(hash label="Tags" href=(href-to "dc.services.show.tags") selected=(is-href "dc.services.show.tags"))
|
(hash label="Tags" href=(href-to "dc.services.show.tags") selected=(is-href "dc.services.show.tags"))
|
||||||
)
|
)
|
||||||
}}/>
|
}}/>
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="actions">
|
<BlockSlot @name="actions">
|
||||||
{{#if urls.service}}
|
{{#if urls.service}}
|
||||||
|
|
|
@ -8,48 +8,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<ChangeableSet @dispatcher={{searchable}}>
|
<ChangeableSet @dispatcher={{searchable}}>
|
||||||
<BlockSlot @name="set" as |filtered|>
|
<BlockSlot @name="set" as |filtered|>
|
||||||
<TabularCollection
|
<ConsulServiceInstanceList @routeName="dc.services.instance" @items={{filtered}} @proxies={{keyedProxies}}/>
|
||||||
data-test-instances
|
|
||||||
@items={{filtered}} as |item index|
|
|
||||||
>
|
|
||||||
<BlockSlot @name="header">
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Node</th>
|
|
||||||
<th>Address</th>
|
|
||||||
<th>Node Checks</th>
|
|
||||||
<th>Service Checks</th>
|
|
||||||
</BlockSlot>
|
|
||||||
<BlockSlot @name="row">
|
|
||||||
<td data-test-id={{item.Service.ID}}>
|
|
||||||
<a href={{href-to 'dc.services.instance' item.Service.Service item.Node.Node (or item.Service.ID item.Service.Service)}}>
|
|
||||||
{{#let (service/external-source item.Service) as |externalSource| }}
|
|
||||||
{{#if externalSource }}
|
|
||||||
<span data-test-external-source={{externalSource}} style={{concat 'background-image: var(--' externalSource '-icon)'}}></span>
|
|
||||||
{{else}}
|
|
||||||
<span></span>
|
|
||||||
{{/if}}
|
|
||||||
{{/let}}
|
|
||||||
{{or item.Service.ID item.Service.Service}}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td data-test-node>
|
|
||||||
<a href={{href-to 'dc.nodes.show' item.Node.Node}}>{{item.Node.Node}}</a>
|
|
||||||
</td>
|
|
||||||
<td data-test-address>
|
|
||||||
{{item.Service.Address}}:{{item.Service.Port}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{#with (reject-by 'ServiceID' '' item.Checks) as |checks|}}
|
|
||||||
<HealthcheckInfo @passing={{filter-by "Status" "passing" checks}} @warning={{filter-by "Status" "warning" checks}} @critical={{filter-by "Status" "critical" checks}} />
|
|
||||||
{{/with}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{#with (filter-by 'ServiceID' '' item.Checks) as |checks|}}
|
|
||||||
<HealthcheckInfo @passing={{filter-by "Status" "passing" checks}} @warning={{filter-by "Status" "warning" checks}} @critical={{filter-by "Status" "critical" checks}} />
|
|
||||||
{{/with}}
|
|
||||||
</td>
|
|
||||||
</BlockSlot>
|
|
||||||
</TabularCollection>
|
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
<BlockSlot @name="empty">
|
<BlockSlot @name="empty">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -14,7 +14,11 @@ const clickEvent = function($el) {
|
||||||
export default function(closest, click = clickEvent) {
|
export default function(closest, click = clickEvent) {
|
||||||
// TODO: Decide whether we should use `e` for ease
|
// TODO: Decide whether we should use `e` for ease
|
||||||
// or `target`/`el`
|
// or `target`/`el`
|
||||||
return function(e) {
|
// TODO: currently, using a string stopElement to tell the func
|
||||||
|
// where to stop looking and currenlty default is 'tr' because
|
||||||
|
// it's backwards compatible.
|
||||||
|
// Long-term this func shouldn't default to 'tr'
|
||||||
|
return function(e, stopElement = 'tr') {
|
||||||
// click on row functionality
|
// click on row functionality
|
||||||
// so if you click the actual row but not a link
|
// so if you click the actual row but not a link
|
||||||
// find the first link and fire that instead
|
// find the first link and fire that instead
|
||||||
|
@ -26,9 +30,7 @@ export default function(closest, click = clickEvent) {
|
||||||
case 'button':
|
case 'button':
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: why should this be restricted to a tr
|
const $a = closest(stopElement, e.target).querySelector('a');
|
||||||
// closest should probably be relaced with a finder function
|
|
||||||
const $a = closest('tr', e.target).querySelector('a');
|
|
||||||
if ($a) {
|
if ($a) {
|
||||||
click($a);
|
click($a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,26 +127,30 @@ Feature: components / catalog-filter
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
Scenario: Freetext filtering the service listing
|
Scenario: Freetext filtering the service listing
|
||||||
Given 1 datacenter model with the value "dc-1"
|
Given 1 datacenter model with the value "dc-1"
|
||||||
And 3 service models from yaml
|
And 6 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
|
||||||
Tags: ['one', 'two', 'three']
|
Tags: ['one', 'two', 'three']
|
||||||
ChecksPassing: 0
|
ChecksPassing: 0
|
||||||
ChecksWarning: 0
|
ChecksWarning: 0
|
||||||
ChecksCritical: 1
|
ChecksCritical: 1
|
||||||
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
|
||||||
Tags: ['two', 'three']
|
Tags: ['two', 'three']
|
||||||
ChecksPassing: 0
|
ChecksPassing: 0
|
||||||
ChecksWarning: 1
|
ChecksWarning: 1
|
||||||
ChecksCritical: 0
|
ChecksCritical: 0
|
||||||
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
|
||||||
Tags: ['three']
|
Tags: ['three']
|
||||||
ChecksPassing: 1
|
ChecksPassing: 1
|
||||||
ChecksWarning: 0
|
ChecksWarning: 0
|
||||||
ChecksCritical: 0
|
ChecksCritical: 0
|
||||||
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
|
|
||||||
---
|
---
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
---
|
---
|
||||||
|
|
|
@ -6,14 +6,17 @@ Feature: dc / error: Recovering from a dc 500 error
|
||||||
- dc-1
|
- dc-1
|
||||||
- dc-500
|
- dc-500
|
||||||
---
|
---
|
||||||
And 3 service models from yaml
|
And 6 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
And the url "/v1/internal/ui/services" responds with a 500 status
|
And the url "/v1/internal/ui/services" responds with a 500 status
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
|
|
|
@ -32,7 +32,7 @@ Feature: dc / list-blocking
|
||||||
When I visit the [Page] page for yaml
|
When I visit the [Page] page for yaml
|
||||||
---
|
---
|
||||||
dc: dc-1
|
dc: dc-1
|
||||||
service: service-0-proxy
|
service: service
|
||||||
---
|
---
|
||||||
Then the url should be /dc-1/[Url]
|
Then the url should be /dc-1/[Url]
|
||||||
And pause until I see 3 [Model] models
|
And pause until I see 3 [Model] models
|
||||||
|
@ -45,5 +45,5 @@ Feature: dc / list-blocking
|
||||||
Where:
|
Where:
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
| Page | Model | Url |
|
| Page | Model | Url |
|
||||||
| service | instance | services/service-0-proxy/instances |
|
| service | instance | services/service/instances |
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
|
|
@ -13,20 +13,26 @@ Feature: dc / nspaces / manage : Managing Namespaces
|
||||||
---
|
---
|
||||||
- dc-1
|
- dc-1
|
||||||
---
|
---
|
||||||
And 6 service models from yaml
|
And 12 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-3
|
- Name: Service-3
|
||||||
Kind: consul
|
- Name: Service-3-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-4
|
- Name: Service-4
|
||||||
Kind: consul
|
- Name: Service-4-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-5
|
- Name: Service-5
|
||||||
Kind: consul
|
- Name: Service-5-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
|
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
|
|
|
@ -6,21 +6,28 @@ Feature: dc / services / dc-switch : Switching Datacenters
|
||||||
- dc-1
|
- dc-1
|
||||||
- dc-2
|
- dc-2
|
||||||
---
|
---
|
||||||
And 6 service models from yaml
|
And 12 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-3
|
- Name: Service-3
|
||||||
Kind: consul
|
- Name: Service-3-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-4
|
- Name: Service-4
|
||||||
Kind: consul
|
- Name: Service-4-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-5
|
- Name: Service-5
|
||||||
Kind: consul
|
- Name: Service-5-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
|
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
---
|
---
|
||||||
dc: dc-1
|
dc: dc-1
|
||||||
|
|
|
@ -2,36 +2,42 @@
|
||||||
Feature: dc / services / index: List Services
|
Feature: dc / services / index: List Services
|
||||||
Scenario:
|
Scenario:
|
||||||
Given 1 datacenter model with the value "dc-1"
|
Given 1 datacenter model with the value "dc-1"
|
||||||
And 4 service models from yaml
|
And 10 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service 1
|
- Name: Service-0
|
||||||
Kind: consul
|
ExternalSources:
|
||||||
ExternalSources:
|
- consul
|
||||||
- consul
|
- Name: Service-0-proxy
|
||||||
- Name: Service 2
|
Kind: 'connect-proxy'
|
||||||
Kind: consul
|
- Name: Service-1
|
||||||
ExternalSources:
|
ExternalSources:
|
||||||
- nomad
|
- nomad
|
||||||
- Name: Service 3
|
- Name: Service-1-proxy
|
||||||
Kind: consul
|
Kind: 'connect-proxy'
|
||||||
ExternalSources:
|
- Name: Service-2
|
||||||
- terraform
|
ExternalSources:
|
||||||
- Name: Service 4
|
- terraform
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
ExternalSources:
|
Kind: 'connect-proxy'
|
||||||
- kubernetes
|
- Name: Service-3
|
||||||
- Name: Service 5
|
ExternalSources:
|
||||||
Kind: consul
|
- kubernetes
|
||||||
ExternalSources:
|
- Name: Service-3-proxy
|
||||||
- aws
|
Kind: 'connect-proxy'
|
||||||
|
- Name: Service-4
|
||||||
|
ExternalSources:
|
||||||
|
- aws
|
||||||
|
- Name: Service-4-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
|
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
---
|
---
|
||||||
dc: dc-1
|
dc: dc-1
|
||||||
---
|
---
|
||||||
Then the url should be /dc-1/services
|
Then the url should be /dc-1/services
|
||||||
And the title should be "Services - Consul"
|
And the title should be "Services - Consul"
|
||||||
Then I see 4 service models
|
Then I see 5 service models
|
||||||
And I see externalSource on the services like yaml
|
And I see externalSource on the services like yaml
|
||||||
---
|
---
|
||||||
- consul
|
- consul
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
Feature: dc / services / list blocking
|
Feature: dc / services / list blocking
|
||||||
Scenario: Viewing the listing pages for service
|
Scenario: Viewing the listing pages for service
|
||||||
Given 1 datacenter model with the value "dc-1"
|
Given 1 datacenter model with the value "dc-1"
|
||||||
Given 3 service models from yaml
|
And 6 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
And a network latency of 100
|
And a network latency of 100
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
Feature: dc / services / list
|
Feature: dc / services / list
|
||||||
Scenario: Listing service
|
Scenario: Listing service
|
||||||
Given 1 datacenter model with the value "dc-1"
|
Given 1 datacenter model with the value "dc-1"
|
||||||
And 3 service models from yaml
|
And 6 service models from yaml
|
||||||
---
|
---
|
||||||
- Name: Service-0
|
- Name: Service-0
|
||||||
Kind: consul
|
- Name: Service-0-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-1
|
- Name: Service-1
|
||||||
Kind: consul
|
- Name: Service-1-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
- Name: Service-2
|
- Name: Service-2
|
||||||
Kind: consul
|
- Name: Service-2-proxy
|
||||||
|
Kind: 'connect-proxy'
|
||||||
---
|
---
|
||||||
When I visit the services page for yaml
|
When I visit the services page for yaml
|
||||||
---
|
---
|
||||||
|
|
|
@ -6,7 +6,6 @@ Feature: dc / services / Show Routing for Service
|
||||||
And 1 service model from yaml
|
And 1 service model from yaml
|
||||||
---
|
---
|
||||||
- Service:
|
- Service:
|
||||||
Kind: consul
|
|
||||||
Name: service-0
|
Name: service-0
|
||||||
ID: service-0-with-id
|
ID: service-0-with-id
|
||||||
---
|
---
|
||||||
|
@ -17,31 +16,12 @@ Feature: dc / services / Show Routing for Service
|
||||||
---
|
---
|
||||||
And the title should be "service-0 - Consul"
|
And the title should be "service-0 - Consul"
|
||||||
And I see routing on the tabs
|
And I see routing on the tabs
|
||||||
Scenario: Given a service proxy, the Routing tab should not display
|
|
||||||
Given 1 datacenter model with the value "dc1"
|
|
||||||
And 1 node models
|
|
||||||
And 1 service model from yaml
|
|
||||||
---
|
|
||||||
- Service:
|
|
||||||
Kind: connect-proxy
|
|
||||||
Name: service-0-proxy
|
|
||||||
ID: service-0-proxy-with-id
|
|
||||||
---
|
|
||||||
When I visit the service page for yaml
|
|
||||||
---
|
|
||||||
dc: dc1
|
|
||||||
service: service-0-proxy
|
|
||||||
---
|
|
||||||
And the title should be "service-0-proxy - Consul"
|
|
||||||
And I don't see routing on the tabs
|
|
||||||
|
|
||||||
Scenario: Given connect is disabled, the Routing tab should not display or error
|
Scenario: Given connect is disabled, the Routing tab should not display or error
|
||||||
Given 1 datacenter model with the value "dc1"
|
Given 1 datacenter model with the value "dc1"
|
||||||
And 1 node models
|
And 1 node models
|
||||||
And 1 service model from yaml
|
And 1 service model from yaml
|
||||||
---
|
---
|
||||||
- Service:
|
- Service:
|
||||||
Kind: consul
|
|
||||||
Name: service-0
|
Name: service-0
|
||||||
ID: service-0-with-id
|
ID: service-0-with-id
|
||||||
---
|
---
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { module, skip } from 'qunit';
|
||||||
|
import { setupRenderingTest } from 'ember-qunit';
|
||||||
|
import { render } from '@ember/test-helpers';
|
||||||
|
import { hbs } from 'ember-cli-htmlbars';
|
||||||
|
|
||||||
|
module('Integration | Component | consul-service-instance-list', function(hooks) {
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
|
skip('it renders', async function(assert) {
|
||||||
|
// Set any properties with this.set('myProperty', 'value');
|
||||||
|
// Handle any actions with this.set('myAction', function(val) { ... });
|
||||||
|
|
||||||
|
await render(hbs`<ConsulServiceInstanceList />`);
|
||||||
|
|
||||||
|
assert.equal(this.element.textContent.trim(), '');
|
||||||
|
|
||||||
|
// Template block usage:
|
||||||
|
await render(hbs`
|
||||||
|
<ConsulServiceInstanceList>
|
||||||
|
template block text
|
||||||
|
</ConsulServiceInstanceList>
|
||||||
|
`);
|
||||||
|
|
||||||
|
assert.equal(this.element.textContent.trim(), 'template block text');
|
||||||
|
});
|
||||||
|
});
|
|
@ -78,16 +78,7 @@ export default {
|
||||||
services(visitable, clickable, text, attribute, collection, page, catalogFilter, radiogroup)
|
services(visitable, clickable, text, attribute, collection, page, catalogFilter, radiogroup)
|
||||||
),
|
),
|
||||||
service: create(
|
service: create(
|
||||||
service(
|
service(visitable, attribute, collection, text, consulIntentionList, catalogFilter, tabgroup)
|
||||||
visitable,
|
|
||||||
clickable,
|
|
||||||
attribute,
|
|
||||||
collection,
|
|
||||||
text,
|
|
||||||
consulIntentionList,
|
|
||||||
catalogFilter,
|
|
||||||
tabgroup
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
instance: create(instance(visitable, attribute, collection, text, tabgroup)),
|
instance: create(instance(visitable, attribute, collection, text, tabgroup)),
|
||||||
nodes: create(nodes(visitable, clickable, attribute, collection, catalogFilter)),
|
nodes: create(nodes(visitable, clickable, attribute, collection, catalogFilter)),
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
export default function(
|
export default function(visitable, attribute, collection, text, intentions, filter, tabs) {
|
||||||
visitable,
|
|
||||||
clickable,
|
|
||||||
attribute,
|
|
||||||
collection,
|
|
||||||
text,
|
|
||||||
intentions,
|
|
||||||
filter,
|
|
||||||
tabs
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
visit: visitable('/:dc/services/:service'),
|
visit: visitable('/:dc/services/:service'),
|
||||||
externalSource: attribute('data-test-external-source', 'h1 span'),
|
externalSource: attribute('data-test-external-source', '[data-test-external-source]', {
|
||||||
|
scope: '.title-bar',
|
||||||
|
}),
|
||||||
dashboardAnchor: {
|
dashboardAnchor: {
|
||||||
href: attribute('href', '[data-test-dashboard-anchor]'),
|
href: attribute('href', '[data-test-dashboard-anchor]'),
|
||||||
},
|
},
|
||||||
|
@ -18,7 +11,7 @@ export default function(
|
||||||
filter: filter,
|
filter: filter,
|
||||||
|
|
||||||
// TODO: These need to somehow move to subpages
|
// TODO: These need to somehow move to subpages
|
||||||
instances: collection('#instances [data-test-tabular-row]', {
|
instances: collection('.consul-service-instance-list > ul > li:not(:first-child)', {
|
||||||
address: text('[data-test-address]'),
|
address: text('[data-test-address]'),
|
||||||
}),
|
}),
|
||||||
intentions: intentions(),
|
intentions: intentions(),
|
||||||
|
|
|
@ -1211,9 +1211,9 @@
|
||||||
js-yaml "^3.13.1"
|
js-yaml "^3.13.1"
|
||||||
|
|
||||||
"@hashicorp/consul-api-double@^2.6.2":
|
"@hashicorp/consul-api-double@^2.6.2":
|
||||||
version "2.14.0"
|
version "2.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-2.14.0.tgz#ecef725fc22490011a671bc0a285a16013ca5e53"
|
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-2.14.1.tgz#c4beefa853368319324a6092fc4eb4371f9f8ffc"
|
||||||
integrity sha512-1rGMg/XSHR2ROr8a7OVEwOUy8UWuYdNUMijMxCuFHR201vDAGK9EDmkJCPF2PfYsDrcsiyb/0dxIL6Mba9p32Q==
|
integrity sha512-ZJtjkAuFHqcLTRjVaqx4NYnkZ17v5/DjaDhjH/kRVBx0gXcyKUEeMe34g69PfqgRo6ZYMVYMbSDq0JHTGcIShQ==
|
||||||
|
|
||||||
"@hashicorp/ember-cli-api-double@^3.0.2":
|
"@hashicorp/ember-cli-api-double@^3.0.2":
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
|
|
Loading…
Reference in New Issue