From 36bb04caef91175693fbdfccc724f318342f127e Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:56:48 +0200 Subject: [PATCH 1/4] Revert monaco-editor to fix auto-complete --- packages/toolpad-app/package.json | 2 +- renovate.json | 4 + test/integration/editor/fixture/toolpad.yml | 62 ----------- .../.generated/functions/toolpad_main.js | 104 ++++++++++++++++++ .../fixture/toolpad/pages/page1/page.yml | 17 +++ .../fixture/toolpad/pages/page2/page.yml | 19 ++++ test/integration/editor/index.spec.ts | 26 +++++ test/models/ToolpadEditor.ts | 5 +- yarn.lock | 8 +- 9 files changed, 179 insertions(+), 68 deletions(-) delete mode 100644 test/integration/editor/fixture/toolpad.yml create mode 100644 test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js create mode 100644 test/integration/editor/fixture/toolpad/pages/page1/page.yml create mode 100644 test/integration/editor/fixture/toolpad/pages/page2/page.yml diff --git a/packages/toolpad-app/package.json b/packages/toolpad-app/package.json index e145006fae3..3c56785a995 100644 --- a/packages/toolpad-app/package.json +++ b/packages/toolpad-app/package.json @@ -98,7 +98,7 @@ "lodash-es": "^4.17.21", "markdown-to-jsx": "^7.2.0", "mime": "^3.0.0", - "monaco-editor": "0.37.1", + "monaco-editor": "0.36.1", "mysql2": "^3.2.3", "nanoid": "^4.0.2", "next": "^13.3.1", diff --git a/renovate.json b/renovate.json index 2237e5ac1b7..742bdd17213 100644 --- a/renovate.json +++ b/renovate.json @@ -67,6 +67,10 @@ "matchPackageNames": ["core-js"], "allowedVersions": "< 2.0.0" }, + { + "groupName": "monaco-editor", + "matchPackageNames": ["monaco-editor"] + }, { "matchDepTypes": ["action"], "pinDigests": true diff --git a/test/integration/editor/fixture/toolpad.yml b/test/integration/editor/fixture/toolpad.yml deleted file mode 100644 index de27c49782b..00000000000 --- a/test/integration/editor/fixture/toolpad.yml +++ /dev/null @@ -1,62 +0,0 @@ -{ - 'root': 'y3c19mb', - 'nodes': - { - 'ft63r75': - { - 'id': 'ft63r75', - 'name': 'textField1', - 'type': 'element', - 'props': { 'label': { 'type': 'const', 'value': 'textField1' } }, - 'layout': {}, - 'parentId': 'w173rcy', - 'attributes': { 'component': { 'type': 'const', 'value': 'TextField' } }, - 'parentProp': 'children', - 'parentIndex': 'a0', - }, - 'rl83rbf': - { - 'id': 'rl83rbf', - 'name': 'textField2', - 'type': 'element', - 'props': { 'label': { 'type': 'const', 'value': 'textField2' } }, - 'layout': {}, - 'parentId': 'w173rcy', - 'attributes': { 'component': { 'type': 'const', 'value': 'TextField' } }, - 'parentProp': 'children', - 'parentIndex': 'a1', - }, - 'w173rcy': - { - 'id': 'w173rcy', - 'name': 'pageRow', - 'type': 'element', - 'props': {}, - 'layout': {}, - 'parentId': 'y4d19z0', - 'attributes': { 'component': { 'type': 'const', 'value': 'PageRow' } }, - 'parentProp': 'children', - 'parentIndex': 'a0', - }, - 'y3c19mb': - { - 'id': 'y3c19mb', - 'name': 'Application', - 'type': 'app', - 'parentId': null, - 'attributes': {}, - 'parentProp': null, - 'parentIndex': null, - }, - 'y4d19z0': - { - 'id': 'y4d19z0', - 'name': 'page1', - 'type': 'page', - 'parentId': 'y3c19mb', - 'attributes': { 'title': { 'type': 'const', 'value': 'Page 1' } }, - 'parentProp': 'pages', - 'parentIndex': 'a0', - }, - }, -} diff --git a/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js b/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js new file mode 100644 index 00000000000..6e0923218d9 --- /dev/null +++ b/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js @@ -0,0 +1,104 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// toolpad:main.ts +var import_server = require("@mui/toolpad-core/server"); +var import_errors = require("@mui/toolpad-utils/errors"); +var import_node_fetch = __toESM(require("node-fetch")); +if (!global.fetch) { + global.fetch = import_node_fetch.default; + global.Headers = import_node_fetch.Headers; + global.Request = import_node_fetch.Request; + global.Response = import_node_fetch.Response; +} +var resolversPromise; +async function getResolvers() { + if (!resolversPromise) { + resolversPromise = (async () => { + const functions = await import("./toolpad/resources/functions.ts").catch((err) => { + console.error(err); + return {}; + }); + const functionsFileResolvers = Object.entries(functions).flatMap(([name, resolver]) => { + return typeof resolver === "function" ? [[name, resolver]] : []; + }); + return new Map(functionsFileResolvers); + })(); + } + return resolversPromise; +} +async function loadResolver(name) { + const resolvers = await getResolvers(); + const resolver = resolvers.get(name); + if (!resolver) { + throw new Error(`Can't find "${name}"`); + } + return resolver; +} +async function execResolver(name, parameters) { + const resolver = await loadResolver(name); + return resolver({ parameters }); +} +process.on("message", async (msg) => { + switch (msg.kind) { + case "exec": { + let data, error; + try { + data = await execResolver(msg.name, msg.parameters); + } catch (err) { + error = (0, import_errors.serializeError)((0, import_errors.errorFrom)(err)); + } + process.send({ + kind: "result", + id: msg.id, + data, + error + }); + break; + } + case "introspect": { + let data, error; + try { + const resolvers = await getResolvers(); + const resolvedResolvers = Array.from(resolvers, ([name, resolver]) => [ + name, + resolver[import_server.TOOLPAD_FUNCTION] || {} + ]); + data = { + functions: Object.fromEntries(resolvedResolvers.filter(Boolean)) + }; + } catch (err) { + error = (0, import_errors.serializeError)((0, import_errors.errorFrom)(err)); + } + process.send({ + kind: "result", + id: msg.id, + data, + error + }); + break; + } + default: + console.log(`Unknown message kind "${msg.kind}"`); + } +}); diff --git a/test/integration/editor/fixture/toolpad/pages/page1/page.yml b/test/integration/editor/fixture/toolpad/pages/page1/page.yml new file mode 100644 index 00000000000..f4eb65bb505 --- /dev/null +++ b/test/integration/editor/fixture/toolpad/pages/page1/page.yml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: page +spec: + id: y4d19z0 + title: Page 1 + content: + - component: PageRow + name: pageRow + children: + - component: TextField + name: textField1 + props: + label: textField1 + - component: TextField + name: textField2 + props: + label: textField2 diff --git a/test/integration/editor/fixture/toolpad/pages/page2/page.yml b/test/integration/editor/fixture/toolpad/pages/page2/page.yml new file mode 100644 index 00000000000..fe570b2e874 --- /dev/null +++ b/test/integration/editor/fixture/toolpad/pages/page2/page.yml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: page +spec: + id: K7SkzhT + title: page2 + display: shell + content: + - component: PageRow + name: pageRow + children: + - component: TextField + name: textField + - component: PageRow + name: pageRow1 + children: + - component: Text + name: text + props: + value: text-foo diff --git a/test/integration/editor/index.spec.ts b/test/integration/editor/index.spec.ts index 8f835b93162..892f7f32f0e 100644 --- a/test/integration/editor/index.spec.ts +++ b/test/integration/editor/index.spec.ts @@ -1,4 +1,5 @@ import * as path from 'path'; +import { setTimeout } from 'timers/promises'; import { test, expect } from '../../playwright/localTest'; import { ToolpadEditor } from '../../models/ToolpadEditor'; import clickCenter from '../../utils/clickCenter'; @@ -90,3 +91,28 @@ test('can delete elements from page', async ({ page }) => { await expect(canvasInputLocator).toHaveCount(0); }); + +test('code editor auto-complete', async ({ page }) => { + const editorModel = new ToolpadEditor(page); + + await editorModel.goToPageById('K7SkzhT'); + + await editorModel.waitForOverlay(); + + const text = editorModel.appCanvas.getByText('text-foo'); + + await clickCenter(page, text); + + const bindingButton = editorModel.componentEditor.getByLabel('Bind property "Value"'); + + await bindingButton.click(); + + const editor = page + .getByRole('dialog', { name: 'Bind property "Value"' }) + .locator('.monaco-editor'); + + await editor.waitFor(); + + await page.keyboard.type('textF'); + await expect(page.getByRole('option', { name: 'textField' })).toBeVisible(); +}); diff --git a/test/models/ToolpadEditor.ts b/test/models/ToolpadEditor.ts index 7e408c6e631..3ea237a7b58 100644 --- a/test/models/ToolpadEditor.ts +++ b/test/models/ToolpadEditor.ts @@ -104,7 +104,10 @@ export class ToolpadEditor { async goToPage(name: string) { await this.explorer.getByText(name).click(); - this.page.waitForNavigation(); + } + + async goToPageById(id: string) { + await gotoIfNotCurrent(this.page, `/_toolpad/app/pages/${id}`); } async createComponent(name: string) { diff --git a/yarn.lock b/yarn.lock index fba218c6b04..89a419ba0c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9478,10 +9478,10 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -monaco-editor@0.37.1: - version "0.37.1" - resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.37.1.tgz#d6f5ffb593e019e74e19bf8a2bdef5a691876f4e" - integrity sha512-jLXEEYSbqMkT/FuJLBZAVWGuhIb4JNwHE9kPTorAVmsdZ4UzHAfgWxLsVtD7pLRFaOwYPhNG9nUCpmFL1t/dIg== +monaco-editor@0.36.1: + version "0.36.1" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.36.1.tgz#aad528c815605307473a1634612946921d8079b5" + integrity sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg== mri@^1.1.5: version "1.2.0" From c10789c325a0159b851ed7a59e9685af65f9e7db Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:58:55 +0200 Subject: [PATCH 2/4] not this --- .../.generated/functions/toolpad_main.js | 104 ------------------ 1 file changed, 104 deletions(-) delete mode 100644 test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js diff --git a/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js b/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js deleted file mode 100644 index 6e0923218d9..00000000000 --- a/test/integration/editor/fixture/toolpad/.generated/functions/toolpad_main.js +++ /dev/null @@ -1,104 +0,0 @@ -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); - -// toolpad:main.ts -var import_server = require("@mui/toolpad-core/server"); -var import_errors = require("@mui/toolpad-utils/errors"); -var import_node_fetch = __toESM(require("node-fetch")); -if (!global.fetch) { - global.fetch = import_node_fetch.default; - global.Headers = import_node_fetch.Headers; - global.Request = import_node_fetch.Request; - global.Response = import_node_fetch.Response; -} -var resolversPromise; -async function getResolvers() { - if (!resolversPromise) { - resolversPromise = (async () => { - const functions = await import("./toolpad/resources/functions.ts").catch((err) => { - console.error(err); - return {}; - }); - const functionsFileResolvers = Object.entries(functions).flatMap(([name, resolver]) => { - return typeof resolver === "function" ? [[name, resolver]] : []; - }); - return new Map(functionsFileResolvers); - })(); - } - return resolversPromise; -} -async function loadResolver(name) { - const resolvers = await getResolvers(); - const resolver = resolvers.get(name); - if (!resolver) { - throw new Error(`Can't find "${name}"`); - } - return resolver; -} -async function execResolver(name, parameters) { - const resolver = await loadResolver(name); - return resolver({ parameters }); -} -process.on("message", async (msg) => { - switch (msg.kind) { - case "exec": { - let data, error; - try { - data = await execResolver(msg.name, msg.parameters); - } catch (err) { - error = (0, import_errors.serializeError)((0, import_errors.errorFrom)(err)); - } - process.send({ - kind: "result", - id: msg.id, - data, - error - }); - break; - } - case "introspect": { - let data, error; - try { - const resolvers = await getResolvers(); - const resolvedResolvers = Array.from(resolvers, ([name, resolver]) => [ - name, - resolver[import_server.TOOLPAD_FUNCTION] || {} - ]); - data = { - functions: Object.fromEntries(resolvedResolvers.filter(Boolean)) - }; - } catch (err) { - error = (0, import_errors.serializeError)((0, import_errors.errorFrom)(err)); - } - process.send({ - kind: "result", - id: msg.id, - data, - error - }); - break; - } - default: - console.log(`Unknown message kind "${msg.kind}"`); - } -}); From a4882f5812cd317ef59f552a516a06a8a15eb88c Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Thu, 27 Apr 2023 16:00:40 +0200 Subject: [PATCH 3/4] not this --- test/integration/editor/index.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/editor/index.spec.ts b/test/integration/editor/index.spec.ts index 892f7f32f0e..f94e4787820 100644 --- a/test/integration/editor/index.spec.ts +++ b/test/integration/editor/index.spec.ts @@ -1,5 +1,4 @@ import * as path from 'path'; -import { setTimeout } from 'timers/promises'; import { test, expect } from '../../playwright/localTest'; import { ToolpadEditor } from '../../models/ToolpadEditor'; import clickCenter from '../../utils/clickCenter'; From 6af6fd7c56294372661bc55a12a16a6e34af5072 Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Thu, 27 Apr 2023 17:36:21 +0200 Subject: [PATCH 4/4] real fix --- packages/toolpad-app/package.json | 2 +- packages/toolpad-app/src/components/MonacoEditor.tsx | 2 +- renovate.json | 4 ---- yarn.lock | 8 ++++---- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/toolpad-app/package.json b/packages/toolpad-app/package.json index 3c56785a995..e145006fae3 100644 --- a/packages/toolpad-app/package.json +++ b/packages/toolpad-app/package.json @@ -98,7 +98,7 @@ "lodash-es": "^4.17.21", "markdown-to-jsx": "^7.2.0", "mime": "^3.0.0", - "monaco-editor": "0.36.1", + "monaco-editor": "0.37.1", "mysql2": "^3.2.3", "nanoid": "^4.0.2", "next": "^13.3.1", diff --git a/packages/toolpad-app/src/components/MonacoEditor.tsx b/packages/toolpad-app/src/components/MonacoEditor.tsx index 051d076b0b4..5ecf38fa102 100644 --- a/packages/toolpad-app/src/components/MonacoEditor.tsx +++ b/packages/toolpad-app/src/components/MonacoEditor.tsx @@ -370,7 +370,7 @@ export default React.forwardRef(function } } } else { - const pathUri = monaco.Uri.parse(`./scripts/${nanoid(7)}${getExtension(language)}`); + const pathUri = monaco.Uri.parse(`/scripts/${nanoid(7)}${getExtension(language)}`); const model = monaco.editor.createModel(value || '', language, pathUri); instance = monaco.editor.create(rootRef.current, { diff --git a/renovate.json b/renovate.json index 742bdd17213..2237e5ac1b7 100644 --- a/renovate.json +++ b/renovate.json @@ -67,10 +67,6 @@ "matchPackageNames": ["core-js"], "allowedVersions": "< 2.0.0" }, - { - "groupName": "monaco-editor", - "matchPackageNames": ["monaco-editor"] - }, { "matchDepTypes": ["action"], "pinDigests": true diff --git a/yarn.lock b/yarn.lock index 89a419ba0c7..fba218c6b04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9478,10 +9478,10 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -monaco-editor@0.36.1: - version "0.36.1" - resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.36.1.tgz#aad528c815605307473a1634612946921d8079b5" - integrity sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg== +monaco-editor@0.37.1: + version "0.37.1" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.37.1.tgz#d6f5ffb593e019e74e19bf8a2bdef5a691876f4e" + integrity sha512-jLXEEYSbqMkT/FuJLBZAVWGuhIb4JNwHE9kPTorAVmsdZ4UzHAfgWxLsVtD7pLRFaOwYPhNG9nUCpmFL1t/dIg== mri@^1.1.5: version "1.2.0"