ui: Various amends for 1.7beta (#6965)

* Remove empty init

* Actually make the disco chain endpoint send the nspace, note:

The backend doesn't support this as yet.

* Tweak the font size of flash-messages ever so slightly

* Make sure the nspace menu is kept up to date when creating a new one

* Move comment to the correct place

* Only refresh the namespace menu if you specifically created a nspace

* Change FIXMEs to TODOs as we are happy for these to wait until later
This commit is contained in:
John Cowen 2019-12-18 18:27:54 +00:00 committed by GitHub
parent aa680d5f0c
commit 36728b961f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 86 additions and 45 deletions

View File

@ -1,14 +1,18 @@
import Adapter from './application'; import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({ export default Adapter.extend({
requestForQueryRecord: function(request, { dc, index, id }) { requestForQueryRecord: function(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') { if (typeof id === 'undefined') {
throw new Error('You must specify an id'); throw new Error('You must specify an id');
} }
return request` return request`
GET /v1/discovery-chain/${id}?${{ dc }} GET /v1/discovery-chain/${id}?${{ dc }}
${{ index }} ${{
...this.formatNspace(ns),
index,
}}
`; `;
}, },
}); });

View File

@ -34,12 +34,14 @@ const keys = {
horizontal: {}, horizontal: {},
}; };
const COMPONENT_ID = 'component-aria-menu-'; const COMPONENT_ID = 'component-aria-menu-';
// ^menuitem supports menuitemradio and menuitemcheckbox
const MENU_ITEMS = '[role^="menuitem"]';
export default Component.extend({ export default Component.extend({
tagName: '', tagName: '',
dom: service('dom'), dom: service('dom'),
guid: '', guid: '',
expanded: false, expanded: false,
direction: 'vertical', orientation: 'vertical',
init: function() { init: function() {
this._super(...arguments); this._super(...arguments);
set(this, 'guid', this.dom.guid(this)); set(this, 'guid', this.dom.guid(this));
@ -67,9 +69,8 @@ export default Component.extend({
// Also we may do this but not need it if we return early below // Also we may do this but not need it if we return early below
// although once we add support for [A-Za-z] it unlikely we won't use // although once we add support for [A-Za-z] it unlikely we won't use
// the keypress // the keypress
// ^menuitem supports menuitemradio and menuitemcheckbox
// TODO: We need to use > somehow here so we don't select submenus // TODO: We need to use > somehow here so we don't select submenus
const $items = [...this.dom.elements('[role^="menuitem"]', this.$menu)]; const $items = [...this.dom.elements(MENU_ITEMS, this.$menu)];
if (!this.expanded) { if (!this.expanded) {
this.$trigger.dispatchEvent(new MouseEvent('click')); this.$trigger.dispatchEvent(new MouseEvent('click'));
if (e.keyCode === ENTER || e.keyCode === SPACE) { if (e.keyCode === ENTER || e.keyCode === SPACE) {
@ -79,17 +80,17 @@ export default Component.extend({
} }
// this will prevent anything happening if you haven't pushed a // this will prevent anything happening if you haven't pushed a
// configurable key // configurable key
if (typeof keys[this.direction][e.keyCode] === 'undefined') { if (typeof keys[this.orientation][e.keyCode] === 'undefined') {
return; return;
} }
const $focused = this.dom.element('[role="menuitem"]:focus', this.$menu); const $focused = this.dom.element(`${MENU_ITEMS}:focus`, this.$menu);
let i; let i;
if ($focused) { if ($focused) {
i = $items.findIndex(function($item) { i = $items.findIndex(function($item) {
return $item === $focused; return $item === $focused;
}); });
} }
const $next = $items[keys[this.direction][e.keyCode]($items, i)]; const $next = $items[keys[this.orientation][e.keyCode]($items, i)];
$next.focus(); $next.focus();
}, },
// TODO: The argument here needs to change to an event // TODO: The argument here needs to change to an event

View File

@ -10,7 +10,7 @@ const getNodesByType = function(nodes = {}, type) {
const targetsToFailover = function(targets, a) { const targetsToFailover = function(targets, a) {
let type; let type;
const Targets = targets.map(function(b) { const Targets = targets.map(function(b) {
// FIXME: this isn't going to work past namespace for services // TODO: this isn't going to work past namespace for services
// with dots in the name // with dots in the name
const [aRev, bRev] = [a, b].map(item => item.split('.').reverse()); const [aRev, bRev] = [a, b].map(item => item.split('.').reverse());
const types = ['Datacenter', 'Namespace', 'Service', 'Subset']; const types = ['Datacenter', 'Namespace', 'Service', 'Subset'];
@ -57,7 +57,7 @@ const getTargetResolvers = function(dc, nspace = 'default', targets = [], nodes
let failoverable = resolver; let failoverable = resolver;
if (item.ServiceSubset) { if (item.ServiceSubset) {
failoverable = item; failoverable = item;
// FIXME: Sometimes we have set the resolvers ID to the ID of the // TODO: Sometimes we have set the resolvers ID to the ID of the
// subset this just shifts the subset of the front of the URL for the moment // subset this just shifts the subset of the front of the URL for the moment
const temp = item.ID.split('.'); const temp = item.ID.split('.');
temp.shift(); temp.shift();
@ -65,7 +65,7 @@ const getTargetResolvers = function(dc, nspace = 'default', targets = [], nodes
resolver.Children.push(item); resolver.Children.push(item);
} }
if (typeof node.Resolver.Failover !== 'undefined') { if (typeof node.Resolver.Failover !== 'undefined') {
// FIXME: Figure out if we can get rid of this // TODO: Figure out if we can get rid of this
/* eslint ember/no-side-effects: "warn" */ /* eslint ember/no-side-effects: "warn" */
set(failoverable, 'Failover', targetsToFailover(node.Resolver.Failover.Targets, item.ID)); set(failoverable, 'Failover', targetsToFailover(node.Resolver.Failover.Targets, item.ID));
} else { } else {
@ -245,7 +245,7 @@ export default Component.extend({
// the developer access to the mouse event therefore we just use JS to add our events // the developer access to the mouse event therefore we just use JS to add our events
// revisit this post Octane // revisit this post Octane
addPathListeners: function() { addPathListeners: function() {
// FIXME: Figure out if we can remove this next // TODO: Figure out if we can remove this next
next(() => { next(() => {
this._listeners.remove(); this._listeners.remove();
[...this.dom.elements('path.split', this.element)].forEach(item => { [...this.dom.elements('path.split', this.element)].forEach(item => {

View File

@ -22,14 +22,14 @@ export default Helper.extend({
atts = atts.concat(getRouteParams(parent, params)); atts = atts.concat(getRouteParams(parent, params));
current = parent; current = parent;
} }
let route = this.router.currentRoute.name; let route = this.router.currentRouteName;
// TODO: this is specific to consul/nspaces // TODO: this is specific to consul/nspaces
// 'ideally' we could try and do this elsewhere // 'ideally' we could try and do this elsewhere
// not super important though. // not super important though.
// This will turn an URL that has no nspace (/ui/dc-1/nodes) into one // This will turn an URL that has no nspace (/ui/dc-1/nodes) into one
// that does have a namespace (/ui/~nspace/dc-1/nodes) if you href-mut with // that does have a namespace (/ui/~nspace/dc-1/nodes) if you href-mut with
// a nspace parameter // a nspace parameter
if (typeof params.nspace !== 'undefined' && !route.startsWith('nspace.')) { if (typeof params.nspace !== 'undefined' && route.startsWith('dc.')) {
route = `nspace.${route}`; route = `nspace.${route}`;
atts.push(params.nspace); atts.push(params.nspace);
} }

View File

@ -11,7 +11,7 @@ export function initialize(container) {
.root() .root()
.classList.add('has-nspaces'); .classList.add('has-nspaces');
} }
// FIXME: This needs to live in its own initializer, either: // TODO: This needs to live in its own initializer, either:
// 1. Make it be about adding classes to the root dom node // 1. Make it be about adding classes to the root dom node
// 2. Make it be about config and things to do on initialization re: config // 2. Make it be about config and things to do on initialization re: config
// If we go with 1 then we need to move both this and the above nspaces class // If we go with 1 then we need to move both this and the above nspaces class

View File

@ -11,9 +11,6 @@ const removeLoading = function($from) {
}; };
export default Route.extend(WithBlockingActions, { export default Route.extend(WithBlockingActions, {
dom: service('dom'), dom: service('dom'),
init: function() {
this._super(...arguments);
},
nspacesRepo: service('repository/nspace/disabled'), nspacesRepo: service('repository/nspace/disabled'),
repo: service('repository/dc'), repo: service('repository/dc'),
settings: service('settings'), settings: service('settings'),
@ -79,6 +76,7 @@ export default Route.extend(WithBlockingActions, {
const $root = this.dom.root(); const $root = this.dom.root();
hash({ hash({
error: error, error: error,
nspace: this.nspacesRepo.getActive(),
dc: dc:
error.status.toString().indexOf('5') !== 0 error.status.toString().indexOf('5') !== 0
? this.repo.getActive() ? this.repo.getActive()
@ -89,6 +87,9 @@ export default Route.extend(WithBlockingActions, {
}) })
.then(model => { .then(model => {
removeLoading($root); removeLoading($root);
model.nspaces = [model.nspace];
// we can't use setupController as we received an error
// so we do it manually instead
next(() => { next(() => {
this.controllerFor('error').setProperties(model); this.controllerFor('error').setProperties(model);
}); });

View File

@ -69,4 +69,22 @@ export default Route.extend({
setupController: function(controller, model) { setupController: function(controller, model) {
controller.setProperties(model); controller.setProperties(model);
}, },
actions: {
// TODO: This will eventually be deprecated please see
// https://deprecations.emberjs.com/v3.x/#toc_deprecate-router-events
willTransition: function(transition) {
this._super(...arguments);
if (typeof transition !== 'undefined' && transition.from.name.endsWith('nspaces.create')) {
// Only when we create, reload the nspaces in the main menu to update them
// as we don't block for those
this.nspacesRepo.findAll().then(items => {
if (typeof this.controller !== 'undefined') {
this.controller.setProperties({
nspaces: items,
});
}
});
}
},
},
}); });

View File

@ -1,5 +1,6 @@
import Route from '@ember/routing/route'; import Route from '@ember/routing/route';
import { get } from '@ember/object'; import { get } from '@ember/object';
import { config } from 'consul-ui/env';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import WithBlockingActions from 'consul-ui/mixins/with-blocking-actions'; import WithBlockingActions from 'consul-ui/mixins/with-blocking-actions';
export default Route.extend(WithBlockingActions, { export default Route.extend(WithBlockingActions, {
@ -31,7 +32,9 @@ export default Route.extend(WithBlockingActions, {
return false; return false;
}); });
} else { } else {
if (get(item, 'token.Namespace') !== nspace) { // TODO: Ideally we wouldn't need to use config() at a route level
// transitionTo should probably remove it instead if NSPACES aren't enabled
if (config('CONSUL_NSPACES_ENABLED') && get(item, 'token.Namespace') !== nspace) {
let routeName = this.router.currentRouteName; let routeName = this.router.currentRouteName;
if (!routeName.startsWith('nspace')) { if (!routeName.startsWith('nspace')) {
routeName = `nspace.${routeName}`; routeName = `nspace.${routeName}`;

View File

@ -14,9 +14,10 @@ export default Route.extend({
}, },
model: function(params) { model: function(params) {
const dc = this.modelFor('dc').dc.Name; const dc = this.modelFor('dc').dc.Name;
const nspace = this.modelFor('nspace').nspace.substr(1);
return hash({ return hash({
item: this.repo.findBySlug(params.name, dc, this.modelFor('nspace').nspace.substr(1)), item: this.repo.findBySlug(params.name, dc, nspace),
chain: this.chainRepo.findBySlug(params.name, dc), chain: this.chainRepo.findBySlug(params.name, dc, nspace),
urls: this.settings.findBySlug('urls'), urls: this.settings.findBySlug('urls'),
dc: dc, dc: dc,
}); });

View File

@ -33,7 +33,7 @@
@extend %blink-in-fade-out-active; @extend %blink-in-fade-out-active;
} }
%resolver-card dt { %resolver-card dt {
@extend %with-pseudo-tooltip; @extend %with-pseudo-tooltip, %tooltip-right;
} }
%discovery-chain { %discovery-chain {

View File

@ -2,32 +2,14 @@
.healthchecked-resource > div { .healthchecked-resource > div {
@extend %stats-card; @extend %stats-card;
} }
%tooltip-below::after {
top: calc(100% - 8px);
bottom: auto;
border-top: none;
border-bottom: 18px solid $gray-500;
}
%tooltip-below::before {
top: calc(100% + 4px);
bottom: auto;
/*TODO: This should probably go into base*/
line-height: 1em;
}
%tooltip-left::before {
right: 0;
}
%tooltip-right::before {
left: -10px;
}
%stats-card-icon { %stats-card-icon {
@extend %tooltip-below; @extend %tooltip-below;
} }
%stats-card-icon:first-child::before { %stats-card-icon:first-child::before {
right: 0; @extend %tooltip-left;
} }
%stats-card-icon:last-child::before { %stats-card-icon:last-child::before {
left: -10px; @extend %tooltip-right;
} }
%stats-card-icon:last-child { %stats-card-icon:last-child {

View File

@ -15,6 +15,7 @@
@import './app-view'; @import './app-view';
@import './product'; @import './product';
@import './tooltip';
@import './tag-list'; @import './tag-list';
@import './healthcheck-output'; @import './healthcheck-output';
@import './healthcheck-info'; @import './healthcheck-info';
@ -30,6 +31,5 @@
@import './feedback-dialog'; @import './feedback-dialog';
@import './modal-dialog'; @import './modal-dialog';
@import './notice'; @import './notice';
@import './tooltip';
@import './sort-control'; @import './sort-control';
@import './discovery-chain'; @import './discovery-chain';

View File

@ -13,6 +13,10 @@
padding: 5px 12px; padding: 5px 12px;
white-space: nowrap; white-space: nowrap;
} }
%main-nav-horizontal input + label > * {
/* less space as the chevron adds space */
padding-right: 4px !important;
}
%main-nav-horizontal-drop-nav { %main-nav-horizontal-drop-nav {
z-index: 400; z-index: 400;
/* TODO: We should probably make menu-panel default to left hand side*/ /* TODO: We should probably make menu-panel default to left hand side*/
@ -30,7 +34,6 @@
padding-top: 0.35em; padding-top: 0.35em;
} }
%main-nav-horizontal-drop-nav-separator:not(:first-child) { %main-nav-horizontal-drop-nav-separator:not(:first-child) {
padding-top: 0.7em;
margin-top: 0.35em; margin-top: 0.35em;
} }
%main-nav-horizontal-drop-nav-header { %main-nav-horizontal-drop-nav-header {
@ -151,6 +154,14 @@
min-width: 266px; min-width: 266px;
} }
%main-nav-horizontal input + label { %main-nav-horizontal input + label {
padding-right: 5px !important; /* Usually there is no space between buttons which is */
/* fine as the button only highlights when its selected */
/* therefore no two siblings are highlighted at the same time */
/* which means you don't notice there is no space between the */
/* buttons. popover-menu triggers on the other hand can be */
/* at the same time as a sibling, therefore they need a little */
/* space between it and its sibling - this is a poroperty of */
/* the main nav not the popover-menu */
padding-right: 5px;
} }
} }

View File

@ -7,6 +7,25 @@
/* override structure min-width for the moment */ /* override structure min-width for the moment */
/* TODO: Clarify whether these should actually use */ /* TODO: Clarify whether these should actually use */
/* the min-width from structure */ /* the min-width from structure */
/* TODO: See if we can move all these to base */
%tooltip-bubble { %tooltip-bubble {
min-width: 0; min-width: 0;
} }
%tooltip-below::after {
top: calc(100% - 8px);
bottom: auto;
border-top: none;
border-bottom: 18px solid $gray-500;
}
%tooltip-below::before {
top: calc(100% + 4px);
bottom: auto;
/*TODO: This should probably go into base*/
line-height: 1em;
}
%tooltip-left::before {
right: 0;
}
%tooltip-right::before {
left: -7px;
}

View File

@ -38,6 +38,7 @@ fieldset > header,
pre code, pre code,
%notice, %notice,
%notice p, %notice p,
%flash-message p,
%filter-bar input, %filter-bar input,
%phrase-editor input { %phrase-editor input {
@extend %p1; @extend %p1;