diff --git a/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.hbs b/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.hbs index 76e2256925..f59e996d82 100644 --- a/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.hbs +++ b/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.hbs @@ -33,8 +33,7 @@ @text="Preview" @color="tertiary" @icon="eye" - disabled={{and (not @message.title @message.message)}} - {{on "click" (fn (mut this.showMessagePreviewModal) true)}} + {{on "click" this.displayPreviewModal}} data-test-button="preview" /> diff --git a/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.js b/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.js index 9d74a26e22..1f2059e884 100644 --- a/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.js +++ b/ui/lib/config-ui/addon/components/messages/page/create-and-edit-message-form.js @@ -44,15 +44,20 @@ export default class MessagesList extends Component { } } + validate() { + const { isValid, state, invalidFormMessage } = this.args.message.validate(); + this.modelValidations = isValid ? null : state; + this.invalidFormAlert = invalidFormMessage; + return isValid; + } + @task *save(event) { event.preventDefault(); try { this.userConfirmation = ''; - const { isValid, state, invalidFormMessage } = this.args.message.validate(); - this.modelValidations = isValid ? null : state; - this.invalidFormAlert = invalidFormMessage; + const isValid = this.validate(); if (this.args.hasSomeActiveModals && this.args.message.type === 'modal') { this.showMultipleModalsMessage = true; @@ -87,6 +92,14 @@ export default class MessagesList extends Component { } } + @action + displayPreviewModal() { + const isValid = this.validate(); + if (isValid) { + this.showMessagePreviewModal = true; + } + } + @action updateUserConfirmation(userConfirmation) { this.userConfirmation = userConfirmation; diff --git a/ui/lib/config-ui/addon/components/messages/page/details.js b/ui/lib/config-ui/addon/components/messages/page/details.js index 56e5ad73cc..e5e49da02d 100644 --- a/ui/lib/config-ui/addon/components/messages/page/details.js +++ b/ui/lib/config-ui/addon/components/messages/page/details.js @@ -6,6 +6,7 @@ import Component from '@glimmer/component'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; +import errorMessage from 'vault/utils/error-message'; /** * @module Page::MessageDetails @@ -26,10 +27,15 @@ export default class MessageDetails extends Component { @action async deleteMessage() { - this.store.clearDataset('config-ui/message'); - await this.args.message.destroyRecord(this.args.message.id); - this.router.transitionTo('vault.cluster.config-ui.messages'); - this.customMessages.fetchMessages(this.namespace.path); - this.flashMessages.success(`Successfully deleted ${this.args.message.title}.`); + try { + this.store.clearDataset('config-ui/message'); + await this.args.message.destroyRecord(this.args.message.id); + this.router.transitionTo('vault.cluster.config-ui.messages'); + this.customMessages.fetchMessages(this.namespace.path); + this.flashMessages.success(`Successfully deleted ${this.args.message.title}.`); + } catch (e) { + const message = errorMessage(e); + this.flashMessages.danger(message); + } } } diff --git a/ui/lib/config-ui/addon/components/messages/page/list.hbs b/ui/lib/config-ui/addon/components/messages/page/list.hbs index c1819373bb..e43bd519bc 100644 --- a/ui/lib/config-ui/addon/components/messages/page/list.hbs +++ b/ui/lib/config-ui/addon/components/messages/page/list.hbs @@ -13,9 +13,9 @@ {{/if}} diff --git a/ui/lib/config-ui/addon/components/messages/page/list.js b/ui/lib/config-ui/addon/components/messages/page/list.js index ce0d3f4813..f97e477555 100644 --- a/ui/lib/config-ui/addon/components/messages/page/list.js +++ b/ui/lib/config-ui/addon/components/messages/page/list.js @@ -9,6 +9,8 @@ import { task } from 'ember-concurrency'; import { dateFormat } from 'core/helpers/date-format'; import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; +import errorMessage from 'vault/utils/error-message'; +import { next } from '@ember/runloop'; /** * @module Page::MessagesList @@ -29,6 +31,26 @@ export default class MessagesList extends Component { @tracked showMaxMessageModal = false; + // This follows the pattern in sync/addon/components/secrets/page/destinations for FilterInput. + // Currently, FilterInput doesn't do a full page refresh causing it to lose focus. + // The work around is to verify that a transition from this route was completed and then focus the input. + constructor(owner, args) { + super(owner, args); + this.router.on('routeDidChange', this.focusNameFilter); + } + + willDestroy() { + super.willDestroy(); + this.router.off('routeDidChange', this.focusNameFilter); + } + + focusNameFilter(transition) { + const route = 'vault.cluster.config-ui.messages.index'; + if (transition?.from?.name === route && transition?.to?.name === route) { + next(() => document.getElementById('message-filter')?.focus()); + } + } + get formattedMessages() { return this.args.messages.map((message) => { let badgeDisplayText = ''; @@ -79,11 +101,16 @@ export default class MessagesList extends Component { @task *deleteMessage(message) { - this.store.clearDataset('config-ui/message'); - yield message.destroyRecord(message.id); - this.router.transitionTo('vault.cluster.config-ui.messages'); - this.customMessages.fetchMessages(this.namespace.path); - this.flashMessages.success(`Successfully deleted ${message.title}.`); + try { + this.store.clearDataset('config-ui/message'); + yield message.destroyRecord(message.id); + this.router.transitionTo('vault.cluster.config-ui.messages'); + this.customMessages.fetchMessages(this.namespace.path); + this.flashMessages.success(`Successfully deleted ${message.title}.`); + } catch (e) { + const message = errorMessage(e); + this.flashMessages.danger(message); + } } @action diff --git a/ui/lib/config-ui/addon/controllers/messages/index.js b/ui/lib/config-ui/addon/controllers/messages/index.js index 06bb5661ed..586afcb863 100644 --- a/ui/lib/config-ui/addon/controllers/messages/index.js +++ b/ui/lib/config-ui/addon/controllers/messages/index.js @@ -5,7 +5,7 @@ import Controller from '@ember/controller'; export default class MessagesController extends Controller { - queryParams = ['authenticated', 'page']; + queryParams = ['authenticated', 'page', 'pageFilter']; authenticated = true; page = 1; diff --git a/ui/tests/integration/components/config-ui/messages/page/list-test.js b/ui/tests/integration/components/config-ui/messages/page/list-test.js index 1b06b48e48..5bcbd42b1e 100644 --- a/ui/tests/integration/components/config-ui/messages/page/list-test.js +++ b/ui/tests/integration/components/config-ui/messages/page/list-test.js @@ -10,6 +10,7 @@ import { setupEngine } from 'ember-engines/test-support'; import { render, click } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; import { PAGE } from 'vault/tests/helpers/config-ui/message-selectors'; +import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs'; const META = { currentPage: 1, @@ -26,7 +27,7 @@ module('Integration | Component | messages/page/list', function (hooks) { setupMirage(hooks); hooks.beforeEach(function () { - this.context = { owner: this.engine }; + this.server.post('/sys/capabilities-self', allowAllCapabilitiesStub()); this.store = this.owner.lookup('service:store'); this.store.pushPayload('config-ui/message', {