diff --git a/etc/plugin-config-ui-lib.api.md b/etc/plugin-config-ui-lib.api.md index fe6250de..00d07c7b 100644 --- a/etc/plugin-config-ui-lib.api.md +++ b/etc/plugin-config-ui-lib.api.md @@ -9,14 +9,17 @@ import { BoxProps } from '@mui/material/Box'; import { ButtonProps } from '@mui/material/Button'; import { ChangeEventHandler } from 'react'; import { Controller } from 'react-hook-form'; +import { EditorProps } from '@monaco-editor/react'; import { FormMessagePayload } from '@cloudquery/plugin-config-ui-connector'; import { FormProvider } from 'react-hook-form'; import { ForwardRefExoticComponent } from 'react'; import { ImgHTMLAttributes } from 'react'; +import { JSONSchema } from 'monaco-yaml'; import { JSX as JSX_2 } from 'react/jsx-runtime'; import { LinkProps as LinkProps_2 } from '@mui/material/Link'; import { ListItemProps } from '@mui/material/ListItem'; import { ListProps } from '@mui/material/List'; +import type * as Monaco from 'monaco-editor'; import { PluginUiMessageHandler } from '@cloudquery/plugin-config-ui-connector'; import { PluginUiMessagePayload } from '@cloudquery/plugin-config-ui-connector'; import { default as React_2 } from 'react'; diff --git a/package-lock.json b/package-lock.json index dee3d747..cce2c4ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cloudquery/plugin-config-ui-lib", - "version": "6.0.2", + "version": "7.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cloudquery/plugin-config-ui-lib", - "version": "6.0.2", + "version": "7.0.0", "license": "MPL-2.0", "dependencies": { "@babel/runtime": "^7.26.7", @@ -21,7 +21,7 @@ "react-virtuoso": "^4.12.5" }, "bin": { - "create-app": "dist/scripts/generate-cloud-config-ui.mjs" + "create-app": "dist/scripts/generate-cloud-config-ui.js" }, "devDependencies": { "@babel/plugin-syntax-dynamic-import": "^7.8.3", @@ -35,6 +35,7 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.4", "@microsoft/api-extractor": "^7.49.2", + "@monaco-editor/react": "^4.7.0", "@mui/icons-material": "^6.0.0", "@mui/lab": "^6.0.0-beta.9", "@mui/material": "^6.0.0", @@ -74,6 +75,8 @@ "eslint-plugin-unicorn": "^56.0.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "monaco-editor": "^0.52.2", + "monaco-yaml": "^5.3.1", "prettier": "^3.4.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -86,6 +89,7 @@ "source-map-explorer": "^2.5.3", "storybook": "^8.5.3", "typescript": "^5.7.3", + "vite-plugin-monaco-editor": "^1.1.0", "yup": "^1.6.1" }, "peerDependencies": { @@ -93,12 +97,15 @@ "@emotion/cache": "^11.11.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.4", + "@monaco-editor/react": "^4.7.0", "@mui/icons-material": "^6.0.0", "@mui/lab": "^6.0.0-beta.9", "@mui/material": "^6.0.0", "@mui/system": "^6.0.0", "@mui/x-date-pickers": "^7.6.2", "@playwright/test": "^1.47.2", + "monaco-editor": "^0.52.2", + "monaco-yaml": "^5.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", "yup": "^1.4.0" @@ -181,6 +188,16 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", @@ -228,6 +245,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", @@ -250,6 +277,16 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", @@ -268,6 +305,16 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", @@ -1904,6 +1951,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/preset-flow": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.25.9.tgz", @@ -3954,6 +4011,31 @@ "resolve": "~1.22.2" } }, + "node_modules/@monaco-editor/loader": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.5.0.tgz", + "integrity": "sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@mui/base": { "version": "5.0.0-beta.69", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.69.tgz", @@ -5336,19 +5418,6 @@ } } }, - "node_modules/@storybook/core/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@storybook/csf": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.12.tgz", @@ -6235,19 +6304,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { "version": "8.23.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", @@ -6935,6 +6991,16 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", @@ -6982,6 +7048,16 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.10.6", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", @@ -8637,6 +8713,16 @@ "node": "*" } }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-import/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -8834,6 +8920,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-sort-destructure-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-2.0.0.tgz", @@ -8915,19 +9011,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-unicorn/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -10297,19 +10380,6 @@ "semver": "^7.6.3" } }, - "node_modules/is-bun-module/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -10763,19 +10833,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -11715,19 +11772,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -12020,6 +12064,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -12222,19 +12273,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -12404,6 +12442,90 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/monaco-languageserver-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/monaco-languageserver-types/-/monaco-languageserver-types-0.4.0.tgz", + "integrity": "sha512-QQ3BZiU5LYkJElGncSNb5AKoJ/LCs6YBMCJMAz9EA7v+JaOdn3kx2cXpPTcZfKA5AEsR0vc97sAw+5mdNhVBmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "monaco-types": "^0.1.0", + "vscode-languageserver-protocol": "^3.0.0", + "vscode-uri": "^3.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/monaco-marker-data-provider": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/monaco-marker-data-provider/-/monaco-marker-data-provider-1.2.4.tgz", + "integrity": "sha512-4DsPgsAqpTyUDs3humXRBPUJoihTv+L6v9aupQWD80X2YXaCXUd11mWYeSCYHuPgdUmjFaNWCEOjQ6ewf/QA1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "monaco-types": "^0.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/monaco-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/monaco-types/-/monaco-types-0.1.0.tgz", + "integrity": "sha512-aWK7SN9hAqNYi0WosPoMjenMeXJjwCxDibOqWffyQ/qXdzB/86xshGQobRferfmNz7BSNQ8GB0MD0oby9/5fTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/monaco-worker-manager": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/monaco-worker-manager/-/monaco-worker-manager-2.0.1.tgz", + "integrity": "sha512-kdPL0yvg5qjhKPNVjJoym331PY/5JC11aPJXtCZNwWRvBr6jhkIamvYAyiY5P1AWFmNOy0aRDRoMdZfa71h8kg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "monaco-editor": ">=0.30.0" + } + }, + "node_modules/monaco-yaml": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/monaco-yaml/-/monaco-yaml-5.3.1.tgz", + "integrity": "sha512-1MN8i1Tnc8d8RugQGqv5jp+Ce2xtNhrnbm0ZZbe5ceExj9C2PkKZfHJhY9kbdUS4G7xSVwKlVdMTmLlStepOtw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "examples/*" + ], + "dependencies": { + "jsonc-parser": "^3.0.0", + "monaco-languageserver-types": "^0.4.0", + "monaco-marker-data-provider": "^1.0.0", + "monaco-types": "^0.1.0", + "monaco-worker-manager": "^2.0.0", + "path-browserify": "^1.0.0", + "prettier": "^3.0.0", + "vscode-languageserver-textdocument": "^1.0.0", + "vscode-languageserver-types": "^3.0.0", + "vscode-uri": "^3.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + }, + "peerDependencies": { + "monaco-editor": ">=0.36" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -12830,6 +12952,13 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13589,9 +13718,9 @@ } }, "node_modules/recast": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", "dev": true, "license": "MIT", "dependencies": { @@ -14229,13 +14358,16 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/serialize-javascript": { @@ -14664,6 +14796,13 @@ "node": ">=8" } }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "dev": true, + "license": "MIT" + }, "node_modules/storybook": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.5.3.tgz", @@ -15744,6 +15883,58 @@ } } }, + "node_modules/vite-plugin-monaco-editor": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-plugin-monaco-editor/-/vite-plugin-monaco-editor-1.1.0.tgz", + "integrity": "sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "monaco-editor": ">=0.33.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -16102,8 +16293,6 @@ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "license": "ISC", - "optional": true, - "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index d356cb2a..283f8e6c 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "@cloudquery/plugin-config-ui-lib", "description": "Plugin configuration UI library for CloudQuery Cloud App", - "version": "6.0.2", + "version": "7.0.0", "private": false, "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts", "bin": { - "create-app": "./dist/scripts/generate-cloud-config-ui.mjs" + "create-app": "./dist/scripts/generate-cloud-config-ui.js" }, "exports": { ".": { @@ -26,8 +26,10 @@ "require": "./dist/e2e-utils/index.cjs.js" }, "./scripts/*": { - "require": "./dist/scripts/*" + "import": "./dist/scripts/*" }, + "./configs/tsconfig.app.json": "./dist/configs/tsconfig.app.json", + "./configs/vite.config.app.js": "./dist/configs/vite.config.app.js", "./.eslintrc.js": "./.eslintrc.js", "./.prettierrc.js": "./.prettierrc.js" }, @@ -92,12 +94,15 @@ "@emotion/cache": "^11.11.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.4", + "@monaco-editor/react": "^4.7.0", "@mui/icons-material": "^6.0.0", "@mui/lab": "^6.0.0-beta.9", "@mui/material": "^6.0.0", "@mui/system": "^6.0.0", "@mui/x-date-pickers": "^7.6.2", "@playwright/test": "^1.47.2", + "monaco-editor": "^0.52.2", + "monaco-yaml": "^5.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", "yup": "^1.4.0" @@ -114,6 +119,7 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.4", "@microsoft/api-extractor": "^7.49.2", + "@monaco-editor/react": "^4.7.0", "@mui/icons-material": "^6.0.0", "@mui/lab": "^6.0.0-beta.9", "@mui/material": "^6.0.0", @@ -153,6 +159,8 @@ "eslint-plugin-unicorn": "^56.0.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "monaco-editor": "^0.52.2", + "monaco-yaml": "^5.3.1", "prettier": "^3.4.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -165,6 +173,7 @@ "source-map-explorer": "^2.5.3", "storybook": "^8.5.3", "typescript": "^5.7.3", + "vite-plugin-monaco-editor": "^1.1.0", "yup": "^1.6.1" } } diff --git a/rollup.config.js b/rollup.config.js index 23c6433e..59ad2c1b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -39,6 +39,13 @@ export default [ comments: /webpackIgnore:/, }, }), + copy({ + targets: [ + { src: 'src/scripts', dest: 'dist' }, + { src: 'src/template', dest: 'dist' }, + { src: 'src/configs', dest: 'dist' }, + ] + }) ], }, { @@ -77,12 +84,6 @@ export default [ comments: /webpackIgnore:/, }, }), - copy({ - targets: [ - { src: 'src/scripts', dest: 'dist' }, - { src: 'src/template', dest: 'dist' } - ] - }) ], }, { diff --git a/src/components/display/formFooter/index.tsx b/src/components/display/formFooter/index.tsx index 17c37a56..30508acc 100644 --- a/src/components/display/formFooter/index.tsx +++ b/src/components/display/formFooter/index.tsx @@ -1,5 +1,4 @@ import { PluginUiMessagePayload } from '@cloudquery/plugin-config-ui-connector'; -import LoadingButton from '@mui/lab/LoadingButton'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; @@ -120,7 +119,7 @@ export function FormFooter({ - {submitLabel || 'Test connection and save'} - + {(isTestingConnection || testConnectionError || submitPayload) && ( diff --git a/src/components/form/configUIForm.tsx b/src/components/form/configUIForm.tsx index b77fe037..a3dec5a4 100644 --- a/src/components/form/configUIForm.tsx +++ b/src/components/form/configUIForm.tsx @@ -181,18 +181,28 @@ export function ConfigUIForm({ prepareSubmitValues, container }: ConfigUIFormPro const theme = useMemo(() => { const themeOptions = createThemeOptions(); - if (container) { - themeOptions.components = { - ...themeOptions.components, - MuiMenu: { - ...themeOptions.components?.MuiMenu, - defaultProps: { - ...themeOptions.components?.MuiMenu?.defaultProps, - container: container as any, + themeOptions.components = { + ...themeOptions.components, + MuiMenu: { + ...themeOptions.components?.MuiMenu, + defaultProps: { + ...themeOptions.components?.MuiMenu?.defaultProps, + ...(container ? { container: container as any } : {}), + }, + }, + MuiInputLabel: { + ...themeOptions.components?.MuiInputLabel, + styleOverrides: { + ...themeOptions.components?.MuiInputLabel?.styleOverrides, + root: { + ...(typeof themeOptions.components?.MuiInputLabel?.styleOverrides?.root === 'object' + ? themeOptions.components?.MuiInputLabel?.styleOverrides?.root + : {}), + top: '-4px', }, }, - }; - } + }, + }; return createTheme(themeOptions); }, [container]); @@ -212,6 +222,8 @@ export function ConfigUIForm({ prepareSubmitValues, container }: ConfigUIFormPro sx={{ flex: '1 1 0', minWidth: 0, + position: 'relative', + zIndex: 2, }} >
@@ -228,7 +240,11 @@ export function ConfigUIForm({ prepareSubmitValues, container }: ConfigUIFormPro step === index && ( {children.map((section, index) => ( - + ))} ) @@ -260,7 +276,14 @@ export function ConfigUIForm({ prepareSubmitValues, container }: ConfigUIFormPro
- + diff --git a/src/components/form/controls/controlCodeField.tsx b/src/components/form/controls/controlCodeField.tsx new file mode 100644 index 00000000..1d5a9913 --- /dev/null +++ b/src/components/form/controls/controlCodeField.tsx @@ -0,0 +1,169 @@ +'use client'; + +import React, { forwardRef, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; + +import { Editor, EditorProps, loader, OnMount } from '@monaco-editor/react'; +import { Box, CircularProgress, FormControl, FormHelperText, FormLabel } from '@mui/material'; +import Stack from '@mui/material/Stack'; + +import * as monaco from 'monaco-editor'; +import { configureMonacoYaml, JSONSchema } from 'monaco-yaml'; +import { Controller } from 'react-hook-form'; + +import type * as Monaco from 'monaco-editor'; + +type MonacoType = typeof Monaco; +type MonacoEditor = Monaco.editor.IStandaloneCodeEditor; + +export interface ControlCodeFieldProps extends Omit { + name: string; + label?: string; + helperText?: ReactNode; + editorRef?: React.MutableRefObject; + onMount?: (editor: MonacoEditor, monaco: MonacoType) => Promise | void; + yamlSchema?: JSONSchema; + container?: HTMLElement | ShadowRoot; +} + +export const ControlCodeField = forwardRef( + ({ onMount, options = {}, yamlSchema, container, name, label, helperText, ...props }, ref) => { + const [isLoading, setIsLoading] = useState(true); + const [initialized, setInitialized] = useState(false); + const disposeRef = useRef<() => void>(); + + useEffect(() => { + loader.config({ monaco }); + + setInitialized(true); + }, []); + + const handleEditorMount: OnMount = useCallback( + async (editor, monaco) => { + if (ref) { + if (typeof ref === 'function') { + ref(editor); + } else { + ref.current = editor; + } + } + + monaco.editor.defineTheme('custom-theme', { + base: 'vs-dark', + colors: { + 'editor.background': '#15202E', + 'editor.foreground': '#FFFFFF', + }, + inherit: true, + rules: [], + }); + monaco.editor.setTheme('custom-theme'); + + if (props.language === 'yaml' && yamlSchema) { + const { dispose } = configureMonacoYaml(monaco, { + schemas: [ + { + fileMatch: ['*'], + schema: yamlSchema, + uri: 'inmemory://my-schema.json', + }, + ], + validate: false, + }); + disposeRef.current = dispose; + } + + if (onMount) { + await onMount(editor, monaco); + } + + setIsLoading(false); + }, + [onMount, props.language, yamlSchema, ref], + ); + + useEffect(() => { + return () => { + disposeRef.current?.(); + }; + }, []); + + const Loader = () => ( + + + + ); + + if (!initialized) { + return ; + } + + return ( + + {!!label && {label}} + ( + <> + {!!helperText && ( + + {!!fieldState.error?.message && ( + {fieldState.error?.message} + )} + {helperText} + + )} + + {isLoading && } + } + onChange={(value) => field.onChange(value ?? '')} + onMount={handleEditorMount} + options={{ + automaticLayout: true, + minimap: { + enabled: false, + }, + quickSuggestions: true, + suggestOnTriggerCharacters: true, + lineNumbers: 'off', + folding: false, + lineDecorationsWidth: 0, + lineNumbersMinChars: 0, + glyphMargin: false, + scrollbar: { + alwaysConsumeMouseWheel: false, + }, + overflowWidgetsDomNode: container as HTMLElement, + ...options, + }} + value={field.value} + /> + + + )} + /> + + ); + }, +); + +ControlCodeField.displayName = 'ControlCodeField'; diff --git a/src/components/form/controls/controlDateField.tsx b/src/components/form/controls/controlDateField.tsx index cb874e09..ec68b5c8 100644 --- a/src/components/form/controls/controlDateField.tsx +++ b/src/components/form/controls/controlDateField.tsx @@ -40,6 +40,7 @@ export function ControlDateField({ e.target instanceof HTMLElement && e.target.blur()} sx={{ 'input::-webkit-inner-spin-button': { - '-webkit-appearance': 'none', + WebkitAppearance: 'none', margin: 0, }, input: { - '-moz-appearance': 'textfield', + MozAppearance: 'textfield', }, }} /> diff --git a/src/components/form/controls/controlOAuthField.tsx b/src/components/form/controls/controlOAuthField.tsx index f23cf3e2..312cb6a8 100644 --- a/src/components/form/controls/controlOAuthField.tsx +++ b/src/components/form/controls/controlOAuthField.tsx @@ -1,7 +1,6 @@ import { useEffect } from 'react'; import CheckIcon from '@mui/icons-material/Check'; -import LoadingButton from '@mui/lab/LoadingButton'; import Button from '@mui/material/Button'; @@ -95,7 +94,7 @@ export function ControlOAuthField({ alignItems: 'center', }} > - + {isLoading && ( ); } return ( - ); diff --git a/src/components/inputs/multiAutocomplete.tsx b/src/components/inputs/multiAutocomplete.tsx index d010c39d..78d510b2 100644 --- a/src/components/inputs/multiAutocomplete.tsx +++ b/src/components/inputs/multiAutocomplete.tsx @@ -1,6 +1,7 @@ import React from 'react'; import Autocomplete from '@mui/material/Autocomplete'; +import { inputBaseClasses } from '@mui/material/InputBase'; import TextField from '@mui/material/TextField'; import { getFieldHelperText } from '../../utils/getFieldHelperText'; @@ -73,6 +74,12 @@ export const MultiAutocomplete = React.forwardRef( {...textFieldProps} ref={ref} name={name} + size="small" /> {isSecret && ( ( inputSelectorToFocus={`input[name="${name}"]`} onCancel={() => handelCancelReset()} onReset={() => handleReset()} - sx={{ minHeight: 55 }} + sx={{ minHeight: 48 }} /> )} diff --git a/src/components/inputs/tableSelector/filters.tsx b/src/components/inputs/tableSelector/filters.tsx index ee1bf6b4..af24543e 100644 --- a/src/components/inputs/tableSelector/filters.tsx +++ b/src/components/inputs/tableSelector/filters.tsx @@ -40,6 +40,7 @@ export function TableSelectorFilters({ placeholder="Search tables" value={searchValue} disabled={disabled} + size="small" />