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

[CodeEditor] add support of triple quotes #112656

Merged
merged 10 commits into from
Oct 21, 2021

Conversation

alexwizp
Copy link
Contributor

@alexwizp alexwizp commented Sep 21, 2021

Closes: #107723

Summary:

[Vis editor] Triple quote for multiline script support in JSON input

Testing notes:

  1. create or open classic visualization e.g. Area
  2. set Average aggregation for Y-Axis
  3. expand Advanced panel and set the following JSON
{
    "script": {
        "lang": "painless",
        "source": """
            return 42
        """
    }
}

Expected result: JSON should be valid, script should be passed into ES request

Screens:

image

image

@alexwizp alexwizp self-assigned this Sep 21, 2021
@alexwizp alexwizp added Feature:Visualizations Generic visualization features (in case no more specific feature label is available) Team:Visualizations Visualization editors, elastic-charts and infrastructure release_note:fix labels Sep 21, 2021
@alexwizp alexwizp marked this pull request as ready for review September 21, 2021 14:05
@alexwizp alexwizp requested review from a team as code owners September 21, 2021 14:05
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-vis-editors (Team:VisEditors)

Copy link
Member

@ppisljar ppisljar left a comment

Choose a reason for hiding this comment

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

i have my doubts about this:

  • is this something a lot of customers are asking for ? seems very specific
  • why would we support tripple quotes in visualize aggregation advanced config but not in other places json can be entered ? seems we should either support this everywhere or not support it at all.

@flash1293
Copy link
Contributor

flash1293 commented Sep 22, 2021

@ppisljar See the linked issue for the reason behind switching - actually I think it would be nice for all raw JSON inputs in Kibana to support xjson as well, we can work on this incrementally (even though I have a hard time thinking of other places where JSON can be entered directly). The only place I can think of is dev tools which is already supporting xjson, so it's more about aligning with this (making it easier to copy over something from dev tools which is a common thing to do):
Screenshot 2021-09-22 at 10 06 28

Copy link
Contributor

@alisonelizabeth alisonelizabeth left a comment

Choose a reason for hiding this comment

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

Hi @alexwizp! Thanks for working on this.

I know the existing code is probably not the best example, but I think it would be helpful to add some code comments in the grammar file to help explain the implementation as well as tests. If I'm not mistaken, triple quotes was already supported via #67485, but this is more specifically implementing multiline support. Is that correct?

The XJSON lang is currently being used in Ingest Node Pipelines UI so I'd like to make sure there are no regressions.

@alexwizp
Copy link
Contributor Author

@alisonelizabeth I see that we have no tests for the packages/kbn-monaco 😢 About #67485 looks like only syntax highlighting was added here. @jloleysens could you please confirm that and maybe you can review that PR as well?

}
else string += ch;
}
for (; next(); ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

in this part, only the if statement has been removed.

if (peek('""')) {
.....
}

Copy link
Contributor

@jloleysens jloleysens left a comment

Choose a reason for hiding this comment

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

This is looking cool @alexwizp 🍻 ! I think it makes sense to support XJSON everywhere 👍

looks like only syntax highlighting was added here

That PR did add grammar parsing too (see comments for more details).

I'd like to get your (and perhaps @alisonelizabeth's) thoughts on my comments. Let me know what you think!

Comment on lines +14 to +23
function collapseLiteralStrings(xjson: string) {
const tripleQuotes = '"""';
const splitData = xjson.split(tripleQuotes);

for (let idx = 1; idx < splitData.length - 1; idx += 2) {
splitData[idx] = JSON.stringify(splitData[idx]);
}

return splitData.join('');
}
Copy link
Contributor

@jloleysens jloleysens Sep 23, 2021

Choose a reason for hiding this comment

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

I'm guessing this was copy-pasted from src/plugins/es_ui_shared/__packages_do_not_import__/xjson/json_xjson_translation_tools/index.ts?

I wonder whether it is worth moving that function to common in es-ui-shared and import from there (then also re-exporting it from where it was originally exported). Not sure you have to do that in this PR, but would be nice to not have too many of these around :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jloleysens not sure that it's a working idea due to two thoughts:

  • es-ui-shared plugin is responsible only for ui code and not sure that it's semantically right to create a common folder here.
  • es-ui-shared already depends on data plugin and this will cause cross-dependency import problem

If you want to reuse that code probably it should be moved into kibanaUtils. But in this case probably all XJSON related code should be there.

I thing now you see why that code was duplicated

Copy link
Contributor

Choose a reason for hiding this comment

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

es-ui-shared already depends on data plugin and this will cause cross-dependency import problem

Ah I see, that does make sense.

@alisonelizabeth Looking closer at the dependence on data only the const value indexPatterns is being imported and only the value ILLEGAL_CHARACTERS_VISIBLE is being used. This is actually from the data_views plugin now. We should be able to remove the dependence on data from es_ui_shared and replace with dataViews. That way we can import collapseLiteralStrings from es_ui_shared/common in data to only have one function defined. Your call though 👍🏻

@@ -96,37 +83,42 @@ export const createParser = () => {
(string += ch), next();
return (number = +string), isNaN(number) ? (error('Bad number'), void 0) : number;
},
stringLiteral = function(quotes: string) {
Copy link
Contributor

@jloleysens jloleysens Sep 23, 2021

Choose a reason for hiding this comment

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

The original functionality was airlifted out of:

}), ace.define("ace/mode/json/json_parse", ["require", "exports", "module"], function() {

This is, unfortunately, not exactly the most reader-friendly code and so without tests it's all the more tough to say if a regression has snuck in or not. I know with it being "the same-ish" as Console we had more guarantees that the code worked as expected (according to the tests on Console). It has also been fairly "manually" tested since then. I apologise for not adding tests here at the time 🤦🏻.

I think it would be useful to add tests for the difference you're expecting to see with these changes, but AFAICT it looks like this was just a refactor and we are expecting the same behaviour? If that's the case I'd recommend breaking this change out into a follow up PR that adds tests for the "before" and "after" behaviour against this parser.

Let me know what you think, or whether I've missed something!

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be useful to add tests for the difference you're expecting to see with these changes, but AFAICT it looks like this was just a refactor and we are expecting the same behaviour? If that's the case I'd recommend breaking this change out into a follow up PR that adds tests for the "before" and "after" behaviour against this parser.

++ Great suggestion. I'd also feel more comfortable with this change if I better understood the difference in behavior we're expecting (if any) to help ensure we're not introducing any regressions.

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've pushed some tests to be sure that everything works as before. Please if you see some specific case which you want to cover please let me know.

…le-quotes

# Conflicts:
#	src/plugins/vis_default_editor/kibana.json
@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor

@jloleysens jloleysens left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests @alexwizp and explaining the reasoning.

I still think it would be best to cherry-pick the parser-related changes onto a separate PR since they are not related to this PR's goal.

That being said, I won't block moving ahead but I think the PR description should explain that the parser was slightly refactored and we expect the same behaviour and added some tests.

Left a suggestion for one more test, thanks for adding those 🍻

expect(
parser(`
{"menu": {
"id": """
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder what would happen if we added \" at the end of a triple quote value, so \""""

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thank you, that case was broken 🥇

@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor

@jloleysens jloleysens left a comment

Choose a reason for hiding this comment

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

This is looking in a good state, @alexwizp. Happy to merge pending green CI.

@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor

@stratoula stratoula left a comment

Choose a reason for hiding this comment

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

KibanaVisEditors changes LGTM. I tested it locally and triple quotes are supported now :)

@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

@alexwizp
Copy link
Contributor Author

@elastic/kibana-stack-management please review

@kibanamachine
Copy link
Contributor

💛 Build succeeded, but was flaky


Test Failures

Kibana Pipeline / general / X-Pack API Integration Tests.x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples·ts.apis Machine Learning jobs Categorization example endpoint - invalid, too many tokens.

Link to Jenkins

Standard Out

Failed Tests Reporter:
  - Test has not failed recently on tracked branches

[00:00:00]     │
[00:00:00]       └-: apis
[00:00:00]         └-> "before all" hook in "apis"
[00:11:40]         └-: Machine Learning
[00:11:40]           └-> "before all" hook in "Machine Learning"
[00:11:40]           └-> "before all" hook in "Machine Learning"
[00:11:40]             │ debg creating role ft_ml_source
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_source]
[00:11:40]             │ debg creating role ft_ml_source_readonly
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_source_readonly]
[00:11:40]             │ debg creating role ft_ml_dest
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_dest]
[00:11:40]             │ debg creating role ft_ml_dest_readonly
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_dest_readonly]
[00:11:40]             │ debg creating role ft_ml_ui_extras
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_ui_extras]
[00:11:40]             │ debg creating role ft_default_space_ml_all
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_all]
[00:11:40]             │ debg creating role ft_default_space1_ml_all
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space1_ml_all]
[00:11:40]             │ debg creating role ft_all_spaces_ml_all
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_all_spaces_ml_all]
[00:11:40]             │ debg creating role ft_default_space_ml_read
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_read]
[00:11:40]             │ debg creating role ft_default_space1_ml_read
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space1_ml_read]
[00:11:40]             │ debg creating role ft_all_spaces_ml_read
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_all_spaces_ml_read]
[00:11:40]             │ debg creating role ft_default_space_ml_none
[00:11:40]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_none]
[00:11:40]             │ debg creating user ft_ml_poweruser
[00:11:40]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser]
[00:11:40]             │ debg created user ft_ml_poweruser
[00:11:40]             │ debg creating user ft_ml_poweruser_spaces
[00:11:40]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_spaces]
[00:11:40]             │ debg created user ft_ml_poweruser_spaces
[00:11:40]             │ debg creating user ft_ml_poweruser_space1
[00:11:40]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_space1]
[00:11:40]             │ debg created user ft_ml_poweruser_space1
[00:11:40]             │ debg creating user ft_ml_poweruser_all_spaces
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_all_spaces]
[00:11:41]             │ debg created user ft_ml_poweruser_all_spaces
[00:11:41]             │ debg creating user ft_ml_viewer
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer]
[00:11:41]             │ debg created user ft_ml_viewer
[00:11:41]             │ debg creating user ft_ml_viewer_spaces
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_spaces]
[00:11:41]             │ debg created user ft_ml_viewer_spaces
[00:11:41]             │ debg creating user ft_ml_viewer_space1
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_space1]
[00:11:41]             │ debg created user ft_ml_viewer_space1
[00:11:41]             │ debg creating user ft_ml_viewer_all_spaces
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_all_spaces]
[00:11:41]             │ debg created user ft_ml_viewer_all_spaces
[00:11:41]             │ debg creating user ft_ml_unauthorized
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_unauthorized]
[00:11:41]             │ debg created user ft_ml_unauthorized
[00:11:41]             │ debg creating user ft_ml_unauthorized_spaces
[00:11:41]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_unauthorized_spaces]
[00:11:41]             │ debg created user ft_ml_unauthorized_spaces
[00:16:22]           └-: jobs
[00:16:22]             └-> "before all" hook in "jobs"
[00:16:22]             └-: Categorization example endpoint - 
[00:16:22]               └-> "before all" hook for "valid with good number of tokens"
[00:16:22]               └-> "before all" hook for "valid with good number of tokens"
[00:16:22]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Loading "mappings.json"
[00:16:22]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Loading "data.json.gz"
[00:16:22]                 │ info [o.e.c.m.MetadataCreateIndexService] [node-01] [ft_categorization] creating index, cause [api], templates [], shards [1]/[0]
[00:16:22]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Created index "ft_categorization"
[00:16:22]                 │ debg [x-pack/test/functional/es_archives/ml/categorization] "ft_categorization" settings {"index":{"number_of_replicas":"0","number_of_shards":"1"}}
[00:16:23]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Indexed 1501 docs into "ft_categorization"
[00:16:23]                 │ debg applying update to kibana config: {"dateFormat:tz":"UTC"}
[00:16:23]               └-> valid with good number of tokens
[00:16:23]                 └-> "before each" hook: global before each for "valid with good number of tokens"
[00:16:24]                 └- ✓ pass  (158ms)
[00:16:24]               └-> invalid, too many tokens.
[00:16:24]                 └-> "before each" hook: global before each for "invalid, too many tokens."
[00:16:24]                 │ info [r.suppressed] [node-01] path: /_analyze, params: {}
[00:16:24]                 │      org.elasticsearch.transport.RemoteTransportException: [node-01][127.0.0.1:63121][indices:admin/analyze[s]]
[00:16:24]                 │      Caused by: java.lang.IllegalStateException: The number of tokens produced by calling _analyze has exceeded the allowed maximum of [10000]. This limit can be set by changing the [index.analyze.max_token_count] index level setting.
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction$TokenCounter.increment(TransportAnalyzeAction.java:397) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.simpleAnalyze(TransportAnalyzeAction.java:229) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:204) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:122) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:110) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.support.single.shard.TransportSingleShardAction.lambda$asyncShardOperation$0(TransportSingleShardAction.java:99) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:47) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.action.ActionRunnable$2.doRun(ActionRunnable.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:737) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:16:24]                 │      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
[00:16:24]                 │      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
[00:16:24]                 │      	at java.lang.Thread.run(Thread.java:833) [?:?]
[00:16:24]                 └- ✖ fail: apis Machine Learning jobs Categorization example endpoint -  invalid, too many tokens.
[00:16:24]                 │       Error: expected 'partially_valid' to sort of equal 'invalid'
[00:16:24]                 │       + expected - actual
[00:16:24]                 │ 
[00:16:24]                 │       -partially_valid
[00:16:24]                 │       +invalid
[00:16:24]                 │       
[00:16:24]                 │       at Assertion.assert (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/expect/expect.js:100:11)
[00:16:24]                 │       at Assertion.eql (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/expect/expect.js:244:8)
[00:16:24]                 │       at Context.<anonymous> (test/api_integration/apis/ml/jobs/categorization_field_examples.ts:302:44)
[00:16:24]                 │       at runMicrotasks (<anonymous>)
[00:16:24]                 │       at processTicksAndRejections (node:internal/process/task_queues:96:5)
[00:16:24]                 │       at Object.apply (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/test/target_node/functional_test_runner/lib/mocha/wrap_function.js:87:16)
[00:16:24]                 │ 
[00:16:24]                 │ 

Stack Trace

Error: expected 'partially_valid' to sort of equal 'invalid'
    at Assertion.assert (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/expect/expect.js:100:11)
    at Assertion.eql (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/expect/expect.js:244:8)
    at Context.<anonymous> (test/api_integration/apis/ml/jobs/categorization_field_examples.ts:302:44)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Object.apply (/dev/shm/workspace/parallel/12/kibana/node_modules/@kbn/test/target_node/functional_test_runner/lib/mocha/wrap_function.js:87:16) {
  actual: 'partially_valid',
  expected: 'invalid',
  showDiff: true
}

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
visDefaultEditor 152.7KB 152.7KB +42.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
data 465.9KB 466.0KB +111.0B
kbnUiSharedDeps-srcJs 3.8MB 3.8MB +27.0B
visDefaultEditor 19.3KB 19.5KB +140.0B
total +278.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @alexwizp

@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

@alexwizp
Copy link
Contributor Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
visDefaultEditor 152.7KB 152.7KB +42.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
data 469.3KB 469.4KB +111.0B
kbnUiSharedDeps-srcJs 3.8MB 3.8MB +27.0B
visDefaultEditor 19.3KB 19.5KB +140.0B
total +278.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @alexwizp

Copy link
Member

@sabarasaba sabarasaba left a comment

Choose a reason for hiding this comment

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

Thanks for working on this @alexwizp! Code changes LGTM, tested locally also and triple quotes work as expected 🚀

@alexwizp alexwizp merged commit 079fbce into elastic:master Oct 21, 2021
alexwizp added a commit to alexwizp/kibana that referenced this pull request Oct 21, 2021
* [CodeEditor] add support of triple quotes

* add tests for grammar

* an escaped quote can be appended to the end of triple quotes'

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
alexwizp added a commit that referenced this pull request Oct 21, 2021
* [CodeEditor] add support of triple quotes

* add tests for grammar

* an escaped quote can be appended to the end of triple quotes'

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
shivindera pushed a commit to shivindera/kibana that referenced this pull request Oct 25, 2021
* [CodeEditor] add support of triple quotes

* add tests for grammar

* an escaped quote can be appended to the end of triple quotes'

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Visualizations Generic visualization features (in case no more specific feature label is available) release_note:fix Team:Visualizations Visualization editors, elastic-charts and infrastructure v7.16.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Vis editor] Triple quote for multiline script support in JSON input
9 participants