diff --git a/.changelog/20359.txt b/.changelog/20359.txt new file mode 100644 index 0000000000..c010b32ef5 --- /dev/null +++ b/.changelog/20359.txt @@ -0,0 +1,3 @@ +```release-note:feature +ui: Adds a redirect and warning message around unavailable UI with V2 enabled +``` diff --git a/ui/packages/consul-ui/app/routes/application.js b/ui/packages/consul-ui/app/routes/application.js index 40dce71533..8cc6ce87e2 100644 --- a/ui/packages/consul-ui/app/routes/application.js +++ b/ui/packages/consul-ui/app/routes/application.js @@ -13,13 +13,21 @@ export default class ApplicationRoute extends Route.extend(WithBlockingActions) @service('client/http') client; @service('env') env; @service() hcp; + @service() router; data; + beforeModel() { + if (this.env.var('CONSUL_V2_CATALOG_ENABLED')) { + this.router.replaceWith('unavailable'); + } + } + async model() { if (this.env.var('CONSUL_ACLS_ENABLED')) { await this.hcp.updateTokenIfNecessary(this.env.var('CONSUL_HTTP_TOKEN')); } + return {}; } diff --git a/ui/packages/consul-ui/app/routes/unavailable.js b/ui/packages/consul-ui/app/routes/unavailable.js new file mode 100644 index 0000000000..8bee82ffb2 --- /dev/null +++ b/ui/packages/consul-ui/app/routes/unavailable.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Route from 'consul-ui/routing/route'; +import { inject as service } from '@ember/service'; + +export default class UnavailableRoute extends Route { + @service('env') env; + @service() router; + + beforeModel() { + if (!this.env.var('CONSUL_V2_CATALOG_ENABLED')) { + this.router.replaceWith('index'); + } + } +} diff --git a/ui/packages/consul-ui/app/templates/application.hbs b/ui/packages/consul-ui/app/templates/application.hbs index bab98e7b1f..b0c9054ce6 100644 --- a/ui/packages/consul-ui/app/templates/application.hbs +++ b/ui/packages/consul-ui/app/templates/application.hbs @@ -7,41 +7,46 @@ {{! Add the a11y route announcer }} - {{! Tell CSS what we have enabled }} - {{#if (can 'use acls')}} - {{document-attrs class="has-acls"}} - {{/if}} - {{#if (can 'use nspaces')}} - {{document-attrs class="has-nspaces" }} - {{/if}} - {{#if (can 'use partitions')}} - {{document-attrs class="has-partitions" }} - {{/if}} - {{! Listen out for blocking query/client setting changes }} - + {{#unless (env 'CONSUL_V2_CATALOG_ENABLED')}} + {{! Tell CSS what we have enabled }} + {{#if (can 'use acls')}} + {{document-attrs class='has-acls'}} + {{/if}} + {{#if (can 'use nspaces')}} + {{document-attrs class='has-nspaces'}} + {{/if}} + {{#if (can 'use partitions')}} + {{document-attrs class='has-partitions'}} + {{/if}} - {{! Tell CSS about our theme }} - - {{#each-in source.data as |key value|}} - {{#if (and value (includes key (array 'color-scheme' 'contrast')))}} - {{document-attrs class=(concat "prefers-" key "-" value) }} - {{/if}} - {{/each-in}} - - - {{! If ACLs are enabled try get a token }} - {{#if (can 'use acls')}} + {{! Listen out for blocking query/client setting changes }} - {{/if}} - {{#if (not-eq route.currentName 'oauth-provider-debug')}} + {{! Tell CSS about our theme }} + + {{#each-in source.data as |key value|}} + {{#if (and value (includes key (array 'color-scheme' 'contrast')))}} + {{document-attrs class=(concat 'prefers-' key '-' value)}} + {{/if}} + {{/each-in}} + + + {{! If ACLs are enabled try get a token }} + {{#if (can 'use acls')}} + + {{/if}} + {{/unless}} + + {{#if + (and (not (env 'CONSUL_V2_CATALOG_ENABLED')) (not-eq route.currentName 'oauth-provider-debug')) + }} {{! redirect if we aren't on a URL with dc information }} {{#if (eq route.currentName 'index')}} @@ -140,4 +145,4 @@ {{outlet}} {{/if}} - + \ No newline at end of file diff --git a/ui/packages/consul-ui/app/templates/unavailable.hbs b/ui/packages/consul-ui/app/templates/unavailable.hbs new file mode 100644 index 0000000000..8c591f8238 --- /dev/null +++ b/ui/packages/consul-ui/app/templates/unavailable.hbs @@ -0,0 +1,106 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: BUSL-1.1 +}} + + + {{#if (env 'CONSUL_V2_CATALOG_ENABLED')}} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ {{/if}} +
\ No newline at end of file diff --git a/ui/packages/consul-ui/tests/acceptance/unavailable-test.js b/ui/packages/consul-ui/tests/acceptance/unavailable-test.js new file mode 100644 index 0000000000..9a983dc994 --- /dev/null +++ b/ui/packages/consul-ui/tests/acceptance/unavailable-test.js @@ -0,0 +1,65 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { currentURL, visit } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import { setupTestEnv } from 'consul-ui/services/env'; + +const unavailableHeaderSelector = '[data-test-unavailable-header]'; +const unavailableBodySelector = '[data-test-unavailable-body]'; + +module('Acceptance | unavailable page', function (hooks) { + setupApplicationTest(hooks); + + test('it redirects to the unavailable page when the v2 catalog is enabled', async function (assert) { + assert.expect(3); + + setupTestEnv(this.owner, { + CONSUL_V2_CATALOG_ENABLED: true, + }); + + await visit('/'); + assert.equal(currentURL(), '/unavailable', 'It should redirect to the unavailable page'); + + // Expect the warning message to be visible + assert.dom(unavailableHeaderSelector).hasText('User Interface Unavailable'); + assert.dom(unavailableBodySelector).exists({ count: 1 }); + }); + + test('it does not redirect to the unavailable page', async function (assert) { + assert.expect(3); + + setupTestEnv(this.owner, { + CONSUL_V2_CATALOG_ENABLED: false, + }); + + await visit('/'); + assert.equal( + currentURL(), + '/dc1/services', + 'It should continue to the services page when v2 catalog is disabled' + ); + + // Expect the warning message to be not be visible + assert.dom(unavailableHeaderSelector).doesNotExist(); + assert.dom(unavailableBodySelector).doesNotExist(); + }); + + test('it redirects away from the unavailable page when v2 catalog is not enabled', async function (assert) { + assert.expect(3); + + setupTestEnv(this.owner, { + CONSUL_V2_CATALOG_ENABLED: false, + }); + + await visit('/unavailable'); + assert.equal(currentURL(), '/dc1/services', 'It should redirect to the services page'); + + // Expect the warning message to be not be visible + assert.dom(unavailableHeaderSelector).doesNotExist(); + assert.dom(unavailableBodySelector).doesNotExist(); + }); +}); diff --git a/ui/packages/consul-ui/vendor/consul-ui/routes.js b/ui/packages/consul-ui/vendor/consul-ui/routes.js index 07abd5c1b7..214b8fc8b8 100644 --- a/ui/packages/consul-ui/vendor/consul-ui/routes.js +++ b/ui/packages/consul-ui/vendor/consul-ui/routes.js @@ -439,6 +439,9 @@ redirect: '../settings', }, }, + unavailable: { + _options: { path: '/unavailable' }, + }, notfound: { _options: { path: '/*notfound' }, },