UI Release Merge (1.8-beta-2: ui-staging merge) (#7919)

* ui: Styling fixes (#7885)

* Move cellHeight to ListCollection js file

* Fix composite row border-top-color onHover state

* Add empty health check icon to CompositeRow styling

* ui: Slightly refactor %composite-rows and reuse ConsulServiceList component (#7886)

* ui: Move individual component types into a single %composite-list plus

1. Removes all out separate CSS components (that match HTML components)
to favour not having those separate for the moemnt at least
2. Reuses <ConsulServiceList /> component for Terminating Gateways >
Linked Services

* ui: Tweak breadcrumb spacing for '/' separator

* Fix up the tests i.e. services per tab so we can call them all services

* ui: Misc discovery chain fixes (#7892)

1. Look for a default splitter before looking for a default resolver in
order to route to.
2. Delay adding svg listeners until afterRender (fixes split tooltip)
3. Make router id's consistent for highlighting default routers in when
clicking the graph

* ui: If an error occurs on the server, surface it in the notification (#7893)

* ui: Delete old unused CSS (#7909)

This commit deletes CSS that we no longer use and we definitely will not
ever use.

We also dedup all of our imports here as it turns out SASS doesn't
dedupe imports. Strangely this increases out CSS weight by ~1kb instead
of reducing but we'd rather keep things deduped as that was the
intention

* ui: Redesign - Exposed Paths (#7912)

* Add new exposed paths icons to codebase

* Redesign Exposed Paths and create copy-button hover on Composite Row

* Refactor FeedbackDialog and CopyButton

* Change this.element to use `{{ref }}` now we don't have an element

We changed this to a tagless component with an eye to moving this to a
glimmer component, without spotting that this would also remove the
`this.element` property.

This adds an equivalent using the ref modifier.

Co-authored-by: John Cowen <jcowen@hashicorp.com>

* ui: Remove box-shadow and pointer cursor from metada list hover effect (#7914)

Co-authored-by: Kenia <19161242+kaxcode@users.noreply.github.com>
This commit is contained in:
John Cowen 2020-05-19 17:18:04 +01:00 committed by GitHub
parent 511343d2aa
commit 696aeb7840
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 433 additions and 551 deletions

View File

@ -6,11 +6,11 @@
{{#let (lowercase component.flashType) (lowercase flash.action) as |status type|}}
{{! flashes automatically ucfirst the type }}
<p data-notification class={{concat status ' notification-' type}}>
<p data-notification role="alert" class={{concat status ' notification-' type}}>
<strong>
{{capitalize status}}!
</strong>
{{#yield-slot name="notification" params=(block-params status type flash.item)}}
{{#yield-slot name="notification" params=(block-params status type flash.item flash.error)}}
{{yield}}
{{#if (eq type 'logout')}}
{{#if (eq status 'success') }}

View File

@ -1,5 +1,6 @@
<TabularCollection
data-test-metadata
class="consul-metadata-list"
@items={{items}} as |item index|
>
<BlockSlot @name="header">

View File

@ -1,6 +1,6 @@
{{yield}}
{{#if (gt items.length 0)}}
<ListCollection @cellHeight={{73}} @items={{items}} class="consul-service-instance-list" as |item index|>
<ListCollection @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>

View File

@ -1,10 +1,17 @@
{{yield}}
{{#if (gt items.length 0)}}
<ListCollection @cellHeight={{73}} @items={{items}} class="consul-service-list" as |item index|>
<ListCollection @items={{items}} class="consul-service-list" as |item index|>
<a data-test-service-name href={{href-to routeName item.Name}} class={{service/health-checks item}}>
{{item.Name}}
</a>
<ul>
{{#if (and nspace (env 'CONSUL_NSPACES_ENABLED'))}}
{{#if (not-eq item.Namespace nspace)}}
<li class="nspace">
{{item.Namespace}}
</li>
{{/if}}
{{/if}}
<ConsulKind @item={{item}} as |Kind|>
<li>
<Kind />

View File

@ -1,4 +1,4 @@
<FeedbackDialog @type="inline">
<FeedbackDialog class="copy-button" @type="inline">
<BlockSlot @name="action" as |success error|>
<Ref @target={{this}} @name="success" @value={{success}} />
<Ref @target={{this}} @name="error" @value={{error}} />

View File

@ -95,7 +95,7 @@
<path
id={{concat 'splitter:' splitter.Name '>' item.NextNode}}
class="split"
data-percentage={{item.Weight}}
data-percentage={{or item.Weight 0}}
d={{
svg-curve (hash
x=dest.x

View File

@ -1,13 +1,9 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { set, get, computed } from '@ember/object';
import { schedule } from '@ember/runloop';
import {
createRoute,
getSplitters,
getRoutes,
getResolvers,
} from 'consul-ui/utils/components/discovery-chain/index';
import { createRoute, getSplitters, getRoutes, getResolvers } from './utils';
export default Component.extend({
dom: service('dom'),
@ -67,13 +63,15 @@ export default Component.extend({
let nextNode;
const resolverID = `resolver:${this.chain.ServiceName}.${this.chain.Namespace}.${this.chain.Datacenter}`;
const splitterID = `splitter:${this.chain.ServiceName}.${this.chain.Namespace}`;
if (typeof this.chain.Nodes[resolverID] !== 'undefined') {
nextNode = resolverID;
} else if (typeof this.chain.Nodes[splitterID] !== 'undefined') {
// The default router should look for a splitter first,
// if there isn't one try the default resolver
if (typeof this.chain.Nodes[splitterID] !== 'undefined') {
nextNode = splitterID;
} else if (typeof this.chain.Nodes[resolverID] !== 'undefined') {
nextNode = resolverID;
}
if (typeof nextNode !== 'undefined') {
routes.push({
const route = {
Default: true,
ID: `route:${this.chain.ServiceName}`,
Name: this.chain.ServiceName,
@ -85,7 +83,8 @@ export default Component.extend({
},
},
NextNode: nextNode,
});
};
routes.push(createRoute(route, this.chain.ServiceName, this.dom.guid));
}
}
return routes;
@ -98,16 +97,14 @@ export default Component.extend({
get(this, 'chain.Nodes')
);
}),
graph: computed('splitters', 'routes', function() {
graph: computed('splitters', 'routes.[]', function() {
const graph = this.dataStructs.graph();
const router = this.chain.ServiceName;
this.splitters.forEach(item => {
item.Splits.forEach(splitter => {
graph.addLink(item.ID, splitter.NextNode);
});
});
this.routes.forEach((route, i) => {
route = createRoute(route, router, this.dom.guid);
graph.addLink(route.ID, route.NextNode);
});
return graph;
@ -146,7 +143,12 @@ export default Component.extend({
// the developer access to the mouse event therefore we just use JS to add our events
// revisit this post Octane
addPathListeners: function() {
schedule('afterRender', () => {
this._listeners.remove();
// as this is now afterRender, theoretically
// it could happen after the component is destroyed?
// watch for that incase
if (this.element && !this.isDestroyed) {
this._listeners.add(this.dom.document(), {
click: e => {
// all route/splitter/resolver components currently
@ -163,6 +165,8 @@ export default Component.extend({
mouseout: e => this.actions.hideSplit.apply(this, [e]),
});
});
}
});
// TODO: currently don't think there is a way to listen
// for an element being removed inside a component, possibly
// using IntersectionObserver. It's a tiny detail, but we just always

View File

@ -138,7 +138,7 @@ export const getResolvers = function(dc, nspace = 'default', targets = {}, nodes
export const createRoute = function(route, router, uid) {
return {
...route,
Default: typeof route.Definition.Match === 'undefined',
Default: route.Default || typeof route.Definition.Match === 'undefined',
ID: `route:${router}-${uid(route.Definition)}`,
};
};

View File

@ -1,3 +1,4 @@
<div {{ref this '$feedback'}} class="with-feedback" ...attributes>
{{yield}}
{{#if (eq state 'success') }}
<YieldSlot @name="success" @params={{block-params transition}}>{{yield}}</YieldSlot>
@ -7,3 +8,4 @@
{{#if (or permanent (eq state 'ready')) }}
<YieldSlot @name="action" @params={{block-params success error}}>{{yield}}{{message}}</YieldSlot>
{{/if}}
</div>

View File

@ -9,11 +9,11 @@ const STATE_ERROR = 'error';
export default Component.extend(SlotsMixin, {
wait: service('timeout'),
dom: service('dom'),
classNames: ['with-feedback'],
transition: '',
transitionClassName: 'feedback-dialog-out',
state: STATE_READY,
permanent: true,
tagName: '',
init: function() {
this._super(...arguments);
this.success = this._success.bind(this);
@ -31,7 +31,7 @@ export default Component.extend(SlotsMixin, {
.then(() => {
return new Promise(resolve => {
this.dom
.element(`.${className}`, this.element)
.element(`.${className}`, this.$feedback)
.addEventListener('transitionend', resolve);
});
})

View File

@ -10,6 +10,7 @@ export default Component.extend(WithResizing, {
tagName: 'div',
attributeBindings: ['style'],
height: 500,
cellHeight: 73,
style: style('getStyle'),
classNames: ['list-collection'],
init: function() {

View File

@ -17,6 +17,7 @@ export default Route.extend({
item: this.repo.findBySlug(params.name, dc, nspace),
urls: this.settings.findBySlug('urls'),
dc: dc,
nspace: nspace || 'default',
proxies: [],
})
.then(model => {

View File

@ -55,6 +55,7 @@ export default Service.extend({
...notificationDefaults(),
type: getStatus(TYPE_ERROR, e),
action: getAction(),
error: e,
});
}
})

View File

@ -1,5 +1,4 @@
@charset 'utf-8';
@import 'base/reset/index';
@import 'base/index';
@import 'variables/index';
@ -8,13 +7,13 @@
@import 'ember-power-select';
/**/
@import 'base/components/index';
@import 'components/index';
@import 'core/typography';
@import 'core/layout';
@import 'routes/dc/settings/index';
@import 'routes/dc/nodes/index';
@import 'routes/dc/services/index';
@import 'routes/dc/intention/index';
@import 'routes/dc/kv/index';
@import 'routes/dc/acls/index';

View File

@ -1,18 +0,0 @@
@import '../toggle-button/index';
@import '../menu-panel/index';
@import '../confirmation-alert/index';
@import './skin';
@import './layout';
%action-group > div {
@extend %menu-panel;
}
%action-group > label:first-of-type {
@extend %toggle-button;
}
%action-group .confirmation-alert {
@extend %confirmation-alert;
}
%action-group .type-delete {
@extend %internal-button-dangerous;
}

View File

@ -1,57 +0,0 @@
%action-group {
display: inline-block;
position: relative;
width: 30px;
height: 30px;
}
%action-group > div {
transition: min-height 150ms;
min-height: 0;
width: 192px;
}
%action-group .confirmation-alert {
position: absolute;
top: 0;
left: 100%;
width: 100%;
}
%action-group > label span {
display: none;
}
%action-group > label {
display: block;
height: 100%;
}
%action-group > label:last-of-type {
position: absolute;
width: 100%;
z-index: -1;
top: 0;
}
%action-group input[type='radio'],
%action-group input[type='radio'] ~ div,
%action-group input[type='radio'] ~ .with-confirmation > ul {
display: none;
}
%action-group input[type='radio']:checked ~ div,
%action-group input[type='radio']:checked ~ .with-confirmation > ul {
display: block;
}
/*TODO: If anything this is %toggle-button*/
%action-group input[type='radio']:checked ~ label[for='actions_close'] {
z-index: 1;
}
%action-group input[type='checkbox'] {
@extend %action-group-confirm-toggle;
}
%action-group-confirm-toggle {
display: none;
}
%action-group-confirm-toggle + div > ul,
%action-group-confirm-toggle + div > ul + div {
transition: transform 150ms;
}
%action-group-confirm-toggle:checked + div > ul,
%action-group-confirm-toggle:checked + div > ul + div {
transform: translateX(-100%);
}

View File

@ -1,12 +0,0 @@
%action-group input[type='radio']:checked + label:first-of-type {
/* frame-gray */
background-color: $gray-050;
}
%action-group > label {
cursor: pointer;
}
%action-group > label:first-of-type::after {
@extend %with-more-horizontal-icon;
@extend %as-pseudo;
opacity: 0.7;
}

View File

@ -7,7 +7,9 @@
display: inline-block;
}
%breadcrumb {
margin-left: 8px;
/* as the separator is a '/' the left margin needs */
/* to be different from the right in order to center it */
margin-left: 6px;
}
%breadcrumb::before {
margin-right: 8px;

View File

@ -0,0 +1,20 @@
@import './anchors/index';
@import './breadcrumbs/index';
@import './buttons/index';
@import './checkbox-group/index';
@import './confirmation-alert/index';
@import './display-toggle/index';
@import './form-elements/index';
@import './inline-alert/index';
@import './menu-panel/index';
@import './modal-dialog/index';
@import './notice/index';
@import './pill/index';
@import './popover-menu/index';
@import './radio-group/index';
@import './sliding-toggle/index';
@import './stats-card/index';
@import './table/index';
@import './tabs/index';
@import './toggle-button/index';
@import './tooltip/index';

View File

@ -1,7 +1,3 @@
@import '../display-toggle/index';
@import '../toggle-button/index';
@import '../menu-panel/index';
@import '../confirmation-alert/index';
@import './skin';
@import './layout';
%with-popover-menu > input {

View File

@ -1,7 +1,9 @@
%with-popover-menu {
position: relative;
}
%with-popover-menu > [type='checkbox'] {
@extend %popover-menu;
}
%more-popover-menu {
@extend %display-toggle-siblings;
}

View File

@ -14,6 +14,3 @@
font-size: 0;
background-color: $transparent;
}
%popover-menu + label > * {
@extend %split-button, %sort-button;
}

View File

@ -1 +0,0 @@
@import './skin';

View File

@ -1,17 +0,0 @@
%sort-control input {
display: none;
}
%sort-control label {
@extend %user-select-none;
cursor: pointer;
}
%sort-control input[type='checkbox'] + label::after {
@extend %as-pseudo;
opacity: 0.7;
}
%sort-control input[type='checkbox'] + label::after {
@extend %with-arrow-down-icon;
}
%sort-control input[type='checkbox']:checked + label::after {
@extend %with-arrow-up-icon;
}

View File

@ -126,10 +126,13 @@ $notification-outline-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0
$outline-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 4c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2v16c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V4zm2 0v16h14V4H5zm5.996 7.006v2h3v-2h-3zM15 15v2h-4v-2h4zm-4-6h6V7h-6v2zm-4 3.006a1 1 0 0 1 .998-.998 1 1 0 0 1 .998.998 1 1 0 0 1-.998.998A1 1 0 0 1 7 12.006zM7.998 15a1 1 0 0 0-.998.998 1 1 0 0 0 .998.998 1 1 0 0 0 .998-.998A1 1 0 0 0 7.998 15zM7 7.998A1 1 0 0 1 7.998 7a1 1 0 0 1 .998.998 1 1 0 0 1-.998.998A1 1 0 0 1 7 7.998z" fill="%23000"/></svg>');
$page-outline-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 2c1.05 0 1.918.82 1.994 1.851L21 4v16c0 1.05-.82 1.918-1.851 1.994L19 22H5c-1.05 0-1.918-.82-1.994-1.851L3 20V4c0-1.05.82-1.918 1.851-1.994L5 2h14zm0 2H5v16h14V4zM7.952 15.004a1 1 0 0 1 .998.998 1 1 0 0 1-.998.998 1 1 0 0 1-.998-.998 1 1 0 0 1 .998-.998zM15.944 15v2h-6v-2h6zm-2-4v2h-4v-2h4zm-5.992 0a1 1 0 0 1 .998.998 1 1 0 0 1-.998.998 1 1 0 0 1-.998-.998A1 1 0 0 1 7.952 11zm8.992-4v2h-7V7h7zm-8.992.004a1 1 0 0 1 .998.998A1 1 0 0 1 7.952 9a1 1 0 0 1-.998-.998 1 1 0 0 1 .998-.998z" fill="%23000"/></svg>');
$partner-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.478 8.41l2.556-2.339H8.341L5 8.075H2v6.99h4.572l2.441 2.184c.913.779 1.473.779 2.028.54.61-.262.959-.699.959-.699l.613.517c.587.54 1.537.294 2.027-.192.745-.741.724-1.188.724-1.188l.517.43c.39.233.988-.025 1.187-.228.44-.446.54-.944.064-1.395l-4.124-3.669c-.545-.471-.562-.464-1.008-.094l-.491.445c-1.02.765-2.34.775-3.168-.128a2.25 2.25 0 0 1 .137-3.177zm7.813-2.045l-.707-.294H12.9a1 1 0 0 0-.675.263L9.153 9.145l-.005.006-.004.007a1.242 1.242 0 0 0-.066 1.749c.397.434 1.231.55 1.753.084l.007-.003.006-.003 2.497-2.287a.5.5 0 1 1 .675.737l-.816.747 4.797 4.216H22V8.07h-4.003L16.29 6.365z" fill="%23000"/></svg>');
$path-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18.8532 7.87695C20.0944 7.50942 21 6.36046 21 5C21 3.34315 19.6569 2 18 2C16.3431 2 15 3.34315 15 5C15 6.25039 15.765 7.3221 16.8524 7.77269L16.602 10.0262C15.9316 10.115 15.3311 10.4253 14.8763 10.881L8.97505 8.6113C8.78445 7.13807 7.52513 6 6 6C4.34315 6 3 7.34315 3 9C3 10.3062 3.83481 11.4175 5 11.8293V16.1707C3.83481 16.5825 3 17.6938 3 19C3 20.6569 4.34315 22 6 22C7.65685 22 9 20.6569 9 19C9 17.6938 8.16519 16.5825 7 16.1707V11.8293C7.64469 11.6014 8.18824 11.1595 8.54521 10.5888L14.0155 12.6928C14.0053 12.7938 14 12.8963 14 13C14 14.6569 15.3431 16 17 16C18.6569 16 20 14.6569 20 13C20 11.9179 19.4271 10.9697 18.5682 10.442L18.8532 7.87695ZM18 6C18.5523 6 19 5.55228 19 5C19 4.44772 18.5523 4 18 4C17.4477 4 17 4.44772 17 5C17 5.55228 17.4477 6 18 6ZM7 9C7 9.55228 6.55228 10 6 10C5.44772 10 5 9.55228 5 9C5 8.44772 5.44772 8 6 8C6.55228 8 7 8.44772 7 9Z" fill="%23000"/></svg>');
$plus-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" fill="%23000"/></svg>');
$plus-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" fill="%23000"/></svg>');
$plus-plain-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" fill="%23000"/></svg>');
$plus-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" fill="%23000"/></svg>');
$port-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.35 3.00001C8.35 2.08874 9.08873 1.35001 10 1.35001H14C14.9113 1.35001 15.65 2.08874 15.65 3.00001V7.00001C15.65 7.91128 14.9113 8.65001 14 8.65001H12.5834C12.5836 8.66071 12.5836 8.67147 12.5833 8.68229L12.5329 10.7L21.35 10.7C21.709 10.7 22 10.991 22 11.35C22 11.709 21.709 12 21.35 12H17.5826C17.594 12.0482 17.6 12.0984 17.6 12.15V14.35H19C19.9113 14.35 20.65 15.0887 20.65 16V20C20.65 20.9113 19.9113 21.65 19 21.65H15C14.0887 21.65 13.35 20.9113 13.35 20V16C13.35 15.0887 14.0887 14.35 15 14.35H16.3V12.15C16.3 12.0984 16.306 12.0482 16.3174 12H12.012C11.96 12.012 11.9056 12.0176 11.8498 12.0162C11.8053 12.0151 11.762 12.0096 11.7202 12H7.58261C7.59398 12.0482 7.6 12.0984 7.6 12.15V14.35H9C9.91127 14.35 10.65 15.0887 10.65 16V20C10.65 20.9113 9.91127 21.65 9 21.65H5C4.08873 21.65 3.35 20.9113 3.35 20V16C3.35 15.0887 4.08873 14.35 5 14.35H6.3V12.15C6.3 12.0984 6.30602 12.0482 6.31739 12H2.65C2.29102 12 2 11.709 2 11.35C2 10.991 2.29101 10.7 2.65 10.7L11.2325 10.7L11.2838 8.65001H10C9.08873 8.65001 8.35 7.91128 8.35 7.00001V3.00001ZM10 2.65001C9.8067 2.65001 9.65 2.80671 9.65 3.00001V7.00001C9.65 7.19331 9.8067 7.35001 10 7.35001H14C14.1933 7.35001 14.35 7.19331 14.35 7.00001V3.00001C14.35 2.80671 14.1933 2.65001 14 2.65001H10ZM5 15.65C4.8067 15.65 4.65 15.8067 4.65 16V20C4.65 20.1933 4.8067 20.35 5 20.35H9C9.1933 20.35 9.35 20.1933 9.35 20V16C9.35 15.8067 9.1933 15.65 9 15.65H5ZM14.65 16C14.65 15.8067 14.8067 15.65 15 15.65H19C19.1933 15.65 19.35 15.8067 19.35 16V20C19.35 20.1933 19.1933 20.35 19 20.35H15C14.8067 20.35 14.65 20.1933 14.65 20V16Z" fill="%236F7682"/></svg>');
$protocol-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM11.8104 19.9978C11.9269 19.8258 12.0639 19.6117 12.212 19.3572C12.5111 18.8431 12.8544 18.1657 13.1663 17.3382C12.9879 17.3233 12.8084 17.3101 12.6278 17.2987C11.9536 17.2562 11.2715 17.2398 10.5929 17.2563C10.8669 18.1335 11.2168 19.0463 11.6554 19.9927C11.7069 19.9949 11.7586 19.9966 11.8104 19.9978ZM9.897 19.7207C9.55842 18.9089 9.28019 18.1195 9.05511 17.354C8.53381 17.4089 8.01993 17.4871 7.51892 17.5915C7.73118 18.0727 7.97418 18.5653 8.25086 19.0689C8.7684 19.344 9.31972 19.5638 9.897 19.7207ZM5.45938 16.6077C5.48104 16.6001 5.50273 16.5925 5.52445 16.585C4.46623 13.3833 4.62347 10.6454 5.21707 8.50224C5.09245 8.46738 4.97167 8.43251 4.85496 8.39777C4.30807 9.4804 4 10.7042 4 12C4 13.7156 4.54003 15.3051 5.45938 16.6077ZM5.69311 7.07772C5.69614 7.07856 5.69918 7.07939 5.70221 7.08023C5.70623 7.07039 5.71025 7.06056 5.71427 7.05076C5.7072 7.05973 5.70015 7.06872 5.69311 7.07772ZM8.96894 4.59417C8.93129 4.63447 8.8765 4.69478 8.80813 4.77455C8.66145 4.94568 8.45292 5.20563 8.21744 5.5491C7.8904 6.02611 7.51351 6.66107 7.17773 7.44022C7.68086 7.54828 8.21954 7.64986 8.78391 7.73875L8.79848 7.68326C9.18148 6.23496 9.70589 5.06597 10.1744 4.20925C9.75921 4.30615 9.35646 4.43539 8.96894 4.59417ZM12.0548 4.00018C11.938 4.17254 11.8005 4.38729 11.6519 4.64277C11.2113 5.40008 10.6747 6.5116 10.2841 7.93527C10.6414 7.97247 11.0048 8.00331 11.3722 8.02649C12.1215 8.07374 12.8805 8.08863 13.6336 8.06207C13.3315 6.79045 12.8705 5.435 12.2062 4.00261C12.1559 4.00133 12.1054 4.00052 12.0548 4.00018ZM15.0311 19.4058C14.5954 19.5843 14.1406 19.7255 13.6705 19.8253C14.0078 19.2125 14.3757 18.4365 14.6998 17.5098C15.227 17.5833 15.7354 17.6688 16.2175 17.7617C16.0682 18.019 15.9209 18.2491 15.7826 18.4509C15.5471 18.7944 15.3386 19.0543 15.1919 19.2255C15.1235 19.3052 15.0687 19.3655 15.0311 19.4058ZM18.4508 16.7325C19.4247 15.4072 20 13.7708 20 12C20 10.7332 19.7056 9.53525 19.1814 8.47072C19.0626 8.52056 18.9428 8.56843 18.8221 8.61438C19.5339 11.495 19.2703 13.9558 18.6676 15.8898C18.5781 16.1768 18.4814 16.4516 18.3797 16.7138C18.4035 16.72 18.4272 16.7262 18.4508 16.7325ZM15.7491 4.93109C16.2637 5.8677 16.6617 6.76614 16.9623 7.6241C16.3749 7.76946 15.7668 7.87585 15.147 7.94868C14.8822 6.77294 14.493 5.53469 13.9502 4.23938C14.5831 4.39792 15.1861 4.63186 15.7491 4.93109ZM6.67301 8.86539C7.23389 8.98964 7.83778 9.10647 8.47251 9.20809C8.16114 11.101 8.13055 13.3457 8.68042 15.8864C8.10403 15.9541 7.53135 16.0491 6.96921 16.176C5.97706 13.2159 6.14482 10.7469 6.67301 8.86539ZM9.9596 9.4091C9.66322 11.1785 9.63171 13.3152 10.1908 15.7687C11.047 15.7336 11.8982 15.7497 12.7222 15.8017C13.0281 15.8209 13.3313 15.8453 13.6308 15.8739C14.0706 14.1822 14.3018 12.0541 13.9234 9.55152C13.0288 9.59288 12.1384 9.57779 11.2778 9.52351C10.8317 9.49538 10.3912 9.45656 9.9596 9.4091ZM16.9025 16.3689C16.3454 16.2539 15.7517 16.1474 15.1319 16.0564C15.5821 14.232 15.7965 12.0001 15.4213 9.42649C16.0858 9.3447 16.7447 9.22621 17.3877 9.06387C18.0053 11.6354 17.7519 13.7864 17.2355 15.4435C17.1337 15.7703 17.0212 16.0789 16.9025 16.3689Z" fill="%236F7682"/></svg>');
$provider-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm.97 4.778l2.993-1.728a7.946 7.946 0 0 0-2.993-.992v2.72zm-1.94 1.12v-3.84a7.946 7.946 0 0 0-3.025 1.01v4.576l3.025-1.746zm-4.965 2.866V6.637A7.97 7.97 0 0 0 4 11.957l2.065-1.193zm0 2.24v4.359a7.987 7.987 0 0 1-1.801-3.319l1.801-1.04zm1.94 3.423v-4.543l3.025-1.746v4.543l-3.025 1.746zm4.965-2.866V9.018l3.065-1.77v4.543l-3.065 1.77zm5.005-2.89V6.682a7.99 7.99 0 0 1 1.688 3.015l-1.688.974zm-5.005 5.13l3.065-1.77v4.877c-.92.54-1.958.9-3.065 1.034V15.8zm5.005-2.89v4.407a7.97 7.97 0 0 0 2.021-5.574l-2.02 1.167zm-6.945 4.01l-3.25 1.876a7.948 7.948 0 0 0 3.25 1.145V16.92z" fill="%23000"/></svg>');
$public-default-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" fill="%23000"/></svg>');
$public-locked-svg: url('data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 3v-.5a2.5 2.5 0 0 0-5 0V3c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V3zm-2.28 8c.04.33.08.66.08 1 0 2.08-.8 3.97-2.1 5.39-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H6v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2V2.46c-.95-.3-1.95-.46-3-.46C4.48 2 0 6.48 0 12s4.48 10 10 10 10-4.48 10-10c0-.34-.02-.67-.05-1h-2.03zM9 19.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L7 15v1c0 1.1.9 2 2 2v1.93z" fill="%23000"/></svg>');

View File

@ -1268,6 +1268,16 @@
mask-image: $partner-svg;
}
%with-path-icon {
@extend %with-icon;
background-image: $path-svg;
}
%with-path-mask {
@extend %with-mask;
-webkit-mask-image: $path-svg;
mask-image: $path-svg;
}
%with-plus-circle-fill-icon {
@extend %with-icon;
background-image: $plus-circle-fill-svg;
@ -1308,6 +1318,26 @@
mask-image: $plus-square-fill-svg;
}
%with-port-icon {
@extend %with-icon;
background-image: $port-svg;
}
%with-port-mask {
@extend %with-mask;
-webkit-mask-image: $port-svg;
mask-image: $port-svg;
}
%with-protocol-icon {
@extend %with-icon;
background-image: $protocol-svg;
}
%with-protocol-mask {
@extend %with-mask;
-webkit-mask-image: $protocol-svg;
mask-image: $protocol-svg;
}
%with-provider-icon {
@extend %with-icon;
background-image: $provider-svg;

View File

@ -1,4 +1,3 @@
@import '../base/components/anchors/index';
a[rel*='external']::after {
@extend %with-exit-icon, %as-pseudo;
margin-left: 8px;

View File

@ -1,8 +1,4 @@
@import './app-view/index';
@import './filter-bar/index';
@import '../base/components/buttons/index';
@import '../base/components/popover-menu/index';
%app-view-actions label + div {
/* We need this extra to allow tooltips to show */

View File

@ -1,4 +1,3 @@
@import '../base/components/breadcrumbs/index';
main header nav:first-child {
position: absolute;
top: -38px;

View File

@ -1,4 +1,3 @@
@import '../base/components/buttons/index';
button[type='submit'],
a.type-create {
@extend %primary-button;

View File

@ -0,0 +1,28 @@
@import './composite-row/index';
.proxy-upstreams > ul > li,
.proxy-exposed-paths > ul > li,
.list-collection > ul > li:not(:first-child) {
@extend %composite-row;
}
/* hoverable rows */
.consul-upstream-list > ul > li:not(:first-child),
.consul-gateway-service-list > ul > li:not(:first-child),
.consul-service-instance-list > ul > li:not(:first-child),
.consul-service-list > ul > li:not(:first-child) {
@extend %with-composite-row-intent;
}
.proxy-exposed-paths tbody tr {
cursor: default !important;
}
.proxy-exposed-paths tbody tr:hover {
box-shadow: none !important;
}
.proxy-exposed-paths tbody tr .combined-address button:hover {
// In this case we do not need a background on the icon
background-color: $transparent !important;
}
.proxy-upstreams > ul,
.proxy-exposed-paths > ul {
border-top: 1px solid $gray-200;
}

View File

@ -25,13 +25,25 @@
%composite-row-detail .node::before {
margin-top: 2px;
}
// In this case we do not need a background on the icon
%composite-row-detail .port button {
// Copy Button with Feedback
%composite-row .copy-button button {
padding: 0 !important;
margin-top: 1px !important;
margin: 0 !important;
}
%composite-row-detail .port button:hover {
background-color: transparent !important;
%composite-row-detail .copy-button {
margin-left: 4px;
}
%composite-row-header .copy-button {
top: 3px;
}
%composite-row-header .copy-button,
%composite-row-detail .copy-button {
display: none;
}
%composite-row-header:hover .copy-button,
%composite-row-detail:hover .copy-button {
display: inline-flex;
}
// Tooltip

View File

@ -8,6 +8,7 @@
%composite-row-intent {
border-color: $gray-200;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-top-color: $transparent;
cursor: pointer;
}
%composite-row-header {
@ -30,6 +31,10 @@
@extend %with-cancel-square-fill-color-mask, %as-pseudo;
background-color: $red-500;
}
%composite-row .empty::before {
@extend %with-minus-square-fill-color-mask, %as-pseudo;
background-color: $gray-500;
}
// Metadata
%composite-row .node a {
@ -59,3 +64,20 @@
@extend %with-folder-outline-mask, %as-pseudo;
background-color: $gray-500;
}
%composite-row-detail .path::before {
@extend %with-path-mask, %as-pseudo;
background-color: $gray-500;
}
%composite-row-detail .port::before {
@extend %with-port-mask, %as-pseudo;
background-color: $gray-500;
}
%composite-row-detail .protocol::before {
@extend %with-protocol-mask, %as-pseudo;
background-color: $gray-500;
}
// In this case we do not need a background on the icon
%composite-row .combined-address .copy-button button:hover,
%composite-row-detail .port .copy-button button:hover {
background-color: transparent !important;
}

View File

@ -1,9 +0,0 @@
@import './consul-intention-list/index';
.consul-intention-list {
@extend %consul-intention-list;
}
@media #{$--lt-wide-table} {
%consul-intention-list tr > :nth-last-child(2) {
display: none;
}
}

View File

@ -1,5 +0,0 @@
@import './skin';
@import './layout';
%consul-intention-list td.destination {
@extend %tbody-th;
}

View File

@ -1,10 +0,0 @@
%consul-intention-list td strong {
visibility: hidden;
}
%consul-intention-list td.intent-allow strong::before {
@extend %with-arrow-right-color-icon, %as-pseudo;
background-size: 24px;
}
%consul-intention-list td.intent-deny strong::before {
@extend %with-deny-color-icon, %as-pseudo;
}

View File

@ -1,9 +0,0 @@
.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, %with-composite-row-intent;
}

View File

@ -1,12 +0,0 @@
.consul-service-list > ul {
@extend %consul-service-list;
}
%consul-service-list > li:not(:first-child) {
@extend %consul-service-row;
}
%consul-service-row {
@extend %composite-row, %with-composite-row-intent;
}
%consul-service-row > ul {
margin-left: 26px;
}

View File

@ -1,4 +1,3 @@
@import './card/index';
@import './discovery-chain/index';
.discovery-chain {
@extend %discovery-chain;

View File

@ -1,10 +1,3 @@
/*TODO: This remains a mix of form-elements */
/* form-elements should probably be a collection of these */
@import '../base/components/inline-alert/index';
@import '../base/components/form-elements/index';
@import '../base/components/sliding-toggle/index';
@import '../base/components/radio-group/index';
@import '../base/components/checkbox-group/index';
label span {
@extend %user-select-none;
}

View File

@ -1,4 +1,3 @@
@import '../base/components/stats-card/index';
.healthchecked-resource > div {
@extend %stats-card;
}

View File

@ -1,3 +1,4 @@
@import './card/index';
@import './form-elements';
@import './breadcrumbs';
@import './anchors';
@ -8,14 +9,12 @@
@import './tabs';
@import './pill';
@import './table';
@import './form-elements';
@import './tooltip';
@import './tag-list';
@import './healthcheck-output';
@import './healthcheck-info';
@import './healthchecked-resource';
@import './freetext-filter';
@import './phrase-editor';
@import './filter-bar';
@import './tomography-graph';
@import './flash-message';
@ -26,17 +25,13 @@
@import './auth-form';
@import './auth-modal';
@import './notice';
@import './sort-control';
@import './oidc-select';
@import './discovery-chain';
@import './consul-intention-list';
@import './empty-state';
@import './tabular-details';
@import './tabular-collection';
@import './list-collection';
@import './grid-collection';
@import './consul-service-list';
@import './consul-service-instance-list';
@import './popover-select';
/**/

View File

@ -1,4 +1,3 @@
@import '../base/components/modal-dialog/index';
[role='dialog'] {
@extend %modal-dialog;
}

View File

@ -1,4 +1,3 @@
@import '../base/components/notice/index';
%notice {
margin-bottom: 1em;
}

View File

@ -1,2 +0,0 @@
@import './skin';
@import './layout';

View File

@ -1,50 +0,0 @@
%phrase-editor {
display: flex;
margin-top: 14px;
margin-bottom: 5px;
}
%phrase-editor ul {
overflow: hidden;
}
%phrase-editor li {
@extend %pill;
float: left;
margin-right: 4px;
}
%phrase-editor span {
display: none;
}
%phrase-editor label {
flex-grow: 1;
}
%phrase-editor input {
width: 100%;
height: 33px;
padding: 8px 10px;
box-sizing: border-box;
}
%phrase-editor button::before {
// TODO: Look at why this isn't automatically centering
vertical-align: inherit !important;
}
@media #{$--horizontal-selects} {
%phrase-editor {
margin-top: 14px;
}
%phrase-editor ul {
padding-top: 5px;
padding-left: 5px;
}
%phrase-editor input {
padding-left: 3px;
}
}
@media #{$--lt-horizontal-selects} {
%phrase-editor {
margin-top: 9px;
}
%phrase-editor label {
display: block;
margin-top: 5px;
}
}

View File

@ -1,18 +0,0 @@
@media #{$--horizontal-selects} {
%phrase-editor {
border: 1px solid $gray-300;
border-radius: 2px;
}
%phrase-editor input:focus {
outline: 0;
}
}
@media #{$--lt-horizontal-selects} {
%phrase-editor label {
border: 1px solid $gray-300;
border-radius: 2px;
}
}
%phrase-editor input {
-webkit-appearance: none;
}

View File

@ -1,4 +1,3 @@
@import '../base/components/pill/index';
td strong {
@extend %pill;
margin-right: 3px;

View File

@ -1,11 +1,13 @@
.popover-select {
@extend %popover-select;
}
%popover-select > [type='checkbox'] {
@extend %popover-menu;
%popover-select {
@extend %with-popover-menu;
}
%popover-select label > * {
@extend %split-button, %sort-button;
}
%popover-select {
position: relative;
z-index: 3;
padding-left: 12px;
height: 100%;

View File

@ -1,4 +0,0 @@
@import '../base/components/sort-control/index';
.sort-control {
@extend %sort-control;
}

View File

@ -1,5 +1,3 @@
@import '../base/components/table/index';
@import '../base/components/popover-menu/index';
%main-content table {
@extend %table;
}
@ -60,16 +58,35 @@ td.folder::before {
margin-top: 1px;
margin-right: 5px;
}
td.destination {
@extend %tbody-th;
}
td.intent-allow strong,
td.intent-deny strong {
visibility: hidden;
}
td.intent-allow strong::before {
@extend %with-arrow-right-color-icon, %as-pseudo;
background-size: 24px;
}
td.intent-deny strong::before {
@extend %with-deny-color-icon, %as-pseudo;
}
table:not(.sessions) tbody tr {
cursor: pointer;
}
table:not(.sessions) td:first-child {
padding: 0;
}
table:not(.sessions) tbody tr:hover {
box-shadow: $decor-elevation-300;
}
table.consul-metadata-list tbody tr {
cursor: default;
}
table.consul-metadata-list tbody tr:hover {
box-shadow: none;
}
/* Header Tooltips/Icon*/
th {
overflow: visible;
@ -111,4 +128,7 @@ th span em {
html.template-node.template-show #lock-sessions td:last-child {
padding: 0;
}
.consul-intention-list tr > :nth-last-child(2) {
display: none;
}
}

View File

@ -1,4 +1,3 @@
@import '../base/components/tabs/index';
.tab-nav {
@extend %tab-nav;
}

View File

@ -1,4 +1,3 @@
@import '../base/components/tooltip/index';
%app-view h1 span[data-tooltip] {
@extend %with-pseudo-tooltip;
text-indent: -9000px;

View File

@ -1,31 +0,0 @@
// Services - Linked Services tab
// TODO - move this into composite-row
.consul-gateway-services-list > ul {
@extend %consul-gateway-services-list;
}
%consul-gateway-services-list > li:not(:first-child) {
@extend %gateway-service-row;
}
%gateway-service-row {
@extend %composite-row, %with-composite-row-intent;
}
// Service Detail - Proxy Info tab
.proxy-upstreams > ul {
@extend %proxy-upstreams-list;
border-top: 1px solid $gray-200;
}
%proxy-upstreams-list > li {
@extend %composite-row;
}
.proxy-exposed-paths tbody tr {
@extend %proxy-exposed-paths-row;
cursor: default !important;
}
%proxy-exposed-paths-row:hover {
box-shadow: none !important;
}
%proxy-exposed-paths-row .combined-address button:hover {
// In this case we do not need a background on the icon
background-color: transparent !important;
}

View File

@ -17,4 +17,9 @@
There was an error deleting your policy.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -13,7 +13,7 @@
@authorized={{isAuthorized}}
@enabled={{isEnabled}}
>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/acls/policies/notifications'}}
</BlockSlot>
<BlockSlot @name="disabled">

View File

@ -17,4 +17,9 @@
There was an error deleting your role.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -13,7 +13,7 @@
@authorized={{isAuthorized}}
@enabled={{isEnabled}}
>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/acls/roles/notifications'}}
</BlockSlot>
<BlockSlot @name="disabled">

View File

@ -29,4 +29,9 @@
There was an error using that ACL token.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -13,7 +13,7 @@
@authorized={{isAuthorized}}
@enabled={{isEnabled}}
>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/acls/tokens/notifications'}}
</BlockSlot>
<BlockSlot @name="disabled">

View File

@ -19,4 +19,9 @@
There was an error deleting your intention.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -5,7 +5,7 @@
{{/if}}
<AppView @class="intention edit" @loading={{isLoading}}>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/intentions/notifications'}}
</BlockSlot>
<BlockSlot @name="breadcrumbs">

View File

@ -23,4 +23,9 @@
There was an error invalidating your session.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -4,7 +4,7 @@
{{title 'Edit Key/Value'}}
{{/if}}
<AppView @class="kv edit" @loading={{isLoading}}>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/kv/notifications'}}
</BlockSlot>
<BlockSlot @name="breadcrumbs">

View File

@ -17,4 +17,9 @@
There was an error deleting your namespace.
{{/if}}
{{/if}}
{{#let error.errors.firstObject as |error|}}
{{#if error.detail }}
<br />{{concat '(' (if error.status (concat error.status ': ')) error.detail ')'}}
{{/if}}
{{/let}}

View File

@ -4,7 +4,7 @@
{{title 'Edit Namespace'}}
{{/if}}
<AppView @class="nspace edit" @loading={{isLoading}}>
<BlockSlot @name="notification" as |status type|>
<BlockSlot @name="notification" as |status type item error|>
{{partial 'dc/nspaces/notifications'}}
</BlockSlot>
<BlockSlot @name="breadcrumbs">

View File

@ -32,11 +32,11 @@
{{#if (gt item.LocalBindPort 0)}}
{{#let (concat (or item.LocalBindAddress '127.0.0.1') ':' item.LocalBindPort) as |combinedAddress| }}
<li class="port">
<span>{{combinedAddress}}</span>
<CopyButton
@value={{combinedAddress}}
@name="Address"
/>
<span>{{combinedAddress}}</span>
</li>
{{/let}}
{{/if}}
@ -47,49 +47,51 @@
</ul>
</section>
{{/if}}
{{#if (gt proxy.Proxy.Upstreams.length 0)}}
{{#if (gt proxy.Proxy.Expose.Paths.length 0)}}
<section class="proxy-exposed-paths">
<h3>Exposed paths</h3>
<p>
The following list shows individual HTTP paths exposed through Envoy for external services like Prometheus. Read more about this in our documentation.
</p>
<table data-test-proxy-exposed-paths>
<thead>
<th>Path</th>
<th>Protocol</th>
<th>Listener port</th>
<th>Local path port</th>
<th>Combined address<span><em role="tooltip">Service address, listener port, and path all combined into one URL.</em></span></th>
</thead>
<tbody>
<ul data-test-proxy-exposed-paths>
{{#each proxy.Proxy.Expose.Paths as |path|}}
<tr>
<td>
<span>{{or path.Path '-'}}</span>
</td>
<td>
{{or path.Protocol '-'}}
</td>
<td>
{{or path.ListenerPort '-'}}
</td>
<td>
{{or path.LocalPathPort '-'}}
</td>
{{#let (concat item.Address ':' path.ListenerPort path.Path) as |combinedAddress| }}
<td class="combined-address">
{{#if combinedAddress}}
<span data-test-combined-address>{{combinedAddress}}</span>
<CopyButton @copy={{combinedAddress}} @name="Combined Address" />
{{else}}
{{'-'}}
{{/if}}
</td>
<li>
{{#let (concat item.Address ':' path.Path) as |combinedAddress| }}
<p class="combined-address">
<span>
{{combinedAddress}}
</span>
<CopyButton
@value={{combinedAddress}}
@name="Address"
/>
</p>
{{/let}}
</tr>
<ul>
{{#if path.Protocol}}
<li class="protocol">
{{path.Protocol}}
</li>
{{/if}}
{{#if path.ListenerPort}}
<li class="port">
listening on :{{path.ListenerPort}}
</li>
{{/if}}
{{#if path.LocalPathPort}}
<li class="port">
local port :{{path.LocalPathPort}}
</li>
{{/if}}
{{#if path.Path}}
<li class="path">
{{path.Path}}
</li>
{{/if}}
</ul>
</li>
{{/each}}
</tbody>
</table>
</ul>
</section>
{{/if}}
</div>

View File

@ -4,35 +4,9 @@
<section>
<p>
The following services may receive traffic from external services through this gateway. Learn more about configuring gateways in our
<a href="{{env 'CONSUL_DOCS_URL'}}/connect/terminating_gateway.html" target="_blank" rel="noopener noreferrer">step-by-step guide.</a>
<a href="{{env 'CONSUL_DOCS_URL'}}/connect/terminating_gateway.html" target="_blank" rel="noopener noreferrer">step-by-step guide</a>.
</p>
{{#let item.Service.Namespace as |nspace|}}
<ListCollection @cellHeight={{73}} @items={{gateway.Services}} class="consul-gateway-services-list" as |item index|>
<a data-test-service-name href={{href-to 'dc.services.show' item.Name}} class={{service/health-checks item}}>
{{item.Name}}
</a>
<ul>
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
{{#if (not-eq item.Namespace nspace)}}
<li class="nspace">
{{item.Namespace}}
</li>
{{/if}}
{{/if}}
{{#if (not-eq item.InstanceCount 0)}}
<li>
{{format-number item.InstanceCount}} {{pluralize item.InstanceCount 'Instance' without-count=true}}
</li>
{{/if}}
<TagList @item={{item}} as |Tags|>
<li>
<Tags />
</li>
</TagList>
</ul>
</ListCollection>
{{/let}}
<ConsulServiceList @routeName="dc.services.show" @items={{gateway.Services}} @nspace={{nspace}} />
</section>
{{else}}
<p>

View File

@ -3,11 +3,10 @@
{{#if (gt gateway.Services.length 0)}}
<section>
<p>
Upstreams are services that may receive traffic from this gateway. Learn more about configuring gateways in our
<a href="{{env 'CONSUL_DOCS_URL'}}/connect/ingress_gateway.html" target="_blank" rel="noopener noreferrer">documentation.</a>
Upstreams are services that may receive traffic from this gateway. Learn more about configuring gateways in our <a href="{{env 'CONSUL_DOCS_URL'}}/connect/ingress_gateway.html" target="_blank" rel="noopener noreferrer">documentation</a>.
</p>
{{#let item.Service.Namespace as |nspace|}}
<ListCollection @cellHeight={{73}} @items={{gateway.Services}} class="consul-gateway-services-list" as |item index|>
<ListCollection @items={{gateway.Services}} class="consul-upstream-list" as |item index|>
<a data-test-service-name href={{href-to 'dc.services.show' item.Name}}>
{{item.Name}}
</a>
@ -21,11 +20,11 @@
{{/if}}
{{#if (not-eq item.GatewayConfig.ListenerPort 0)}}
<li class="port">
<span>:{{item.GatewayConfig.ListenerPort}}</span>
<CopyButton
@value={{item.GatewayConfig.ListenerPort}}
@name="Port"
/>
<span>:{{item.GatewayConfig.ListenerPort}}</span>
</li>
{{/if}}
</ul>

View File

@ -28,7 +28,7 @@ Feature: dc / services / show / services
---
And the title should be "terminating-gateway-1 - Consul"
When I click linkedServices on the tabs
Then I see 3 service models
Then I see 3 service models on the tabs.linkedServicesTab component
Scenario: Don't see the Linked Services tab
Given 1 datacenter model with the value "dc1"
And 1 node models

View File

@ -20,7 +20,7 @@ Feature: dc / services / show / upstreams
When I click upstreams on the tabs
And I see upstreamsIsSelected on the tabs
Scenario: Seeing the list of Upstreams
Given 3 service models from yaml
Given 3 service models
When I visit the service page for yaml
---
dc: dc1
@ -28,7 +28,7 @@ Feature: dc / services / show / upstreams
---
And the title should be "ingress-gateway-1 - Consul"
When I click upstreams on the tabs
Then I see 3 service models
Then I see 3 service models on the tabs.upstreamsTab component
Scenario: Don't see the Upstreams tab
Given 1 datacenter model with the value "dc1"
And 1 node models

View File

@ -1,5 +1,5 @@
export default function(visitable, attribute, collection, text, intentions, filter, tabs) {
return {
const page = {
visit: visitable('/:dc/services/:service'),
externalSource: attribute('data-test-external-source', '[data-test-external-source]', {
scope: '.title',
@ -22,8 +22,16 @@ export default function(visitable, attribute, collection, text, intentions, filt
address: text('[data-test-address]'),
}),
intentions: intentions(),
services: collection('.consul-gateway-services-list> ul > li:not(:first-child)', {
};
page.tabs.upstreamsTab = {
services: collection('.consul-upstream-list > ul > li:not(:first-child)', {
name: text('[data-test-service-name]'),
}),
};
page.tabs.linkedServicesTab = {
services: collection('.consul-service-list > ul > li:not(:first-child)', {
name: text('[data-test-service-name]'),
}),
};
return page;
}

View File

@ -1,7 +1,7 @@
import { getAlternateServices } from 'consul-ui/utils/components/discovery-chain/index';
import { getAlternateServices } from 'consul-ui/components/discovery-chain/utils';
import { module, test } from 'qunit';
module('Unit | Utility | components/discovery-chain/get-alternative-services', function() {
module('Unit | Component | discovery-chain/get-alternative-services', function() {
test('it guesses a different namespace', function(assert) {
const expected = {
Type: 'Namespace',

View File

@ -1,4 +1,4 @@
import { getResolvers } from 'consul-ui/utils/components/discovery-chain/index';
import { getResolvers } from 'consul-ui/components/discovery-chain/utils';
import { module, test } from 'qunit';
import { get } from 'consul-ui/tests/helpers/api';
@ -7,7 +7,7 @@ const nspace = 'default';
const request = {
url: `/v1/discovery-chain/service-name?dc=${dc}`,
};
module('Unit | Utility | components/discovery-chain/get-resolvers', function() {
module('Unit | Component | discovery-chain/get-resolvers', function() {
test('it assigns Subsets correctly', function(assert) {
return get(request.url, {
headers: {

View File

@ -1,7 +1,7 @@
import { getSplitters } from 'consul-ui/utils/components/discovery-chain/index';
import { getSplitters } from 'consul-ui/components/discovery-chain/utils';
import { module, test } from 'qunit';
module('Unit | Utility | components/discovery-chain/get-splitters', function() {
module('Unit | Component | discovery-chain/get-splitters', function() {
test('it collects and correctly parses splitter Names', function(assert) {
const actual = getSplitters({
'splitter:splitter-name.default': {