ui: ConsulKind explanatory tooltip panels (#8048)

* ui: Add tooltip panels to ConsulKind
This commit is contained in:
John Cowen 2020-06-09 11:10:14 +01:00 committed by GitHub
parent 0f343332da
commit aafbfa167c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 220 additions and 42 deletions

View File

@ -1,11 +1,93 @@
{{#if item.Kind}} {{#if item.Kind}}
{{#if (has-block)}} {{#let (titleize (humanize item.Kind)) as |Name|}}
{{yield {{#if (has-block)}}
(component 'consul-kind' item=item) {{yield
}} (component 'consul-kind' item=item withInfo=withInfo)
{{else}} }}
<span data-test-kind={{item.Kind}} class="consul-kind gateway"> {{else}}
<span>{{titleize (humanize item.Kind)}}</span> {{#if withInfo}}
</span> <dl class="tooltip-panel">
{{/if}} <dt>
<span data-test-kind={{item.Kind}} class="consul-kind gateway">
<span>{{Name}}</span>
</span>
</dt>
<dd>
<MenuPanel @position="left">
<BlockSlot @name="header">
{{#if (eq item.Kind 'ingress-gateway')}}
Ingress gateways enable ingress traffic from services outside the Consul service mesh to services inside the Consul service mesh.
{{else if (eq item.Kind 'terminating-gateway')}}
Terminating gateways allow connect-enabled services in Consul service mesh to communicate with services outside the service mesh.
{{else}}
Mesh gateways enable routing of Connect traffic between different Consul datacenters.
{{/if}}
</BlockSlot>
<BlockSlot @name="menu">
<li role="separator">
{{#if (eq item.Kind 'ingress-gateway')}}
About Ingress gateways
{{else if (eq item.Kind 'terminating-gateway')}}
About Terminating gateways
{{else}}
About Mesh gateways
{{/if}}
</li>
{{#let (from-entries
(array 'ingress-gateway' '/consul/developer-mesh/ingress-gateways')
(array 'terminating-gateway' '/consul/developer-mesh/understand-terminating-gateways')
(array 'mesh-gateway' '/consul/developer-mesh/connect-gateways')
) as |link|}}
<li role="none" class="learn-link">
<a tabindex="-1" role="menuitem" href={{concat (env 'CONSUL_DOCS_LEARN_URL') (get link item.Kind)}} rel="noopener noreferrer" target="_blank">
Learn guides
</a>
</li>
{{/let}}
{{#let (from-entries
(array 'ingress-gateway' '/connect/ingress_gateway.html')
(array 'terminating-gateway' '/connect/terminating_gateway.html')
(array 'mesh-gateway' '/connect/mesh_gateway.html')
) as |link|}}
<li role="none" class="docs-link">
<a tabindex="-1" role="menuitem" href={{concat (env 'CONSUL_DOCS_URL') (get link item.Kind)}} rel="noopener noreferrer" target="_blank">
Documentation
</a>
</li>
<li role="separator">
Other gateway types
</li>
{{#if (not-eq item.Kind 'mesh-gateway')}}
<li role="none" class="docs-link">
<a tabindex="-1" role="menuitem" href={{concat (env 'CONSUL_DOCS_URL') (get link 'mesh-gateway')}} rel="noopener noreferrer" target="_blank">
Mesh gateways
</a>
</li>
{{/if}}
{{#if (not-eq item.Kind 'terminating-gateway')}}
<li role="none" class="docs-link">
<a tabindex="-1" role="menuitem" href={{concat (env 'CONSUL_DOCS_URL') (get link 'terminating-gateway')}} rel="noopener noreferrer" target="_blank">
Terminating gateways
</a>
</li>
{{/if}}
{{#if (not-eq item.Kind 'ingress-gateway')}}
<li role="none" class="docs-link">
<a tabindex="-1" role="menuitem" href={{concat (env 'CONSUL_DOCS_URL') (get link 'ingress-gateway')}} rel="noopener noreferrer" target="_blank">
Ingress gateways
</a>
</li>
{{/if}}
{{/let}}
</BlockSlot>
</MenuPanel>
</dd>
</dl>
{{else}}
<span data-test-kind={{item.Kind}} class="consul-kind gateway">
<span>{{Name}}</span>
</span>
{{/if}}
{{/if}}
{{/let}}
{{/if}} {{/if}}

View File

@ -13,7 +13,7 @@
{{#if dc}} {{#if dc}}
<ul> <ul>
{{#if (and (env 'CONSUL_NSPACES_ENABLED') (gt nspaces.length 0))}} {{#if (and (env 'CONSUL_NSPACES_ENABLED') (gt nspaces.length 0))}}
<li data-test-nspace-menu> <li class="nspaces" data-test-nspace-menu>
{{#if (and (eq nspaces.length 1) (not canManageNspaces)) }} {{#if (and (eq nspaces.length 1) (not canManageNspaces)) }}
<span data-test-nspace-selected={{nspace.Name}}>{{nspace.Name}}</span> <span data-test-nspace-selected={{nspace.Name}}>{{nspace.Name}}</span>
{{ else }} {{ else }}

View File

@ -0,0 +1,15 @@
{{yield}}
<div class="menu-panel {{position}}">
<YieldSlot @name="controls">
{{yield}}
</YieldSlot>
{{#yield-slot name="header"}}
<div>{{yield}}</div>
{{else}}
{{/yield-slot}}
<ul role="menu" ...attributes>
<YieldSlot @name="menu">
{{yield}}
</YieldSlot>
</ul>
</div>

View File

@ -0,0 +1,7 @@
import Component from '@ember/component';
import Slotted from 'block-slots';
export default Component.extend(Slotted, {
tagName: '',
});

View File

@ -11,21 +11,22 @@
</YieldSlot> </YieldSlot>
</button> </button>
</ToggleButton> </ToggleButton>
<div class={{position}}> <MenuPanel @position={{position}} id={{ariaControls}} aria-labelledby={{ariaLabelledBy}} aria-expanded={{ariaExpanded}}>
<input type="checkbox" id={{concat 'popover-menu-' guid '-'}} /> <BlockSlot @name="controls">
{{#each submenus as |sub|}} <input type="checkbox" id={{concat 'popover-menu-' guid '-'}} />
<input type="checkbox" id={{concat 'popover-menu-' guid '-' sub}} /> {{#each submenus as |sub|}}
{{/each}} <input type="checkbox" id={{concat 'popover-menu-' guid '-' sub}} />
{{#yield-slot name='header'}} {{/each}}
<div> </BlockSlot>
{{yield}} {{#if hasHeader}}
</div> <BlockSlot @name="header">
{{else}} {{#yield-slot name="header"}}{{yield}}{{else}}{{/yield-slot}}
{{/yield-slot}} </BlockSlot>
<ul role="menu" id={{ariaControls}} aria-labelledby={{ariaLabelledBy}} aria-expanded={{ariaExpanded}}> {{/if}}
<BlockSlot @name="menu">
<YieldSlot @name="menu" @params={{block-params (concat "popover-menu-" guid "-") send keypressClick this.toggle.click}}> <YieldSlot @name="menu" @params={{block-params (concat "popover-menu-" guid "-") send keypressClick this.toggle.click}}>
{{yield}} {{yield}}
</YieldSlot> </YieldSlot>
</ul> </BlockSlot>
</div> </MenuPanel>
</AriaMenu> </AriaMenu>

View File

@ -2,6 +2,7 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import Slotted from 'block-slots'; import Slotted from 'block-slots';
import { set } from '@ember/object';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
@ -16,6 +17,9 @@ export default Component.extend(Slotted, {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
}, },
willRender: function() {
set(this, 'hasHeader', this._isRegistered('header'));
},
actions: { actions: {
change: function(e) { change: function(e) {
if (!e.target.checked) { if (!e.target.checked) {

View File

@ -0,0 +1,5 @@
import { helper } from '@ember/component/helper';
export default helper(function fromEntries(params /*, hash*/) {
return Object.fromEntries(params);
});

View File

@ -4,6 +4,7 @@
@extend %user-select-none; @extend %user-select-none;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
text-decoration: none;
} }
%button:disabled, %button:disabled,
%internal-button:disabled { %internal-button:disabled {

View File

@ -1,6 +1,5 @@
%menu-panel { %menu-panel {
position: absolute; position: absolute;
overflow: hidden;
} }
%menu-panel [type='checkbox'] { %menu-panel [type='checkbox'] {
display: none; display: none;
@ -15,8 +14,14 @@
/* or be hardcoded */ /* or be hardcoded */
/* min-height: 143px; */ /* min-height: 143px; */
} }
%menu-panel [role='menuitem']::after { %menu-panel [role='menuitem'] {
float: right; display: flex;
justify-content: space-between;
}
%menu-panel [role='menuitem']:after {
@extend %as-pseudo;
display: block !important;
background-position: center right !important;
} }
%menu-panel-sub-panel { %menu-panel-sub-panel {
position: absolute; position: absolute;
@ -70,7 +75,7 @@
} }
%menu-panel-header { %menu-panel-header {
padding: 10px; padding: 10px;
padding-left: 36px; white-space: normal;
} }
/* here the !important is only needed for what seems to be a difference */ /* here the !important is only needed for what seems to be a difference */
/* with the CSS before and after compression */ /* with the CSS before and after compression */

View File

@ -22,12 +22,12 @@
border-top: $decor-border-100; border-top: $decor-border-100;
border-color: $gray-300; border-color: $gray-300;
} }
%menu-panel-header {
background-color: $gray-050; %menu-panel .docs-link a::after {
@extend %with-docs-mask, %as-pseudo;
} }
%menu-panel-header::before { %menu-panel .learn-link a::after {
@extend %with-info-circle-fill-color-icon, %as-pseudo; @extend %with-learn-mask, %as-pseudo;
font-size: 1.1em;
} }
%menu-panel .is-active > *::after { %menu-panel .is-active > *::after {
@extend %with-check-plain-mask, %as-pseudo; @extend %with-check-plain-mask, %as-pseudo;

View File

@ -16,6 +16,7 @@
padding: 0 8px; padding: 0 8px;
border-radius: $decor-radius-100; border-radius: $decor-radius-100;
height: 18px; height: 18px;
display: inline-block;
line-height: 0.7rem; line-height: 0.7rem;
} }
%reduced-pill > span { %reduced-pill > span {

View File

@ -12,6 +12,7 @@
%popover-menu + label > * { %popover-menu + label > * {
@extend %toggle-button; @extend %toggle-button;
} }
%more-popover-menu-panel,
%popover-menu-panel { %popover-menu-panel {
@extend %menu-panel; @extend %menu-panel;
} }

View File

@ -11,7 +11,7 @@
@extend %toggle-button; @extend %toggle-button;
} }
%more-popover-menu-panel { %more-popover-menu-panel {
@extend %menu-panel; overflow: hidden;
width: 192px; width: 192px;
} }
%more-popover-menu + label + div { %more-popover-menu + label + div {

View File

@ -6,6 +6,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
white-space: nowrap; white-space: nowrap;
position: relative;
z-index: 1;
} }
%app-view-actions { %app-view-actions {
margin-left: auto; margin-left: auto;

View File

@ -33,6 +33,8 @@
@import './list-collection'; @import './list-collection';
@import './grid-collection'; @import './grid-collection';
@import './popover-select'; @import './popover-select';
@import './tooltip-panel';
@import './menu-panel';
/**/ /**/

View File

@ -9,7 +9,7 @@
@extend %with-docs-icon, %as-pseudo; @extend %with-docs-icon, %as-pseudo;
} }
%main-nav-horizontal .feedback-link a::after { %main-nav-horizontal .feedback-link a::after {
@extend %with-logo-github-monochrome-icon, %as-pseudo; @extend %with-logo-github-monochrome-mask, %as-pseudo;
} }
%main-header-horizontal::before { %main-header-horizontal::before {
background-color: var(--swatch-brand-600, $black); background-color: var(--swatch-brand-600, $black);

View File

@ -10,6 +10,15 @@
%secondary-nav { %secondary-nav {
@extend %main-nav-horizontal; @extend %main-nav-horizontal;
} }
%primary-nav .nspaces .menu-panel > div {
background-color: $gray-050;
padding-left: 36px;
}
%primary-nav .nspaces .menu-panel > div::before {
@extend %with-info-circle-fill-mask, %as-pseudo;
color: $blue-500;
font-size: 1.1em;
}
%main-header-horizontal > div { %main-header-horizontal > div {
@extend %main-nav-horizontal-panel; @extend %main-nav-horizontal-panel;

View File

@ -0,0 +1,3 @@
.menu-panel {
@extend %menu-panel;
}

View File

@ -0,0 +1,4 @@
@import './tooltip-panel/index';
.tooltip-panel {
@extend %tooltip-panel;
}

View File

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

View File

@ -0,0 +1,21 @@
%tooltip-panel {
margin: 0 !important;
}
%tooltip-panel dd > div {
top: auto !important;
}
%tooltip-panel dt {
cursor: pointer;
}
%tooltip-panel dd {
display: none;
position: relative;
padding-top: 10px;
margin-bottom: -10px;
}
%tooltip-panel:hover dd {
display: block;
}
%tooltip-panel dd > div {
width: 250px;
}

View File

@ -0,0 +1,13 @@
/* This is the top chevron */
%tooltip-panel dd > div::before {
@extend %as-pseudo;
width: 12px;
height: 12px;
background: white;
border-top: 1px solid $gray-300;
border-right: 1px solid $gray-300;
transform: rotate(-45deg);
position: absolute;
left: 16px;
top: -7px;
}

View File

@ -14,7 +14,7 @@
{{ item.ID }} {{ item.ID }}
</h1> </h1>
<ConsulExternalSource @item={{item}} /> <ConsulExternalSource @item={{item}} />
<ConsulKind @item={{item}} /> <ConsulKind @item={{item}} @withInfo={{true}} />
</BlockSlot> </BlockSlot>
<BlockSlot @name="nav"> <BlockSlot @name="nav">
<dl> <dl>

View File

@ -14,7 +14,7 @@
{{item.Service.Service}} {{item.Service.Service}}
</h1> </h1>
<ConsulExternalSource @item={{item.Service}} /> <ConsulExternalSource @item={{item.Service}} />
<ConsulKind @item={{item.Service}} /> <ConsulKind @item={{item.Service}} @withInfo={{true}} />
</BlockSlot> </BlockSlot>
<BlockSlot @name="nav"> <BlockSlot @name="nav">
{{#if (not-eq item.Service.Kind 'mesh-gateway')}} {{#if (not-eq item.Service.Kind 'mesh-gateway')}}
@ -22,19 +22,19 @@
compact compact
(array (array
(hash label="Instances" href=(href-to "dc.services.show.instances") selected=(is-href "dc.services.show.instances")) (hash label="Instances" href=(href-to "dc.services.show.instances") selected=(is-href "dc.services.show.instances"))
(if (eq item.Service.Kind 'terminating-gateway') (if (eq item.Service.Kind 'terminating-gateway')
(hash label="Linked Services" href=(href-to "dc.services.show.services") selected=(is-href "dc.services.show.services")) (hash label="Linked Services" href=(href-to "dc.services.show.services") selected=(is-href "dc.services.show.services"))
'') '')
(if (eq item.Service.Kind 'ingress-gateway') (if (eq item.Service.Kind 'ingress-gateway')
(hash label="Upstreams" href=(href-to "dc.services.show.upstreams") selected=(is-href "dc.services.show.upstreams")) (hash label="Upstreams" href=(href-to "dc.services.show.upstreams") selected=(is-href "dc.services.show.upstreams"))
'') '')
(if (not item.Service.Kind) (if (not item.Service.Kind)
(hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions")) (hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions"))
'') '')
(if chain (if chain
(hash label="Routing" href=(href-to "dc.services.show.routing") selected=(is-href "dc.services.show.routing")) (hash label="Routing" href=(href-to "dc.services.show.routing") selected=(is-href "dc.services.show.routing"))
'') '')
(if (not item.Service.Kind) (if (not item.Service.Kind)
(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"))
'') '')
) )