diff --git a/ui-v2/app/components/feedback-dialog.js b/ui-v2/app/components/feedback-dialog.js index 9f4a78bf2..5f0a97ac1 100644 --- a/ui-v2/app/components/feedback-dialog.js +++ b/ui-v2/app/components/feedback-dialog.js @@ -1,6 +1,8 @@ import Component from '@ember/component'; import { get, set } from '@ember/object'; import { inject as service } from '@ember/service'; +import qsaFactory from 'consul-ui/utils/qsa-factory'; +const $$ = qsaFactory(); import SlotsMixin from 'ember-block-slots'; const STATE_READY = 'ready'; @@ -8,8 +10,9 @@ const STATE_SUCCESS = 'success'; const STATE_ERROR = 'error'; export default Component.extend(SlotsMixin, { wait: service('timeout'), - interval: null, classNames: ['with-feedback'], + transition: '', + transitionClassName: 'feedback-dialog-out', state: STATE_READY, permanent: true, init: function() { @@ -17,26 +20,30 @@ export default Component.extend(SlotsMixin, { this.success = this._success.bind(this); this.error = this._error.bind(this); }, - _success: function() { - set(this, 'state', STATE_SUCCESS); - get(this, 'wait') - .execute(3000, interval => { - clearInterval(get(this, 'interval')); - set(this, 'interval', interval); + applyTransition: function() { + const wait = get(this, 'wait').execute; + const className = get(this, 'transitionClassName'); + wait(0) + .then(() => { + set(this, 'transition', className); + return wait(0); }) .then(() => { + return new Promise(resolve => { + $$(`.${className}`, this.element)[0].addEventListener('transitionend', resolve); + }); + }) + .then(() => { + set(this, 'transition', ''); set(this, 'state', STATE_READY); }); }, + _success: function() { + set(this, 'state', STATE_SUCCESS); + this.applyTransition(); + }, _error: function() { set(this, 'state', STATE_ERROR); - get(this, 'wait') - .execute(3000, interval => { - clearInterval(get(this, 'interval')); - set(this, 'interval', interval); - }) - .then(() => { - set(this, 'state', STATE_READY); - }); + this.applyTransition(); }, }); diff --git a/ui-v2/app/styles/base/animation/index.scss b/ui-v2/app/styles/base/animation/index.scss new file mode 100644 index 000000000..ca83a1355 --- /dev/null +++ b/ui-v2/app/styles/base/animation/index.scss @@ -0,0 +1,13 @@ +%blink-in-fade-out { + transition-property: opacity; + transition-duration: 0.1s; + transition-timing-function: linear; + opacity: 0; + pointer-events: none; +} +%blink-in-fade-out-active { + transition-duration: 0; + transition-duration: unset; + opacity: 1; + pointer-events: auto; +} diff --git a/ui-v2/app/styles/base/index.scss b/ui-v2/app/styles/base/index.scss index 1f66f3803..8fed6a285 100644 --- a/ui-v2/app/styles/base/index.scss +++ b/ui-v2/app/styles/base/index.scss @@ -1,4 +1,5 @@ @import './decoration/index'; @import './color/index'; +@import './animation/index'; @import './typography/index'; @import './icons/index'; diff --git a/ui-v2/app/styles/components/feedback-dialog.scss b/ui-v2/app/styles/components/feedback-dialog.scss index 5f23cc853..7fbeff2d7 100644 --- a/ui-v2/app/styles/components/feedback-dialog.scss +++ b/ui-v2/app/styles/components/feedback-dialog.scss @@ -2,6 +2,10 @@ main .with-feedback { @extend %feedback-dialog-inline; } +%feedback-dialog-inline .feedback-dialog-out { + @extend %blink-in-fade-out; + transition-delay: 3s; +} @media #{$--lt-spacious-page-header} { .actions .with-feedback p { bottom: auto; @@ -9,6 +13,8 @@ main .with-feedback { } .actions .with-feedback p::after { bottom: auto; - top: -5px; + top: -13px !important; + border-bottom: 18px solid $ui-gray-800; + border-top: 0; } } diff --git a/ui-v2/app/styles/components/feedback-dialog/index.scss b/ui-v2/app/styles/components/feedback-dialog/index.scss index bc1825219..0820684cc 100644 --- a/ui-v2/app/styles/components/feedback-dialog/index.scss +++ b/ui-v2/app/styles/components/feedback-dialog/index.scss @@ -1,2 +1 @@ -@import './skin'; @import './layout'; diff --git a/ui-v2/app/styles/components/feedback-dialog/layout.scss b/ui-v2/app/styles/components/feedback-dialog/layout.scss index 9ead44e9d..dd1ca76aa 100644 --- a/ui-v2/app/styles/components/feedback-dialog/layout.scss +++ b/ui-v2/app/styles/components/feedback-dialog/layout.scss @@ -1,23 +1,12 @@ %feedback-dialog-inline { - position: relative; - display: flex; - justify-content: center; + @extend %tooltip; } + %feedback-dialog-inline p::after { - content: ''; - display: block; - position: absolute; - left: 50%; - margin-left: -5px; - bottom: -5px; - width: 10px; - height: 10px; - transform: rotate(45deg); + @extend %tooltip-tail; + top: auto !important; + bottom: -13px; } %feedback-dialog-inline p { - padding: 10px; - position: absolute; - bottom: 100%; - text-align: center; - white-space: nowrap; //temp + @extend %tooltip-bubble; } diff --git a/ui-v2/app/styles/components/feedback-dialog/skin.scss b/ui-v2/app/styles/components/feedback-dialog/skin.scss deleted file mode 100644 index 172a9f508..000000000 --- a/ui-v2/app/styles/components/feedback-dialog/skin.scss +++ /dev/null @@ -1,5 +0,0 @@ -%feedback-dialog-inline p, -%feedback-dialog-inline p::after { - color: $ui-white; - background-color: $ui-gray-800; -} diff --git a/ui-v2/app/styles/components/with-tooltip.scss b/ui-v2/app/styles/components/with-tooltip.scss index 9ae6b7959..df1a62d51 100644 --- a/ui-v2/app/styles/components/with-tooltip.scss +++ b/ui-v2/app/styles/components/with-tooltip.scss @@ -1,9 +1,4 @@ @import './with-tooltip/index'; %app-view h1 span { - @extend %with-tooltip; -} -%app-view h1 span { - text-indent: -9000px; - font-size: 0; - top: -9px; + @extend %with-pseudo-tooltip; } diff --git a/ui-v2/app/styles/components/with-tooltip/index.scss b/ui-v2/app/styles/components/with-tooltip/index.scss index bc1825219..3ee08c67c 100644 --- a/ui-v2/app/styles/components/with-tooltip/index.scss +++ b/ui-v2/app/styles/components/with-tooltip/index.scss @@ -1,2 +1,27 @@ @import './skin'; @import './layout'; +%with-pseudo-tooltip { + @extend %tooltip; +} +%with-pseudo-tooltip::before { + @extend %tooltip-bubble; +} +%with-pseudo-tooltip::after { + @extend %tooltip-tail; +} +%with-pseudo-tooltip { + text-indent: -9000px; + font-size: 0; + top: -9px; +} + +%with-pseudo-tooltip::after, +%with-pseudo-tooltip::before { + @extend %blink-in-fade-out; +} +%with-pseudo-tooltip:hover::after, +%with-pseudo-tooltip:hover::before, +%with-pseudo-tooltip:focus::after, +%with-pseudo-tooltip:focus::before { + @extend %blink-in-fade-out-active; +} diff --git a/ui-v2/app/styles/components/with-tooltip/layout.scss b/ui-v2/app/styles/components/with-tooltip/layout.scss index 4bc659307..7e16331c0 100644 --- a/ui-v2/app/styles/components/with-tooltip/layout.scss +++ b/ui-v2/app/styles/components/with-tooltip/layout.scss @@ -1,14 +1,14 @@ -%with-tooltip { +%tooltip { position: relative; display: inline-flex; justify-content: center; align-items: center; } -%with-tooltip::before, -%with-tooltip::after { +%tooltip-bubble, +%tooltip-tail { position: absolute; } -%with-tooltip::before { +%tooltip-bubble { padding: 10px; bottom: calc(100% + 5px); text-align: center; @@ -18,22 +18,16 @@ // text of the element %with-tooltip text-indent: 0; } -%with-tooltip::after { +%tooltip-tail { content: ''; left: 50%; - margin-left: -5px; + margin-left: -10px; top: -10px; - width: 10px; - height: 10px; - transform: rotate(45deg); -} -%with-tooltip::after, -%with-tooltip::before { - display: none; -} -%with-tooltip:hover::after, -%with-tooltip:hover::before, -%with-tooltip:focus::after, -%with-tooltip:focus::before { - display: block; + transform: scale(1, 0.5); + width: 0; + height: 0; + background-color: transparent !important; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + border-top: 18px solid $ui-gray-800; } diff --git a/ui-v2/app/styles/components/with-tooltip/skin.scss b/ui-v2/app/styles/components/with-tooltip/skin.scss index 1617d21d9..f8fbf8ac1 100644 --- a/ui-v2/app/styles/components/with-tooltip/skin.scss +++ b/ui-v2/app/styles/components/with-tooltip/skin.scss @@ -1,9 +1,9 @@ -%with-tooltip::before, -%with-tooltip::after { +%tooltip-bubble, +%tooltip-tail { color: $ui-white; background-color: $ui-gray-800; } -%with-tooltip::before { +%tooltip-bubble { border-radius: $decor-radius-200; box-shadow: 0 3px 1px 0 rgba($ui-black, 0.12); } diff --git a/ui-v2/app/styles/core/layout.scss b/ui-v2/app/styles/core/layout.scss index e91ad74ea..974d63447 100644 --- a/ui-v2/app/styles/core/layout.scss +++ b/ui-v2/app/styles/core/layout.scss @@ -28,7 +28,7 @@ html.template-edit main { } @media #{$--lt-spacious-page-header} { .actions button.copy-btn { - margin-top: -42px; + margin-top: -56px; padding: 0; } } @@ -38,7 +38,7 @@ main form + div .with-confirmation { margin-bottom: 2em; } @media #{$--lt-wide-form} { - main form [type="reset"] { + main form [type='reset'] { float: right; margin-right: 0 !important; } diff --git a/ui-v2/app/styles/core/typography.scss b/ui-v2/app/styles/core/typography.scss index beb4407fb..e39a068e3 100644 --- a/ui-v2/app/styles/core/typography.scss +++ b/ui-v2/app/styles/core/typography.scss @@ -51,7 +51,7 @@ th, %breadcrumbs a, %action-group a, %tab-nav, -%with-tooltip::before { +%tooltip-bubble { font-weight: $typo-weight-medium; } main label a[rel*='help'], @@ -84,7 +84,7 @@ td { } th, %form-element > span, -%with-tooltip::before, +%tooltip-bubble, %healthchecked-resource strong, %footer { font-size: $typo-size-700; diff --git a/ui-v2/app/styles/layouts/containers.scss b/ui-v2/app/styles/layouts/containers.scss index 1648a426a..1f1d854c5 100644 --- a/ui-v2/app/styles/layouts/containers.scss +++ b/ui-v2/app/styles/layouts/containers.scss @@ -3,7 +3,7 @@ $ideal-viewport-width: #{$ideal-viewport-width-num}px; $ideal-content-width-num: 1150; $ideal-content-width: #{$ideal-content-width-num}px; $ideal-viewport-padding-num: 24; -$ideal-viewport-padding: #{ideal-viewport-padding-num}px; +$ideal-viewport-padding: #{$ideal-viewport-padding-num}px; $minimum-viewport-padding: 10px; $ideal-content-padding: 33px; @@ -29,15 +29,17 @@ $ideal-content-padding: 33px; padding-left: calc(#{$ideal-viewport-padding-num}vw / (#{$ideal-viewport-width-num} / 100)); padding-right: calc(#{$ideal-viewport-padding-num}vw / (#{$ideal-viewport-width-num} / 100)); } +%content-container { + padding-left: calc(33% / (#{$ideal-viewport-width-num} / 100)); + padding-right: calc(33% / (#{$ideal-viewport-width-num} / 100)); + padding-left: calc(24vw / (#{$ideal-viewport-width-num} / 100)); + padding-right: calc(24vw / (#{$ideal-viewport-width-num} / 100)); +} @media #{$--min-padding} { %viewport-container { padding-left: $minimum-viewport-padding; padding-right: $minimum-viewport-padding; } - %content-container { - padding-left: $ideal-viewport-padding; - padding-right: $ideal-viewport-padding; - } } @media #{$--max-padding} { %viewport-container { @@ -49,9 +51,3 @@ $ideal-content-padding: 33px; padding-right: $ideal-viewport-padding; } } -%content-container { - padding-left: calc(33% / (#{$ideal-viewport-width-num} / 100)); - padding-right: calc(33% / (#{$ideal-viewport-width-num} / 100)); - padding-left: calc(24vw / (#{$ideal-viewport-width-num} / 100)); - padding-right: calc(24vw / (#{$ideal-viewport-width-num} / 100)); -} diff --git a/ui-v2/app/templates/components/feedback-dialog.hbs b/ui-v2/app/templates/components/feedback-dialog.hbs index 87ca58c99..eb6e3adbc 100644 --- a/ui-v2/app/templates/components/feedback-dialog.hbs +++ b/ui-v2/app/templates/components/feedback-dialog.hbs @@ -1,8 +1,8 @@ {{yield}} {{#if (eq state 'success') }} - {{#yield-slot 'success'}}{{yield}}{{/yield-slot}} + {{#yield-slot 'success' (block-params transition)}}{{yield}}{{/yield-slot}} {{else if (eq state 'error') }} - {{#yield-slot 'error'}}{{yield}}{{/yield-slot}} + {{#yield-slot 'error' (block-params transition)}}{{yield}}{{/yield-slot}} {{/if}} {{#if (or permanent (eq state 'ready')) }} {{#yield-slot 'action' (block-params success error)}}{{yield}}{{message}}{{/yield-slot}} diff --git a/ui-v2/app/templates/components/healthcheck-status.hbs b/ui-v2/app/templates/components/healthcheck-status.hbs index c6a507ee1..05a75e40a 100644 --- a/ui-v2/app/templates/components/healthcheck-status.hbs +++ b/ui-v2/app/templates/components/healthcheck-status.hbs @@ -4,15 +4,15 @@ Copy Output {{/copy-button}} {{/block-slot}} - {{#block-slot 'success'}} -

- Copied output! -

+ {{#block-slot 'success' as |transition|}} +

+ Copied IP Address! +

{{/block-slot}} - {{#block-slot 'error'}} -

- Sorry, something went wrong! -

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

+ Sorry, something went wrong! +

{{/block-slot}} {{/feedback-dialog}}
diff --git a/ui-v2/app/templates/dc/acls/edit.hbs b/ui-v2/app/templates/dc/acls/edit.hbs index dde086202..5cb731916 100644 --- a/ui-v2/app/templates/dc/acls/edit.hbs +++ b/ui-v2/app/templates/dc/acls/edit.hbs @@ -24,13 +24,13 @@ Copy token ID {{/copy-button}} {{/block-slot}} - {{#block-slot 'success'}} -

+ {{#block-slot 'success' as |transition|}} +

Copied token ID!

{{/block-slot}} - {{#block-slot 'error'}} -

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

Sorry, something went wrong!

{{/block-slot}} diff --git a/ui-v2/app/templates/dc/intentions/edit.hbs b/ui-v2/app/templates/dc/intentions/edit.hbs index 8ee321c36..5002bbfe1 100644 --- a/ui-v2/app/templates/dc/intentions/edit.hbs +++ b/ui-v2/app/templates/dc/intentions/edit.hbs @@ -24,13 +24,13 @@ Copy UUID {{/copy-button}} {{/block-slot}} - {{#block-slot 'success'}} -

+ {{#block-slot 'success' as |transition|}} +

Copied UUID!

{{/block-slot}} - {{#block-slot 'error'}} -

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

Sorry, something went wrong!

{{/block-slot}} diff --git a/ui-v2/app/templates/dc/nodes/show.hbs b/ui-v2/app/templates/dc/nodes/show.hbs index 91bb73b32..10a12fc57 100644 --- a/ui-v2/app/templates/dc/nodes/show.hbs +++ b/ui-v2/app/templates/dc/nodes/show.hbs @@ -32,13 +32,13 @@ {{item.Address}} {{/copy-button}} {{/block-slot}} - {{#block-slot 'success'}} -

+ {{#block-slot 'success' as |transition|}} +

Copied IP Address!

{{/block-slot}} - {{#block-slot 'error'}} -

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

Sorry, something went wrong!

{{/block-slot}} diff --git a/ui-v2/app/utils/promisedTimeout.js b/ui-v2/app/utils/promisedTimeout.js index be616e103..cd16f0987 100644 --- a/ui-v2/app/utils/promisedTimeout.js +++ b/ui-v2/app/utils/promisedTimeout.js @@ -1,6 +1,6 @@ export default function(P = Promise, timeout = setTimeout) { // var interval; - return function(milliseconds, cb) { + return function(milliseconds, cb = function() {}) { // clearInterval(interval); // const cb = typeof _cb !== 'function' ? (i) => { clearInterval(interval);interval = i; } : _cb; return new P((resolve, reject) => {