-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Web console: improve JSON paste experience #10256
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,187 @@ | ||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
|
||
| exports[`spec dialog matches snapshot 1`] = ` | ||
| exports[`spec dialog matches snapshot no initSpec 1`] = ` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's all this new stuff for and what are the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, interesting… Do we bundle this with the released app or is it skipped? I didn't realize it was a test file at first, because it's in the same
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. none of the tests (and test aids like this one) are included in the bundle because none of the code depends on any of the test code (if it did then it would not compile because tests run in a different environment In general the web console follows a standard where every class (or functional component) lives in a file next to the style and the test ... this has been the case from day one (of the unified console) and is pretty idiomatic of the modern web-dev world. The tests are separated from the code with file extensions
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL |
||
| <div | ||
| class="bp3-portal" | ||
| > | ||
| <div | ||
| class="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container" | ||
| > | ||
| <div | ||
| class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active" | ||
| /> | ||
| <div | ||
| class="bp3-dialog-container bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active" | ||
| tabindex="0" | ||
| > | ||
| <div | ||
| class="bp3-dialog spec-dialog" | ||
| > | ||
| <div | ||
| class="bp3-dialog-header" | ||
| > | ||
| <h4 | ||
| class="bp3-heading" | ||
| > | ||
| test | ||
| </h4> | ||
| <button | ||
| aria-label="Close" | ||
| class="bp3-button bp3-minimal bp3-dialog-close-button" | ||
| type="button" | ||
| > | ||
| <span | ||
| class="bp3-icon bp3-icon-small-cross" | ||
| icon="small-cross" | ||
| > | ||
| <svg | ||
| data-icon="small-cross" | ||
| height="20" | ||
| viewBox="0 0 20 20" | ||
| width="20" | ||
| > | ||
| <desc> | ||
| small-cross | ||
| </desc> | ||
| <path | ||
| d="M11.41 10l3.29-3.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42L8.59 10 5.3 13.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l3.29-3.3 3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z" | ||
| fill-rule="evenodd" | ||
| /> | ||
| </svg> | ||
| </span> | ||
| </button> | ||
| </div> | ||
| <div | ||
| class=" ace_editor ace-tm spec-dialog-textarea" | ||
| id="brace-editor" | ||
| style="width: 100%; height: 500px;" | ||
| > | ||
| <textarea | ||
| autocapitalize="off" | ||
| autocorrect="off" | ||
| class="ace_text-input" | ||
| spellcheck="false" | ||
| style="opacity: 0;" | ||
| wrap="off" | ||
| /> | ||
| <div | ||
| aria-hidden="true" | ||
| class="ace_gutter" | ||
| > | ||
| <div | ||
| class="ace_layer ace_gutter-layer ace_folding-enabled" | ||
| /> | ||
| <div | ||
| class="ace_gutter-active-line" | ||
| /> | ||
| </div> | ||
| <div | ||
| class="ace_scroller" | ||
| > | ||
| <div | ||
| class="ace_content" | ||
| > | ||
| <div | ||
| class="ace_layer ace_print-margin-layer" | ||
| > | ||
| <div | ||
| class="ace_print-margin" | ||
| style="left: 4px; visibility: hidden;" | ||
| /> | ||
| </div> | ||
| <div | ||
| class="ace_layer ace_marker-layer" | ||
| /> | ||
| <div | ||
| class="ace_layer ace_text-layer" | ||
| style="padding: 0px 4px;" | ||
| /> | ||
| <div | ||
| class="ace_layer ace_marker-layer" | ||
| /> | ||
| <div | ||
| class="ace_layer ace_cursor-layer ace_hidden-cursors" | ||
| > | ||
| <div | ||
| class="ace_cursor" | ||
| /> | ||
| </div> | ||
| </div> | ||
| <div | ||
| class="ace_comment ace_placeholder" | ||
| style="padding: 0px 9px; position: absolute; z-index: 3;" | ||
| > | ||
| { JSON spec... } | ||
| </div> | ||
| </div> | ||
| <div | ||
| class="ace_scrollbar ace_scrollbar-v" | ||
| style="display: none; width: 20px;" | ||
| > | ||
| <div | ||
| class="ace_scrollbar-inner" | ||
| style="width: 20px;" | ||
| /> | ||
| </div> | ||
| <div | ||
| class="ace_scrollbar ace_scrollbar-h" | ||
| style="display: none; height: 20px;" | ||
| > | ||
| <div | ||
| class="ace_scrollbar-inner" | ||
| style="height: 20px;" | ||
| /> | ||
| </div> | ||
| <div | ||
| style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;" | ||
| > | ||
| <div | ||
| style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;" | ||
| /> | ||
| <div | ||
| style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;" | ||
| > | ||
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div | ||
| class="bp3-dialog-footer" | ||
| > | ||
| <div | ||
| class="bp3-dialog-footer-actions" | ||
| > | ||
| <button | ||
| class="bp3-button" | ||
| type="button" | ||
| > | ||
| <span | ||
| class="bp3-button-text" | ||
| > | ||
| Close | ||
| </span> | ||
| </button> | ||
| <button | ||
| class="bp3-button bp3-disabled bp3-intent-primary" | ||
| disabled="" | ||
| tabindex="-1" | ||
| type="button" | ||
| > | ||
| <span | ||
| class="bp3-button-text" | ||
| > | ||
| Submit | ||
| </span> | ||
| </button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| `; | ||
|
|
||
| exports[`spec dialog matches snapshot with initSpec 1`] = ` | ||
| <div | ||
| class="bp3-portal" | ||
| > | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ export interface SpecDialogProps { | |
|
|
||
| export const SpecDialog = React.memo(function SpecDialog(props: SpecDialogProps) { | ||
| const { onClose, onSubmit, title, initSpec } = props; | ||
| const [spec, setSpec] = useState(() => (initSpec ? JSON.stringify(initSpec, null, 2) : '{\n\n}')); | ||
| const [spec, setSpec] = useState(() => (initSpec ? JSON.stringify(initSpec, null, 2) : '')); | ||
|
|
||
| function postSpec(): void { | ||
| if (!validJson(spec)) return; | ||
|
|
@@ -65,6 +65,7 @@ export const SpecDialog = React.memo(function SpecDialog(props: SpecDialogProps) | |
| tabSize: 2, | ||
| }} | ||
| style={{}} | ||
| placeholder="{ JSON spec... }" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two changes in this PR that are thematically similar (when you fix an issue it is better to look for other potential issues in the code). A placeholder is the ghost text that appears in an input that goes away as soon as you start typing. Before this change this dialog (which is not part of the data loader) would start of with |
||
| /> | ||
| <div className={Classes.DIALOG_FOOTER}> | ||
| <div className={Classes.DIALOG_FOOTER_ACTIONS}> | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when the text in the area can't be parsed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it can not parse the editor itself would keep the partial string value inside of it - so nothing interesting would happen. The issue is when it does parse... in simple terms this was the old problem:
Let say you were deleting text and you have
{entered. Then you press backspace.The simplified logic flow would go like this:
''''is valid JSON it parses tonull, notify the parentnullthat is not workable as a spec, adjust it to{}"{}"{}after you pressed backspace on{Now it would go like this:
''''is not valid JSON because it throws, keep waitingNote that
Hjson.parse({})is{}so that is why we need to special case white space only strings. If we were not being that fancy and using boring oldJSON.parsethis would not be an issue asJSON.parsedoes not recognize''as valid json.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed explanation!!