diff --git a/ui/.storybook/preview-head.html b/ui/.storybook/preview-head.html
index 9c353e54b153..13cafd050917 100644
--- a/ui/.storybook/preview-head.html
+++ b/ui/.storybook/preview-head.html
@@ -1,4 +1,6 @@
-
+
+
+
diff --git a/ui/app/app.js b/ui/app/app.js
index 8b963f8e10cb..a215b634c98a 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -8,10 +8,27 @@ defineModifier();
let App;
+/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver,
+ engines: {
+ replication: {
+ dependencies: {
+ services: [
+ 'auth',
+ 'flash-messages',
+ 'namespace',
+ 'replication-mode',
+ 'router',
+ 'store',
+ 'version',
+ 'wizard',
+ ],
+ },
+ },
+ },
});
loadInitializers(App, config.modulePrefix);
diff --git a/ui/app/components/download-button.js b/ui/app/components/download-button.js
index 46ce1219808a..8e3f3727e0d2 100644
--- a/ui/app/components/download-button.js
+++ b/ui/app/components/download-button.js
@@ -3,7 +3,7 @@ import { computed } from '@ember/object';
import hbs from 'htmlbars-inline-precompile';
export default Component.extend({
- layout: hbs`{{#if hasBlock}} {{yield}} {{else}} {{actionText}} {{/if}}`,
+ layout: hbs`{{#if (has-block)}} {{yield}} {{else}} {{actionText}} {{/if}}`,
tagName: 'a',
role: 'button',
attributeBindings: ['role', 'download', 'href'],
diff --git a/ui/app/components/empty-state.js b/ui/app/components/empty-state.js
deleted file mode 100644
index 04e6c3d213c7..000000000000
--- a/ui/app/components/empty-state.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import OuterHTML from './outer-html';
-
-export default OuterHTML.extend({
- title: null,
- message: null,
-});
diff --git a/ui/app/components/i-con.js b/ui/app/components/i-con.js
deleted file mode 100644
index 589aa600da97..000000000000
--- a/ui/app/components/i-con.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import { camelize } from '@ember/string';
-import Component from '@ember/component';
-import { computed } from '@ember/object';
-import hbs from 'htmlbars-inline-precompile';
-
-/**
- * @module ICon
- * `ICon` components are glyphs used to indicate important information.
- *
- * @example
- * ```js
- *
- * ```
- * @param glyph=null {String} - The glyph type.
- *
- */
-
-export const GLYPHS_WITH_SVG_TAG = [
- 'cancel-square-outline',
- 'cancel-square-fill',
- 'check-circle-fill',
- 'check-plain',
- 'checkmark-circled-outline',
- 'close-circled-outline',
- 'console',
- 'control-lock',
- 'docs',
- 'download',
- 'edition-enterprise',
- 'edition-oss',
- 'false',
- 'file',
- 'folder',
- 'hidden',
- 'information-reversed',
- 'learn',
- 'neutral-circled-outline',
- 'perf-replication',
- 'person',
- 'plus-plain',
- 'role',
- 'status-indicator',
- 'stopwatch',
- 'tour',
- 'true',
- 'upload',
- 'video',
- 'visible',
-];
-
-export default Component.extend({
- layout: hbs`
- {{#if excludeSVG}}
- {{partial partialName}}
- {{else}}
-
- {{partial partialName}}
-
- {{/if}}
- `,
-
- tagName: 'span',
- excludeIconClass: false,
- classNameBindings: ['excludeIconClass::icon'],
- classNames: ['has-current-color-fill'],
-
- attributeBindings: ['aria-label', 'aria-hidden'],
-
- glyph: null,
-
- excludeSVG: computed('glyph', function() {
- let glyph = this.get('glyph');
- return glyph.startsWith('enable/') || GLYPHS_WITH_SVG_TAG.includes(glyph);
- }),
-
- size: computed('glyph', function() {
- return this.get('glyph').startsWith('enable/') ? 48 : 12;
- }),
-
- partialName: computed('glyph', function() {
- const glyph = this.get('glyph');
- return `svg/icons/${camelize(glyph)}`;
- }),
-});
diff --git a/ui/app/components/info-table-row.js b/ui/app/components/info-table-row.js
deleted file mode 100644
index 1be591196dc0..000000000000
--- a/ui/app/components/info-table-row.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { typeOf } from '@ember/utils';
-import { computed } from '@ember/object';
-import { or } from '@ember/object/computed';
-import Component from '@ember/component';
-
-export default Component.extend({
- 'data-test-component': 'info-table-row',
- classNames: ['info-table-row'],
- isVisible: or('alwaysRender', 'value'),
-
- /*
- * @param boolean
- * indicates if the component content should be always be rendered.
- * when false, the value of `value` will be used to determine if the component should render
- */
- alwaysRender: false,
-
- /*
- * @param string
- * the display name for the value
- *
- */
- label: null,
-
- /*
- *
- * the value of the data passed in - by default the content of the component will only show if there is a value
- */
- value: null,
-
- valueIsBoolean: computed('value', function() {
- return typeOf(this.get('value')) === 'boolean';
- }),
-});
diff --git a/ui/app/components/popup-menu.js b/ui/app/components/popup-menu.js
deleted file mode 100644
index 3f263270c4e2..000000000000
--- a/ui/app/components/popup-menu.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
- tagName: 'span',
-});
diff --git a/ui/app/components/secret-form-header.js b/ui/app/components/secret-form-header.js
deleted file mode 100644
index d8b27ca6ee34..000000000000
--- a/ui/app/components/secret-form-header.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import { alias } from '@ember/object/computed';
-import Component from '@ember/component';
-import hbs from 'htmlbars-inline-precompile';
-
-export default Component.extend({
- key: null,
- mode: null,
- path: null,
- actionClass: null,
-
- title: alias('key.keyWithoutParent'),
-
- layout: hbs`
-
`,
-});
diff --git a/ui/app/components/status-menu.js b/ui/app/components/status-menu.js
index 642ff3d8db4a..406749a0cf92 100644
--- a/ui/app/components/status-menu.js
+++ b/ui/app/components/status-menu.js
@@ -18,7 +18,7 @@ export default Component.extend({
glyphName: computed('type', function() {
const glyphs = {
cluster: 'status-indicator',
- user: 'person',
+ user: 'user-square-outline',
};
return glyphs[this.type];
}),
diff --git a/ui/app/components/toolbar-actions.js b/ui/app/components/toolbar-actions.js
deleted file mode 100644
index 2f278cc523a2..000000000000
--- a/ui/app/components/toolbar-actions.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import OuterHTML from './outer-html';
-
-export default OuterHTML.extend({});
diff --git a/ui/app/components/toolbar.js b/ui/app/components/toolbar.js
deleted file mode 100644
index d24354b9c5cc..000000000000
--- a/ui/app/components/toolbar.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import OuterHTML from './outer-html';
-
-export default OuterHTML.extend({
- classNames: ['toolbar'],
- tagName: 'nav',
-});
diff --git a/ui/app/controllers/vault/cluster/replication/mode/secondaries/add.js b/ui/app/controllers/vault/cluster/replication/mode/secondaries/add.js
deleted file mode 100644
index 01da58dffbe3..000000000000
--- a/ui/app/controllers/vault/cluster/replication/mode/secondaries/add.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import ReplicationController from '../../../replication';
-
-export default ReplicationController.extend();
diff --git a/ui/app/controllers/vault/cluster/replication/mode/secondaries/index.js b/ui/app/controllers/vault/cluster/replication/mode/secondaries/index.js
deleted file mode 100644
index 01da58dffbe3..000000000000
--- a/ui/app/controllers/vault/cluster/replication/mode/secondaries/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import ReplicationController from '../../../replication';
-
-export default ReplicationController.extend();
diff --git a/ui/app/controllers/vault/cluster/replication/mode/secondaries/revoke.js b/ui/app/controllers/vault/cluster/replication/mode/secondaries/revoke.js
deleted file mode 100644
index 9be89e9d34fb..000000000000
--- a/ui/app/controllers/vault/cluster/replication/mode/secondaries/revoke.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '../../../replication';
diff --git a/ui/app/helpers/includes.js b/ui/app/helpers/includes.js
deleted file mode 100644
index ff61d3586b9d..000000000000
--- a/ui/app/helpers/includes.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { helper as buildHelper } from '@ember/component/helper';
-
-export function includes([haystack, needle]) {
- return haystack.includes(needle);
-}
-
-export default buildHelper(includes);
diff --git a/ui/app/helpers/reduce-to-array.js b/ui/app/helpers/reduce-to-array.js
deleted file mode 100644
index b6d76d9e2b24..000000000000
--- a/ui/app/helpers/reduce-to-array.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { helper as buildHelper } from '@ember/component/helper';
-import { isNone, typeOf } from '@ember/utils';
-
-export function reduceToArray(params) {
- return params.reduce(function(result, param) {
- if (isNone(param)) {
- return result;
- }
- if (typeOf(param) === 'array') {
- return result.concat(param);
- } else {
- return result.concat([param]);
- }
- }, []);
-}
-
-export default buildHelper(reduceToArray);
diff --git a/ui/app/initializers/enable-engines.js b/ui/app/initializers/enable-engines.js
new file mode 100644
index 000000000000..858f36b06d08
--- /dev/null
+++ b/ui/app/initializers/enable-engines.js
@@ -0,0 +1,13 @@
+import config from '../config/environment';
+
+export function initialize(/* application */) {
+ // attach mount hooks to the environment config
+ // context will be the router DSL
+ config.addRootMounts = function() {
+ this.mount('replication');
+ };
+}
+
+export default {
+ initialize,
+};
diff --git a/ui/app/mixins/cluster-route.js b/ui/app/mixins/cluster-route.js
index 9b814c99ed14..2b7ff244ed23 100644
--- a/ui/app/mixins/cluster-route.js
+++ b/ui/app/mixins/cluster-route.js
@@ -13,6 +13,7 @@ export { INIT, UNSEAL, AUTH, CLUSTER, DR_REPLICATION_SECONDARY };
export default Mixin.create({
auth: service(),
+ store: service(),
transitionToTargetRoute(transition) {
const targetRoute = this.targetRouteName(transition);
@@ -28,7 +29,7 @@ export default Mixin.create({
},
clusterModel() {
- return this.modelFor(CLUSTER);
+ return this.modelFor(CLUSTER) || this.store.peekRecord('cluster', 'vault');
},
authToken() {
diff --git a/ui/app/models/cluster.js b/ui/app/models/cluster.js
index 2ed2686cb110..5084d63ed3d0 100644
--- a/ui/app/models/cluster.js
+++ b/ui/app/models/cluster.js
@@ -70,7 +70,7 @@ export default DS.Model.extend({
}),
stateGlyph(state) {
- const glyph = 'checkmark-circled-outline';
+ const glyph = 'check-circled-outline';
const glyphs = {
'stream-wals': 'android-sync',
diff --git a/ui/app/router.js b/ui/app/router.js
index b1b87d87904e..de87a5433917 100644
--- a/ui/app/router.js
+++ b/ui/app/router.js
@@ -114,22 +114,9 @@ Router.map(function() {
this.route('edit', { path: '/:policy_name/edit' });
});
this.route('replication-dr-promote');
- this.route('replication', function() {
- this.route('index', { path: '/' });
- this.route('mode', { path: '/:replication_mode' }, function() {
- //details
- this.route('index', { path: '/' });
- this.route('manage');
- this.route('secondaries', function() {
- this.route('add', { path: '/add' });
- this.route('revoke', { path: '/revoke' });
- this.route('config-show', { path: '/config/show/:secondary_id' });
- this.route('config-edit', { path: '/config/edit/:secondary_id' });
- this.route('config-create', { path: '/config/create/:secondary_id' });
- });
- });
- });
-
+ if (config.addRootMounts) {
+ config.addRootMounts.call(this);
+ }
this.route('not-found', { path: '/*path' });
});
this.route('not-found', { path: '/*path' });
diff --git a/ui/app/routes/vault/cluster/replication/mode/index.js b/ui/app/routes/vault/cluster/replication/mode/index.js
deleted file mode 100644
index b2663787983c..000000000000
--- a/ui/app/routes/vault/cluster/replication/mode/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { inject as service } from '@ember/service';
-import Route from '@ember/routing/route';
-
-export default Route.extend({
- replicationMode: service(),
- beforeModel() {
- const replicationMode = this.paramsFor('vault.cluster.replication.mode').replication_mode;
- this.get('replicationMode').setMode(replicationMode);
- },
- model() {
- return this.modelFor('vault.cluster.replication.mode');
- },
-});
diff --git a/ui/app/styles/components/console-ui-panel.scss b/ui/app/styles/components/console-ui-panel.scss
index 26523f76c115..170af92dec9b 100644
--- a/ui/app/styles/components/console-ui-panel.scss
+++ b/ui/app/styles/components/console-ui-panel.scss
@@ -106,7 +106,7 @@
margin-left: calc(#{$console-spacing} - 0.33rem);
position: relative;
- .icon {
+ .hs-icon {
position: absolute;
left: 0;
top: 0;
diff --git a/ui/app/styles/components/env-banner.scss b/ui/app/styles/components/env-banner.scss
index d2851dcf6965..607abd2447fb 100644
--- a/ui/app/styles/components/env-banner.scss
+++ b/ui/app/styles/components/env-banner.scss
@@ -1,10 +1,24 @@
.env-banner {
- &,
- &:not(:last-child):not(:last-child) {
+ align-self: center;
+ border-radius: 3rem;
+ background: linear-gradient(135deg, $blue, $purple);
+ animation: env-banner-color-rotate 8s infinite linear alternate;
+ color: $white;
+ margin-top: -20px;
+
+ .hs-icon {
margin: 0;
}
- .level-item {
- padding: $size-10 $size-8;
+ .notification {
+ background-color: transparent;
+ line-height: 1.66;
+ padding: 0 $spacing-s;
+ }
+}
+
+@keyframes env-banner-color-rotate {
+ 100% {
+ filter: hue-rotate(105deg);
}
}
diff --git a/ui/app/styles/components/hs-icon.scss b/ui/app/styles/components/hs-icon.scss
new file mode 100644
index 000000000000..7cfc1bc0ecf6
--- /dev/null
+++ b/ui/app/styles/components/hs-icon.scss
@@ -0,0 +1,37 @@
+.hs-icon {
+ flex: 0 0 auto;
+ display: inline-flex;
+ justify-content: center;
+ align-items: flex-start;
+ vertical-align: middle;
+ width: 16px;
+ min-width: fit-content;
+ margin: 2px 4px;
+}
+
+.hs-icon svg {
+ fill: currentColor;
+ flex: 1 1 0;
+}
+
+.hs-icon-button-right {
+ margin-left: 0.25rem;
+ margin-right: -0.5rem;
+ align-items: center;
+}
+
+.hs-icon-s {
+ width: 12px;
+}
+
+.hs-icon-l {
+ width: 20px;
+}
+
+.hs-icon-xl {
+ width: 28px;
+}
+
+.hs-icon-xxl {
+ width: 32px;
+}
diff --git a/ui/app/styles/components/info-table-row.scss b/ui/app/styles/components/info-table-row.scss
index c887102bc4a8..bca18fd24b7c 100644
--- a/ui/app/styles/components/info-table-row.scss
+++ b/ui/app/styles/components/info-table-row.scss
@@ -27,9 +27,15 @@
}
}
- .icon {
+ .hs-icon {
margin-right: 0.25rem;
}
+ .icon-true {
+ color: $green-500;
+ }
+ .icon-false {
+ color: $ui-gray-300;
+ }
}
.info-table-row:not(.is-mobile) .column {
diff --git a/ui/app/styles/components/navigate-input.scss b/ui/app/styles/components/navigate-input.scss
new file mode 100644
index 000000000000..471e851770ac
--- /dev/null
+++ b/ui/app/styles/components/navigate-input.scss
@@ -0,0 +1,5 @@
+.search-icon {
+ position: absolute;
+ top: 6px;
+ left: 2px;
+}
diff --git a/ui/app/styles/components/search-select.scss b/ui/app/styles/components/search-select.scss
index fe117126d91d..cd764ae96bec 100644
--- a/ui/app/styles/components/search-select.scss
+++ b/ui/app/styles/components/search-select.scss
@@ -122,3 +122,9 @@
animation: drop-fade-above 0.15s;
}
}
+
+.search-select .search-icon {
+ position: absolute;
+ width: 20px;
+ top: 5px;
+}
diff --git a/ui/app/styles/components/tool-tip.scss b/ui/app/styles/components/tool-tip.scss
index 13591c3970f6..36ff3991812d 100644
--- a/ui/app/styles/components/tool-tip.scss
+++ b/ui/app/styles/components/tool-tip.scss
@@ -50,18 +50,6 @@
.ember-basic-dropdown-content--above.tool-tip {
margin-top: -2px;
}
-.tool-tip-trigger {
- border: none;
- border-radius: 20px;
- height: 18px;
- width: 18px;
- outline: none;
- box-shadow: none;
- cursor: pointer;
- padding: 0;
- color: $grey-dark;
- margin-left: 8px;
-}
.b-checkbox .tool-tip-trigger {
position: relative;
diff --git a/ui/app/styles/components/ui-wizard.scss b/ui/app/styles/components/ui-wizard.scss
index dbc2a659fb87..186bfadbe820 100644
--- a/ui/app/styles/components/ui-wizard.scss
+++ b/ui/app/styles/components/ui-wizard.scss
@@ -70,7 +70,7 @@
.wizard-header {
border-bottom: $light-border;
- padding: 0 $size-4 $size-8 2rem;
+ padding: 0 $size-4 $size-8 0;
margin: $size-4 0;
position: relative;
@@ -78,12 +78,6 @@
margin-top: 0;
padding-top: 0;
}
-
- .title .icon {
- left: 0;
- position: absolute;
- top: 0;
- }
}
.wizard-dismiss-menu {
@@ -117,10 +111,6 @@
.title {
color: $white;
-
- .icon {
- top: -0.1rem;
- }
}
.wizard-header {
@@ -154,12 +144,6 @@
}
}
-.wizard-section .title .icon {
- height: auto;
- margin-right: $size-11;
- width: auto;
-}
-
.wizard-section:last-of-type {
margin-bottom: $size-5;
}
@@ -236,6 +220,7 @@
transform: translate(-50%, -50%);
width: $wizard-progress-check-size;
z-index: 10;
+ margin: 0 !important;
}
.feature-progress-container .feature-check {
@@ -258,10 +243,10 @@
}
}
-.incomplete-check svg {
- fill: $ui-gray-200;
+.incomplete-check {
+ color: $ui-gray-200;
}
-.completed-check svg {
- fill: $green;
+.completed-check {
+ color: $green;
}
diff --git a/ui/app/styles/core.scss b/ui/app/styles/core.scss
index 03e9e933fe3e..0eb83f62b46e 100644
--- a/ui/app/styles/core.scss
+++ b/ui/app/styles/core.scss
@@ -66,6 +66,7 @@
@import './components/masked-input';
@import './components/namespace-picker';
@import './components/namespace-reminder';
+@import './components/navigate-input';
@import './components/page-header';
@import './components/popup-menu';
@import './components/radial-progress';
@@ -83,3 +84,6 @@
@import './components/upgrade-overlay';
@import './components/ui-wizard';
@import './components/vault-loading';
+
+// bulma-free-zone
+@import './components/hs-icon';
diff --git a/ui/app/styles/core/buttons.scss b/ui/app/styles/core/buttons.scss
index 6d1d74578545..8f696d408cc2 100644
--- a/ui/app/styles/core/buttons.scss
+++ b/ui/app/styles/core/buttons.scss
@@ -158,20 +158,17 @@ $button-box-shadow-standard: 0 3px 1px 0 rgba($black, 0.12);
.has-text-info & {
font-weight: $font-weight-semibold;
-
- .icon {
- vertical-align: middle;
- }
}
&.tool-tip-trigger {
- color: $black;
+ color: $grey-dark;
min-width: auto;
+ padding: 0;
}
&.has-icon-left,
&.has-icon-right {
- .icon {
+ .hs-icon {
height: 16px;
min-width: auto;
width: 16px;
@@ -179,7 +176,7 @@ $button-box-shadow-standard: 0 3px 1px 0 rgba($black, 0.12);
}
&.has-icon-left {
- .icon {
+ .hs-icon {
&,
&:first-child:last-child {
position: relative;
@@ -189,7 +186,7 @@ $button-box-shadow-standard: 0 3px 1px 0 rgba($black, 0.12);
}
&.has-icon-right {
- .icon {
+ .hs-icon {
&,
&:first-child:last-child {
margin-left: $spacing-xxs;
diff --git a/ui/app/styles/core/message.scss b/ui/app/styles/core/message.scss
index 7e8932b91180..151d159f1e61 100644
--- a/ui/app/styles/core/message.scss
+++ b/ui/app/styles/core/message.scss
@@ -101,8 +101,7 @@
display: flex;
margin: 0 0 $spacing-l;
- .icon {
- flex: 0;
+ .hs-icon {
margin: 0 $spacing-xxs 0 0;
min-width: fit-content;
}
diff --git a/ui/app/styles/core/navbar.scss b/ui/app/styles/core/navbar.scss
index 7f6f79e86a83..a981fcf12b10 100644
--- a/ui/app/styles/core/navbar.scss
+++ b/ui/app/styles/core/navbar.scss
@@ -159,7 +159,6 @@
font-size: 1rem;
height: auto;
justify-content: flex-start;
- padding: 0 $spacing-xxs;
text-align: left;
width: 100%;
diff --git a/ui/app/templates/components/alert-inline.hbs b/ui/app/templates/components/alert-inline.hbs
deleted file mode 100644
index 4b841feca4c1..000000000000
--- a/ui/app/templates/components/alert-inline.hbs
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- {{@message}}
-
diff --git a/ui/app/templates/components/alert-popup.hbs b/ui/app/templates/components/alert-popup.hbs
index 3a018dd48e21..ef92bc61c9d8 100644
--- a/ui/app/templates/components/alert-popup.hbs
+++ b/ui/app/templates/components/alert-popup.hbs
@@ -1,11 +1,18 @@
-
+
-
+
{{type.text}}
diff --git a/ui/app/templates/components/auth-form.hbs b/ui/app/templates/components/auth-form.hbs
index c55c7166aa08..bbdbaba435d0 100644
--- a/ui/app/templates/components/auth-form.hbs
+++ b/ui/app/templates/components/auth-form.hbs
@@ -1,7 +1,7 @@