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]'),
};