From 7e6bb1fb7c7c90c850970b8b788d0b9e1071c66b Mon Sep 17 00:00:00 2001 From: malinac02 <104539507+malinac02@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:29:43 -0700 Subject: [PATCH] UI: Display minus icon for empty MaskedInput value. Show MaskedInput for KV secrets without values (#22039) * changed MaskedInput to show a minus icon when there is no value. changed SecretFormShow to show this MaskedInput with minus icon instead of showing just a minus icon * fixed copy button for blank value in MaskedInput; added changelog * reword changelog to be more concise * added test to check if minus icon shows for MaskedInput when value is empty string * edited a test to make sytnax more concise * changed MaskedInput to show 'danger' message when copying empty value * added 2 tests to check for flash messages * changed naming of a MaskedInput test to be more descriptive --- changelog/22039.txt | 3 + .../templates/components/secret-form-show.hbs | 18 +++--- ui/lib/core/addon/components/masked-input.hbs | 10 +++- .../components/masked-input-test.js | 59 +++++++++++++++++++ ui/tests/pages/components/masked-input.js | 1 + 5 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 changelog/22039.txt diff --git a/changelog/22039.txt b/changelog/22039.txt new file mode 100644 index 0000000000..09c3e6ad80 --- /dev/null +++ b/changelog/22039.txt @@ -0,0 +1,3 @@ +```release-note:improvement +ui: Display minus icon for empty MaskedInput value. Show MaskedInput for KV secrets without values +``` \ No newline at end of file diff --git a/ui/app/templates/components/secret-form-show.hbs b/ui/app/templates/components/secret-form-show.hbs index 4616b5dd3a..ff37072329 100644 --- a/ui/app/templates/components/secret-form-show.hbs +++ b/ui/app/templates/components/secret-form-show.hbs @@ -65,17 +65,13 @@ {{#if @modelForData.secretKeyAndValue}} {{#each @modelForData.secretKeyAndValue as |secret|}} - {{#if secret.value}} - - {{else}} - - {{/if}} + {{/each}} {{else}} diff --git a/ui/lib/core/addon/components/masked-input.hbs b/ui/lib/core/addon/components/masked-input.hbs index c08edb9eb0..550f4d7481 100644 --- a/ui/lib/core/addon/components/masked-input.hbs +++ b/ui/lib/core/addon/components/masked-input.hbs @@ -6,7 +6,12 @@ > {{#if @displayOnly}} {{#if this.showValue}} -
{{@value}}
+ {{! Show minus icon if there is no value }} + {{#if (eq @value "")}} + + {{else}} +
{{@value}}
+ {{/if}} {{else}}
***********
{{/if}} @@ -28,6 +33,7 @@ @@ -50,7 +56,7 @@ type="button" aria-label={{if this.showValue "mask value" "show value"}} title={{if this.showValue "mask value" "show value"}} - class="{{if (eq @value '') 'has-text-grey'}} masked-input-toggle button" + class="masked-input-toggle button" data-test-button="toggle-masked" > diff --git a/ui/tests/integration/components/masked-input-test.js b/ui/tests/integration/components/masked-input-test.js index e6feff1f6b..f81a99ad55 100644 --- a/ui/tests/integration/components/masked-input-test.js +++ b/ui/tests/integration/components/masked-input-test.js @@ -16,6 +16,13 @@ const component = create(maskedInput); module('Integration | Component | masked input', function (hooks) { setupRenderingTest(hooks); + hooks.beforeEach(function () { + this.flashMessages = this.owner.lookup('service:flash-messages'); + this.flashMessages.registerTypes(['success', 'danger']); + this.flashSuccessSpy = sinon.spy(this.flashMessages, 'success'); + this.flashDangerSpy = sinon.spy(this.flashMessages, 'danger'); + }); + test('it renders', async function (assert) { await render(hbs``); assert.dom('[data-test-masked-input]').exists('shows masked input'); @@ -96,4 +103,56 @@ module('Integration | Component | masked input', function (hooks) { const unMaskedValue = document.querySelector('.masked-value').value; assert.strictEqual(unMaskedValue, this.value); }); + + test('it renders a minus icon when an empty string is provided as a value', async function (assert) { + await render(hbs` + + `); + assert.dom('[data-test-masked-input]').exists('shows masked input'); + assert.ok(component.copyButtonIsPresent); + assert.ok(component.downloadButtonIsPresent); + assert.dom('[data-test-button="toggle-masked"]').exists('shows toggle mask button'); + + await component.toggleMasked(); + assert.dom('.masked-value').doesNotHaveClass('masked-font', 'it unmasks when show button is clicked'); + assert + .dom('[data-test-icon="minus"]') + .exists('shows minus icon when unmasked because value is empty string'); + }); + + test('it shows "success" flash message when the value is successfully copied', async function (assert) { + await render(hbs` + + `); + assert.dom('[data-test-masked-input]').exists('shows masked input'); + assert.ok(component.copyButtonIsPresent); + await component.copyValue(); + assert.ok(this.flashSuccessSpy.calledWith('Data copied!'), 'Renders correct flash message'); + }); + + test('it shows "danger" flash message when the value fails to be copied (no value)', async function (assert) { + await render(hbs` + + `); + assert.dom('[data-test-masked-input]').exists('shows masked input'); + assert.ok(component.copyButtonIsPresent); + await component.copyValue(); + assert.ok(this.flashDangerSpy.calledWith('Error copying data'), 'Renders correct flash message'); + }); }); diff --git a/ui/tests/pages/components/masked-input.js b/ui/tests/pages/components/masked-input.js index 61ec76b25b..e1069c9397 100644 --- a/ui/tests/pages/components/masked-input.js +++ b/ui/tests/pages/components/masked-input.js @@ -10,4 +10,5 @@ export default { copyButtonIsPresent: isPresent('[data-test-copy-button]'), downloadButtonIsPresent: isPresent('[data-test-download-button]'), toggleMasked: clickable('[data-test-button="toggle-masked"]'), + copyValue: clickable('[data-test-copy-button]'), };