Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve cntrl+f issue on KVv2 JSON details and edit views #28808

Merged
merged 18 commits into from
Nov 8, 2024

Conversation

Monkeychip
Copy link
Contributor

@Monkeychip Monkeychip commented Oct 30, 2024

  • ent tests pass

Description

Address issue #28053 and closes PR #28604.

  1. Replace the codemirror component on the KVv2 details page with the Hds::CodeBlock component. This solves the original issue, allowing the user to browser search the full secret while also moving us closer to HDS adoption.

  2. For the edit view, this problem is solved by correctly taking advantage of the viewportMargin param provided by CodeMirror.

image

Notes:

  • For KVv2 only I calculate the viewportMargin based on the number of JSON object keys. I use the higher of the two numbers 10 or key count, but no higher than 1,000. Before we would also be using 10 (the default).

  • For the use cases where we were passing in "Infinity" this has negative performance implications and the only upside to us me three years ago misspelling viewportMargin 🫣.

viewportmargin.mov

@Monkeychip Monkeychip added ui backport/ent/1.16.x+ent Changes are backported to 1.16.x+ent backport/1.18.x backport/ent/1.17.x+ent Changes are backported to 1.17.x+ent labels Oct 30, 2024
@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Oct 30, 2024
Copy link

github-actions bot commented Oct 30, 2024

CI Results:
All Go tests succeeded! ✅

@karabanov
Copy link

I agree that this function may not be needed by everyone, but maybe it is possible to somehow make it permanently enabled for those who need it? That is, so that when you press this button, its state is remembered, for example, somewhere in the LocalStorage and remains such that you do not have to press the button every time

@Monkeychip
Copy link
Contributor Author

@karabanov thank you so much for the feedback. We're running into an issue with adding this functionality to our current component and are looking at replace it with a HDS::codeblock component. The HDS codeblock allows you to cntrl + f inside a fixed height container so that you can search a whole secret. Would this solve you're problem, or is there still a desire to see the whole secret with the expand button? See screenshare of the new component below.

Re: localStorage, that's a potential option, but in general we try to minimize our use of localStorage. We've had similar requests for things like pinning an item to the top of a list, and other config-type requests. I'll throw this by the team, but no promises.

search-hds.mov

@karabanov
Copy link

@Monkeychip, I think if the ctrl+f search works correctly, then my colleagues and I will be quite satisfied.

Please tell me, will the search work in edit mode if you use the HDS::codeblock component? The fact is that if you stretch the codemirror window, the search will work both in viewing and editing mode

@Monkeychip Monkeychip added this to the 1.19.0-rc milestone Nov 1, 2024
@Monkeychip
Copy link
Contributor Author

@karabanov the Hds::Codeblock would only be for the details view not the edit as it's not designed to be a code editor. So this would solve the details view but not edit. I can make/push this PR to address the details view but for edit, that is a longer process and will involved doing some modifications to our current code editor (if possible). I'll go ahead and make a ticket for it and see if it's something we can address in another pr.

@karabanov
Copy link

@Monkeychip A working search by ctrl+f is also needed in the editing mode, since the JSON can be large and it is problematic to find the necessary key in it with your eyes to edit it, in addition, the keys are sorted in an unnatural order, which complicates the task even more

For example, if you do not switch to the JSON editing mode, all the keys will be visible on the page at once, they can be found by searching both in the viewing mode and in the editing mode, so why not just stretch the text field by 100% in the JSON editing mode so that all the keys become visible? This will be very similar to the normal editing mode, when all the keys are visible and the problem with searching will be solved.

The improvement that I propose in PR #28604 is to add one line and this will not require replacing the text editor, while solving the problem with searching for keys and displaying the content. This will even make the JSON editing mode more similar to the normal mode, since all the keys will be visible at once

How do you like this solution?

@Monkeychip Monkeychip changed the title Add expand length btn on json codemirror Solve cntrl+f issue on KVv2 details and edit Nov 4, 2024
@Monkeychip Monkeychip changed the title Solve cntrl+f issue on KVv2 details and edit Solve cntrl+f issue on KVv2 JSOn details and edit views Nov 4, 2024
@Monkeychip
Copy link
Contributor Author

Monkeychip commented Nov 4, 2024

@karabanov All very fair points. I went back to debugging why our current code editor does not allow searching beyond the viewport and got to the heart of the problem. We were incorrectly using a param called viewportMargin. This param tells the json editor to render the number of lines beyond what is visible in the viewport. A quick summary: it was defaulting to rendering 10 lines beyond the viewport, which for longer secrets is not enough. I amended this so the viewportMargin is dynamically calculated based on the size of the secret.

In conclusion:

  • Short term fix: Replace details view with new Hds::CodeBlock component that allows search. Update edit view to dynamical render the full secret which will effectively allow you to search the whole secret. No expand button/no change in default height (KVv2 is widely used and one change can cause lots of complaints so we try to avoid any functionality/layout changes unless absolutely necessary).

  • Longer term fix: We're working on getting a new code editor that will solve this problem and possibly include an expand button for the edit and readOnly views because you make a good argument for it and I put a request into the design team —thank you!

@karabanov
Copy link

@Monkeychip Thank you very much
I look forward to these changes being released soon

@@ -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 }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously this was defaulting to 10, so another option is to remove this all together and let it default to 10 until someone complains?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If 100 doesn't have any major performance implications I think that should be okay here. I'm not sure what the data this typically renders - so it's possible 10 may be more reasonable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can gather this is output for the ui console/terminal window. 10 for most situations should be enough unless they're trying to read a really long secret.

Is 100 going to have any performance implications? not that I can tell via testing, but also there's no documentation to say otherwise. From what I gather, they're cautioning against using "Infinity" because that could be bad if your json was millions of lines long.

@@ -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 }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above.

@@ -8,6 +8,6 @@
<Hds::Text::Body @tag="p" @weight="semibold">Reveal subkeys in JSON</Hds::Text::Body>
</Toggle>
{{#if this.showSubkeys}}
<Hds::CodeBlock @value={{stringify @subkeys}} @hasLineNumbers={{false}} data-test-subkeys />
<Hds::CodeBlock @value={{stringify @subkeys}} @hasLineNumbers={{false}} data-test-code-block="subkeys" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated all selectors added to the Hds::CodeBlock component so that we consistently used one GENERAL selector.

);
codemirror().setValue('{ "foo3": { "name": "bar3" } }');
await click(FORM.saveBtn);

// Details view
await click(PAGE.secretTab('Secret'));
assert.dom(FORM.toggleJson).isNotDisabled();
assert.dom(FORM.toggleJson).isChecked();
assert.false(codemirror().getValue().includes('*'), 'Values are not obscured on details view');
Copy link
Contributor Author

@Monkeychip Monkeychip Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little clean up that was missed when we removed obscuring json values from the codemirror editor view PR #28261.

@Monkeychip Monkeychip marked this pull request as ready for review November 6, 2024 22:55
@Monkeychip Monkeychip requested a review from a team as a code owner November 6, 2024 22:55
</Hds::CodeBlock>
{{else}}
<JsonEditor
@title="{{if (eq @type 'create') 'Secret' 'Version'}} data"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: When you create a new version you see Version data vs Secret data.

Copy link

github-actions bot commented Nov 6, 2024

Build Results:
All builds succeeded! ✅

@@ -90,8 +90,8 @@ export const PAGE = {
},
paths: {
copyButton: (label) => `${PAGE.infoRowValue(label)} button`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I go back and forth on putting this in the general selectors. Opted to keep as you see here until it becomes more obvious that these selectors will be used outside of kv.

@@ -206,3 +206,49 @@ export const fillInAwsConfig = async (situation = 'withAccess') => {
await fillIn(GENERAL.ttl.input('Identity token TTL'), '7200');
}
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admittedly, I got carried away on making this helper. I could have saved myself time and hardcoded or modified the KvDataFields defaults during a test situation. However, I can imagine this being a helpful function for future KV things. Gives us a quick way to make longer more complicated json objects. Also, it was kind of fun.

Copy link
Contributor

@hellobontempo hellobontempo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this! Really thorough and nice communication with the reporter to get this resolved the right way.

Mostly just minor cleanup comments and questions. I'm curious about the accessibility change. It's end of day for me so feeling brain dead. Can circle back with an approval tomorrow ☺️

ui/lib/core/addon/components/json-editor.js Outdated Show resolved Hide resolved
@readOnly={{eq @type "details"}}
/>
{{#if (eq @type "details")}}
<Hds::CodeBlock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍 love seeing this component being used more!

@@ -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 }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If 100 doesn't have any major performance implications I think that should be okay here. I'm not sure what the data this typically renders - so it's possible 10 may be more reasonable

ui/lib/kv/addon/components/kv-data-fields.js Outdated Show resolved Hide resolved
this.set('hashi-read-only-theme', 'hashi-read-only auto-height');
setRunOptions({
rules: {
// CodeMirror has a secret textarea without a label that causes this problem
label: { enabled: false },
// TODO: investigate and fix Codemirror styling
'color-contrast': { enabled: false },
// failing on .CodeMirror-scroll
'scrollable-region-focusable': { enabled: false },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I wonder why this is failing now and wasn't before 🤔 is it worth looking into? I wonder if setting a default viewport margin value resolves this 💭

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. This is an ally testing thing—copied the same thing from Chelsea's fixes, here's one example but there are several more. From what I can tell it's because I'm testing just the component and now it scrolls.

@@ -51,7 +51,7 @@
mode=@mode
readOnly=@readOnly
theme=@theme
viewportMarg=@viewportMargin
viewportMargin=@viewportMargin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we set a default here?

Copy link
Contributor Author

@Monkeychip Monkeychip Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is inherit from CodeMirror. If you don't pass viewportMargin it will default to 10, which is what it was doing when I incorrectly spelled the param.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh - is that default just builtin? In codemirror I see a default of an empty string (here) Maybe we could include that in the JSDOC below that it defaults to 10?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do, and good call out. I also modified the code-mirror line that you pointed out to explicitly state the default. Codemirror docs give this rec:

You should usually leave it at its default, 10

setRunOptions({
rules: {
// failing on .CodeMirror-scroll
'scrollable-region-focusable': { enabled: false },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment wondering why this is failing now

@@ -129,4 +133,31 @@ module('Integration | Component | json-editor', function (hooks) {
'even after hitting enter the value is still set correctly'
);
});

test('when @viewportMargin is not set user is unable to search a long secret', async function (assert) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test name feels a little confusing. Is there a default viewport margin and so the data is cut off so only a portion is rendered on the DOM? Or is there none at all so there's no scrolling?

Rewording to something like "no viewport margin renders only X (the default if we have one) lines of data on the DOM" feels a little more like it's explaining what's happening. Then in the test we can see we're testing by using ctrl+F

Copy link
Contributor

@hellobontempo hellobontempo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Just a comment about mentioning the default viewportMargin in the jsdoc for JsonEditor

@Monkeychip Monkeychip changed the title Solve cntrl+f issue on KVv2 JSOn details and edit views Solve cntrl+f issue on KVv2 JSON details and edit views Nov 8, 2024
@Monkeychip Monkeychip enabled auto-merge (squash) November 8, 2024 16:20
@Monkeychip Monkeychip merged commit c7ca295 into main Nov 8, 2024
32 checks passed
@Monkeychip Monkeychip deleted the ui/VAULT-33227/btn-codemirror-expand branch November 8, 2024 18:23
Monkeychip added a commit that referenced this pull request Nov 12, 2024
* 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 <[email protected]>

* Update ui/lib/kv/addon/components/kv-data-fields.js

Co-authored-by: claire bontempo <[email protected]>

* update test name

* add default to modifier

---------

Co-authored-by: claire bontempo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/ent/1.16.x+ent Changes are backported to 1.16.x+ent backport/ent/1.17.x+ent Changes are backported to 1.17.x+ent backport/1.18.x hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed ui
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants