From 5041e7c8aac28f7a786f376a46edfc5785811097 Mon Sep 17 00:00:00 2001 From: Angel Garbarino Date: Fri, 8 Nov 2024 11:23:01 -0700 Subject: [PATCH 1/4] Solve cntrl+f issue on KVv2 JSON details and edit views (#28808) * initial changes need to add test coverage * change icon * replace original idea with hds::codeblock on kvv2 details view * changelog * fixing edit view by addressing viewportMargin * fix failing test * missedone * Update 28808.txt * Update json-editor.js * test coverage * update codeblock selector * Update general-selectors.ts * Update kv-data-fields.js * Update ui/lib/core/addon/components/json-editor.js Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * Update ui/lib/kv/addon/components/kv-data-fields.js Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * update test name * add default to modifier --------- Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> --- changelog/28808.txt | 6 +++ .../templates/components/console/log-json.hbs | 3 +- .../components/control-group-success.hbs | 3 +- ui/lib/core/addon/components/json-editor.hbs | 2 +- ui/lib/core/addon/components/json-editor.js | 2 +- ui/lib/core/addon/modifiers/code-mirror.js | 2 +- ui/lib/kv/addon/components/kv-data-fields.hbs | 27 ++++++++--- ui/lib/kv/addon/components/kv-data-fields.js | 9 ++++ .../components/kv-patch/subkeys-reveal.hbs | 2 +- ui/lib/kv/addon/components/kv-paths-card.hbs | 4 +- .../page/library/details/accounts.hbs | 2 +- .../kv/kv-v2-workflow-edge-cases-test.js | 30 +++++++++--- ui/tests/helpers/general-selectors.ts | 2 + ui/tests/helpers/kv/kv-selectors.js | 4 +- .../secret-engine/secret-engine-helpers.js | 46 +++++++++++++++++++ .../components/json-editor-test.js | 31 +++++++++++++ .../components/kv/kv-data-fields-test.js | 32 +++++++++++-- .../kv/kv-patch/editor/form-test.js | 6 +-- .../components/kv/kv-patch/json-form-test.js | 6 +-- .../kv/page/kv-page-secret-details-test.js | 16 +++++-- .../page/library/details/accounts-test.js | 8 +++- 21 files changed, 203 insertions(+), 40 deletions(-) create mode 100644 changelog/28808.txt diff --git a/changelog/28808.txt b/changelog/28808.txt new file mode 100644 index 000000000000..20d4d1ce4e36 --- /dev/null +++ b/changelog/28808.txt @@ -0,0 +1,6 @@ +```release-note:improvement +ui: Replace KVv2 json secret details view with Hds::CodeBlock component allowing users to search the full secret height. +``` +```release-note:bug +ui: Allow users to search the full json object within the json code-editor edit/create view. +``` diff --git a/ui/app/templates/components/console/log-json.hbs b/ui/app/templates/components/console/log-json.hbs index 6a1044791aca..f1c64321bbea 100644 --- a/ui/app/templates/components/console/log-json.hbs +++ b/ui/app/templates/components/console/log-json.hbs @@ -8,7 +8,8 @@ @showToolbar={{false}} @value={{stringify this.content}} @readOnly={{true}} - @viewportMargin="Infinity" + {{! ideally we calculate the "height" of the json data, but 100 should cover most cases }} + @viewportMargin="100" @gutters={{false}} @theme="hashi auto-height" /> diff --git a/ui/app/templates/components/control-group-success.hbs b/ui/app/templates/components/control-group-success.hbs index fd79e5ec2d17..b5a913b7a2ee 100644 --- a/ui/app/templates/components/control-group-success.hbs +++ b/ui/app/templates/components/control-group-success.hbs @@ -21,7 +21,8 @@ @showToolbar={{false}} @value={{stringify this.unwrapData}} @readOnly={{true}} - @viewportMargin="Infinity" + {{! ideally we calculate the "height" of the json data, but 100 should cover most cases }} + @viewportMargin="100" @gutters={{false}} @theme="hashi-read-only auto-height" /> diff --git a/ui/lib/core/addon/components/json-editor.hbs b/ui/lib/core/addon/components/json-editor.hbs index 28b784a9e439..a7587a0cdffd 100644 --- a/ui/lib/core/addon/components/json-editor.hbs +++ b/ui/lib/core/addon/components/json-editor.hbs @@ -51,7 +51,7 @@ mode=@mode readOnly=@readOnly theme=@theme - viewportMarg=@viewportMargin + viewportMargin=@viewportMargin onSetup=this.onSetup onUpdate=this.onUpdate onFocus=this.onFocus diff --git a/ui/lib/core/addon/components/json-editor.js b/ui/lib/core/addon/components/json-editor.js index 66507a6181cd..88b36ef8ff9b 100644 --- a/ui/lib/core/addon/components/json-editor.js +++ b/ui/lib/core/addon/components/json-editor.js @@ -24,7 +24,7 @@ import { action } from '@ember/object'; * @param {Boolean} [readOnly] - Sets the view to readOnly, allowing for copying but no editing. It also hides the cursor. Defaults to false. * @param {String} [theme] - Specify or customize the look via a named "theme" class in scss. * @param {String} [value] - Value within the display. Generally, a json string. - * @param {String} [viewportMargin] - Size of viewport. Often set to "Infinity" to load/show all text regardless of length. + * @param {String} [viewportMargin] - Specifies the amount of lines rendered on the DOM (this is not the editor display height). The codemirror default is 10 which we set explicity in the code-mirror modifier per the recommendations from the codemirror docs. * @param {string} [example] - Example to show when value is null -- when example is provided a restore action will render in the toolbar to clear the current value and show the example after input * @param {string} [screenReaderLabel] - This label is read by the screen readers when CodeMirror text area is focused. This is helpful for accessibility. * @param {string} [container] - **REQUIRED if rendering within a modal** Selector string or element object of containing element, set the focused element as the container value. This is for the Hds::Copy::Button and to set `autoRefresh=true` so content renders https://hds-website-hashicorp.vercel.app/components/copy/button?tab=code diff --git a/ui/lib/core/addon/modifiers/code-mirror.js b/ui/lib/core/addon/modifiers/code-mirror.js index b9b46900dcc8..8b6c73f66783 100644 --- a/ui/lib/core/addon/modifiers/code-mirror.js +++ b/ui/lib/core/addon/modifiers/code-mirror.js @@ -76,7 +76,7 @@ export default class CodeMirrorModifier extends Modifier { readOnly: namedArgs.readOnly || false, theme: namedArgs.theme || 'hashi', value: namedArgs.content || '', - viewportMargin: namedArgs.viewportMargin || '', + viewportMargin: namedArgs.viewportMargin || 10, autoRefresh: namedArgs.autoRefresh, }); diff --git a/ui/lib/kv/addon/components/kv-data-fields.hbs b/ui/lib/kv/addon/components/kv-data-fields.hbs index e6af5effb985..1b75d56762bc 100644 --- a/ui/lib/kv/addon/components/kv-data-fields.hbs +++ b/ui/lib/kv/addon/components/kv-data-fields.hbs @@ -13,12 +13,27 @@
{{#if @showJson}} - + {{#if (eq @type "details")}} + + + Version data + + + {{else}} + + {{/if}} {{#if (or @modelValidations.secretData.errors this.lintingErrors)}} Reveal subkeys in JSON {{#if this.showSubkeys}} - + {{/if}} \ No newline at end of file diff --git a/ui/lib/kv/addon/components/kv-paths-card.hbs b/ui/lib/kv/addon/components/kv-paths-card.hbs index d7976d92f27c..8e1edceb5a4e 100644 --- a/ui/lib/kv/addon/components/kv-paths-card.hbs +++ b/ui/lib/kv/addon/components/kv-paths-card.hbs @@ -53,7 +53,7 @@ for other CLI commands.

`[data-test-sidebar-nav-link="${label}"]`, cancelButton: '[data-test-cancel]', saveButton: '[data-test-save]', + backButton: '[data-test-back-button]', + codeBlock: (label: string) => `[data-test-code-block="${label}"]`, codemirror: `[data-test-component="code-mirror-modifier"]`, codemirrorTextarea: `[data-test-component="code-mirror-modifier"] textarea`, }; diff --git a/ui/tests/helpers/kv/kv-selectors.js b/ui/tests/helpers/kv/kv-selectors.js index 3c0b4af42c46..67b766fdf9f9 100644 --- a/ui/tests/helpers/kv/kv-selectors.js +++ b/ui/tests/helpers/kv/kv-selectors.js @@ -90,8 +90,8 @@ export const PAGE = { }, paths: { copyButton: (label) => `${PAGE.infoRowValue(label)} button`, - codeSnippet: (section) => `[data-test-commands="${section}"] code`, - snippetCopy: (section) => `[data-test-commands="${section}"] button`, + codeSnippet: (section) => `[data-test-code-block="${section}"] code`, + snippetCopy: (section) => `[data-test-code-block="${section}"] button`, }, }; diff --git a/ui/tests/helpers/secret-engine/secret-engine-helpers.js b/ui/tests/helpers/secret-engine/secret-engine-helpers.js index 2a9c88601c4d..e970bd0afa23 100644 --- a/ui/tests/helpers/secret-engine/secret-engine-helpers.js +++ b/ui/tests/helpers/secret-engine/secret-engine-helpers.js @@ -206,3 +206,49 @@ export const fillInAwsConfig = async (situation = 'withAccess') => { await fillIn(GENERAL.ttl.input('Identity token TTL'), '7200'); } }; + +// Example usage +// createLongJson (2, 3) will create a json object with 2 original keys, each with 3 nested keys +// { +// "key-0": { +// "nested-key-0": { +// "nested-key-1": { +// "nested-key-2": "nested-value" +// } +// } +// }, +// "key-1": { +// "nested-key-0": { +// "nested-key-1": { +// "nested-key-2": "nested-value" +// } +// } +// } +// } + +export function createLongJson(lines = 10, nestLevel = 3) { + const keys = Array.from({ length: nestLevel }, (_, i) => `nested-key-${i}`); + const jsonObject = {}; + + for (let i = 0; i < lines; i++) { + nestLevel > 0 + ? (jsonObject[`key-${i}`] = createNestedObject({}, keys, 'nested-value')) + : (jsonObject[`key-${i}`] = 'non-nested-value'); + } + return jsonObject; +} + +function createNestedObject(obj = {}, keys, value) { + let current = obj; + + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + if (!current[key]) { + current[key] = {}; + } + current = current[key]; + } + + current[keys[keys.length - 1]] = value; + return obj; +} diff --git a/ui/tests/integration/components/json-editor-test.js b/ui/tests/integration/components/json-editor-test.js index 100b7d8ef9b8..56f4a674f8d9 100644 --- a/ui/tests/integration/components/json-editor-test.js +++ b/ui/tests/integration/components/json-editor-test.js @@ -11,6 +11,7 @@ import hbs from 'htmlbars-inline-precompile'; import jsonEditor from '../../pages/components/json-editor'; import sinon from 'sinon'; import { setRunOptions } from 'ember-a11y-testing/test-support'; +import { createLongJson } from 'vault/tests/helpers/secret-engine/secret-engine-helpers'; const component = create(jsonEditor); @@ -29,6 +30,7 @@ module('Integration | Component | json-editor', function (hooks) { this.set('onFocusOut', sinon.spy()); this.set('json_blob', JSON_BLOB); this.set('bad_json_blob', BAD_JSON_BLOB); + this.set('long_json', JSON.stringify(createLongJson(), null, `\t`)); this.set('hashi-read-only-theme', 'hashi-read-only auto-height'); setRunOptions({ rules: { @@ -36,6 +38,8 @@ module('Integration | Component | json-editor', function (hooks) { label: { enabled: false }, // TODO: investigate and fix Codemirror styling 'color-contrast': { enabled: false }, + // failing on .CodeMirror-scroll + 'scrollable-region-focusable': { enabled: false }, }, }); }); @@ -129,4 +133,31 @@ module('Integration | Component | json-editor', function (hooks) { 'even after hitting enter the value is still set correctly' ); }); + + test('no viewportMargin renders only default 10 lines of data on the DOM', async function (assert) { + await render(hbs` + + `); + assert + .dom('.CodeMirror-code') + .doesNotIncludeText('key-9', 'Without viewportMargin, user cannot search for key-9'); + }); + + test('when viewportMargin is set user is able to search a long secret', async function (assert) { + await render(hbs` + + `); + assert + .dom('.CodeMirror-code') + .containsText('key-9', 'With viewportMargin set, user can search for key-9'); + }); }); diff --git a/ui/tests/integration/components/kv/kv-data-fields-test.js b/ui/tests/integration/components/kv/kv-data-fields-test.js index e9e18d99f368..ac3d5ed8b606 100644 --- a/ui/tests/integration/components/kv/kv-data-fields-test.js +++ b/ui/tests/integration/components/kv/kv-data-fields-test.js @@ -11,6 +11,9 @@ import { hbs } from 'ember-cli-htmlbars'; import { fillIn, render, click } from '@ember/test-helpers'; import codemirror from 'vault/tests/helpers/codemirror'; import { PAGE, FORM } from 'vault/tests/helpers/kv/kv-selectors'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; +import { setRunOptions } from 'ember-a11y-testing/test-support'; +import { createLongJson } from 'vault/tests/helpers/secret-engine/secret-engine-helpers'; module('Integration | Component | kv-v2 | KvDataFields', function (hooks) { setupRenderingTest(hooks); @@ -22,6 +25,12 @@ module('Integration | Component | kv-v2 | KvDataFields', function (hooks) { this.backend = 'my-kv-engine'; this.path = 'my-secret'; this.secret = this.store.createRecord('kv/data', { backend: this.backend }); + setRunOptions({ + rules: { + // failing on .CodeMirror-scroll + 'scrollable-region-focusable': { enabled: false }, + }, + }); }); test('it updates the secret model', async function (assert) { @@ -88,7 +97,7 @@ module('Integration | Component | kv-v2 | KvDataFields', function (hooks) { assert.dom(PAGE.infoRowValue('foo')).hasText('bar', 'secret value shows after toggle'); }); - test('it shows readonly json editor when viewing secret details of complex secret', async function (assert) { + test('it shows hds codeblock when viewing secret details of complex secret', async function (assert) { this.secret.secretData = { foo: { bar: 'baz', @@ -100,7 +109,24 @@ module('Integration | Component | kv-v2 | KvDataFields', function (hooks) { owner: this.engine, }); assert.dom(PAGE.infoRowValue('foo')).doesNotExist('does not render rows of secret data'); - assert.dom('[data-test-component="code-mirror-modifier"]').hasClass('readonly-codemirror'); - assert.dom('[data-test-component="code-mirror-modifier"]').includesText(`{ "foo": { "bar": "baz" }}`); + assert.dom(GENERAL.codeBlock('secret-data')).exists('hds codeBlock exists'); + assert + .dom(GENERAL.codeBlock('secret-data')) + .hasText(`Version data { "foo": { "bar": "baz" } } `, 'Json data is displayed'); + }); + + test('it defaults to a viewportMargin 10 when there is no secret data', async function (assert) { + await render(hbs``, { owner: this.engine }); + assert.strictEqual(codemirror().options.viewportMargin, 10, 'viewportMargin defaults to 10'); + }); + + test('it calculates viewportMargin based on secret size', async function (assert) { + this.secret.secretData = createLongJson(100); + await render(hbs``, { owner: this.engine }); + assert.strictEqual( + codemirror().options.viewportMargin, + 100, + 'viewportMargin is set to 100 matching the height of the json' + ); }); }); diff --git a/ui/tests/integration/components/kv/kv-patch/editor/form-test.js b/ui/tests/integration/components/kv/kv-patch/editor/form-test.js index 4096feb945be..3cc72291067a 100644 --- a/ui/tests/integration/components/kv/kv-patch/editor/form-test.js +++ b/ui/tests/integration/components/kv/kv-patch/editor/form-test.js @@ -96,14 +96,14 @@ module('Integration | Component | kv | kv-patch/editor/form', function (hooks) { await this.renderComponent(); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isNotChecked('toggle is initially unchecked'); - assert.dom('[data-test-subkeys]').doesNotExist(); + assert.dom(GENERAL.codeBlock('subkeys')).doesNotExist(); await click(GENERAL.toggleInput('Reveal subkeys')); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isChecked(); - assert.dom('[data-test-subkeys]').hasText(JSON.stringify(this.subkeys, null, 2)); + assert.dom(GENERAL.codeBlock('subkeys')).hasText(JSON.stringify(this.subkeys, null, 2)); await click(GENERAL.toggleInput('Reveal subkeys')); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isNotChecked(); - assert.dom('[data-test-subkeys]').doesNotExist('unchecking re-hides subkeys'); + assert.dom(GENERAL.codeBlock('subkeys')).doesNotExist('unchecking re-hides subkeys'); }); test('it enables and disables inputs', async function (assert) { diff --git a/ui/tests/integration/components/kv/kv-patch/json-form-test.js b/ui/tests/integration/components/kv/kv-patch/json-form-test.js index 166ea8d2fa7a..37703e2bd985 100644 --- a/ui/tests/integration/components/kv/kv-patch/json-form-test.js +++ b/ui/tests/integration/components/kv/kv-patch/json-form-test.js @@ -59,14 +59,14 @@ module('Integration | Component | kv | kv-patch/editor/json-form', function (hoo await this.renderComponent(); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isNotChecked('toggle is initially unchecked'); - assert.dom('[data-test-subkeys]').doesNotExist(); + assert.dom(GENERAL.codeBlock('subkeys')).doesNotExist(); await click(GENERAL.toggleInput('Reveal subkeys')); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isChecked(); - assert.dom('[data-test-subkeys]').hasText(JSON.stringify(this.subkeys, null, 2)); + assert.dom(GENERAL.codeBlock('subkeys')).hasText(JSON.stringify(this.subkeys, null, 2)); await click(GENERAL.toggleInput('Reveal subkeys')); assert.dom(GENERAL.toggleInput('Reveal subkeys')).isNotChecked(); - assert.dom('[data-test-subkeys]').doesNotExist('unchecking re-hides subkeys'); + assert.dom(GENERAL.codeBlock('subkeys')).doesNotExist('unchecking re-hides subkeys'); }); test('it renders linting errors', async function (assert) { diff --git a/ui/tests/integration/components/kv/page/kv-page-secret-details-test.js b/ui/tests/integration/components/kv/page/kv-page-secret-details-test.js index 430ff3765f08..298d1fd330a3 100644 --- a/ui/tests/integration/components/kv/page/kv-page-secret-details-test.js +++ b/ui/tests/integration/components/kv/page/kv-page-secret-details-test.js @@ -7,13 +7,14 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { setupEngine } from 'ember-engines/test-support'; import { setupMirage } from 'ember-cli-mirage/test-support'; -import { click, find, render } from '@ember/test-helpers'; +import { click, render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; import { kvDataPath } from 'vault/utils/kv-path'; -import { FORM, PAGE, parseJsonEditor } from 'vault/tests/helpers/kv/kv-selectors'; +import { FORM, PAGE } from 'vault/tests/helpers/kv/kv-selectors'; import { syncStatusResponse } from 'vault/mirage/handlers/sync'; import { encodePath } from 'vault/utils/path-encoding-helpers'; import { baseSetup } from 'vault/tests/helpers/kv/kv-run-commands'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; module('Integration | Component | kv-v2 | Page::Secret::Details', function (hooks) { setupRenderingTest(hooks); @@ -126,19 +127,24 @@ module('Integration | Component | kv-v2 | Page::Secret::Details', function (hook await click(FORM.toggleMasked); assert.dom(PAGE.infoRowValue('foo')).hasText('bar', 'renders secret value'); await click(FORM.toggleJson); - assert.propEqual(parseJsonEditor(find), this.secretData, 'json editor renders secret data'); + assert.dom(GENERAL.codeBlock('secret-data')).hasText( + `Version data { + "foo": "bar" +}`, + 'json editor renders secret data' + ); assert .dom(PAGE.detail.versionTimestamp) .includesText(`Version ${this.version} created`, 'renders version and time created'); }); - test('it renders json view when secret is complex', async function (assert) { + test('it renders hds codeblock view when secret is complex', async function (assert) { assert.expect(4); await this.renderComponent(this.modelComplex); assert.dom(PAGE.infoRowValue('foo')).doesNotExist('does not render rows of secret data'); assert.dom(FORM.toggleJson).isChecked(); assert.dom(FORM.toggleJson).isNotDisabled(); - assert.dom('[data-test-component="code-mirror-modifier"]').exists('shows json editor'); + assert.dom(GENERAL.codeBlock('secret-data')).exists('hds codeBlock exists'); }); test('it renders deleted empty state', async function (assert) { diff --git a/ui/tests/integration/components/ldap/page/library/details/accounts-test.js b/ui/tests/integration/components/ldap/page/library/details/accounts-test.js index 94b0048cc512..c7f7aa6ebbeb 100644 --- a/ui/tests/integration/components/ldap/page/library/details/accounts-test.js +++ b/ui/tests/integration/components/ldap/page/library/details/accounts-test.js @@ -11,6 +11,7 @@ import { render, click, fillIn } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs'; import sinon from 'sinon'; +import { GENERAL } from 'vault/tests/helpers/general-selectors'; module('Integration | Component | ldap | Page::Library::Details::Accounts', function (hooks) { setupRenderingTest(hooks); @@ -76,7 +77,10 @@ module('Integration | Component | ldap | Page::Library::Details::Accounts', func assert.dom('[data-test-checked-out-card]').exists('Accounts checked out card renders'); assert - .dom('[data-test-accounts-code-block] code') - .hasText('vault lease renew ad/library/test-library/check-out/:lease_id', 'Renew cli command renders'); + .dom(`${GENERAL.codeBlock('accounts')} code`) + .hasText( + 'vault lease renew ldap-test/library/test-library/check-out/:lease_id', + 'Renew cli command renders with backend path' + ); }); }); From 416dfc613ba968bc1e42e88db815478ec923d54e Mon Sep 17 00:00:00 2001 From: Angel Garbarino Date: Mon, 25 Nov 2024 10:22:26 -0700 Subject: [PATCH 2/4] Update accounts-test.js return to original test --- .../components/ldap/page/library/details/accounts-test.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ui/tests/integration/components/ldap/page/library/details/accounts-test.js b/ui/tests/integration/components/ldap/page/library/details/accounts-test.js index c7f7aa6ebbeb..94b0048cc512 100644 --- a/ui/tests/integration/components/ldap/page/library/details/accounts-test.js +++ b/ui/tests/integration/components/ldap/page/library/details/accounts-test.js @@ -11,7 +11,6 @@ import { render, click, fillIn } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs'; import sinon from 'sinon'; -import { GENERAL } from 'vault/tests/helpers/general-selectors'; module('Integration | Component | ldap | Page::Library::Details::Accounts', function (hooks) { setupRenderingTest(hooks); @@ -77,10 +76,7 @@ module('Integration | Component | ldap | Page::Library::Details::Accounts', func assert.dom('[data-test-checked-out-card]').exists('Accounts checked out card renders'); assert - .dom(`${GENERAL.codeBlock('accounts')} code`) - .hasText( - 'vault lease renew ldap-test/library/test-library/check-out/:lease_id', - 'Renew cli command renders with backend path' - ); + .dom('[data-test-accounts-code-block] code') + .hasText('vault lease renew ad/library/test-library/check-out/:lease_id', 'Renew cli command renders'); }); }); From df57a6b99322774c6d9018f2195be9a2cb8e5feb Mon Sep 17 00:00:00 2001 From: Angel Garbarino Date: Mon, 25 Nov 2024 10:22:55 -0700 Subject: [PATCH 3/4] Update accounts.hbs --- .../ldap/addon/components/page/library/details/accounts.hbs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/lib/ldap/addon/components/page/library/details/accounts.hbs b/ui/lib/ldap/addon/components/page/library/details/accounts.hbs index 045f9db5e6f4..747ac0d0f475 100644 --- a/ui/lib/ldap/addon/components/page/library/details/accounts.hbs +++ b/ui/lib/ldap/addon/components/page/library/details/accounts.hbs @@ -55,7 +55,7 @@ <:content> -{{/if}} \ No newline at end of file +{{/if}} From 230a39795f9184abd04be150fd52db5b725f1abe Mon Sep 17 00:00:00 2001 From: Angel Garbarino Date: Mon, 25 Nov 2024 10:35:38 -0700 Subject: [PATCH 4/4] remove extra space grr gh editing --- ui/lib/ldap/addon/components/page/library/details/accounts.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/lib/ldap/addon/components/page/library/details/accounts.hbs b/ui/lib/ldap/addon/components/page/library/details/accounts.hbs index 747ac0d0f475..c00504a1d718 100644 --- a/ui/lib/ldap/addon/components/page/library/details/accounts.hbs +++ b/ui/lib/ldap/addon/components/page/library/details/accounts.hbs @@ -86,4 +86,4 @@ -{{/if}} +{{/if}} \ No newline at end of file