From e53f72f33ecf694b57022c1855b127c55b7cbfd9 Mon Sep 17 00:00:00 2001 From: jingyu Date: Tue, 16 May 2023 19:23:33 +0800 Subject: [PATCH 01/36] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8D=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/.eslintrc.js | 42 +++++++ packages/plugin-multiple-editor/package.json | 4 +- .../plugin-multiple-editor/src/Controller.ts | 38 +++--- .../delete-hidden-transducer/index.ts | 10 +- .../sample-plugins/set-ref-prop/index.tsx | 12 +- .../src/dev-config/universal/plugin.tsx | 15 ++- .../src/dev-config/universal/utils.ts | 4 +- packages/plugin-multiple-editor/src/index.tsx | 6 +- .../plugin-multiple-editor/src/types/index.ts | 4 +- .../plugin-multiple-editor/src/utils/code.ts | 11 +- .../src/utils/get-methods.ts | 2 +- packages/plugin-multiple-editor/tsconfig.json | 111 ++++++++++++++++-- 12 files changed, 184 insertions(+), 75 deletions(-) create mode 100644 packages/plugin-multiple-editor/.eslintrc.js diff --git a/packages/plugin-multiple-editor/.eslintrc.js b/packages/plugin-multiple-editor/.eslintrc.js new file mode 100644 index 0000000..103b0c3 --- /dev/null +++ b/packages/plugin-multiple-editor/.eslintrc.js @@ -0,0 +1,42 @@ +module.exports = { + 'env': { + 'browser': true, + 'es2021': true + }, + 'extends': [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/recommended', + "react-app", + ], + 'parser': '@typescript-eslint/parser', + 'parserOptions': { + 'ecmaFeatures': { + 'jsx': true + }, + 'ecmaVersion': 'latest', + 'sourceType': 'module' + }, + 'plugins': [ + '@typescript-eslint' + ], + 'rules': { + 'indent': [ + 'error', + 2 + ], + 'linebreak-style': [ + 'error', + 'unix' + ], + 'quotes': [ + 'error', + 'single' + ], + 'semi': [ + 'error', + 'always' + ], + "@typescript-eslint/ban-ts-comment": 0 + } +}; diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 7c537aa..0c79b6a 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -98,10 +98,10 @@ "postcss-normalize": "^10.0.1", "postcss-preset-env": "^7.0.1", "prompts": "^2.4.2", - "react": "^17.0.2", + "react": "*", "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.0", - "react-dom": "^17.0.2", + "react-dom": "*", "react-refresh": "^0.11.0", "resolve": "^1.20.0", "resolve-url-loader": "^4.0.0", diff --git a/packages/plugin-multiple-editor/src/Controller.ts b/packages/plugin-multiple-editor/src/Controller.ts index 112ddde..cce1d56 100644 --- a/packages/plugin-multiple-editor/src/Controller.ts +++ b/packages/plugin-multiple-editor/src/Controller.ts @@ -1,6 +1,5 @@ import type { Project, Event } from '@alilc/lowcode-shell'; -import { ProjectSchema } from '@alilc/lowcode-types'; -import { skeleton } from '@alilc/lowcode-engine'; +import { skeleton, common } from '@alilc/lowcode-engine'; import { beautifyCSS, compatGetSourceCodeMap, @@ -11,7 +10,6 @@ import { treeToMap, } from './utils'; import { FunctionEventParams, Monaco, ObjectType } from './types'; -import { common } from '@alilc/lowcode-engine'; import type { editor } from 'monaco-editor'; import { addFunction, @@ -29,7 +27,7 @@ export * from './EditorHook'; export interface EditorControllerState { declarationsMap: Record; - extraLibs: { path: string; content: string }[]; + extraLibs: Array<{ path: string; content: string }>; } export type HookHandleFn = (fn: T) => () => void; @@ -51,7 +49,7 @@ export class EditorController extends EditorHook { defaultFiles: ObjectType; - public monaco?: Monaco; + monaco?: Monaco; private codeTemp?: CodeTemp; @@ -61,20 +59,20 @@ export class EditorController extends EditorHook { private state: EditorControllerState; - public codeEditor?: editor.IStandaloneCodeEditor; + codeEditor?: editor.IStandaloneCodeEditor; private codeEditorCtx?: EditorContextType; - public service!: Service; + service!: Service; - public onImportSchema: HookHandleFn< - (schema: ProjectSchema) => void | Promise - > = this.hookFactory(HookKeys.onImport); + onImportSchema: HookHandleFn<(schema: any) => void | Promise> = + this.hookFactory(HookKeys.onImport); - public onSourceCodeChange: HookHandleFn<(code: any) => void> = - this.hookFactory(HookKeys.onSourceCodeChange); + onSourceCodeChange: HookHandleFn<(code: any) => void> = this.hookFactory( + HookKeys.onSourceCodeChange + ); - public onEditCodeChange: HookHandleFn< + onEditCodeChange: HookHandleFn< (code: { content: string; file: string }) => void > = this.hookFactory(HookKeys.onEditCodeChange); @@ -124,7 +122,7 @@ export class EditorController extends EditorHook { this.applyLibs(); } - addComponentDeclarations(list: [string, string][] = []) { + addComponentDeclarations(list: Array<[string, string]> = []) { for (const [key, dec] of list) { this.state.declarationsMap[key] = dec; } @@ -133,7 +131,7 @@ export class EditorController extends EditorHook { } private publishExtraLib() { - const libs: { path: string; content: string }[] = []; + const libs: Array<{ path: string; content: string }> = []; this.extraLibMap.forEach((content, path) => libs.push({ content, path })); this.state.extraLibs = libs; this.publish(); @@ -156,7 +154,7 @@ export class EditorController extends EditorHook { const { getMonaco } = await import( '@alilc/lowcode-plugin-base-monaco-editor' ); - this.monaco = await getMonaco(undefined); + this.monaco = await getMonaco(undefined) as any; } const decStr = Object.keys(this.state.declarationsMap).reduce( (v, k) => `${v}\n${k}: ${this.state.declarationsMap[k]};\n`, @@ -175,7 +173,7 @@ export class EditorController extends EditorHook { }); } - getSchema(pure?: boolean): ProjectSchema { + getSchema(pure?: boolean): any { const schema = this.project.exportSchema( common.designerCabin.TransformStage.Save ); @@ -192,7 +190,7 @@ export class EditorController extends EditorHook { return schema; } - importSchema(schema: ProjectSchema) { + importSchema(schema: any) { this.project.importSchema(schema); this.initCodeTempBySchema(schema); this.triggerHook(HookKeys.onImport, schema); @@ -219,7 +217,7 @@ export class EditorController extends EditorHook { }; } - public initCodeTempBySchema(schema: ProjectSchema) { + initCodeTempBySchema(schema: any) { const componentSchema = schema.componentsTree[0] || {}; const { css, methods, state, lifeCycles } = componentSchema; const codeMap = (componentSchema as any)._sourceCodeMap; @@ -343,7 +341,7 @@ export class EditorController extends EditorHook { return true; } - public resetSaveStatus() { + resetSaveStatus() { this.codeEditorCtx?.updateState({ modifiedKeys: [] }); } diff --git a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts index 9382a1b..921cd03 100644 --- a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts +++ b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts @@ -1,14 +1,14 @@ -import { ILowCodePluginContext, project } from '@alilc/lowcode-engine'; -import { CompositeObject, TransformStage } from '@alilc/lowcode-types'; +import { project } from '@alilc/lowcode-engine'; +import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; -export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => { +export const deleteHiddenTransducer = (ctx: any) => { return { name: 'deleteHiddenTransducer', async init() { - project.addPropsTransducer((props: CompositeObject): CompositeObject => { + project.addPropsTransducer((props: any): any => { delete props.hidden; return props; - }, TransformStage.Save); + }, IPublicEnumTransformStage.Save); }, }; } diff --git a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/set-ref-prop/index.tsx b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/set-ref-prop/index.tsx index 7a8efbd..b85e750 100644 --- a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/set-ref-prop/index.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/set-ref-prop/index.tsx @@ -1,11 +1,7 @@ -import { - TransformedComponentMetadata, - FieldConfig, -} from '@alilc/lowcode-types'; import { v4 as uuidv4 } from 'uuid'; import { material } from '@alilc/lowcode-engine'; -function addonCombine(metadata: TransformedComponentMetadata) { +function addonCombine(metadata: any) { const { componentName, configure = {} } = metadata; const isRoot: boolean = @@ -15,9 +11,9 @@ function addonCombine(metadata: TransformedComponentMetadata) { return metadata; } - let advancedGroup: FieldConfig | undefined; + let advancedGroup: any | undefined; - const refItem: FieldConfig = { + const refItem: any = { title: { label: 'refId', tip: '用于获取组件实例,调用物料内部方法', @@ -57,7 +53,7 @@ function addonCombine(metadata: TransformedComponentMetadata) { advancedGroup.items = [refItem]; } - const advanceItems: FieldConfig[] = advancedGroup.items || []; + const advanceItems: any[] = advancedGroup.items || []; if ( !advanceItems || diff --git a/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx index 440b5f7..c55ddff 100644 --- a/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, skeleton, project, @@ -41,7 +40,7 @@ export default async function registerPlugins() { SchemaPlugin.pluginName = 'SchemaPlugin'; await plugins.register(SchemaPlugin); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -66,7 +65,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -110,7 +109,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -145,7 +144,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -170,7 +169,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -204,7 +203,7 @@ export default async function registerPlugins() { saveSample.pluginName = 'saveSample'; await plugins.register(saveSample); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -228,7 +227,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts b/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts index e952c6a..e6e3af7 100644 --- a/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts +++ b/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts @@ -1,7 +1,7 @@ import { material, project } from '@alilc/lowcode-engine'; import { filterPackages } from '@alilc/lowcode-plugin-inject'; import { Message, Dialog } from '@alifd/next'; -import { TransformStage } from '@alilc/lowcode-types'; +import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; export const loadIncrementalAssets = () => { material?.onChangeAssets(() => { @@ -252,7 +252,7 @@ const setProjectSchemaToLocalStorage = (scenarioName: string) => { } window.localStorage.setItem( getLSName(scenarioName), - JSON.stringify(project.exportSchema(TransformStage.Save)) + JSON.stringify(project.exportSchema(IPublicEnumTransformStage.Save)) ); }; diff --git a/packages/plugin-multiple-editor/src/index.tsx b/packages/plugin-multiple-editor/src/index.tsx index 630a06a..117870b 100644 --- a/packages/plugin-multiple-editor/src/index.tsx +++ b/packages/plugin-multiple-editor/src/index.tsx @@ -1,8 +1,4 @@ import { project, editor } from '@alilc/lowcode-engine'; -import type { - ILowCodePluginConfig, - ILowCodePluginContext, -} from '@alilc/lowcode-engine'; import { controller as baseController } from '@alilc/lowcode-plugin-base-monaco-editor/es/controller'; import { EditorProvider } from './Context'; import MultipleFileEditor from './MultipleFileEditor'; @@ -26,7 +22,7 @@ const pluginCodeEditor = ( defaultFiles?: Record; } = {} ) => { - const plugin = (ctx: ILowCodePluginContext): ILowCodePluginConfig => { + const plugin = (ctx: any): any => { return { exports: () => ({}), init() { diff --git a/packages/plugin-multiple-editor/src/types/index.ts b/packages/plugin-multiple-editor/src/types/index.ts index 664f73e..4682325 100644 --- a/packages/plugin-multiple-editor/src/types/index.ts +++ b/packages/plugin-multiple-editor/src/types/index.ts @@ -1,9 +1,7 @@ -import { JSExpression } from '@alilc/lowcode-types'; - export type Monaco = typeof import('monaco-editor/esm/vs/editor/editor.api'); export type ObjectType = Record; -export interface IState extends JSExpression { +export interface IState { originCode?: string; } diff --git a/packages/plugin-multiple-editor/src/utils/code.ts b/packages/plugin-multiple-editor/src/utils/code.ts index dd10a96..796f89d 100644 --- a/packages/plugin-multiple-editor/src/utils/code.ts +++ b/packages/plugin-multiple-editor/src/utils/code.ts @@ -1,10 +1,3 @@ -import { - isJSExpression, - ProjectSchema, - RootSchema, - JSFunction, - JSExpression, -} from '@alilc/lowcode-types'; // @ts-ignore import prettier from 'prettier/esm/standalone.mjs'; import parserBabel from 'prettier/parser-babel'; @@ -30,7 +23,7 @@ const prettierCssConfig = { printWidth: 120, // 超过120个字符强制换行 }; -export const initCode = (componentSchema: RootSchema | undefined) => { +export const initCode = (componentSchema: any | undefined) => { return ( (componentSchema as any)?.originCode || `export default class LowcodeComponent extends Component { @@ -79,6 +72,6 @@ export const beautifyCSS = (input: string, options: any): string => { }; // schema转换为CSS代码 -export const schema2CssCode = (schema: ProjectSchema, prettierOptions: any) => { +export const schema2CssCode = (schema: any, prettierOptions: any) => { return beautifyCSS(schema.componentsTree[0]?.css || '', prettierOptions); }; diff --git a/packages/plugin-multiple-editor/src/utils/get-methods.ts b/packages/plugin-multiple-editor/src/utils/get-methods.ts index 1d51709..4d3b760 100644 --- a/packages/plugin-multiple-editor/src/utils/get-methods.ts +++ b/packages/plugin-multiple-editor/src/utils/get-methods.ts @@ -111,7 +111,7 @@ export const getMethods = (fileContent: string) => { ?.code; const compiledCode = pureTranspile(codeStr, { esm: true }); state[ - (property.key as Identifier).name ?? property?.key?.extra?.rawValue + (property.key as Identifier).name ?? property?.key?.extra?.rawValue as string ] = { type: 'JSExpression', value: compiledCode.replace(/var *name *= */, '').replace(/;$/, ''), diff --git a/packages/plugin-multiple-editor/tsconfig.json b/packages/plugin-multiple-editor/tsconfig.json index 8c6bf06..c820ed9 100644 --- a/packages/plugin-multiple-editor/tsconfig.json +++ b/packages/plugin-multiple-editor/tsconfig.json @@ -1,22 +1,109 @@ { - "extends": "../../tsconfig.json", "compilerOptions": { - "rootDir": "./src", - "baseUrl": "./", - "outDir": "./es", - "moduleResolution": "node", - "declaration": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "module": "es2020", - "target": "ES5", + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ES5" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "jsx": "react" /* Specify what JSX code is generated. */, + "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "ES2020" /* Specify what module code is generated. */, + "rootDir": "./src", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ "paths": { "@/*": ["./src/*"], "utils": ["./src/utils"], "utils/*": ["./src/utils/*"], "types": ["./src/types"], "types/*": ["./src/types/*"] - } + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true /* Enable importing .json files */, + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./es", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": false /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, - "include": ["src"] + "include": ["src"], + "exclude": ["src/dev-config/*"] } From c6a8fb3639ee30fb758897a207138f0c518a9f23 Mon Sep 17 00:00:00 2001 From: jingyu Date: Tue, 16 May 2023 19:25:10 +0800 Subject: [PATCH 02/36] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 0c79b6a..1b5c99f 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -174,6 +174,6 @@ "es" ], "fastPublish": { - "npmClient": "tnpm" + "npmClient": "npm" } } From 7dd8994ae1d9b06459d0e0f3d7bcccc2513061db Mon Sep 17 00:00:00 2001 From: jingyu Date: Mon, 16 Oct 2023 19:44:48 +0800 Subject: [PATCH 03/36] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/README.md | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 packages/plugin-multiple-editor/README.md diff --git a/packages/plugin-multiple-editor/README.md b/packages/plugin-multiple-editor/README.md new file mode 100644 index 0000000..02ad03b --- /dev/null +++ b/packages/plugin-multiple-editor/README.md @@ -0,0 +1,63 @@ +# 多文件编辑器 + +借助此插件可在低码引擎上使用任意层级的文件树进行代码的组织 + +## Demo + +```ts +import multipleFileCodeEditorFactory from '@alipay/lowcode-plugin-multiple-editor'; +import { PrettierPlugin } from '@alilc/lowcode-plugin-multiple-editor/es/plugins/prettier-plugin'; + + +const PLUGIN_NAME = 'multiple-file-code-editor'; +// 详细参数可见 ts 类型声明 +const plugin: any = multipleFileCodeEditorFactory({ + softSave: true, // true 保存代码时将代码保存在插件类上,并不会调用引擎的 importSchema + es6: true, // 编译选项,true 时仅做 es module 的编译 + // 可选择使用插进进行代码编辑器功能的拓展 + plugins: [searchPlugin as any, lintPlugin, new PrettierPlugin()], + // 内置钩子,在插件初始化时进行一些操作,例如添加类型声明 + onInstall(controller: EditorController) { + for (const [path, content] of extraLibList) { + controller.addExtraLib(content, path); + } + controller.addComponentDeclarations(declarations); + controller.onImportSchema(async (schema) => { + // Todo sth. + }); + window.codeEditorController = controller; + }, + defaultFiles: { + utils: ` +export function helloWorld() { + console.log('hello world'); +} + ` + } +}); + +plugin.pluginName = PLUGIN_NAME; + +await plugins.register(plugin); +``` + +## 工作原理 + +使用该插件时,每次保存时: + +1. 编译代码,生成 __initExtra 函数方法,该方法用于初始化各个方法、生命周期的真实定义 +1. 修改 constructor 函数体,函数体内执行 __initExtra,constructor 将会在渲染引擎内执行,执行完成后即可得到所有方法和生命周期的真实定义 +1. 在 schema 上保存一个文件 Map,保存位置为 `schema.componentsTree[0]._sourceCodeMap` + +## 使用注意事项 + +1. 建议所有 project.importSchema 和 project.exportSchema 替换为 codeEditorController.importSchema 和 codeEditorController.exportSchema。原因是插件内部需要对文件内容进行处理 +2. 不能在 index.js 的 Class 之外进行函数、变量定义,如需定义则在其他文件内定义 +3. 不能在 index.js Class 的 state 定义中使用表达式 +4. 如需在 setter 内适用类型定义,请开启 base-editor 的单例模式,仅需在应用入口处调用如下方法即可: +5. 如果低码项目有使用出码,则需对出码进行定制,将 _sourceCodeMap 中的文件生成到项目中,并对文件的引用进行处理,具体处理方式可自行组织 + +```ts +import { configure } from '@alilc/lowcode-plugin-base-monaco-editor'; +configure({ singleton: true }); +``` From f6d81bdb50d5b7b55e98a90c0cef109207a72fc0 Mon Sep 17 00:00:00 2001 From: carrot Date: Mon, 16 Oct 2023 11:53:24 +0000 Subject: [PATCH 04/36] feat: add readme --- packages/plugin-multiple-editor/README.md | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 packages/plugin-multiple-editor/README.md diff --git a/packages/plugin-multiple-editor/README.md b/packages/plugin-multiple-editor/README.md new file mode 100644 index 0000000..02ad03b --- /dev/null +++ b/packages/plugin-multiple-editor/README.md @@ -0,0 +1,63 @@ +# 多文件编辑器 + +借助此插件可在低码引擎上使用任意层级的文件树进行代码的组织 + +## Demo + +```ts +import multipleFileCodeEditorFactory from '@alipay/lowcode-plugin-multiple-editor'; +import { PrettierPlugin } from '@alilc/lowcode-plugin-multiple-editor/es/plugins/prettier-plugin'; + + +const PLUGIN_NAME = 'multiple-file-code-editor'; +// 详细参数可见 ts 类型声明 +const plugin: any = multipleFileCodeEditorFactory({ + softSave: true, // true 保存代码时将代码保存在插件类上,并不会调用引擎的 importSchema + es6: true, // 编译选项,true 时仅做 es module 的编译 + // 可选择使用插进进行代码编辑器功能的拓展 + plugins: [searchPlugin as any, lintPlugin, new PrettierPlugin()], + // 内置钩子,在插件初始化时进行一些操作,例如添加类型声明 + onInstall(controller: EditorController) { + for (const [path, content] of extraLibList) { + controller.addExtraLib(content, path); + } + controller.addComponentDeclarations(declarations); + controller.onImportSchema(async (schema) => { + // Todo sth. + }); + window.codeEditorController = controller; + }, + defaultFiles: { + utils: ` +export function helloWorld() { + console.log('hello world'); +} + ` + } +}); + +plugin.pluginName = PLUGIN_NAME; + +await plugins.register(plugin); +``` + +## 工作原理 + +使用该插件时,每次保存时: + +1. 编译代码,生成 __initExtra 函数方法,该方法用于初始化各个方法、生命周期的真实定义 +1. 修改 constructor 函数体,函数体内执行 __initExtra,constructor 将会在渲染引擎内执行,执行完成后即可得到所有方法和生命周期的真实定义 +1. 在 schema 上保存一个文件 Map,保存位置为 `schema.componentsTree[0]._sourceCodeMap` + +## 使用注意事项 + +1. 建议所有 project.importSchema 和 project.exportSchema 替换为 codeEditorController.importSchema 和 codeEditorController.exportSchema。原因是插件内部需要对文件内容进行处理 +2. 不能在 index.js 的 Class 之外进行函数、变量定义,如需定义则在其他文件内定义 +3. 不能在 index.js Class 的 state 定义中使用表达式 +4. 如需在 setter 内适用类型定义,请开启 base-editor 的单例模式,仅需在应用入口处调用如下方法即可: +5. 如果低码项目有使用出码,则需对出码进行定制,将 _sourceCodeMap 中的文件生成到项目中,并对文件的引用进行处理,具体处理方式可自行组织 + +```ts +import { configure } from '@alilc/lowcode-plugin-base-monaco-editor'; +configure({ singleton: true }); +``` From 9deb22a98bf75c8ee6bfe21b4147bd1bf07ee3bc Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 18 Dec 2023 19:22:59 +0800 Subject: [PATCH 05/36] chore: update publish actions, add commit --- .github/workflows/publish npm.yml | 3 +++ packages/plugin-test/package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish npm.yml b/.github/workflows/publish npm.yml index 7b686d9..668e0f9 100644 --- a/.github/workflows/publish npm.yml +++ b/.github/workflows/publish npm.yml @@ -43,5 +43,8 @@ jobs: echo "PACKAGE_NAME=$(node -p "require('./package.json').name")" >> $GITHUB_ENV echo "PACKAGE_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV + git add package.json + git commit -m "Bump version to ${PACKAGE_VERSION}" + git tag -a "${PACKAGE_NAME}@${PACKAGE_VERSION}" -m "Release ${PACKAGE_NAME} version ${PACKAGE_VERSION}" git push origin "${PACKAGE_NAME}@${PACKAGE_VERSION}" \ No newline at end of file diff --git a/packages/plugin-test/package.json b/packages/plugin-test/package.json index 650c04a..6c630e6 100644 --- a/packages/plugin-test/package.json +++ b/packages/plugin-test/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-test", - "version": "1.0.0", + "version": "1.0.1", "description": "alibaba lowcode editor test plugin", "files": [ "es", From 4a0370468829f228c5f202bd192eeb1599bae2ca Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 18 Dec 2023 11:26:54 +0000 Subject: [PATCH 06/36] Bump version to --- packages/plugin-test/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-test/package.json b/packages/plugin-test/package.json index 6c630e6..09d5504 100644 --- a/packages/plugin-test/package.json +++ b/packages/plugin-test/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-test", - "version": "1.0.1", + "version": "1.0.2", "description": "alibaba lowcode editor test plugin", "files": [ "es", From 42943b5ed848a2a5bb9afeb658bab7d2c9befb03 Mon Sep 17 00:00:00 2001 From: SuSunSam <339341037@qq.com> Date: Tue, 19 Dec 2023 15:09:20 +0800 Subject: [PATCH 07/36] feat: add renderAddFileComponent Option --- .../plugin-view-manager-pane/src/components/addFile/index.tsx | 4 ++++ packages/plugin-view-manager-pane/src/index.tsx | 2 ++ 2 files changed, 6 insertions(+) diff --git a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx index b66e4e2..fe5be11 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx @@ -8,6 +8,10 @@ import './index.scss'; import { intl } from '../../locale'; function AddFileComponent(props: { options: IOptions }) { + if (props.options?.renderAddFileComponent && typeof props.options.renderAddFileComponent === 'function') { + return props.options.renderAddFileComponent(); + } + if (!props.options?.onAddPage && !props.options?.onAddComponent) { return null; } diff --git a/packages/plugin-view-manager-pane/src/index.tsx b/packages/plugin-view-manager-pane/src/index.tsx index c0c6308..f834eca 100644 --- a/packages/plugin-view-manager-pane/src/index.tsx +++ b/packages/plugin-view-manager-pane/src/index.tsx @@ -12,6 +12,8 @@ import { intl } from './locale'; export interface IOptions { init?: (ctx: IPublicModelPluginContext) => {}; + renderAddFileComponent?: () => React.JSX.Element; + onAddPage?: () => {}; onDeletePage?: (resource: IPublicModelResource) => {}; From d3453831604ebfb10eae56c231e9d35988924a5b Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 19 Dec 2023 07:22:54 +0000 Subject: [PATCH 08/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index 12fc34f..6cd3df9 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "1.0.4", + "version": "1.0.5", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From 62dec4216dffa3622c6e2fbf0c28a8f77726607c Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 22 Dec 2023 17:16:16 +0800 Subject: [PATCH 09/36] feat(plugin-view-manager-pane): replace Overlay + div with Balloon + Menu --- .../src/components/addFile/behaviors.tsx | 105 +++++++++--------- .../src/components/addFile/index.scss | 12 -- .../src/components/addFile/index.tsx | 54 ++++----- .../src/components/resourceTree/index.tsx | 19 ++-- 4 files changed, 92 insertions(+), 98 deletions(-) diff --git a/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx b/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx index c421f9c..497c349 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx +++ b/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx @@ -1,10 +1,13 @@ import React from 'react'; -import { Balloon } from '@alifd/next'; +import { Overlay, Menu } from '@alifd/next'; import { IPublicModelResource } from '@alilc/lowcode-types'; import { OthersIcon } from '../resourceTree/icon'; import { IOptions } from '../..'; import { intl } from '../../locale'; +const { Item } = Menu; +const { Popup } = Overlay; + export function Behaviors(props: { resource: IPublicModelResource; options: IOptions; @@ -29,7 +32,7 @@ export function Behaviors(props: { } return ( - - {behaviors.map((d) => { - let text, handleLowcodeClick, handlePageClick; - switch (d) { - case 'edit': - text = intl( - 'view_manager.components.addFile.behaviors.DescriptionSettings', - { description: description } - ); - handleLowcodeClick = props.options?.onEditComponent; - handlePageClick = props.options?.onEditPage; - break; - case 'copy': - text = intl( - 'view_manager.components.addFile.behaviors.CopyDescription', - { description: description } - ); - handleLowcodeClick = props.options?.onCopyComponent; - handlePageClick = props.options?.onCopyPage; - break; - case 'delete': - text = intl( - 'view_manager.components.addFile.behaviors.DeleteDescription', - { description: description } - ); - handleLowcodeClick = props.options?.onDeleteComponent; - handlePageClick = props.options?.onDeletePage; - break; - } + + {behaviors.map((d) => { + let text, handleLowcodeClick: any, handlePageClick: any; + switch (d) { + case 'edit': + text = intl( + 'view_manager.components.addFile.behaviors.DescriptionSettings', + { description: description } + ); + handleLowcodeClick = props.options?.onEditComponent; + handlePageClick = props.options?.onEditPage; + break; + case 'copy': + text = intl( + 'view_manager.components.addFile.behaviors.CopyDescription', + { description: description } + ); + handleLowcodeClick = props.options?.onCopyComponent; + handlePageClick = props.options?.onCopyPage; + break; + case 'delete': + text = intl( + 'view_manager.components.addFile.behaviors.DeleteDescription', + { description: description } + ); + handleLowcodeClick = props.options?.onDeleteComponent; + handlePageClick = props.options?.onDeletePage; + break; + } - return ( -
{ - e.stopPropagation(); - e.preventDefault(); - props.onVisibleChange(false); - if (name === 'lowcode') { - handleLowcodeClick(props.resource); - } else { - handlePageClick(props.resource); - } - }} - className="view-pane-popup-item" - > - {text} -
- ); - })} - + return ( + { + e.stopPropagation(); + e.preventDefault(); + props.onVisibleChange(false); + if (name === 'lowcode') { + handleLowcodeClick?.(props.resource); + } else { + handlePageClick?.(props.resource); + } + }} + > + {text} + + ); + })} +
+ ); } diff --git a/packages/plugin-view-manager-pane/src/components/addFile/index.scss b/packages/plugin-view-manager-pane/src/components/addFile/index.scss index 0f3f1e2..e6621c3 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/index.scss +++ b/packages/plugin-view-manager-pane/src/components/addFile/index.scss @@ -7,18 +7,6 @@ &::after { display: none; } - - .view-pane-popup-item { - height: 28px; - line-height: 28px; - padding: 0 12px; - color: var(--color-text); - cursor: pointer; - - &:hover { - background-color: var(--color-block-background-light, #f1f3f6); - } - } } .add-file-icon-wrap { diff --git a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx index fe5be11..685050a 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx @@ -1,4 +1,4 @@ -import { Balloon } from '@alifd/next'; +import { Overlay, Menu } from '@alifd/next'; import * as React from 'react'; import { observer } from 'mobx-react'; import { AddIcon } from '../../icon'; @@ -7,18 +7,21 @@ import { IOptions } from '../..'; import './index.scss'; import { intl } from '../../locale'; +const { Popup } = Overlay; +const { Item } = Menu; + function AddFileComponent(props: { options: IOptions }) { if (props.options?.renderAddFileComponent && typeof props.options.renderAddFileComponent === 'function') { return props.options.renderAddFileComponent(); } - + if (!props.options?.onAddPage && !props.options?.onAddComponent) { return null; } return ( <> - @@ -27,31 +30,30 @@ function AddFileComponent(props: { options: IOptions }) { } triggerType="click" align="bl" - popupClassName="view-pane-popup" - closable={false} + className="view-pane-popup" > - {props.options.onAddPage ? ( -
{ - props.options.onAddPage?.(); - }} - className="view-pane-popup-item" - > - {intl('view_manager.components.addFile.CreatePage')} -
- ) : null} + + {props.options.onAddPage ? ( + { + props.options.onAddPage?.(); + }} + > + {intl('view_manager.components.addFile.CreatePage')} + + ) : null} - {props.options.onAddComponent ? ( -
{ - props.options.onAddComponent?.(); - }} - > - {intl('view_manager.components.addFile.CreateAComponent')} -
- ) : null} - + {props.options.onAddComponent ? ( + { + props.options.onAddComponent?.(); + }} + > + {intl('view_manager.components.addFile.CreateAComponent')} + + ) : null} +
+ ); } diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx index c83e419..4302e76 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx @@ -3,7 +3,7 @@ import { IPublicModelPluginContext, IPublicModelResource, } from '@alilc/lowcode-types'; -import { Search, Overlay, Balloon } from '@alifd/next'; +import { Search, Overlay, Balloon, Menu } from '@alifd/next'; import React, { useCallback, useState, useEffect, useRef } from 'react'; import { FileIcon, IconArrowRight } from './icon'; import './index.scss'; @@ -11,6 +11,9 @@ import { IOptions } from '../..'; import { intl } from '../../locale'; import { AddFile } from '../addFile'; +const { Popup } = Overlay; +const { Item } = Menu; + export function ResourcePaneContent(props: IPluginOptions) { const { workspace } = props.pluginContext || {}; const [resourceList, setResourceList] = useState( @@ -177,7 +180,7 @@ function ResourceGroup(
{props.categoryName}
{ [intl('view_manager.components.resourceTree.Page'), intl('view_manager.components.resourceTree.Component')].includes(props.categoryName) ? ( - -
-
+ { if ( props.categoryName === @@ -201,16 +203,15 @@ function ResourceGroup( props.options.onAddComponent?.(); } }} - className="view-pane-popup-item" > {intl('view_manager.components.resourceTree.CreateItem', { categoryName: props.categoryName === intl('view_manager.components.resourceTree.Page') ? intl('view_manager.components.resourceTree.Page') : intl('view_manager.components.resourceTree.Component'), })} -
-
-
+ + + ) : null } From 63886c6952bb422a040cfb80291842400daba94b Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 22 Dec 2023 09:39:21 +0000 Subject: [PATCH 10/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index 6cd3df9..0700867 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "1.0.5", + "version": "1.0.6", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From 50f3fe05fe7e9250a9ab742d99ee3fdcd05c2fd4 Mon Sep 17 00:00:00 2001 From: liujuping Date: Tue, 2 Jan 2024 15:46:34 +0800 Subject: [PATCH 11/36] chore: update ILowCodePluginContext to IPublicModelPluginContext --- packages/plugin-block/src/index.tsx | 4 +-- packages/plugin-code-editor/src/index.tsx | 5 ++-- packages/plugin-datasource-pane/src/index.tsx | 4 +-- packages/plugin-manual/src/index.tsx | 4 +-- .../scenario-switcher/index.tsx | 6 ++-- .../scenarios/basic-antd/plugin.tsx | 18 +++++------ .../plugin.tsx | 18 +++++------ .../scenarios/basic-fusion/plugin.tsx | 18 +++++------ .../dev-config/scenarios/next-pro/plugin.tsx | 18 +++++------ .../node-extended-actions/plugin.tsx | 30 ++++++++----------- packages/plugin-undo-redo/src/index.tsx | 6 ++-- packages/plugin-zh-en/src/index.tsx | 6 ++-- 12 files changed, 62 insertions(+), 75 deletions(-) diff --git a/packages/plugin-block/src/index.tsx b/packages/plugin-block/src/index.tsx index afd3b29..dfbbb71 100644 --- a/packages/plugin-block/src/index.tsx +++ b/packages/plugin-block/src/index.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import { ILowCodePluginContext } from '@alilc/lowcode-engine'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; import { default as BlockPane } from './pane'; -const LowcodePluginCusPlugin = (ctx: ILowCodePluginContext) => { +const LowcodePluginCusPlugin = (ctx: IPublicModelPluginContext) => { return { // 插件名,注册环境下唯一 name: 'LowcodePluginCusPlugin', diff --git a/packages/plugin-code-editor/src/index.tsx b/packages/plugin-code-editor/src/index.tsx index d7caf4c..c40e74e 100644 --- a/packages/plugin-code-editor/src/index.tsx +++ b/packages/plugin-code-editor/src/index.tsx @@ -1,8 +1,9 @@ import { CodeEditorPane } from './pane'; -import { project, ILowCodePluginContext } from '@alilc/lowcode-engine'; +import { project } from '@alilc/lowcode-engine'; import icon from './icon'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; -const plugin = (ctx: ILowCodePluginContext) => { +const plugin = (ctx: IPublicModelPluginContext) => { return { name: 'codeEditor', width: 600, diff --git a/packages/plugin-datasource-pane/src/index.tsx b/packages/plugin-datasource-pane/src/index.tsx index a8098a9..838ada5 100644 --- a/packages/plugin-datasource-pane/src/index.tsx +++ b/packages/plugin-datasource-pane/src/index.tsx @@ -1,10 +1,10 @@ -import { ILowCodePluginContext } from '@alilc/lowcode-engine'; import DataSourcePanePlugin from './pane'; import { DataSourcePaneImportPlugin, DataSourceType, } from './types'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export interface Options { importPlugins?: DataSourcePaneImportPlugin[]; @@ -13,7 +13,7 @@ export interface Options { } // TODO: 2.0插件传参修改,不支持直接options: Options -const plugin = (ctx: ILowCodePluginContext, options: Options) => { +const plugin = (ctx: IPublicModelPluginContext, options: Options) => { return { name: 'com.alibaba.lowcode.datasource.pane', width: 300, diff --git a/packages/plugin-manual/src/index.tsx b/packages/plugin-manual/src/index.tsx index bb57695..cf85189 100644 --- a/packages/plugin-manual/src/index.tsx +++ b/packages/plugin-manual/src/index.tsx @@ -1,7 +1,7 @@ -import { ILowCodePluginContext } from '@alilc/lowcode-engine'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; import { IconQuestion } from './icon'; -const PluginManual = (ctx: ILowCodePluginContext) => { +const PluginManual = (ctx: IPublicModelPluginContext) => { return { init() { // 往引擎增加面板 diff --git a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx index 28bd634..916ba2e 100644 --- a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx @@ -1,9 +1,7 @@ import React from 'react'; -import { - ILowCodePluginContext, -} from '@alilc/lowcode-engine'; import { Select } from '@alifd/next'; import scenarios from '../../universal/scenarios.json'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const { Option } = Select; const getCurrentScenarioName = () => { @@ -25,7 +23,7 @@ function Switcher(props: any) { ) } -export const scenarioSwitcher = (ctx: ILowCodePluginContext) => { +export const scenarioSwitcher = (ctx: IPublicModelPluginContext) => { return { name: 'scenarioSwitcher', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx index c812a4d..a564038 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, - skeleton, project, - setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -34,6 +31,7 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { // await plugins.register(ManualPlugin); @@ -47,7 +45,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: IPublicModelPluginContext) => { return { name: 'editor-init', async init() { @@ -73,7 +71,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'builtin-plugin-registry', async init() { @@ -117,7 +115,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: IPublicModelPluginContext) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -155,7 +153,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: IPublicModelPluginContext) => { return { name: 'loadAssetsSample', async init() { @@ -180,7 +178,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { @@ -228,7 +226,7 @@ export default async function registerPlugins() { CodeGenPlugin.pluginName = 'CodeGenPlugin'; await plugins.register(CodeGenPlugin); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: IPublicModelPluginContext) => { return { name: 'previewSample', async init() { @@ -252,7 +250,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: IPublicModelPluginContext) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx index 14e78be..d500cb3 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, - skeleton, project, - setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -34,6 +31,7 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -47,7 +45,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: IPublicModelPluginContext) => { return { name: 'editor-init', async init() { @@ -73,7 +71,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'builtin-plugin-registry', async init() { @@ -117,7 +115,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: IPublicModelPluginContext) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -155,7 +153,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: IPublicModelPluginContext) => { return { name: 'loadAssetsSample', async init() { @@ -180,7 +178,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { @@ -232,7 +230,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: IPublicModelPluginContext) => { return { name: 'previewSample', async init() { @@ -259,7 +257,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: IPublicModelPluginContext) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx index a05fb96..d8f3b65 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, - skeleton, project, - setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -34,6 +31,7 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -47,7 +45,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: IPublicModelPluginContext) => { return { name: 'editor-init', async init() { @@ -73,7 +71,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'builtin-plugin-registry', async init() { @@ -117,7 +115,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: IPublicModelPluginContext) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -155,7 +153,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: IPublicModelPluginContext) => { return { name: 'loadAssetsSample', async init() { @@ -180,7 +178,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { @@ -232,7 +230,7 @@ export default async function registerPlugins() { CodeGenPlugin.pluginName = 'CodeGenPlugin'; await plugins.register(CodeGenPlugin); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: IPublicModelPluginContext) => { return { name: 'previewSample', async init() { @@ -256,7 +254,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: IPublicModelPluginContext) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx index 1691a9e..a30ea02 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, - skeleton, project, - setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -36,6 +33,7 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -53,7 +51,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: IPublicModelPluginContext) => { return { name: 'editor-init', async init() { @@ -79,7 +77,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'builtin-plugin-registry', async init() { @@ -123,7 +121,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: IPublicModelPluginContext) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -161,7 +159,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: IPublicModelPluginContext) => { return { name: 'loadAssetsSample', async init() { @@ -186,7 +184,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { @@ -230,7 +228,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: IPublicModelPluginContext) => { return { name: 'previewSample', async init() { @@ -254,7 +252,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: IPublicModelPluginContext) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx index 6c229f6..2dd8e88 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx @@ -1,11 +1,6 @@ import React from 'react'; import { - ILowCodePluginContext, plugins, - skeleton, - project, - setters, - Node, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Icon, Message, Button } from '@alifd/next'; @@ -35,9 +30,10 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; +import { IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types'; export default async function registerPlugins() { - const addHelloAction = (ctx: ILowCodePluginContext) => { + const addHelloAction = (ctx: IPublicModelPluginContext) => { return { async init() { const { addBuiltinComponentAction } = ctx.material; @@ -46,12 +42,12 @@ export default async function registerPlugins() { content: { icon: , title: 'hello', - action(node: Node) { + action(node: IPublicModelNode) { Message.show('Welcome to Low-Code engine'); }, }, - condition: (node: Node) => { - return node.componentMeta.componentName === 'NextTable'; + condition: (node: IPublicModelNode) => { + return node.componentMeta?.componentName === 'NextTable'; }, }); }, @@ -60,7 +56,7 @@ export default async function registerPlugins() { addHelloAction.pluginName = 'addHelloAction'; await plugins.register(addHelloAction); - const removeCopyAction = (ctx: ILowCodePluginContext) => { + const removeCopyAction = (ctx: IPublicModelPluginContext) => { return { async init() { const { removeBuiltinComponentAction } = ctx.material; @@ -82,7 +78,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: ILowCodePluginContext) => { + const editorInit = (ctx: IPublicModelPluginContext) => { return { name: 'editor-init', async init() { @@ -108,7 +104,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'builtin-plugin-registry', async init() { @@ -152,7 +148,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: ILowCodePluginContext) => { + const setterRegistry = (ctx: IPublicModelPluginContext) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -190,7 +186,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: ILowCodePluginContext) => { + const loadAssetsSample = (ctx: IPublicModelPluginContext) => { return { name: 'loadAssetsSample', async init() { @@ -215,7 +211,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: ILowCodePluginContext) => { + const saveSample = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { @@ -263,7 +259,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: ILowCodePluginContext) => { + const previewSample = (ctx: IPublicModelPluginContext) => { return { name: 'previewSample', async init() { @@ -290,7 +286,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: ILowCodePluginContext) => { + const customSetter = (ctx: IPublicModelPluginContext) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-undo-redo/src/index.tsx b/packages/plugin-undo-redo/src/index.tsx index e9c1efb..7c42a84 100644 --- a/packages/plugin-undo-redo/src/index.tsx +++ b/packages/plugin-undo-redo/src/index.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; -import { ILowCodePluginContext, project } from '@alilc/lowcode-engine'; +import { project } from '@alilc/lowcode-engine'; import { Button, Icon } from '@alifd/next'; -import { PluginProps, IPublicTypeDisposable } from '@alilc/lowcode-types'; +import { PluginProps, IPublicTypeDisposable, IPublicModelPluginContext } from '@alilc/lowcode-types'; import './index.scss'; @@ -89,7 +89,7 @@ class UndoRedo extends PureComponent { } } -const plugin = (ctx: ILowCodePluginContext) => { +const plugin = (ctx: IPublicModelPluginContext) => { return { // 插件名,注册环境下唯一 name: 'PluginUndoRedo', diff --git a/packages/plugin-zh-en/src/index.tsx b/packages/plugin-zh-en/src/index.tsx index cd54be0..035e423 100644 --- a/packages/plugin-zh-en/src/index.tsx +++ b/packages/plugin-zh-en/src/index.tsx @@ -1,6 +1,6 @@ import { PureComponent } from 'react'; -import { ILowCodePluginContext, common } from '@alilc/lowcode-engine'; -import { PluginProps } from '@alilc/lowcode-types'; +import { common } from '@alilc/lowcode-engine'; +import { IPublicModelPluginContext, PluginProps } from '@alilc/lowcode-types'; import { intl } from './locale'; import { IconZh } from './icons/zh'; import { IconEn } from './icons/en'; @@ -43,7 +43,7 @@ class ZhEn extends PureComponent { } } -const plugin = (ctx: ILowCodePluginContext) => { +const plugin = (ctx: IPublicModelPluginContext) => { return { // 插件名,注册环境下唯一 name: 'PluginZhEn', From 9075f9f428b3b5d510fc4d115a3e793c91f7ae54 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 8 Jan 2024 10:51:44 +0800 Subject: [PATCH 12/36] =?UTF-8?q?feat(plugin-view-manager-pane):=20add=20d?= =?UTF-8?q?isabled=E3=80=81tips=20configs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/resourceTree/index.scss | 13 ++++---- .../src/components/resourceTree/index.tsx | 32 +++++++++++++++---- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss b/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss index 009c22b..b6962ec 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss @@ -72,12 +72,6 @@ font-size: 12px; color: var(--color-title, #5f697a); - - &.resource-tree-group-item-pro-code { - color: var(--color-text-disabled, #bcc5d1); - pointer-events: none; - } - &.active .resource-tree-title { background-color: var(--color-block-background-light, #f7f8fa); } @@ -144,6 +138,13 @@ } } + &-group-disabled { + .resource-tree-title { + opacity: 0.4; + cursor: not-allowed; + } + } + &-title { height: 24px; display: flex; diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx index 4302e76..a7a6cb7 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx @@ -263,13 +263,17 @@ function ResourceItem(props: { } const children = props.children?.filter(d => d.config?.display !== false); + const { + disabled, + tips, + } = props.resource?.config || {}; - return ( + const context = (
{ @@ -281,6 +285,9 @@ function ResourceItem(props: { >
{ + if (disabled) { + return; + } props.resource && props.pluginContext?.workspace.openEditorWindow(props.resource); }} className="resource-tree-title" @@ -316,9 +323,6 @@ function ResourceItem(props: {
{props.resource?.options?.label || props.resource?.title} - {props.resource?.options.isProCodePage - ? intl('view_manager.components.resourceTree.SourceCode') - : ''} { props.resource?.options?.slug || @@ -369,6 +373,22 @@ function ResourceItem(props: { }
); + + if (tips) { + return ( + + {tips} + + ); + } + + return context; } interface IPluginOptions { From b5665c658a418d2b3c114385d576cfa377c2214b Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 8 Jan 2024 18:43:50 +0800 Subject: [PATCH 13/36] chore: update CODEOWNERS --- .github/CODEOWNERS | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c644ba5..281c877 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,13 +2,19 @@ # These owners will be the default owners for everything in # the repo. Unless a later match takes precedence -* @leoyuan @alvarto +* @liujuping @JackLian @alvarto /packages/plugin-manual/ @alvarto -/packages/base-monaco-editor/ @alvarto @wangshihao111 -/packages/plugin-code-editor/ @alvarto +/packages/base-monaco-editor/ @alvarto @wangshihao111 @SuSunSam +/packages/plugin-code-editor/ @alvarto @SuSunSam /packages/plugin-schema/ @alvarto -/packages/plugin-components-pane/ @mark-ck -/packages/plugin-datasource-pane/ @xingmolu -/packages/plugin-zh-en/ @leoyuan -/packages/plugin-undo-redo/ @leoyuan +/packages/plugin-components-pane/ @mark-ck @love999262 +/packages/plugin-datasource-pane/ @YSMJ1994 +/packages/plugin-zh-en/ @JackLian @liujuping +/packages/plugin-undo-redo/ @JackLian @liujuping +/packages/plugin-resource-tabs/ @JackLian @liujuping +/packages/plugin-set-ref-prop/ @JackLian @liujuping +/packages/plugin-view-manager-pane/ @JackLian @liujuping +/packages/base-monaco-editor/ @hzd822 +/packages/plugin-multiple-editor/ @hzd822 +/packages/action-block @liujuping \ No newline at end of file From 53125b8e2f3b5340720f54f82401ae839cee1ec7 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 9 Jan 2024 02:42:39 +0000 Subject: [PATCH 14/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index 0700867..7dd1555 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "1.0.6", + "version": "1.0.7", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From 0c8961fcafe86b62055414a29a1ca6ead75b7e71 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 14:28:04 +0800 Subject: [PATCH 15/36] feat(plugin-resource-tabs): add context menus --- packages/plugin-resource-tabs/package.json | 7 +- packages/plugin-resource-tabs/src/index.tsx | 292 +++++++++++--------- 2 files changed, 162 insertions(+), 137 deletions(-) diff --git a/packages/plugin-resource-tabs/package.json b/packages/plugin-resource-tabs/package.json index 5fdea66..1d0830f 100644 --- a/packages/plugin-resource-tabs/package.json +++ b/packages/plugin-resource-tabs/package.json @@ -18,7 +18,7 @@ "editor" ], "dependencies": { - "@alilc/lowcode-types": "^1.0.0", + "@alilc/lowcode-types": "^1.3.0", "@alilc/lowcode-utils": "^1.0.0", "react": "^16.8.1", "react-dom": "^16.8.1" @@ -27,11 +27,12 @@ "@alib/build-scripts": "^0.1.3", "@alilc/build-plugin-alt": "^1.0.1", "@alilc/lowcode-engine": "^1.0.0", + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@types/react": "^16.9.13", "@types/react-dom": "^16.9.4", "build-plugin-fusion": "^0.1.22", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "build-plugin-moment-locales": "^0.1.0" + "build-plugin-moment-locales": "^0.1.0", + "webpack": "^5.89.0" }, "publishConfig": { "registry": "https://registry.npmjs.org/", diff --git a/packages/plugin-resource-tabs/src/index.tsx b/packages/plugin-resource-tabs/src/index.tsx index 011613c..4444fea 100644 --- a/packages/plugin-resource-tabs/src/index.tsx +++ b/packages/plugin-resource-tabs/src/index.tsx @@ -3,6 +3,7 @@ import { IPublicModelPluginContext, IPublicModelResource, IPublicModelWindow, + IPublicTypeContextMenuAction, IPublicTypePlugin, } from '@alilc/lowcode-types'; import React from 'react'; @@ -12,19 +13,22 @@ import { CloseIcon, LockIcon, WarnIcon } from './icon'; import { intl } from './locale'; function CustomTabItem(props: { - icon: any; - title: string; - onClose: () => void; key: string; - ctx: IPublicModelPluginContext; - id: string; -}) { - const { id: propsId } = props; - const { event } = props.ctx; + pluginContext: IPublicModelPluginContext; + options: IOptions; + resource: IPublicModelResource; +}): React.ReactElement { + const { resource } = props; + const { icon: ResourceIcon } = resource; + const propsId = resource.id || resource.options.id; + const { event } = props.pluginContext; const [changed, setChanged] = useState(false); const [locked, setLocked] = useState(false); const [warned, setWarned] = useState(false); - const [title, setTitle] = useState(props.title); + const [title, setTitle] = useState(resource.title); + const onClose = useCallback(() => { + props.pluginContext.workspace.removeEditorWindow(resource); + }, []); useEffect(() => { event.on('common:windowChanged', (id, changed) => { if (propsId === id) { @@ -56,52 +60,52 @@ function CustomTabItem(props: { } }); }, []); - const ResourceIcon = props.icon; + const ContextMenu = props.pluginContext?.commonUI?.ContextMenu || React.Fragment; return ( -
-
- {ResourceIcon ? : null} -
-
{title}
-
-
{ - e.stopPropagation(); - if (changed) { - Dialog.show({ - v2: true, - title: intl('resource_tabs.src.Warning'), - content: intl('resource_tabs.src.TheCurrentWindowHasUnsaved'), - onOk: () => {}, - onCancel: () => { - props.onClose(); - }, - cancelProps: { - children: intl('resource_tabs.src.DiscardChanges'), - }, - okProps: { - children: intl('resource_tabs.src.ContinueEditing'), - }, - }); - return; - } - props.onClose(); - }} - className="resource-tab-item-close-icon" - > - + +
+
+ {ResourceIcon ? : null}
-
- {changed && !warned ? ( - - ) : null} +
{title}
+
+
{ + e.stopPropagation(); + if (changed) { + Dialog.show({ + v2: true, + title: intl('resource_tabs.src.Warning'), + content: intl('resource_tabs.src.TheCurrentWindowHasUnsaved'), + onOk: () => {}, + onCancel: onClose, + cancelProps: { + children: intl('resource_tabs.src.DiscardChanges'), + }, + okProps: { + children: intl('resource_tabs.src.ContinueEditing'), + }, + }); + return; + } + onClose(); + }} + className="resource-tab-item-close-icon" + > + +
+
+ {changed && !warned ? ( + + ) : null} - {locked ? : null} + {locked ? : null} - {warned ? : null} + {warned ? : null} +
-
+
); } @@ -111,14 +115,17 @@ interface ITabItem { } function Content(props: { - ctx: IPublicModelPluginContext; - appKey?: string; - onSort?: (windows: IPublicModelWindow[]) => IPublicModelWindow[]; - shape?: 'pure' | 'wrapped' | 'text' | 'capsule'; - tabClassName?: string; + pluginContext: IPublicModelPluginContext; + options: IOptions; }) { - const { ctx } = props; - const { workspace } = ctx; + const { pluginContext, options } = props; + const { + onSort, + appKey, + shape, + tabClassName, + } = options; + const { workspace } = pluginContext; const [resourceListMap, setResourceListMap] = useState<{ [key: string]: IPublicModelResource; @@ -126,8 +133,8 @@ function Content(props: { const getTabs = useCallback((): ITabItem[] => { let windows = workspace.windows; - if (props.onSort) { - windows = props.onSort(workspace.windows); + if (onSort) { + windows = onSort(workspace.windows); } return windows.map((d) => { @@ -145,14 +152,14 @@ function Content(props: { const saveTabsToLocal = useCallback(() => { localStorage.setItem( - '___lowcode_plugin_resource_tabs___' + props.appKey, + '___lowcode_plugin_resource_tabs___' + appKey, JSON.stringify(getTabs()) ); localStorage.setItem( - '___lowcode_plugin_resource_tabs_active_title___' + props.appKey, + '___lowcode_plugin_resource_tabs_active_title___' + appKey, JSON.stringify({ id: - workspace.window?.resource.id || + workspace.window?.resource?.id || workspace.window?.resource?.options.id, }) ); @@ -165,7 +172,7 @@ function Content(props: { }); workspace.onChangeActiveWindow(() => { setActiveTitle( - workspace.window?.resource.id || workspace.window?.resource?.options.id + workspace.window?.resource?.id || workspace.window?.resource?.options.id ); saveTabsToLocal(); }); @@ -173,7 +180,9 @@ function Content(props: { useEffect(() => { const initResourceListMap = () => { - const resourceListMap = {}; + const resourceListMap: { + [key: string]: IPublicModelResource; + } = {}; workspace.resourceList.forEach((d) => { resourceListMap[d.id || d.options.id] = d; }); @@ -194,15 +203,15 @@ function Content(props: { } const value: ITabItem[] = JSON.parse( localStorage.getItem( - '___lowcode_plugin_resource_tabs___' + props.appKey - ) + '___lowcode_plugin_resource_tabs___' + appKey + ) || 'null' ); const activeValue: { id: string; } = JSON.parse( localStorage.getItem( - '___lowcode_plugin_resource_tabs_active_title___' + props.appKey - ) + '___lowcode_plugin_resource_tabs_active_title___' + appKey + ) || 'null' ); if (value && value.length) { @@ -227,75 +236,80 @@ function Content(props: { } }, [resourceListMap]); + const ContextMenu = pluginContext?.commonUI?.ContextMenu || React.Fragment; return ( - void; - value: string; - } - ) => ( - - )} - onChange={(name) => { - setActiveTitle(name); - const item = tabs.filter((d) => String(d.id) === String(name))?.[0]; - const resource = resourceListMap[item.id]; - workspace.openEditorWindow(resource); - }} - > - {tabs.map((item) => { - const resource = resourceListMap[item.id]; - if (!resource) { - return null; - } + +
+ ( + + )} + onChange={(name) => { + setActiveTitle(name); + const item = tabs.filter((d) => String(d.id) === String(name))?.[0]; + const resource = resourceListMap[item.id]; + workspace.openEditorWindow(resource); + }} + > + {tabs.map((item) => { + const resource = resourceListMap[item.id]; + if (!resource) { + return null; + } - return ( - { - (workspace as any).removeEditorWindow(resource); - }} - /> - ); - })} - + return ( + + ); + })} + +
+
); } +interface IOptions { + appKey?: string; + onSort?: (windows: IPublicModelWindow[]) => IPublicModelWindow[]; + shape?: 'pure' | 'wrapped' | 'text' | 'capsule'; + tabClassName?: string; + /** + * 右键菜单项 + */ + contextMenuActions: (ctx: IPublicModelPluginContext) => IPublicTypeContextMenuAction[]; + /** + * 右键 Tab 菜单项 + */ + tabContextMenuActions: (ctx: IPublicModelPluginContext, resource: IPublicModelResource) => IPublicTypeContextMenuAction[]; +} + const resourceTabs: IPublicTypePlugin = function ( ctx: IPublicModelPluginContext, - options: { - appKey?: string; - onSort?: (windows: IPublicModelWindow[]) => IPublicModelWindow[]; - shape?: string; - tabClassName?: string; - } + options: IOptions, ) { const { skeleton } = ctx; return { @@ -311,11 +325,8 @@ const resourceTabs: IPublicTypePlugin = function ( index: -1, content: Content, contentProps: { - ctx, - appKey: options?.appKey, - onSort: options?.onSort, - shape: options?.shape, - tabClassName: options?.tabClassName, + pluginContext: ctx, + options, }, }); }, @@ -350,8 +361,21 @@ resourceTabs.meta = { type: 'string', description: 'Tab className', }, + { + key: 'contextMenuActions', + type: 'function', + description: '右键菜单项', + }, + { + key: 'tabContextMenuActions', + type: 'function', + description: '右键 Tab 菜单项', + } ], }, + engines: { + lowcodeEngine: '^1.3.0', // 插件需要配合 ^1.0.0 的引擎才可运行 + }, }; export default resourceTabs; From 492ce9844c5f8fd5d152019d1ce5f4276b19507d Mon Sep 17 00:00:00 2001 From: Zhenfei Date: Mon, 15 Jan 2024 14:36:33 +0800 Subject: [PATCH 16/36] =?UTF-8?q?feat:=20resourceTree=E8=8E=B7=E5=8F=96res?= =?UTF-8?q?ourceList=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/resourceTree/index.tsx | 12 ++++++++++-- packages/plugin-view-manager-pane/src/index.tsx | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx index a7a6cb7..2b0112f 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx @@ -14,13 +14,21 @@ import { AddFile } from '../addFile'; const { Popup } = Overlay; const { Item } = Menu; +function filterResourceList(resourceList: IPublicModelResource[] | undefined, handler?: Function) { + if (typeof handler === 'function') { + return handler(resourceList); + } + + return resourceList; +} + export function ResourcePaneContent(props: IPluginOptions) { const { workspace } = props.pluginContext || {}; const [resourceList, setResourceList] = useState( - workspace?.resourceList + filterResourceList(workspace?.resourceList, props?.options?.filterResourceList) ); workspace?.onResourceListChange(() => { - setResourceList(workspace.resourceList); + setResourceList(filterResourceList(workspace?.resourceList, props?.options?.filterResourceList)); }); return ( void; + filterResourceList?: () => {}; + showIconText?: boolean; skeletonConfig?: IPublicTypeSkeletonConfig; @@ -135,6 +137,11 @@ ViewManagerPane.meta = { type: 'function', description: '', }, + { + key: 'filterResourceList', + type: 'function', + description: '', + }, { key: 'showIconText', type: 'boolean', From fd49aaf3a7368a03c82fa437254f48cf7fbf8b3d Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 15 Jan 2024 06:39:32 +0000 Subject: [PATCH 17/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index 7dd1555..a63790f 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "1.0.7", + "version": "1.0.8", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From db8d8a9e1f63c196be47cc65973242f9d6a98eb1 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 14:45:59 +0800 Subject: [PATCH 18/36] chore: update publish npm.yml --- .github/workflows/publish npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish npm.yml b/.github/workflows/publish npm.yml index 668e0f9..10fe201 100644 --- a/.github/workflows/publish npm.yml +++ b/.github/workflows/publish npm.yml @@ -34,7 +34,7 @@ jobs: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc cd packages/${{ github.event.inputs.packagePath }} npm install --legacy-peer-deps - npm version patch + npm version ${{ github.event.inputs.versionType }} npm run build echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc From 07df40a661e11b0a18f7b1f418f38239f083e2ad Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 15 Jan 2024 06:55:03 +0000 Subject: [PATCH 19/36] Bump version to --- packages/plugin-resource-tabs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-resource-tabs/package.json b/packages/plugin-resource-tabs/package.json index 1d0830f..5d1f8a7 100644 --- a/packages/plugin-resource-tabs/package.json +++ b/packages/plugin-resource-tabs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-resource-tabs", - "version": "1.0.3", + "version": "2.0.0", "description": "alibaba lowcode resource tabs plugin", "files": [ "es", From 23ecb23576962696d2e60b503e9d0b15908bf439 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 15:06:49 +0800 Subject: [PATCH 20/36] chore: add delete npm.yml --- .github/workflows/delete npm.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/delete npm.yml diff --git a/.github/workflows/delete npm.yml b/.github/workflows/delete npm.yml new file mode 100644 index 0000000..b363ecd --- /dev/null +++ b/.github/workflows/delete npm.yml @@ -0,0 +1,30 @@ +name: Delete Package Version + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to be deleted package@version' + required: true + +jobs: + delete-package-version: + runs-on: ubuntu-latest + if: >- + github.ref == 'refs/heads/main' && + (github.actor == 'JackLian' || github.actor == 'liujuping') + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Delete Package Version + run: | + npm unpublish ${{ github.event.inputs.version }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 3bce521eb0af98e68114d00a00492b06204f9cac Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 15:12:23 +0800 Subject: [PATCH 21/36] chore: add delete npm.yml --- .github/workflows/deprecate npm.yml | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/deprecate npm.yml diff --git a/.github/workflows/deprecate npm.yml b/.github/workflows/deprecate npm.yml new file mode 100644 index 0000000..390e171 --- /dev/null +++ b/.github/workflows/deprecate npm.yml @@ -0,0 +1,30 @@ +name: deprecate Package Version + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to be deleted package@version' + required: true + +jobs: + delete-package-version: + runs-on: ubuntu-latest + if: >- + github.ref == 'refs/heads/main' && + (github.actor == 'JackLian' || github.actor == 'liujuping') + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: deprecate Package Version + run: | + npm deprecate ${{ github.event.inputs.version }} "This version is deprecated. Please consider upgrading to a newer version." + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 66146e6a576bd29af650328e39c42affcf3ca1d4 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 15:18:25 +0800 Subject: [PATCH 22/36] chore: add delete npm.yml --- .github/workflows/delete npm.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 .github/workflows/delete npm.yml diff --git a/.github/workflows/delete npm.yml b/.github/workflows/delete npm.yml deleted file mode 100644 index b363ecd..0000000 --- a/.github/workflows/delete npm.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Delete Package Version - -on: - workflow_dispatch: - inputs: - version: - description: 'Version to be deleted package@version' - required: true - -jobs: - delete-package-version: - runs-on: ubuntu-latest - if: >- - github.ref == 'refs/heads/main' && - (github.actor == 'JackLian' || github.actor == 'liujuping') - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up Node.js - uses: actions/setup-node@v2 - with: - node-version: '14' - - - name: Delete Package Version - run: | - npm unpublish ${{ github.event.inputs.version }} - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 291e0a59d67851de39754977f009d368c1874809 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 15:19:40 +0800 Subject: [PATCH 23/36] chore: add delete npm.yml --- .github/workflows/deprecate npm.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deprecate npm.yml b/.github/workflows/deprecate npm.yml index 390e171..ea096ec 100644 --- a/.github/workflows/deprecate npm.yml +++ b/.github/workflows/deprecate npm.yml @@ -25,6 +25,8 @@ jobs: - name: deprecate Package Version run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + + echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc npm deprecate ${{ github.event.inputs.version }} "This version is deprecated. Please consider upgrading to a newer version." - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 23002d888b9b9112f25fc6b33ccecd329c083398 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 14:41:12 +0800 Subject: [PATCH 24/36] feat(view-manager): add context menus --- .../plugin-view-manager-pane/package.json | 2 +- .../src/components/addFile/behaviors.tsx | 102 +------ .../src/components/addFile/index.tsx | 57 +--- .../src/components/resourceTree/index.scss | 5 + .../src/components/resourceTree/index.tsx | 268 ++++++++---------- .../plugin-view-manager-pane/src/index.tsx | 71 ++--- .../plugin-view-manager-pane/src/pane.tsx | 34 ++- 7 files changed, 193 insertions(+), 346 deletions(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index a63790f..7047ce6 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -18,7 +18,7 @@ "editor" ], "dependencies": { - "@alilc/lowcode-types": "^1.0.0", + "@alilc/lowcode-types": "^1.3.0", "@alilc/lowcode-utils": "^1.0.0", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx b/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx index 497c349..a1bda9c 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx +++ b/packages/plugin-view-manager-pane/src/components/addFile/behaviors.tsx @@ -1,105 +1,31 @@ import React from 'react'; -import { Overlay, Menu } from '@alifd/next'; -import { IPublicModelResource } from '@alilc/lowcode-types'; +import { IPublicModelPluginContext, IPublicModelResource } from '@alilc/lowcode-types'; import { OthersIcon } from '../resourceTree/icon'; import { IOptions } from '../..'; -import { intl } from '../../locale'; - -const { Item } = Menu; -const { Popup } = Overlay; export function Behaviors(props: { + pluginContext: IPublicModelPluginContext; resource: IPublicModelResource; options: IOptions; - showBehaviors: boolean; - onVisibleChange: any; safeNode: any; }) { - const { description, name } = props.resource; - let behaviors = []; - if (name === 'lowcode') { - props.options?.onEditComponent && behaviors.push('edit'); - props.options?.onCopyComponent && behaviors.push('copy'); - props.options?.onDeleteComponent && behaviors.push('delete'); - } else if (name === 'page') { - props.options?.onEditPage && behaviors.push('edit'); - props.options?.onCopyPage && behaviors.push('copy'); - props.options?.onDeletePage && behaviors.push('delete'); - } + const menus = (props.options?.resourceContextMenuActions?.(props.pluginContext, props.resource) || []).filter(d => !d.condition || d.condition && d.condition()); + const ContextMenu = props.pluginContext.commonUI?.ContextMenu || React.Fragment; - if (!behaviors.length) { + if (!menus.length) { return null; } return ( - { - e.stopPropagation(); - e.preventDefault(); - }} - > - -
- } - triggerType="click" - align="bl" - className="view-pane-popup" - visible={props.showBehaviors} - safeNode={props.safeNode} - onVisibleChange={props.onVisibleChange} +
{ + e.stopPropagation(); + e.preventDefault(); + ContextMenu.create(menus, e); + }} > - - {behaviors.map((d) => { - let text, handleLowcodeClick: any, handlePageClick: any; - switch (d) { - case 'edit': - text = intl( - 'view_manager.components.addFile.behaviors.DescriptionSettings', - { description: description } - ); - handleLowcodeClick = props.options?.onEditComponent; - handlePageClick = props.options?.onEditPage; - break; - case 'copy': - text = intl( - 'view_manager.components.addFile.behaviors.CopyDescription', - { description: description } - ); - handleLowcodeClick = props.options?.onCopyComponent; - handlePageClick = props.options?.onCopyPage; - break; - case 'delete': - text = intl( - 'view_manager.components.addFile.behaviors.DeleteDescription', - { description: description } - ); - handleLowcodeClick = props.options?.onDeleteComponent; - handlePageClick = props.options?.onDeletePage; - break; - } - - return ( - { - e.stopPropagation(); - e.preventDefault(); - props.onVisibleChange(false); - if (name === 'lowcode') { - handleLowcodeClick?.(props.resource); - } else { - handlePageClick?.(props.resource); - } - }} - > - {text} - - ); - })} - - + +
); } diff --git a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx index 685050a..165e664 100644 --- a/packages/plugin-view-manager-pane/src/components/addFile/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/addFile/index.tsx @@ -1,61 +1,30 @@ -import { Overlay, Menu } from '@alifd/next'; import * as React from 'react'; import { observer } from 'mobx-react'; +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; import { AddIcon } from '../../icon'; import { IOptions } from '../..'; - import './index.scss'; -import { intl } from '../../locale'; - -const { Popup } = Overlay; -const { Item } = Menu; -function AddFileComponent(props: { options: IOptions }) { +function AddFileComponent(props: { options: IOptions, pluginContext: IPublicModelPluginContext }) { if (props.options?.renderAddFileComponent && typeof props.options.renderAddFileComponent === 'function') { return props.options.renderAddFileComponent(); } - if (!props.options?.onAddPage && !props.options?.onAddComponent) { + const menus = props.options?.contextMenuActions?.(props.pluginContext); + + if (!menus || !menus.length) { return null; } - return ( - <> - - - - } - triggerType="click" - align="bl" - className="view-pane-popup" - > - - {props.options.onAddPage ? ( - { - props.options.onAddPage?.(); - }} - > - {intl('view_manager.components.addFile.CreatePage')} - - ) : null} + const ContextMenu = props.pluginContext?.commonUI?.ContextMenu || React.Fragment; - {props.options.onAddComponent ? ( - { - props.options.onAddComponent?.(); - }} - > - {intl('view_manager.components.addFile.CreateAComponent')} - - ) : null} - - - - ); + return ( + { + ContextMenu.create(menus, e) + }} className='add-file-icon-wrap'> + + + ) } export const AddFile = observer(AddFileComponent); diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss b/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss index b6962ec..ad7da44 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.scss @@ -25,6 +25,11 @@ display: flex; align-items: center; height: 30px; + cursor: pointer; + + &:hover { + background-color: var(--color-block-background-light, #f7f8fa); + } } &-expand { diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx index 2b0112f..218454a 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx @@ -3,7 +3,7 @@ import { IPublicModelPluginContext, IPublicModelResource, } from '@alilc/lowcode-types'; -import { Search, Overlay, Balloon, Menu } from '@alifd/next'; +import { Search, Balloon } from '@alifd/next'; import React, { useCallback, useState, useEffect, useRef } from 'react'; import { FileIcon, IconArrowRight } from './icon'; import './index.scss'; @@ -11,9 +11,6 @@ import { IOptions } from '../..'; import { intl } from '../../locale'; import { AddFile } from '../addFile'; -const { Popup } = Overlay; -const { Item } = Menu; - function filterResourceList(resourceList: IPublicModelResource[] | undefined, handler?: Function) { if (typeof handler === 'function') { return handler(resourceList); @@ -83,7 +80,7 @@ function ResourceListTree( value={filterValue} onChange={handleSearchChange} /> - +
{Array.from(Object.entries(category)).map( @@ -122,9 +119,6 @@ function ResourceGroup( props.defaultExpandAll || props.defaultExpandedCategoryKeys?.includes(props.categoryName) ); - const [visible, setVisible] = useState(false); - const ref = useRef(null); - const resourceArr = props.resourceArr.filter( (d) => !props.filterValue || @@ -160,69 +154,40 @@ function ResourceGroup( ); } + const ContextMenu = props.pluginContext?.commonUI?.ContextMenu || React.Fragment; + const indent = props.depth * 28 + 12; + + const style = { + paddingLeft: indent, + marginLeft: -indent, + } + return (
-
{ - e.preventDefault(); - e.stopPropagation(); - setVisible(!visible); - }} - ref={ref} +
{ setExpanded(!expanded); }} > - -
-
- +
+ +
+
+ +
+
{props.categoryName}
-
{props.categoryName}
- { - [intl('view_manager.components.resourceTree.Page'), intl('view_manager.components.resourceTree.Component')].includes(props.categoryName) ? ( - { - setVisible(false); - }} - safeNode={ref?.current} - placement="br" - className="view-pane-popup" - > - - { - if ( - props.categoryName === - intl('view_manager.components.resourceTree.Page') - ) { - props.options.onAddPage?.(); - } else { - props.options.onAddComponent?.(); - } - }} - > - {intl('view_manager.components.resourceTree.CreateItem', { - categoryName: props.categoryName === intl('view_manager.components.resourceTree.Page') - ? intl('view_manager.components.resourceTree.Page') - : intl('view_manager.components.resourceTree.Component'), - })} - - - - ) : null - } -
+ {expanded && (
{resourceArr.map((d) => ( @@ -256,7 +221,6 @@ function ResourceItem(props: { }) { const [expanded, setExpanded] = useState(false); const ref = useRef(null); - const [showBehaviors, setShowBehaviors] = useState(false); const PropsIcon = props.icon; const Behaviors = props.behaviors; const display = (props.resource?.config as any)?.display ?? true; @@ -275,111 +239,105 @@ function ResourceItem(props: { disabled, tips, } = props.resource?.config || {}; + const ContextMenu = props.pluginContext?.commonUI?.ContextMenu || React.Fragment; const context = ( -
{ - e.preventDefault(); - e.stopPropagation(); - setShowBehaviors(!showBehaviors); - }} - data-depth={props.depth} - > +
{ - if (disabled) { - return; - } - props.resource && props.pluginContext?.workspace.openEditorWindow(props.resource); - }} - className="resource-tree-title" - style={style} + ref={ref} + className={`resource-tree-group-node ${ + disabled + ? 'resource-tree-group-disabled' + : '' + } ${props.activeId === props.resource?.options.id || props.activeId === props.resource?.id ? 'active' : ''}`} + data-depth={props.depth} > - {props.resource?.options.modified ? ( -
} - triggerType="hover" - align='bl' - title="" - > - {props.resource.options.modifiedTips} - - ) : null} +
{ + if (disabled) { + return; + } + props.resource && props.pluginContext?.workspace.openEditorWindow(props.resource); + }} + className="resource-tree-title" + style={style} + > + {props.resource?.options.modified ? ( +
} + triggerType="hover" + align='bl' + title="" + > + {props.resource.options.modifiedTips} + + ) : null} - {((children && children.length) || null) && ( -
{ - setExpanded(!expanded); - e.stopPropagation(); - e.preventDefault(); - }} - > - -
- )} + {((children && children.length) || null) && ( +
{ + setExpanded(!expanded); + e.stopPropagation(); + e.preventDefault(); + }} + > + +
+ )} -
- {PropsIcon && } -
-
- {props.resource?.options?.label || props.resource?.title} +
+ {PropsIcon && } +
+
+ {props.resource?.options?.label || props.resource?.title} - { - props.resource?.options?.slug || - props.resource?.options?.componentName ? ( - - ({ props.resource.options?.slug || props.resource.options?.componentName }) - - ) : null - } -
+ { + props.resource?.options?.slug || + props.resource?.options?.componentName ? ( + + ({ props.resource.options?.slug || props.resource.options?.componentName }) + + ) : null + } +
-
- {Behaviors && - (props.resource?.config as any)?.disableBehaviors !== true ? ( - { - setShowBehaviors(visible); - }} - safeNode={ref?.current} - /> - ) : null} +
+ {Behaviors && + (props.resource?.config as any)?.disableBehaviors !== true ? ( + + ) : null} +
-
- { - expanded && children?.length ? ( -
- { - props.children?.map((child) => ( - - )) - } -
- ) : null - } -
+ { + expanded && children?.length ? ( +
+ { + props.children?.map((child) => ( + + )) + } +
+ ) : null + } +
+ ); if (tips) { @@ -402,7 +360,7 @@ function ResourceItem(props: { interface IPluginOptions { defaultExpandedCategoryKeys?: string[]; defaultExpandAll?: boolean; - pluginContext?: IPublicModelPluginContext; + pluginContext: IPublicModelPluginContext; behaviors?: any; options: IOptions; } diff --git a/packages/plugin-view-manager-pane/src/index.tsx b/packages/plugin-view-manager-pane/src/index.tsx index 8895401..c1541f0 100644 --- a/packages/plugin-view-manager-pane/src/index.tsx +++ b/packages/plugin-view-manager-pane/src/index.tsx @@ -3,6 +3,7 @@ import { IPublicModelPluginContext, IPublicModelResource, IPublicTypeSkeletonConfig, + IPublicTypeContextMenuAction, } from '@alilc/lowcode-types'; import Icon from './icon'; import { Pane } from './pane'; @@ -14,22 +15,6 @@ export interface IOptions { renderAddFileComponent?: () => React.JSX.Element; - onAddPage?: () => {}; - - onDeletePage?: (resource: IPublicModelResource) => {}; - - onEditPage?: (resource: IPublicModelResource) => {}; - - onCopyPage?: (resource: IPublicModelResource) => {}; - - onAddComponent?: () => {}; - - onEditComponent?: (resource: IPublicModelResource) => {}; - - onCopyComponent?: (resource: IPublicModelResource) => {}; - - onDeleteComponent?: (resource: IPublicModelResource) => {}; - handleClose?: (force?: boolean) => void; filterResourceList?: () => {}; @@ -37,6 +22,21 @@ export interface IOptions { showIconText?: boolean; skeletonConfig?: IPublicTypeSkeletonConfig; + + /** + * 右键菜单项 + */ + contextMenuActions?: (ctx: IPublicModelPluginContext) => IPublicTypeContextMenuAction[]; + + /** + * 右键资源项,菜单项 + */ + resourceContextMenuActions?: (ctx: IPublicModelPluginContext, resource: IPublicModelResource) => IPublicTypeContextMenuAction[]; + + /** + * 右键资源组,菜单项 + */ + resourceGroupContextMenuActions?: (ctx: IPublicModelPluginContext, resources: IPublicModelResource[]) => IPublicTypeContextMenuAction[]; } const ViewManagerPane = ( @@ -82,7 +82,7 @@ ViewManagerPane.meta = { // 依赖的插件(插件名数组) dependencies: [], engines: { - lowcodeEngine: '^1.0.0', // 插件需要配合 ^1.0.0 的引擎才可运行 + lowcodeEngine: '^1.3.0', // 插件需要配合 ^1.0.0 的引擎才可运行 }, preferenceDeclaration: { title: intl('view_manager.src.ViewManagementPanelPlugIn'), @@ -93,49 +93,34 @@ ViewManagerPane.meta = { description: '', }, { - key: 'onAddPage', - type: 'function', - description: '', - }, - { - key: 'onDeletePage', - type: 'function', - description: '', - }, - { - key: 'onEditPage', - type: 'function', - description: '', - }, - { - key: 'onCopyPage', + key: 'handleClose', type: 'function', description: '', }, { - key: 'onAddComponent', - type: 'function', + key: 'showIconText', + type: 'boolean', description: '', }, { - key: 'onEditComponent', - type: 'function', + key: 'skeletonConfig', + type: 'object', description: '', }, { - key: 'onCopyComponent', + key: 'contextMenuActions', type: 'function', - description: '', + description: '右键菜单项', }, { - key: 'onDeleteComponent', + key: 'resourceContextMenuActions', type: 'function', - description: '', + description: '右键资源项,菜单项', }, { - key: 'handleClose', + key: 'resourceGroupContextMenuActions', type: 'function', - description: '', + description: '右键资源组,菜单项', }, { key: 'filterResourceList', diff --git a/packages/plugin-view-manager-pane/src/pane.tsx b/packages/plugin-view-manager-pane/src/pane.tsx index 4ba6c5c..05eca45 100644 --- a/packages/plugin-view-manager-pane/src/pane.tsx +++ b/packages/plugin-view-manager-pane/src/pane.tsx @@ -12,25 +12,29 @@ export function Pane(props: { props.options?.init?.(props.pluginContext); }, []); + const ContextMenu = props.pluginContext.commonUI?.ContextMenu || React.Fragment; + return ( -
+
{ - e.stopPropagation(); - }} + className="workspace-view-pane" > - { - return ; +
{ + e.stopPropagation(); }} - options={props.options} - /> + > + { + return ; + }} + options={props.options} + /> +
-
+ ); } From 95a06134fda55e67efdb4ce71ce4cda5d09f63c9 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 15 Jan 2024 07:27:13 +0000 Subject: [PATCH 25/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index 7047ce6..a33709c 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "1.0.8", + "version": "2.0.0", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From 9b09ec81329b667aa9f78a27b2b5118a62c56246 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 17:02:54 +0800 Subject: [PATCH 26/36] feat(resource-tabs): fix resource tabs status error --- packages/plugin-resource-tabs/src/index.tsx | 112 +++++++++++--------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/packages/plugin-resource-tabs/src/index.tsx b/packages/plugin-resource-tabs/src/index.tsx index 4444fea..0b376be 100644 --- a/packages/plugin-resource-tabs/src/index.tsx +++ b/packages/plugin-resource-tabs/src/index.tsx @@ -13,7 +13,6 @@ import { CloseIcon, LockIcon, WarnIcon } from './icon'; import { intl } from './locale'; function CustomTabItem(props: { - key: string; pluginContext: IPublicModelPluginContext; options: IOptions; resource: IPublicModelResource; @@ -114,7 +113,7 @@ interface ITabItem { windowId: string; } -function Content(props: { +function TabsContent(props: { pluginContext: IPublicModelPluginContext; options: IOptions; }) { @@ -236,62 +235,69 @@ function Content(props: { } }, [resourceListMap]); - const ContextMenu = pluginContext?.commonUI?.ContextMenu || React.Fragment; return ( - -
- ( - - )} - onChange={(name) => { - setActiveTitle(name); - const item = tabs.filter((d) => String(d.id) === String(name))?.[0]; - const resource = resourceListMap[item.id]; - workspace.openEditorWindow(resource); - }} - > - {tabs.map((item) => { - const resource = resourceListMap[item.id]; - if (!resource) { - return null; - } + ( + + )} + onChange={(name) => { + setActiveTitle(name); + const item = tabs.filter((d) => String(d.id) === String(name))?.[0]; + const resource = resourceListMap[item.id]; + workspace.openEditorWindow(resource); + }} + > + {tabs.map((item) => { + const resource = resourceListMap[item.id]; + if (!resource) { + return null; + } - return ( - - ); - })} - -
-
+ return ( + + ); + })} + ); } +function Content(props: { + pluginContext: IPublicModelPluginContext; + options: IOptions; +}) { + const ContextMenu = props.pluginContext?.commonUI?.ContextMenu || React.Fragment; + return ( + + + + ) +} + interface IOptions { appKey?: string; onSort?: (windows: IPublicModelWindow[]) => IPublicModelWindow[]; From 84a387b96abb4cb891b6172b2415a0df86101e01 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 15 Jan 2024 17:12:28 +0800 Subject: [PATCH 27/36] fix(view-manager): fix view manager tips error --- .../src/components/resourceTree/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx index 218454a..b3f9e95 100644 --- a/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx +++ b/packages/plugin-view-manager-pane/src/components/resourceTree/index.tsx @@ -344,7 +344,7 @@ function ResourceItem(props: { return ( { context }
} triggerType="hover" align='r' title="" From c6e40c77a004c58fbaf867df6b54694a66b97cd5 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 15 Jan 2024 09:17:41 +0000 Subject: [PATCH 28/36] Bump version to --- packages/plugin-resource-tabs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-resource-tabs/package.json b/packages/plugin-resource-tabs/package.json index 5d1f8a7..2e6571c 100644 --- a/packages/plugin-resource-tabs/package.json +++ b/packages/plugin-resource-tabs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-resource-tabs", - "version": "2.0.0", + "version": "2.0.1", "description": "alibaba lowcode resource tabs plugin", "files": [ "es", From 432ba9d71aad6f7426f4983d71d7f7022d24e597 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 15 Jan 2024 09:22:53 +0000 Subject: [PATCH 29/36] Bump version to --- packages/plugin-view-manager-pane/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-view-manager-pane/package.json b/packages/plugin-view-manager-pane/package.json index a33709c..5c7b92c 100644 --- a/packages/plugin-view-manager-pane/package.json +++ b/packages/plugin-view-manager-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-view-manager-pane", - "version": "2.0.0", + "version": "2.0.1", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", From 134976287263e48bc7205376200f5ce80b8c06fd Mon Sep 17 00:00:00 2001 From: jingyu Date: Thu, 22 Feb 2024 17:58:25 +0800 Subject: [PATCH 30/36] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=A4=9A?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=BC=96=E8=BE=91=E5=99=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/README.md | 1 + packages/plugin-multiple-editor/package.json | 6 +- .../plugin-multiple-editor/src/Context.tsx | 34 +++- .../plugin-multiple-editor/src/Controller.ts | 126 +++++++++++---- .../plugin-multiple-editor/src/EditorHook.ts | 1 + .../src/MonacoSuggestions.ts | 67 ++++++++ .../src/MultipleFileEditor/Editor.tsx | 106 ++++++++----- .../src/MultipleFileEditor/index.less | 16 +- .../src/MultipleFileEditor/util.tsx | 16 +- .../plugin-multiple-editor/src/Service.ts | 42 ++++- .../FileTree/TreeNode/img/rename.png | Bin 0 -> 2170 bytes .../components/FileTree/TreeNode/index.less | 24 ++- .../components/FileTree/TreeNode/index.tsx | 75 ++++++--- .../src/components/FileTree/index.less | 10 +- .../src/components/FileTree/index.tsx | 77 ++++++++-- .../src/components/MonacoEditor/index.tsx | 35 +++-- .../src/components/Outline/img/class.png | Bin 0 -> 2229 bytes .../src/components/Outline/img/function.png | Bin 0 -> 3438 bytes .../src/components/Outline/img/props.png | Bin 0 -> 3458 bytes .../src/components/Outline/index.less | 93 +++++++++++ .../src/components/Outline/index.tsx | 145 ++++++++++++++++++ .../src/components/Outline/utils.ts | 59 +++++++ .../delete-hidden-transducer/index.ts | 2 +- .../scenario-switcher/index.tsx | 13 +- .../scenarios/basic-antd/plugin.tsx | 23 +-- .../plugin.tsx | 17 +- .../scenarios/basic-fusion/plugin.tsx | 21 +-- .../dev-config/scenarios/next-pro/plugin.tsx | 17 +- .../node-extended-actions/plugin.tsx | 29 ++-- .../src/dev-config/universal/plugin.tsx | 11 -- .../src/dev-config/universal/utils.ts | 5 +- .../plugin-multiple-editor/src/global.d.ts | 6 + .../plugin-multiple-editor/src/index.dev.tsx | 42 ++++- packages/plugin-multiple-editor/src/index.tsx | 14 +- .../src/plugins/prettier-plugin/index.tsx | 58 +++++++ .../src/plugins/prettier-plugin/prettier.png | Bin 0 -> 3377 bytes .../src/plugins/search-plugin/index.ts | 1 + .../src/plugins/search-plugin/search.ts | 3 + .../plugin-multiple-editor/src/types/index.ts | 4 +- .../plugin-multiple-editor/src/utils/code.ts | 7 +- .../src/utils/constants.ts | 2 + .../plugin-multiple-editor/src/utils/files.ts | 37 +++-- .../src/utils/get-methods.ts | 2 +- .../src/utils/ghostBabel.ts | 77 +++++++++- .../plugin-multiple-editor/src/utils/index.ts | 1 + .../src/utils/multipleFile/babel/compile.ts | 6 +- .../plugin-multiple-editor/src/utils/path.ts | 68 ++++++++ .../src/utils/script-loader.ts | 50 ++++++ .../src/utils/transformUMD.ts | 2 +- packages/plugin-multiple-editor/tsconfig.json | 117 +++----------- 50 files changed, 1222 insertions(+), 346 deletions(-) create mode 100644 packages/plugin-multiple-editor/src/MonacoSuggestions.ts create mode 100644 packages/plugin-multiple-editor/src/components/FileTree/TreeNode/img/rename.png create mode 100644 packages/plugin-multiple-editor/src/components/Outline/img/class.png create mode 100644 packages/plugin-multiple-editor/src/components/Outline/img/function.png create mode 100644 packages/plugin-multiple-editor/src/components/Outline/img/props.png create mode 100644 packages/plugin-multiple-editor/src/components/Outline/index.less create mode 100644 packages/plugin-multiple-editor/src/components/Outline/index.tsx create mode 100644 packages/plugin-multiple-editor/src/components/Outline/utils.ts create mode 100644 packages/plugin-multiple-editor/src/plugins/prettier-plugin/index.tsx create mode 100644 packages/plugin-multiple-editor/src/plugins/prettier-plugin/prettier.png create mode 100644 packages/plugin-multiple-editor/src/utils/path.ts create mode 100644 packages/plugin-multiple-editor/src/utils/script-loader.ts diff --git a/packages/plugin-multiple-editor/README.md b/packages/plugin-multiple-editor/README.md index c53fcf5..dab124a 100644 --- a/packages/plugin-multiple-editor/README.md +++ b/packages/plugin-multiple-editor/README.md @@ -58,6 +58,7 @@ await plugins.register(plugin); 4. 如需在 setter 内适用类型定义,请开启 base-editor 的单例模式,仅需在应用入口处调用如下方法即可: 5. 如果低码项目有使用出码,则需对出码进行定制,将 _sourceCodeMap 中的文件生成到项目中,并对文件的引用进行处理,具体处理方式可自行组织 +__使用单例模式__ ```ts import { configure } from '@alilc/lowcode-plugin-base-monaco-editor'; configure({ singleton: true }); diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 289f34c..053834e 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -24,7 +24,8 @@ "release": "fast-publish" }, "dependencies": { - "@alilc/lowcode-types": "^1.0.3" + "@alilc/lowcode-types": "^1.0.3", + "@babel/types": "^7.16.0" }, "devDependencies": { "@alifd/next": "^1.25.29", @@ -122,6 +123,9 @@ "webpackbar": "^5.0.2", "workbox-webpack-plugin": "^6.4.1" }, + "resolutions": { + "@types/react": "^17.0.2" + }, "browserslist": { "production": [ ">0.2%", diff --git a/packages/plugin-multiple-editor/src/Context.tsx b/packages/plugin-multiple-editor/src/Context.tsx index 9346c35..b90b61b 100644 --- a/packages/plugin-multiple-editor/src/Context.tsx +++ b/packages/plugin-multiple-editor/src/Context.tsx @@ -21,7 +21,6 @@ import { sortDir, } from './utils/files'; import { editorController } from './Controller'; -import { getDefaultFileList } from './MultipleFileEditor/util'; export type CurrentFile = { file?: File; @@ -39,11 +38,13 @@ export interface EditorContextType { updateFileTreeByPath( path: string[], target: Dir | File, - operation: 'delete' | 'add' + operation: 'delete' | 'add' | 'rename', + newName?: string ): void; selectFile(file: File | string, path: string[]): void; selectFileByName(name: string): void; updateState(state: Partial): void; + updateCurrentFile(content: string): void; initialFileMap: Record; extraLibs: { path: string; content: string }[]; } @@ -86,7 +87,9 @@ export const EditorProvider: FC<{ () => editorController.getCodeTemp()?._sourceCodeMap.files || {}, [] ); - const initFileTree = fileMap ? fileMapToTree(fileMap) : new Dir('/'); + const initFileTree = fileMap + ? fileMapToTree(fileMap) + : new Dir('/', [], [], ''); const initState: StoreState = { declarations: '', extraLibs: [], @@ -103,7 +106,7 @@ export const EditorProvider: FC<{ if (typeof file === 'string') { const { fileTree } = state; const targetFile = getFileByPath(fileTree, file, path); - finalFile = targetFile || new File('index.js', ''); + finalFile = targetFile || new File('index.js', '', 'index.js'); } else { finalFile = file; } @@ -123,12 +126,14 @@ export const EditorProvider: FC<{ updateFileTree(tree: Dir) { dispatch({ type: 'update', payload: { fileTree: sortDir(tree) } }); }, - updateFileTreeByPath(path, target, operation) { + updateFileTreeByPath(path, target, operation, newName) { const { fileTree } = state; if (operation === 'add') { insertNodeToTree(fileTree, path, target); } else if (operation === 'delete') { deleteNodeOnTree(fileTree, path, target); + } else if (operation === 'rename') { + target.name = newName as string; } const payload: Partial = { fileTree: sortDir(fileTree) }; // 新增文件时,选中当前文件 @@ -147,12 +152,27 @@ export const EditorProvider: FC<{ updateState(state: Partial) { dispatch({ type: 'update', payload: state }); }, + updateCurrentFile(content) { + if (this.currentFile.file) { + this.currentFile.file.content = content; + this.updateState({ + currentFile: { + ...this.currentFile, + file: { + ...this.currentFile.file, + content, + }, + }, + }); + // this.updateFileTree({...this.fileTree}); + } + }, }), - [fileMap, selectFile, softSave, state] + [fileMap, mode, selectFile, softSave, state] ); useEffect(() => { const off = editorController.onSourceCodeChange((codeMap) => { - const fileTree = fileMapToTree(codeMap) || new Dir('/'); + const fileTree = fileMapToTree(codeMap) || new Dir('/', [], [], ''); dispatch({ type: 'update', payload: { fileTree } }); const targetFile = getFileByPath(fileTree, 'index.js', []); setTimeout(() => { diff --git a/packages/plugin-multiple-editor/src/Controller.ts b/packages/plugin-multiple-editor/src/Controller.ts index cce1d56..401838a 100644 --- a/packages/plugin-multiple-editor/src/Controller.ts +++ b/packages/plugin-multiple-editor/src/Controller.ts @@ -1,8 +1,10 @@ import type { Project, Event } from '@alilc/lowcode-shell'; -import { skeleton, common } from '@alilc/lowcode-engine'; +import { IPublicTypeProjectSchema } from '@alilc/lowcode-types'; +import { skeleton } from '@alilc/lowcode-engine'; import { beautifyCSS, compatGetSourceCodeMap, + fileMapToTree, getConstructorContent, getDefaultDeclaration, getInitFuncContent, @@ -10,7 +12,8 @@ import { treeToMap, } from './utils'; import { FunctionEventParams, Monaco, ObjectType } from './types'; -import type { editor } from 'monaco-editor'; +import { common } from '@alilc/lowcode-engine'; +import { editor } from 'monaco-editor'; import { addFunction, focusByFunctionName, @@ -21,13 +24,14 @@ import { EditorContextType } from './Context'; import { Message } from '@alifd/next'; import { getMethods } from './utils/get-methods'; import { EditorHook, HookKeys } from './EditorHook'; -import { Service } from './Service'; +import { PluginHooks, Service } from './Service'; +import { MonacoSuggestions } from './MonacoSuggestions'; export * from './EditorHook'; export interface EditorControllerState { declarationsMap: Record; - extraLibs: Array<{ path: string; content: string }>; + extraLibs: { path: string; content: string }[]; } export type HookHandleFn = (fn: T) => () => void; @@ -49,7 +53,9 @@ export class EditorController extends EditorHook { defaultFiles: ObjectType; - monaco?: Monaco; + useLess?: boolean; + + public monaco?: Monaco; private codeTemp?: CodeTemp; @@ -59,23 +65,30 @@ export class EditorController extends EditorHook { private state: EditorControllerState; - codeEditor?: editor.IStandaloneCodeEditor; + public codeEditor?: editor.IStandaloneCodeEditor; + + public codeEditorCtx?: EditorContextType; + + public service!: Service; - private codeEditorCtx?: EditorContextType; + private loadMonacoPromise?: Promise; - service!: Service; + private monacoSuggestions: MonacoSuggestions; - onImportSchema: HookHandleFn<(schema: any) => void | Promise> = - this.hookFactory(HookKeys.onImport); + public onImportSchema: HookHandleFn< + (schema: IPublicTypeProjectSchema) => void | Promise + > = this.hookFactory(HookKeys.onImport); - onSourceCodeChange: HookHandleFn<(code: any) => void> = this.hookFactory( - HookKeys.onSourceCodeChange - ); + public onSourceCodeChange: HookHandleFn<(code: any) => void> = + this.hookFactory(HookKeys.onSourceCodeChange); - onEditCodeChange: HookHandleFn< + public onEditCodeChange: HookHandleFn< (code: { content: string; file: string }) => void > = this.hookFactory(HookKeys.onEditCodeChange); + public onMonacoLoaded: HookHandleFn<(monaco: Monaco) => void> = + this.hookFactory(HookKeys.onMonacoLoaded); + constructor() { super(); this.state = { @@ -85,6 +98,21 @@ export class EditorController extends EditorHook { this.listeners = []; this.defaultFiles = {}; this.extraLibMap = new Map(); + this.monacoSuggestions = new MonacoSuggestions(this); + } + + async initMonaco() { + if (!this.monaco) { + if (!this.loadMonacoPromise) { + const { getMonaco } = await import( + '@alilc/lowcode-plugin-base-monaco-editor' + ); + this.loadMonacoPromise = getMonaco(); + } + this.monaco = await this.loadMonacoPromise; + this.triggerHook(HookKeys.onMonacoLoaded, this.monaco); + this.service.triggerHook(PluginHooks.onMonacoLoaded, this.monaco); + } } init(project: Project, editor: Event, service: Service) { @@ -94,6 +122,7 @@ export class EditorController extends EditorHook { this.setupEventListeners(); this.initCodeTempBySchema(this.getSchema(true)); this.triggerHook(HookKeys.onImport, this.getSchema(true)); + this.initMonaco(); } initCodeEditor( @@ -102,6 +131,7 @@ export class EditorController extends EditorHook { ) { this.codeEditor = codeEditor; this.codeEditorCtx = ctx; + this.monacoSuggestions.init(); } setCodeTemp(code: any | ((old: CodeTemp) => CodeTemp)) { @@ -122,7 +152,7 @@ export class EditorController extends EditorHook { this.applyLibs(); } - addComponentDeclarations(list: Array<[string, string]> = []) { + addComponentDeclarations(list: [string, string][] = []) { for (const [key, dec] of list) { this.state.declarationsMap[key] = dec; } @@ -131,7 +161,7 @@ export class EditorController extends EditorHook { } private publishExtraLib() { - const libs: Array<{ path: string; content: string }> = []; + const libs: { path: string; content: string }[] = []; this.extraLibMap.forEach((content, path) => libs.push({ content, path })); this.state.extraLibs = libs; this.publish(); @@ -151,10 +181,7 @@ export class EditorController extends EditorHook { private async applyLibs() { if (!this.monaco) { - const { getMonaco } = await import( - '@alilc/lowcode-plugin-base-monaco-editor' - ); - this.monaco = await getMonaco(undefined) as any; + await this.initMonaco(); } const decStr = Object.keys(this.state.declarationsMap).reduce( (v, k) => `${v}\n${k}: ${this.state.declarationsMap[k]};\n`, @@ -173,7 +200,7 @@ export class EditorController extends EditorHook { }); } - getSchema(pure?: boolean): any { + getSchema(pure?: boolean): IPublicTypeProjectSchema { const schema = this.project.exportSchema( common.designerCabin.TransformStage.Save ); @@ -182,15 +209,21 @@ export class EditorController extends EditorHook { ? treeToMap(this.codeEditorCtx.fileTree) : this.codeTemp?._sourceCodeMap.files; // 获取最新的fileMap if (fileMap && !pure) { - if (!this.compileSourceCode(fileMap)) { - throw new Error('编译失败'); + try { + if (!this.compileSourceCode(fileMap)) { + // 下面会导致整个页面挂掉,先作为弱依赖,给个提示 + throw new Error('编译失败'); + } + Object.assign(schema.componentsTree[0], this.codeTemp); + } catch (error) { + console.error(error); + Message.error('源码编译失败,请返回修改'); } - Object.assign(schema.componentsTree[0], this.codeTemp); } return schema; } - importSchema(schema: any) { + importSchema(schema: IPublicTypeProjectSchema) { this.project.importSchema(schema); this.initCodeTempBySchema(schema); this.triggerHook(HookKeys.onImport, schema); @@ -217,15 +250,15 @@ export class EditorController extends EditorHook { }; } - initCodeTempBySchema(schema: any) { + public initCodeTempBySchema(schema: IPublicTypeProjectSchema) { const componentSchema = schema.componentsTree[0] || {}; - const { css, methods, state, lifeCycles } = componentSchema; + const { css, methods, state, lifeCycles } = componentSchema as any; const codeMap = (componentSchema as any)._sourceCodeMap; const defaultFileMap = { ...this.defaultFiles, - ...getDefaultFileList(schema), + ...getDefaultFileList(schema, this.useLess), }; - const compatMap = compatGetSourceCodeMap(codeMap); + const compatMap = compatGetSourceCodeMap(codeMap, defaultFileMap); this.codeTemp = { css, methods, @@ -233,7 +266,6 @@ export class EditorController extends EditorHook { lifeCycles, _sourceCodeMap: { ...compatMap, - files: defaultFileMap, }, }; } @@ -253,8 +285,8 @@ export class EditorController extends EditorHook { this.editor?.on('common:codeEditor.addFunction', (( params: FunctionEventParams ) => { + this.codeEditorCtx?.selectFile('index.js', []); setTimeout(() => { - this.codeEditorCtx?.selectFile('index.js', []); if (this.monaco && this.codeEditor) { addFunction(this.codeEditor, params, this.monaco); } @@ -306,7 +338,20 @@ export class EditorController extends EditorHook { pageNode.state = state; pageNode.methods = methods; pageNode.lifeCycles = lifeCycles; - pageNode.css = beautifyCSS(fileMap['index.css'] || '', {}); + const lessContent = fileMap['index.less']; + // 没有less文件,走之前的逻辑 + if (!lessContent) { + pageNode.css = beautifyCSS(fileMap['index.css'] || '', {}); + } + if (this.useLess && lessContent) { + window.less?.render(lessContent, {}, (err: any, output: any) => { + if (err) { + Message.error('less 编译失败'); + console.error(err); + } + pageNode.css = output?.css || ''; + }); + } if (lifeCycles.constructor === {}.constructor) { lifeCycles.constructor = { originalCode: 'function constructor() { }', @@ -341,10 +386,25 @@ export class EditorController extends EditorHook { return true; } - resetSaveStatus() { + public resetSaveStatus() { this.codeEditorCtx?.updateState({ modifiedKeys: [] }); } + // 添加一堆文件 + public addFiles(fileMap: ObjectType) { + if (!Object.keys(fileMap || {}).length || !this.codeEditorCtx?.fileTree) { + return; + } + const subTree = fileMapToTree(fileMap); + const { files, dirs } = subTree; + const newTree = { ...this.codeEditorCtx?.fileTree }; + newTree.files?.push(...files); + newTree.dirs?.push(...dirs); + this.codeEditorCtx.updateState({ + fileTree: newTree, + }); + } + triggerHook(key: HookKeys, ...args: any[]): void { super.triggerHook(key, ...args); } diff --git a/packages/plugin-multiple-editor/src/EditorHook.ts b/packages/plugin-multiple-editor/src/EditorHook.ts index 0433d69..8fcf145 100644 --- a/packages/plugin-multiple-editor/src/EditorHook.ts +++ b/packages/plugin-multiple-editor/src/EditorHook.ts @@ -2,6 +2,7 @@ export enum HookKeys { onImport = 'onImport', onSourceCodeChange = 'onSourceCodeChange', onEditCodeChange = 'onEditCodeChange', + onMonacoLoaded = 'onMonacoLoaded', } export class EditorHook { diff --git a/packages/plugin-multiple-editor/src/MonacoSuggestions.ts b/packages/plugin-multiple-editor/src/MonacoSuggestions.ts new file mode 100644 index 0000000..62a35e5 --- /dev/null +++ b/packages/plugin-multiple-editor/src/MonacoSuggestions.ts @@ -0,0 +1,67 @@ +import { EditorController } from './Controller'; +import { getFilesByPath, pathResolve, resolveFilePath } from './utils'; + +export class MonacoSuggestions { + private editorInitialed = false; + constructor(private controller: EditorController) {} + + get monaco() { + return this.controller.monaco!; + } + + get editor() { + return this.controller.codeEditor!; + } + + init() { + if (!this.editorInitialed) { + this.initPathSuggestion(); + } + } + + private initPathSuggestion() { + this.editorInitialed = true; + const monaco = this.monaco; + const getFileMap = () => + this.controller.getCodeTemp()?._sourceCodeMap.files || {}; + this.monaco?.languages.registerCompletionItemProvider( + ['javascript', 'typescript'], + { + triggerCharacters: ['/'], + provideCompletionItems(model, position) { + const textUntilPosition = model.getValueInRange({ + startLineNumber: position.lineNumber, + startColumn: 1, + endLineNumber: position.lineNumber, + endColumn: position.column + 1, + }); + const currentFilePath = resolveFilePath(model.uri.path); + const match = textUntilPosition.match(/('.*')|(".*")/gim); + if (!match) return; + const relativePath = match?.[0]?.replace(/'|"/g, '') || ''; + const filesList = getFilesByPath( + getFileMap(), + pathResolve(currentFilePath, relativePath) + ); + return { + suggestions: filesList.map(({ type, path }) => ({ + label: path, + sortText: type === 'dir' ? '1' : '2', + range: { + startColumn: position.column, + endColumn: position.column, + startLineNumber: position.lineNumber, + endLineNumber: position.lineNumber, + }, + kind: + type === 'file' + ? monaco.languages.CompletionItemKind.File + : monaco.languages.CompletionItemKind.Folder, + insertText: path.replace(/\.\w+$/, ''), + })), + }; + }, + } + ); + } +} diff --git a/packages/plugin-multiple-editor/src/MultipleFileEditor/Editor.tsx b/packages/plugin-multiple-editor/src/MultipleFileEditor/Editor.tsx index ee1b2fc..cb1e374 100644 --- a/packages/plugin-multiple-editor/src/MultipleFileEditor/Editor.tsx +++ b/packages/plugin-multiple-editor/src/MultipleFileEditor/Editor.tsx @@ -1,20 +1,14 @@ import FileTree from '@/components/FileTree'; import MonacoEditor from '@/components/MonacoEditor'; +import Outline from '@/components/Outline'; import { useEditorContext } from '../Context'; import { Dialog, Message } from '@alifd/next'; import cls from 'classnames'; -import React, { - FC, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import './index.less'; import { HandleChangeFn } from '../components/FileTree/TreeNode'; import { languageMap } from '../utils/constants'; -import { getKeyByPath, parseKey, treeToMap } from 'utils/files'; +import { parseKey, treeToMap } from 'utils/files'; import { editorController, HookKeys } from '../Controller'; import { initEditorModel, useUnReactiveFn } from './util'; @@ -22,6 +16,10 @@ import type { editor } from 'monaco-editor'; import { Monaco } from '../types'; import { PluginHooks } from '@/Service'; +// 最大最小宽(带工具栏) +const MINWIDTH = 246; +const MAXWIDTH = 446; + const Editor: FC = () => { const editorContext = useEditorContext(); const { @@ -37,34 +35,30 @@ const Editor: FC = () => { const monacoEditor = useRef(); const monacoRef = useRef(); const [fullscreen, setFullscreen] = useState(false); - + const [fileContent, setFileContent] = useState(file?.content); + const [fileTreeWidth, setFileTreeWidth] = useState('200px'); const containerRef = useRef(); - const filePath = useMemo( - () => [...path, file?.name].join('/'), - [file?.name, path] - ); + const filePath = file?.fullPath || ''; const handleChange = useCallback( (file, path) => { selectFile(file, path); + setFileContent(file?.content); }, [selectFile] ); const handleEditorChange = useCallback( (value: string) => { + setFileContent(value); file && (file.content = value); - const curKey = getKeyByPath(path, file?.name || ''); editorController.triggerHook(HookKeys.onEditCodeChange, { - file: path - .join('/') - .concat('/') - .concat(file?.name || ''), + file: file?.fullPath, content: value, }); - if (!modifiedKeys.find((k) => k === curKey)) { - updateState({ modifiedKeys: [...modifiedKeys, curKey] }); + if (!modifiedKeys.find((k) => k === file?.fullPath)) { + updateState({ modifiedKeys: [...modifiedKeys, file?.fullPath as any] }); } }, - [file, modifiedKeys, path, updateState] + [file, modifiedKeys, updateState] ); const handleCompile = useCallback( @@ -87,7 +81,6 @@ const Editor: FC = () => { }, [fileTree] ); - const { handler: handleSave } = useUnReactiveFn(() => { if (handleCompile(true)) { // 全部保存, 标记清空 @@ -109,6 +102,10 @@ const Editor: FC = () => { monacoRef.current = monaco; initEditorModel(initialFileMap, monaco); editorController.initCodeEditor(codeEditor, editorContext); + editorController.service.triggerHook( + PluginHooks.onEditorMount, + codeEditor + ); }, [editorContext, initialFileMap] ); @@ -120,16 +117,12 @@ const Editor: FC = () => { }, [editorContext]); useEffect(() => { - const filepath = path - .join('/') - .concat('/') - .concat(file?.name || ''); editorController.service.triggerHook(PluginHooks.onSelectFileChange, { - filepath, + filepath: file?.fullPath, content: file?.content, }); editorController.triggerHook(HookKeys.onEditCodeChange, { - file: filepath, + file: file?.fullPath, content: file?.content, }); }, [file, path]); @@ -150,6 +143,27 @@ const Editor: FC = () => { const handleFullScreen = useCallback((enable: boolean) => { setFullscreen(enable); }, []); + const handleMoveDrag = () => { + let first = true; + document.onmousemove = function (e) { + if (first) { + // 只拖动一下视为点击误触 防止偶现点击触发拖动问题 + first = false; + return; + } + const clientX = e.clientX; + const maxWidth = + clientX < MINWIDTH ? MINWIDTH : clientX > MAXWIDTH ? MAXWIDTH : clientX; + setFileTreeWidth(`${fullscreen ? maxWidth : maxWidth - 46}px`); + return false; + }; + + document.onmouseup = function (e) { + document.onmousemove = null; + // document.onmouseup = null; + return false; + }; + }; return (
{ )} ref={containerRef as any} > - handleCompile()} - fullscreen={fullscreen} - onFullscreen={handleFullScreen} +
+ handleCompile()} + fullscreen={fullscreen} + onFullscreen={handleFullScreen} + actions={editorController.service.actionMap} + /> +
+ -
+

{file ? file.name : '无文件'}

{file ? ( => { +export const getDefaultFileList = ( + rootSchema: any, + useLess?: boolean +): ObjectType => { const sourceCodeMap = rootSchema?.componentsTree?.[0]?._sourceCodeMap || {}; const { files } = compatGetSourceCodeMap(sourceCodeMap); // 兼容旧格式 if (files['index.js']) { @@ -28,7 +31,8 @@ export const getDefaultFileList = (rootSchema: any): ObjectType => { {} ) ), - 'index.css': rootSchema?.componentsTree?.[0]?.css || '', + [useLess ? 'index.less' : 'index.css']: + rootSchema?.componentsTree?.[0]?.css || '', ...files, }; @@ -101,9 +105,13 @@ export async function addFunction( if (!monacoEditor || !monaco) { return; } - const count = monacoEditor.getModel()?.getLineCount() ?? 0; - const range = new monaco.Range(count, 1, count, 1); + let count = monacoEditor.getModel()?.getLineCount() ?? 0; + // 找到倒数第一个非空行 + while (!monacoEditor.getModel()?.getLineContent(count)) { + count--; + } + const range = new monaco.Range(count, 1, count, 1); const functionCode = params.template ? params.template : `\n\t${params.functionName}(){\n\t}\n`; diff --git a/packages/plugin-multiple-editor/src/Service.ts b/packages/plugin-multiple-editor/src/Service.ts index 2ceb81c..79dd16c 100644 --- a/packages/plugin-multiple-editor/src/Service.ts +++ b/packages/plugin-multiple-editor/src/Service.ts @@ -1,11 +1,15 @@ -import { EditorController } from './Controller'; +import { ReactElement } from 'react'; +import { EditorController, HookHandleFn } from './Controller'; import { EditorHook } from './EditorHook'; -import type { Skeleton } from '@alilc/lowcode-shell'; +import type {IPublicApiSkeleton} from '@alilc/lowcode-types'; +import { Monaco } from './types'; export enum PluginHooks { onActive = 'onActive', onDeActive = 'onDeActive', onSelectFileChange = 'onSelectFileChange', + onEditorMount = 'onEditorMount', + onMonacoLoaded = 'onMonacoLoaded', } export interface EditorPluginInterface { @@ -16,6 +20,14 @@ export interface ServiceInitOptions { plugins?: EditorPluginInterface[]; } +export interface PluginAction { + key: string; + title: string; + icon: ReactElement; + action: () => any; + priority: number; +} + export class Service extends EditorHook { // private options: ServiceInitOptions; public onActive = this.hookFactory(PluginHooks.onActive); @@ -24,12 +36,19 @@ export class Service extends EditorHook { public onSelectFileChange = this.hookFactory(PluginHooks.onSelectFileChange); - constructor(public controller: EditorController, private skeleton: Skeleton) { + public onEditorMount = this.hookFactory(PluginHooks.onEditorMount); + + public onMonacoLoaded: HookHandleFn<(monaco: Monaco) => void> = + this.hookFactory(PluginHooks.onMonacoLoaded); + + actionMap: Array; + + constructor(public controller: EditorController, private skeleton: IPublicApiSkeleton) { super(); + this.actionMap = []; } init(options: ServiceInitOptions) { - // this.options = options; const { plugins } = options; if (plugins) { for (const plugin of plugins) { @@ -41,12 +60,12 @@ export class Service extends EditorHook { } private setupHooks() { - this.skeleton.onShowPanel((pluginName) => { + this.skeleton.onHidePanel((pluginName) => { if (pluginName === 'codeEditor') { this.triggerHook(PluginHooks.onDeActive); } }); - this.skeleton.onHidePanel((pluginName) => { + this.skeleton.onShowPanel((pluginName) => { if (pluginName === 'codeEditor') { this.triggerHook(PluginHooks.onActive); } @@ -56,4 +75,15 @@ export class Service extends EditorHook { public triggerHook(key: PluginHooks, ...args: any[]): void { super.triggerHook(key, ...args); } + + public registerAction(action: PluginAction) { + const index = this.actionMap.findIndex((item) => item.key === action.key); + if (index > -1) { + console.error( + `Action ${action.key}, 已被注册,此 Action 将覆盖原 Action` + ); + this.actionMap.splice(index, 1); + } + this.actionMap.push(action); + } } diff --git a/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/img/rename.png b/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/img/rename.png new file mode 100644 index 0000000000000000000000000000000000000000..7a82ae226993e8b64c9d91bce5bc275ae26abb9b GIT binary patch literal 2170 zcmcgu`&Scp7N3LxClIp}P(U2?8=|7sf;==tUKyYaD2IpDg+>I?fT$=ku?2aCQ6LCH z;tQ$58f}ZZzIeDrc@}~h1f*iO0xK?4n*`w#5dAA0tO`}*A1IrrRi&&>@E zBo-Q58AA}X(BIEzt6tLoA;d_}Z-(6})eDAnE8zv*dW5}#AjH|<2j7+yF;)^nVgj}y zVS75QLT#J(b>%PBRnxvbeLRudDIjj(K^4pIZ&d1L#`;Z|Xwv5Xg&R>>qm+p>eIx2O zWWZ7GKn7kza4I|lPbOTsjxgXgrp}%3xgvDA;Q9$vq_Dx?1uSR$56;YG_`FAfwhpm< z1m|PcdQtDvJzMP1F9=Sb>BWai+!oLMxm5IKp#lHNd}yj zWP_I(Nonunc3$q4GG>wk8b8x4@{d8td1IHnFLx}xjWz2tdh<4Er|L-dSs0JG;n!Cj zLOw$t{(ca~N9;z2i^@)G;p5=S)9;3A&yc{cBij1YNEHd_;qBK1_IEL4YkU+@?^1^$ zj^xh$9lc&0_}bm7D-ks(^~nC{k@lX=dZeXNUd4~x7QumY!^`TDd78bYb3sd|#joX0fyVj^ zI5+HCS~AcSt>a4mHaMQfBHe%-)E&4>xRY+JTzoogqBIm}Op=kVO7ZLgrPjt9Zf(## zw*Z8J5Z))N8sO?;*^6;2{NNF`kR4?sXZ&hJD4Q*9D9g;19tBvz1gd6y9>pSEyuDG| zYM*HOG1r_r(zqq~1XjZ1`PnvRwJG@kgITibT_!rj*bt{gcE1=2nav`F=)6glS3y6D zuCN?de?#+Rg@Ae0Ol*^bY@+0ioVYy9s~fR7?s{nhDd+L!mUr&BlgPkxF`tHLimQ+R z?dnR3&9rvWmy3$H>!n!hb>Nd!XL)e}#Ws5Gz!7fhKe~mh-f}3;n#>>klww5%Fyk%r zFr%=?1b4-^v2mU{`QX0sY!D-9HdgGh9C>*Rm1LsJ!WlyIRzuvJ^TcNFdEr=REjGa!)tkf*o6d% zk5=M}OL4UfKmLR$!a7cyEfs1 zp$7GVrhe@*`7pnk=CQA;?h3p;aI5}OqE^-^*2NxQ=Qh;w7o4q10{k4tor$ZqHSabd zyV)&FD`EcOEY0Wl`XUW*OjXtB%UKW><-aAS@Bv@$bSAV>+05D=mJPhBJH?(<0cJ+U zTIPaTY+|8vvTJbLy+OPVAww2$eSNjObDxL>(Epl9b3qDpHziZ~vKQ<0AY~q`OB(%_)22MqvNk*rYVFBQk!- z*cb%MA!?EFg|c4#U`m!O&O(5n>dw*YB@oqJ91`*;IOj}EyEHF}#Fb3_GXeR35$JQv HYZvtgRwSS% literal 0 HcmV?d00001 diff --git a/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.less b/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.less index fe1f70f..a93b105 100644 --- a/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.less +++ b/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.less @@ -1,5 +1,8 @@ .ilp-tree-node { width: 100%; + overflow-y: auto; + overflow-x: hidden; + height: calc(100% - 24px); line-height: 24px; font-size: 12px; color: #333; @@ -41,14 +44,14 @@ img { width: 14px; height: 14px; + position: relative; + display: block; } span { margin-left: 4px; } - &-icon { - position: absolute; - right: 8px; - top: calc(50% - 7px); + &-icon-delete { + margin-right: 2px; } } &-title { @@ -85,11 +88,18 @@ height: 6px; border-radius: 50%; } - &-icon { + &-icon-wrap{ + align-items: center; + height: 24px; + padding: 0 8px 0 4px; + background-color: rgba(243, 243, 241); + position: absolute; + right: 0; + transform: all 0.15s; display: none; } - &:hover &-icon { - display: block; + &:hover &-icon-wrap { + display: flex; } } } diff --git a/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.tsx b/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.tsx index 3f19078..8386112 100644 --- a/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.tsx +++ b/packages/plugin-multiple-editor/src/components/FileTree/TreeNode/index.tsx @@ -6,6 +6,7 @@ import dirIcon from './img/file-directory.png'; import fileIcon from './img/file.png'; import menuIcon from './img/menu.png'; import deleteIcon from './img/delete.png'; +import renameIcon from './img/rename.png'; import './index.less'; @@ -15,6 +16,12 @@ export type HandleDeleteFn = (path: string[], target: Dir | File) => void; export type HandleChangeFn = (value: File, path: string[]) => void; +export type HandleRenameFn = ( + type: 'file' | 'dir', + path: string[], + target: Dir | File +) => void; + export interface TreeNodeProps { disableAction?: boolean; dir?: Dir; @@ -25,6 +32,7 @@ export interface TreeNodeProps { onChange?: HandleChangeFn; onAdd?: HandleAddFn; onDelete?: HandleDeleteFn; + onRename?: HandleRenameFn; className?: string; } @@ -37,7 +45,7 @@ const helpPopupProps = { placementOffset: 4, }; -const defaultDir = new Dir('root'); +const defaultDir = new Dir('/', [], [], ''); const TreeNode: FC = ({ dir = defaultDir, @@ -48,6 +56,7 @@ const TreeNode: FC = ({ onChange, onDelete, onAdd, + onRename, modifiedKeys, disableAction, }) => { @@ -75,20 +84,39 @@ const TreeNode: FC = ({ ]; // 根目录不能删除 if (parentKey) { - baseActions.push({ - title: '删除目录', - action: () => { - path.pop(); - onDelete?.(path, dir); + baseActions.push( + { + title: '删除目录', + action: () => { + path.pop(); + onDelete?.(path, dir); + }, + id: 'delete', }, - id: 'delete', - }); + { + title: '修改目录名', + action: () => { + path.pop(); + onRename?.('dir', path, dir); + }, + id: 'rename', + } + ); } return baseActions; - }, [dir, onAdd, onDelete, parentKey]); + }, [dir, onAdd, onDelete, onRename, parentKey]); const handleFileClick = (f: File, key: string) => { onChange?.(f, parseKey(key).path); }; + const handleRename = ( + e: MouseEvent, + file: File, + key: string + ) => { + e.stopPropagation(); + e.preventDefault(); + onRename?.('file', parseKey(key).path, file); + }; const handleDelete = ( e: MouseEvent, file: File, @@ -176,6 +204,7 @@ const TreeNode: FC = ({ parentKey={getKey(parentKey, d.name)} onChange={onChange} onAdd={onAdd} + onRename={onRename} onDelete={onDelete} modifiedKeys={modifiedKeys} /> @@ -188,23 +217,29 @@ const TreeNode: FC = ({ style={{ paddingLeft: 8 * (level + 1) }} className={cls( 'ilp-tree-node-file', - selectedKey === key && 'ilp-tree-node-file-selected', - modifiedKeys?.find((k) => k === key) && + selectedKey === f.fullPath && 'ilp-tree-node-file-selected', + modifiedKeys?.find((k) => k === f.fullPath) && 'ilp-tree-node-file-modified' )} onClick={() => handleFileClick(f, key)} > file {f.name} - {f.ext !== 'css' && - !(f.name === 'index.js' && !parentKey) && - !actionDisabled && ( - handleDelete(e, f, key)} - /> + {!(f.name === 'index.js' && !parentKey) && !actionDisabled && ( +
+ handleDelete(e, f, key)} + /> + handleRename(e, f, key)} + /> +
)}
); diff --git a/packages/plugin-multiple-editor/src/components/FileTree/index.less b/packages/plugin-multiple-editor/src/components/FileTree/index.less index 65d9825..e4511a8 100644 --- a/packages/plugin-multiple-editor/src/components/FileTree/index.less +++ b/packages/plugin-multiple-editor/src/components/FileTree/index.less @@ -1,13 +1,21 @@ .ilp-file-bar { - width: 200px; + width: 100%; padding: 8px; &-title { font-size: 14px; color: #333; margin: 0; + height: 24px; display: flex; justify-content: space-between; align-items: center; + .ilp-tree-action-item { + display: inline-block; + margin-left: 8px; + img { + margin-left: 0; + } + } img { width: 16px; height: 16px; diff --git a/packages/plugin-multiple-editor/src/components/FileTree/index.tsx b/packages/plugin-multiple-editor/src/components/FileTree/index.tsx index b3c51bd..979c8e7 100644 --- a/packages/plugin-multiple-editor/src/components/FileTree/index.tsx +++ b/packages/plugin-multiple-editor/src/components/FileTree/index.tsx @@ -1,18 +1,19 @@ import React, { CSSProperties, FC, useCallback, useRef, useState } from 'react'; import { Form, Input, Dialog, Message } from '@alifd/next'; import cls from 'classnames'; -import { Dir, File, getFileOrDirTarget, getKeyByPath } from '../../utils/files'; +import { Dir, File, getFileOrDirTarget } from '../../utils/files'; import TreeNode, { HandleAddFn, HandleChangeFn, HandleDeleteFn, + HandleRenameFn, } from './TreeNode'; import './index.less'; import { useEditorContext } from '../../Context'; -// import saveIcon from './img/save.svg'; import fullscreenIcon from './img/fullscreen.svg'; import fullscreenExitIcon from './img/fullscreen-exit.svg'; import compileIcon from './img/compile.svg'; +import { PluginAction } from '@/Service'; export interface FileTreeProps { dir?: Dir; @@ -22,9 +23,10 @@ export interface FileTreeProps { onSave?: () => any; onFullscreen?: (enable: boolean) => void; fullscreen?: boolean; + actions?: PluginAction[]; } -const defaultDir = new Dir('/'); +const defaultDir = new Dir('/', [], [], ''); function validate( data: { type: string; path: any }, @@ -46,8 +48,13 @@ function validate( return '文件或文件夹已存在'; } } + if (data.type === 'file' && name.endsWith('.less') && name !== 'index.less') { + return 'less 文件仅支持创建 index.less'; + } if (data.type === 'file') { - return name && /\.(js)$/.test(name) ? undefined : '文件名必填且未js后缀'; + return name && /\.(js|less)$/.test(name) + ? undefined + : '文件名必填且未js后缀'; } } @@ -63,14 +70,33 @@ const FileTree: FC = ({ onFullscreen, fullscreen, mode, + actions, }) => { const { updateFileTreeByPath, fileTree, modifiedKeys, currentFile } = useEditorContext(); const [visible, setVisible] = useState(false); const [value, setValue] = useState({ name: '' }); - const tmp = useRef<{ path: string[]; type: string }>({} as any).current; + const tmp = useRef<{ + path: string[]; + type: string; + fullPath: string; + operation?: string; + target?: any; + }>({} as any).current; const handleAdd = useCallback( (type, path) => { + tmp.operation = 'add'; + tmp.path = path; + tmp.type = type; + setValue({ name: '' }); + setVisible(true); + }, + [tmp] + ); + const handleRename = useCallback( + (type, path, target) => { + tmp.target = target; + tmp.operation = 'rename'; tmp.path = path; tmp.type = type; setValue({ name: '' }); @@ -78,7 +104,6 @@ const FileTree: FC = ({ }, [tmp] ); - const handleClose = useCallback(() => { setVisible(false); }, []); @@ -87,7 +112,7 @@ const FileTree: FC = ({ setValue({ name: v }); }, []); - const handleAddFileToTree = useCallback( + const handleEditFileToTree = useCallback( async (e?: React.KeyboardEvent) => { if (e && !(e.key === 'Enter' || e?.keyCode === 13)) { return; @@ -95,8 +120,16 @@ const FileTree: FC = ({ const { name } = value; const validMsg = validate(tmp, name, fileTree); if (!validMsg) { - const target = tmp.type === 'file' ? new File(name, '') : new Dir(name); - updateFileTreeByPath(tmp.path, target, 'add'); + const fullPath = `${tmp.path}/${name}`; + if (tmp.operation === 'rename') { + updateFileTreeByPath(tmp.path, tmp.target, 'rename', name); + } else { + const target = + tmp.type === 'file' + ? new File(name, '', fullPath) + : new Dir(name, [], [], fullPath); + updateFileTreeByPath(tmp.path, target, 'add'); + } setVisible(false); } else { Message.error(validMsg); @@ -116,6 +149,10 @@ const FileTree: FC = ({ }, [updateFileTreeByPath] ); + let title = tmp.type === 'file' ? '新建文件' : '新建文件夹'; + if (tmp.operation === 'rename') { + title = tmp.type === 'file' ? '重命名文件' : '重命名文件夹'; + } return (

@@ -133,6 +170,16 @@ const FileTree: FC = ({ title="编译代码" onClick={onSave} /> + {actions?.map((item) => ( + + {item.icon} + + ))}

@@ -143,20 +190,18 @@ const FileTree: FC = ({ onChange={onChange} onAdd={handleAdd} onDelete={handleDelete} + onRename={handleRename} modifiedKeys={modifiedKeys} - selectedKey={getKeyByPath( - currentFile.path, - currentFile.file?.name || '' - )} + selectedKey={currentFile.file?.fullPath} /> handleAddFileToTree()} + onOk={() => handleEditFileToTree()} >
= ({ autoFocus value={value.name} onChange={handleChange} - onKeyDown={(e) => handleAddFileToTree(e)} + onKeyDown={(e) => handleEditFileToTree(e)} />
diff --git a/packages/plugin-multiple-editor/src/components/MonacoEditor/index.tsx b/packages/plugin-multiple-editor/src/components/MonacoEditor/index.tsx index b514143..285079e 100644 --- a/packages/plugin-multiple-editor/src/components/MonacoEditor/index.tsx +++ b/packages/plugin-multiple-editor/src/components/MonacoEditor/index.tsx @@ -3,6 +3,7 @@ import BaseMonacoEditor from '@alilc/lowcode-plugin-base-monaco-editor'; import type { editor } from 'monaco-editor'; import './index.css'; import { Monaco } from '../../types'; +import { editorController } from '@/Controller'; export interface MonacoEditorProps { theme?: string; @@ -33,6 +34,11 @@ class MonacoEditor extends PureComponent { componentWillUnmount() { window.removeEventListener('resize', this.handleResize); + editorController.onImportSchema(() => { + setTimeout(() => { + this.editor?.getModel()?.setValue(this.props.value || ''); + }, 500); + }); } componentDidUpdate(prevProps: MonacoEditorProps) { @@ -53,13 +59,6 @@ class MonacoEditor extends PureComponent { minimap: { enabled: this.props.isFullscreen }, }); } - // base editor 的bug,value 改变编辑器不会更新,暂时这么解决 - if ( - this.props.value !== prevProps.value && - this.props.filePath === prevProps.filePath - ) { - this.editor?.getModel()?.setValue(this.props.value || ''); - } } initMonaco = () => { @@ -76,13 +75,15 @@ class MonacoEditor extends PureComponent { // compiler options monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ target: monaco.languages.typescript.ScriptTarget.ES2020, - module: monaco.languages.typescript.ModuleKind.ES2015, + module: monaco.languages.typescript.ModuleKind.CommonJS, allowJs: true, allowNonTsExtensions: true, + moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs, noEmit: true, esModuleInterop: true, jsx: monaco.languages.typescript.JsxEmit.React, reactNamespace: 'React', + typeRoots: ['node_modules/@types'], }); monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true); @@ -90,15 +91,21 @@ class MonacoEditor extends PureComponent { const openEditorBase = editorService.openCodeEditor.bind(editorService); editorService.openCodeEditor = async (input: any, source: any) => { const result = await openEditorBase(input, source); + const { selection } = input.options; if (result === null) { this.props.onGotoFile?.(input.resource?.path); - // console.log('Open definition for:', input); - // console.log( - // 'Corresponding model:', - // monaco.editor.getModel(input.resource) - // ); + // 定位到对应文件位置 + setTimeout(() => { + const position = { + lineNumber: selection.startLineNumber, + column: selection.startColumn, + }; + this.editor?.revealLineInCenter(position.lineNumber); + this.editor?.setPosition(position); + this.editor?.focus(); + }, 50); } - return result; // always return the base result + return result; }; window.addEventListener('resize', this.handleResize); }; diff --git a/packages/plugin-multiple-editor/src/components/Outline/img/class.png b/packages/plugin-multiple-editor/src/components/Outline/img/class.png new file mode 100644 index 0000000000000000000000000000000000000000..a61249b24a2cda32ec95366207fffb209daa8ce3 GIT binary patch literal 2229 zcmdtkYcy0_902e$930X$L%Ad5c$H^0rf4ELj2Vyg6p}}cOzt8Rbt@X085UDsQ}Sv& z3SHHWlDwalGG!zsiAb6up@+vzk>(z2-H-Rn{d8OR!`}Zdd+ojU{_o#^?=w5LQJ1Q$ zPyqm7sjCZl7a9eN4N^q=QlGMXG+>VIqB;U)Pjtor0Aje35zmtWlX-_DwQaBpZ_NhH zdmdR7SV$UuGP>O^ci$ki4qM|ov?L4$*!>_jegMO^ zMZ+Wp10GOwfGI2uqlYOwogvue+@-zrWPsCJL%0rMKvVVg?a4R?9^QtsT%QFybLcq) zIY|B8!>a}$w%FyV1(5W_YMp=I~wWoBu#PKas}B;ww_2kl6$1hj-)|t!j;oYAP zzS17^QjnclTj0d|L6B{%k`%_?_!5&<=XoV|PHe_8iP-FIzT|e?eA%er{T?g#n6vYS z*kYTm9?=f9(%L{TNy*oFjgowWR8GSJ|Gt2{k|`-V1%hMRzi@J=nZx~_gRITdE4uWg zdes`6s;p<-nIA+iZzcD#6ggqdjeW6=9i0W>y=L5mf;vJzUj&X&7ItHwi+eXY@|?li z8sV|;MD25;f%facKh!Zus}D5~rfFYTjdQ@_)^oTm!gd^46^oGfkBA`yMJ{ZxZaNag z$&<0T>?jh4i!tCr!Ui3r6~K`}dO#{nV?hRT#I;l`!2!gvbFvJ%c=*4Z#!%ty0^EFW zXaTO4hy_bc>W)-0Jx|*eNXFKIiU$1Tp!4ngS3(Hp?%jWf?+zf5QAEBL zJ6M5ms&7al<5*1F?XB2cbFAK7h4wwS&p5xed?u9`8csrl+fqX#rk^Sjl|NS27s4O6 zYl)U2ya@34=YtP!EgsX$Cf||R@Wt)Bj$Wq9@NZ6}%vXgSUX(DC=B;^9N$S5~+H|^5 zc>9DQ^o$<@ckBB7lYwd_ng5R-Ctf`nC(`NE;5(xXg8ybPya4|iMhSC}M|AWm`!vQ& zJ5^+qTi!=AvwYfm0-`ZHwj8?9^7`s&H(H&}J}P9e!pe=8)V?)w6qh8*UmG|^YJ;Yj z;fxF|4%c$0JrCe;kNl*!``=j8F%^uxjgWCIC(CoCaj)He7b#AZr&DIzrlW5DL7ct& zVjndZF5F-UzAZ1Zamt>%6uA%a4Sn+Gm!{~?df&N|z9FXSn_ zCS`pAsZ*E9r+^WsD;R;sPwZ2qaekL9&7e<8wPn3C-tdt#FJ$%G?U5?Ynw_#`t;a}y zjA!$Vv8DpNx@g!cT^cvjVf6hs^L+SbX(e^-W7V}A4-9qlAIHyTT%>sX*zjQz+l$mzVGQAC)&Y=N07Pe0+I%<#bX4YGB=Z z-zTVys2e$t&=lemDD6?GfwT=oEp-R%{ih+MG}J&jeU%ex0KdX=6n!V{dV~jE07TWP zNNk51XuFuBstj`vgxtxc0?3pPF!(%r_pzEWhmXshy^EH?uuNA!VBuy`ZF&2 ZRqqzvZ4~xmCZYcjz}0yhxy*4t=PxN2o*V!G literal 0 HcmV?d00001 diff --git a/packages/plugin-multiple-editor/src/components/Outline/img/function.png b/packages/plugin-multiple-editor/src/components/Outline/img/function.png new file mode 100644 index 0000000000000000000000000000000000000000..a8981266a86852c1891f35de738d2258d3d88fa4 GIT binary patch literal 3438 zcmV-!4UzJRP)Px?C`m*?RCr$PolSNdxekR@UQ(QSw^!CLD~mI?yd+m2>WNOZVyQ^r0t8rBlg??A zAb5eVK-TYa;*SbYfx8MU)P@RBf%^&&5M~Dzc%T3QVR}#j0>T`i0x|_yL1enI*Fh8@ zAO{IFrzul_fXH-XuY)K+Kn@aUPE)1;0g>s(UI$TtfE*;yoTf|x0wU9my$+%P0XayZ zd#CyR`}e;~pO24^%YUDqo?fesx3{;?fA`wW)}DZ5izZlteHA_HTFykPwg|DdRh+_tNT%*`?i& z5D?#7bsueX^{5lhT15zmd&>F_7@&H5PWXI2r^~l=4*RB8?$M%DkE-IbEHBya-69~l z8F=V@r0S9Nv@Zc6Af5`O+pH51&-8E}>-qV4bslnexNQ3n0XU~Mm+;^Pio$3a=;{vJmqNnkZk)8p2dos-Ado0!I5!!ML?8E z7`1yqILg}^)7{BSK%!>2!mo&MWPMnQfG83%V%Lap6rD2eJ!*V;nm1ym3w(+SN7khk z0TCo&)Gkrs$h@>7AW^fu(=Wo&DOhK7F0ncVi`1NO*hhna*lTPuLR2`i?>TORMLX)IecFU*Nx;~3AD;V6Q!&BGZpcNcj z&+ErK*LAJmDck~c`FQ8LuD{AhJ+r;zN)jPf5Q%C7`gp)GU|QjaBp~5KbUG1^aX}&= z29i6yJM+Nw>t31ZNZ=Gs01{lz!SRBP6K+ z(ZF#jmyWOCpA`=6ys|-(1`sVAo`7hRXuAxEmQaYfMVr&3WmgJ75O8<_f=HmqXMj-i z%K}MwKu~a$q_f_nqmrli8aaWadyv~Bb>ul#Uqb_egu^-*M}eaxPV4ojmNQ1yacS`( z*TDKN2 z2+5x+nF4|i@{#V!^;%xtrUW7RuOeoE5RR5(_Wd@a04W|>9*By4^qDzJs7(Mt3t$~E zR5Bt1rS$1lyMM9P9GxRb?YD<5I3UOeh&+yFs7i+pkkqg02OD}{K#??vj~hNd2aoX*tm&<=`AVf<(5SppnxE&hcz51UoC=Cle8zn@A=VV zFOGV!ELmQVp`-oMD*2n4t+E*wbEy3Iq z(*uqxAnTqlkN%Dh#G|pU)vi1o_4!C`xg&R7*I)1N@0X_v_kP+0^q8;K$Eya=iiZY7 zm2_TkXqQ(W$+DO5lD}&c&|}_OAB!%?WmXtKyx`Do3_X%WlKicGv3i11ObQ_Bq(1qLZX2Ky@aX2 zg5ZE3w4fD4yARnOH9htuh$_-^L@kN=@$vEZ%_~F8t?4DO=I_ug<7nZq00aexg>P^` zP)BBuN`mxtuadNkWqnXUz=2-EAmOmk4-Uw+il}b{tkuL~(%VYalDMt=fqRhjB!Sg@ zL2y8qFg?07!~nYY_&gcYFmQJhR4`_MM3MyP)2P6Bz>-j+%cDfxtKi*9eC=RTL5gkU zkvZ#fOPU18DguN9Rz0M;+)HvRI4*lbDOoN3jtogzt4p5?M*)I_1LadDILrabSV_82Cu^HKL4x3O|rVp&~xus*wmOt=n6MAZZ7E8+MZEq6e&ZQRlOr#(<4)q`;C zsVe{b5I_jY*8w9OI9=pO{I};YKnTfAAeQCj?d|Py<6`TNm7`TDdAp&25R(4~j+G-` z<)|JF2ju9G5RSNTTn=9H;)Csp-VCG8#C$bNl&^#%HXNY&z;x*_w@Ai+I#voIvhw~rDyT*DBM}{c?~2P2VF_fPwGkL)YAu4s1GQ+XeAfxs@F`NRBo(V^2I}02U zw6yktfLJShW1nz13$7fFfG7p*=}tI$)QZuTfH=j0a5xDK9)^H`1^vn#;cyVyXb1vg zBy2THIE)20Hcvnd1tuJZ;yRfoAVxwH4kKZm%@Pm;!3l?fsDn%r5U}us11#uZa|8q! z0Kx$jGl(ey0ty7-00|k)3;_WIgm3^v3~GXaC<8+{lmZ6tPCyg^A{+|wl5`~?!axxY zp>WB%5fDMZ2!}wlq+JL|XW$4&r(nsOA0CjB@Y|P7FUwNi(*F5d*Y#I@0X5-Bp6vqn z4-1Ik)j{P0o1brO7ihhO?uX01<#8Q}#};$nWQZPIMAuhXG_X7$si_ zM?Pu}0SMv9mzYsJo*oe7$6lmCW95)4H@@H0fDn%H36|Z1X#pV|*;6xy|5F0OJx7e> zn!$_d06|{NlLnZ34ykhS`b`JO=%p3mh?nFVkEQ}7K=pV%pU*FvfUs{Y1*QUIboD5q zjruK;SZSBXo7n(aM@!Eo*60Xe$Dam}0L!b-$VC0z8#Z;0VQm^fA}p_J%CL&e0}lZ) zh$R6r5Ot7A0%9aQmsv)_I-8vdkl`EjZR`k$b0!-NM?kEEU6z-(x3}^XB7cb$m^(Lq#FtAY<3zzB3(&8 zold-I(K(T=hMNYEBGB{mbBI&D+<#c5tH0f;0Ew~>;quBqk*!9Y3XmXGgv%?dY#m^C zIzUEO5iYL=WU=9p1OzB9Z&Cz`8N}3dfD~OvRT1tzf@C$&jVS@S?nPX0J>k*{n3aJ{ zO$&(UbrCMD0%bJVm1zMfI(a}sIKUYh%-qy~SVKZMf@QOTJJSQQf#e_L?eN@l7-VBW zlZODL>W(LdyfkVyi`Y1k-0Kx}lS)kzfi7o2?yeeSru QyZ`_I07*qoM6N<$f;7D(F#rGn literal 0 HcmV?d00001 diff --git a/packages/plugin-multiple-editor/src/components/Outline/img/props.png b/packages/plugin-multiple-editor/src/components/Outline/img/props.png new file mode 100644 index 0000000000000000000000000000000000000000..97309a43a6410554786af3fa038b2f5fb6a5b1eb GIT binary patch literal 3458 zcmdT{S5VXY68JutdCkdHhh8)(GHE*O*fWeJc1BJ2FrT}%`K=xhY?j4(j65J(Uu z4#6_v@z|3i6^{roklxxwv&jea8Cr|)J|ytmN9-}rgoErJ{$jE)V34KFwL?)L?u>Sc zq7{G?gS19^mBIf!8LNQpoL=gDJF&1ep0i^%UW}>V7|6pkyOj^D{=f`PkH%=x)hvGv zxWZ7?Dwf!n>S`?rxOo3Me^s-BQVSd|e*PxMwW}18*vFV&+Gu_|@p_o0OY`VZ^`WGz z=56yM+m<%eEQL?3j~L!uX7C|+l>6{;pT7NdwtQeNsia8?jy6s#`C>CNUoHPmiT=w* z{g~JVJFEh31a{uw$+1y8&KYhp1~ZH=7)suZUL)b@(xtw&6b5m4#I3Q|jhNx6CA)d>)03Fe6I^k0!{u0;@77 zm~n?UCABmPm!MGvQm(1HN`(8o*J5}|7+r(O4Vu8E_gY#(i^LetViQO<`)I?Hj*WS& zZB;juBKHBsO*pZ0ZrNL=KT?E5Oy={k7lhgcI)}ubisOHcYv5jjL>8OaPO^;eHnP<_ zMxMmkr$Jwi3-rhY?qX;tUNX^70Bih%;Vyxc9+rmU1>oo$`t8SvxGsI*E*uyb0yIzZ zK=E(^|J^WdSe(_LuRp+AXRtsMb)rs(F20`&YYgMo=0@k-2CYh;KYs=8G)oOg^sSG@ z_~F%S-b+l6*BrwWztTiN~Ay%&)$K1I^9TlISm62j7f7*VYa=&5icpBf#Zo zsg)ON4{HaYMSMT{k9Jn<-IKdIa^IOyOFUSjQ3#9c;@$14qUojbhuuE^sdz3t1Ppp# zpA*Y-XiDiJ++A_4az0)We`8iFrTao)>beVhdcz%O(5|_F7V?(WtdHS!TQSEvO*bj?cR<`ZC z+~LARBgAf~1YU;bgAbK===>Gc>~eE=-;?OZaaD@OM}tf^j#^N|>s6~4>{w{Rv#HEy z4}{B4IIAjpBia{PJU*CokmhXXk8J0_9PzcM1eI@GI5F}&VtjLA0ez#T5gt!HeD46} z!3|!^JQ!~KjjVGHHt@8RJ>Echj>M0mx4x+ir?zMP_IvAt*6p+6&u$>az+tUeH;Wzx z?~XU7oevgNYuFDOBCoU+HxxoJv_>s=>I97_=(mtm)D6M0_!ffWnt5uO&92>!<#>hV z@c-f8>EW~qhn$MoS>L5{Da9&)DJFYs85>RK7eAq%g2CAb88aN3Tz!RxJzZum*~YCO z@X86x5aq?&VTe$EW9pG}+kEeZ;Qrya!h!ZyP4!y=IzY?BA) zJWcQGA=(@&&-O`v@&4(d6I!Vu2xQhz9+=Mi745UPif&G2 z8b73Q3MwxztINkJX}zucl;WPb@_C}i$BTyHD2f7Wh&KtJu*Q;7Mr)csDZ-4p%V!Xy zN=3;-NGvx7U`4gIYec*q4$1CgFc(8p%LeThm2YBNiEk^cqrTbAD5?25-__!USO#pj z$a{x> ztA3D{+z0mZ21FRKAUD;M()b5cRNX-F-fpc+$}|TOAjsApNNuO%mvh)X$-6 z_*`wDl)*i+nk0SmR~Dyh32YaSi>RKa7;TdxB*B$*|6>JJyf_dn;-9cHhUIJwH?e~! zKNa;zzn8HXgXL-h%3rz&X4)*_N#I!hc7-dfcnnOc+>+WkyD*$}(jtKI)uphqfjMf@)?m79A}UXMg2_e2*XSBRhbXZ)Au1Vd+G9o@lqo}^1w|fuRio;= zrGGG+I@l)tOuy%sUcCpcMOm-ig45DQbrkd|Oa0Gs8&jzdQ>lTSY+7Iw5hP)By*Jtvyen32od z!Cu{B`bA5fF$b;AR{B?CAmtjDh~wtWMViBt>;#Ic`=f^qc6K1$FP$RU8oquN-@J}u zO-0Z+(<4rLecX(6;AsE2C}ivY>%tY8g4v*;fW$2E=)~CuGxcIAr>p0ago{@T{nkga zt&a|L2($GQXHVa1Mf^FWR~ur#42d4o&G)7c)g)HeL4B56e|i|c1?$y|g( z=JJE9`fLpier`f#u+XdEphBlVk&i7f-nZ+$KFj2V+`CbuJTj$Cg6Hno8)-l|pMI^J zxFy2q)^bb0(#;&IMhwlrP3k-f!o?mYj-Ah*?co|7l#9I}+iSIXA;W@y@0+3gLv*F? z5_h?w5;2jwzDB|y?uDmF$FzZ)Kwb$hJ7*|k-gtY?_fMW zwDH%4n9CDUY#Y{mw*kZ&^6F|<#dau-!|oU%imB_FmM6q8$njOv+U_n#xc_9^g`nLt zFG{MO`<3#c7kD_g~;E_A;Mb2#}bW%3aNq+?%ICpIkn#Ic@Cm`wt7uA3y>x(dt?;*>l`V6tpUQ3fN+FdMy<=r)vcZK zZC*gG(shp$p6iif^`Y+^b#`GR(C;#+BR})W`MxXNy$7656;R{WLJi?5exa(ujMl=L zi{E2r^N<%Epnid4X8hHULPM7m0J$>d*ePs>H}jS3GrY(!Z%k9L!H=lD{^B)G2vVta z_uTQZGNrk-xz5d$^J-S3c3?Q zY5tl=^65Eo40nNjBDBHTpzHp$^`c^r{YImI(|TK;g7IhW(?{Z!DRzGw_jWnH8JUH7 z63Ug>I6n6UsYiFaa#4C-mkr+o9N}x7iOTIy)wgUlcO>R%`%1Y1p?LUn*ukv2;XVsv z)wD%ovKVB%K*$MmaHH4zcISO(cCT!|+I(pKVh2Gwp42sJi3B)Xf0d3rK=)h{=kVJB k$Y3gu>4yUU_wH>$7Q*Yu9G5A1_o)J8qcemugLAk31%1mFZvX%Q literal 0 HcmV?d00001 diff --git a/packages/plugin-multiple-editor/src/components/Outline/index.less b/packages/plugin-multiple-editor/src/components/Outline/index.less new file mode 100644 index 0000000..e9cc659 --- /dev/null +++ b/packages/plugin-multiple-editor/src/components/Outline/index.less @@ -0,0 +1,93 @@ + +@leftWidth: 200px; + +.ilp-multiple-editor { + display: flex; + flex-flow: row nowrap; + height: 100%; + width: 100%; + background-color: #fff; + position: relative; + box-sizing: border-box; + padding-left: @leftWidth; + &-outline { + position: absolute; + left: 0; + bottom: 0; + border-right: 1px solid #efeffe; + } +} + +.ilp-outline-node { + width: 100%; + overflow-y: auto; + line-height: 24px; + font-size: 12px; + color: #333; + &-title { + &-content { + display: flex; + justify-content: flex-start; + align-items: center; + flex: 1; + cursor: pointer; + -webkit-user-select: none; + user-select: none; + } + &-prefix { + margin-right: 4px; + transition: all 0.2s; + &-expand { + transform: rotate(90deg); + } + } + } + &-title, + &-file { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + cursor: pointer; + transition: all 0.15s; + position: relative; + &:hover { + background-color: rgba(0, 0, 0, 0.05); + } + img { + width: 14px; + height: 14px; + } + span { + margin-left: 4px; + } + } + &-file { + position: relative; + &-selected { + background-color: rgba(62, 180, 189, 0.15); + } + } + } + .ilp-outline-bar { + width: 200px; + padding: 8px; + height: 100%; + &-title { + font-size: 14px; + height: 24px; + color: #333; + margin: 0; + display: flex; + justify-content: space-between; + align-items: center; + } + } + .ilp-outline-nodeList{ + width: 100%; + overflow-y: auto; + height: calc(100% - 24px); + line-height: 24px; + font-size: 12px; + color: #333; + } \ No newline at end of file diff --git a/packages/plugin-multiple-editor/src/components/Outline/index.tsx b/packages/plugin-multiple-editor/src/components/Outline/index.tsx new file mode 100644 index 0000000..6cdcd37 --- /dev/null +++ b/packages/plugin-multiple-editor/src/components/Outline/index.tsx @@ -0,0 +1,145 @@ +import { parse, generateOutline } from '../../utils/ghostBabel'; +import './index.less'; +import cls from 'classnames'; +import React, { FC, useEffect, useMemo, useState } from 'react'; +import { Icon } from '@alifd/next'; +import classIcon from './img/class.png'; +import functionIcon from './img/function.png'; +import propsIcon from './img/props.png'; +import { focusByContent } from './utils'; +import { editorController } from '../../Controller'; +export interface OutlineProps { + content?: string; + className?: string; + filePath?: string; + ilpOutLineStyle?: any; +} +export interface DirProps { + children?: DirProps[]; + name: string; + type: string; +} +export interface OutlineNodeProps { + disableAction?: boolean; + node: DirProps; + selectedKey?: string; + level?: number; + className?: string; +} +const Outline: FC = ({ + content = '', + className, + filePath, + ilpOutLineStyle, +}) => { + const iconMap: Record = { + FunctionDeclaration: functionIcon, + ClassMethod: functionIcon, + ObjectMethod: functionIcon, + ClassProperty: propsIcon, + VariableDeclarator: propsIcon, + ObjectProperty: propsIcon, + ClassDeclaration: classIcon, + }; + const [dir, setDir] = useState([]); + const [path, setPath] = useState(filePath); + useEffect(() => { + try { + const ast = parse(content); + if (ast && generateOutline(ast)) { + setDir(generateOutline(ast)); + } + } catch (e) { + if (path !== filePath) { + setPath(filePath); + setDir([]); + } + } + if (path !== filePath) { + setPath(filePath); + } + }, [content, filePath, path]); + const OutlineNode: FC = ({ + node, + className, + level = 1, + }) => { + const [selectedKey, setSelectedKey] = useState(); + const [expand, setExpand] = useState(true); // 根目录默认展开 + const levelStyle = useMemo(() => ({ paddingLeft: level * 8 }), [level]); + const onRelatedEventClick = (event: any) => { + setSelectedKey(event); + focusByContent( + editorController.codeEditor!, + event, + editorController.monaco!, + filePath! + ); + }; + return ( +
+
+
{ + onRelatedEventClick(node); + }} + > + {!!node?.children?.length && ( + setExpand(!expand)} + /> + )} + + {node.name} +
+
+
+ {expand && ( + <> + {node?.children?.map((f) => { + return ( +
{ + onRelatedEventClick(f); + }} + className={cls( + 'ilp-outline-node-file', + selectedKey === f.name && 'ilp-outline-node-file-selected' + )} + > + + {f.name} +
+ ); + })} + + )} +
+
+ ); + }; + return dir?.length ? ( +
+
+

+ 大纲树 +

+
+ {dir?.map((item) => { + return ; + })} +
+
+
+ ) : null; +}; +export default Outline; diff --git a/packages/plugin-multiple-editor/src/components/Outline/utils.ts b/packages/plugin-multiple-editor/src/components/Outline/utils.ts new file mode 100644 index 0000000..4f5a460 --- /dev/null +++ b/packages/plugin-multiple-editor/src/components/Outline/utils.ts @@ -0,0 +1,59 @@ +import { Monaco } from '@/types'; +import type { editor } from 'monaco-editor'; +export function focusCodeByContent( + editor: editor.IStandaloneCodeEditor, + content: string +) { + const matchedResult = editor + ?.getModel() + // @ts-ignore + ?.findMatches(content, false, true, false)?.[0]; + if (matchedResult) { + setTimeout(() => { + editor.revealLineInCenter(matchedResult.range.startLineNumber); + editor.setPosition({ + column: matchedResult.range.endColumn, + lineNumber: matchedResult.range.endLineNumber, + }); + editor.focus(); + }, 200); + } +} +export async function focusByContent( + editor: editor.IStandaloneCodeEditor, + params: { + name: string; + type: string; + }, + monaco: Monaco, + path: string +) { + const regMap: Record = { + FunctionDeclaration: 'function', + ClassMethod: 'function', + ObjectMethod: 'function', + ClassProperty: 'declarator', + VariableDeclarator: 'declarator', + ObjectProperty: 'ObjectProperty', + ClassDeclaration: 'ClassDeclaration', + }; + const modelUri = monaco.Uri.parse(path); + const model = monaco.editor.getModel(modelUri); + editor.setModel(model); + let content = ''; + switch (regMap[params.type]) { + case 'function': + content = `\\s*(?:async)?\\s*${params.name}\\s*\\([\\s\\S]*\\)[\\s\\S]*\\{`; + break; + case 'declarator': + content = `\\s*${params.name}\\s*=\\s*`; + break; + case 'ObjectProperty': + content = `\\s*${params.name}:\\s*`; + break; + case 'ClassDeclaration': + content = `${params.name} extends`; + break; + } + focusCodeByContent(editor, content); +} diff --git a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts index 921cd03..faa1714 100644 --- a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts +++ b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/delete-hidden-transducer/index.ts @@ -11,6 +11,6 @@ export const deleteHiddenTransducer = (ctx: any) => { }, IPublicEnumTransformStage.Save); }, }; -} +}; deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer'; diff --git a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx index 916ba2e..7999e65 100644 --- a/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/sample-plugins/scenario-switcher/index.tsx @@ -1,29 +1,28 @@ import React from 'react'; import { Select } from '@alifd/next'; import scenarios from '../../universal/scenarios.json'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const { Option } = Select; const getCurrentScenarioName = () => { // return 'index' - const list = location.href.split('/'); + const list = window.location.href.split('/'); return list[list.length - 1].replace('.html', ''); -} +}; function Switcher(props: any) { return () + ); } -export const scenarioSwitcher = (ctx: IPublicModelPluginContext) => { +export const scenarioSwitcher = (ctx: any) => { return { name: 'scenarioSwitcher', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx index a564038..1abe147 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-antd/plugin.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { plugins, + skeleton, project, + setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -31,7 +33,6 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { // await plugins.register(ManualPlugin); @@ -45,7 +46,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: IPublicModelPluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -71,7 +72,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -115,7 +116,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: IPublicModelPluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -153,7 +154,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: IPublicModelPluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -178,7 +179,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: IPublicModelPluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -206,7 +207,7 @@ export default async function registerPlugins() { ), }); - hotkey.bind('command+s', (e) => { + hotkey.bind('command+s', (e: any) => { e.preventDefault(); saveSchema('basic-antd'); }); @@ -223,10 +224,10 @@ export default async function registerPlugins() { // await plugins.register(CodeEditor); // 注册出码插件 - CodeGenPlugin.pluginName = 'CodeGenPlugin'; - await plugins.register(CodeGenPlugin); + // CodeGenPlugin.pluginName = 'CodeGenPlugin'; + // await plugins.register(CodeGenPlugin); - const previewSample = (ctx: IPublicModelPluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -250,7 +251,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: IPublicModelPluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx index d500cb3..ca06e11 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion-with-single-component/plugin.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { plugins, + skeleton, project, + setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -31,7 +33,6 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -45,7 +46,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: IPublicModelPluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -71,7 +72,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -115,7 +116,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: IPublicModelPluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -153,7 +154,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: IPublicModelPluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -178,7 +179,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: IPublicModelPluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -230,7 +231,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: IPublicModelPluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -257,7 +258,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: IPublicModelPluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx index d8f3b65..8e7103f 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/basic-fusion/plugin.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { plugins, + skeleton, project, + setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -31,7 +33,6 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -45,7 +46,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: IPublicModelPluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -71,7 +72,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -115,7 +116,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: IPublicModelPluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -153,7 +154,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: IPublicModelPluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -178,7 +179,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: IPublicModelPluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -227,10 +228,10 @@ export default async function registerPlugins() { // await plugins.register(CodeEditor); // 注册出码插件 - CodeGenPlugin.pluginName = 'CodeGenPlugin'; - await plugins.register(CodeGenPlugin); + // CodeGenPlugin.pluginName = 'CodeGenPlugin'; + // await plugins.register(CodeGenPlugin); - const previewSample = (ctx: IPublicModelPluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -254,7 +255,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: IPublicModelPluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx index a30ea02..ab2d80c 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/next-pro/plugin.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { plugins, + skeleton, project, + setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; @@ -33,7 +35,6 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; export default async function registerPlugins() { await plugins.register(ManualPlugin); @@ -51,7 +52,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: IPublicModelPluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -77,7 +78,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -121,7 +122,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: IPublicModelPluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -159,7 +160,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: IPublicModelPluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -184,7 +185,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: IPublicModelPluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -228,7 +229,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: IPublicModelPluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -252,7 +253,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: IPublicModelPluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx index 2dd8e88..89e23f7 100644 --- a/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/scenarios/node-extended-actions/plugin.tsx @@ -1,6 +1,10 @@ import React from 'react'; import { plugins, + skeleton, + project, + setters, + Node, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Icon, Message, Button } from '@alifd/next'; @@ -30,10 +34,9 @@ import { } from '../../universal/utils'; import assets from './assets.json'; import schema from './schema.json'; -import { IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types'; export default async function registerPlugins() { - const addHelloAction = (ctx: IPublicModelPluginContext) => { + const addHelloAction = (ctx: any) => { return { async init() { const { addBuiltinComponentAction } = ctx.material; @@ -42,12 +45,12 @@ export default async function registerPlugins() { content: { icon: , title: 'hello', - action(node: IPublicModelNode) { + action(node: Node) { Message.show('Welcome to Low-Code engine'); }, }, - condition: (node: IPublicModelNode) => { - return node.componentMeta?.componentName === 'NextTable'; + condition: (node: Node) => { + return node.componentMeta.componentName === 'NextTable'; }, }); }, @@ -56,7 +59,7 @@ export default async function registerPlugins() { addHelloAction.pluginName = 'addHelloAction'; await plugins.register(addHelloAction); - const removeCopyAction = (ctx: IPublicModelPluginContext) => { + const removeCopyAction = (ctx: any) => { return { async init() { const { removeBuiltinComponentAction } = ctx.material; @@ -78,7 +81,7 @@ export default async function registerPlugins() { (SimulatorResizer as any).pluginName = 'SimulatorResizer'; plugins.register(SimulatorResizer); - const editorInit = (ctx: IPublicModelPluginContext) => { + const editorInit = (ctx: any) => { return { name: 'editor-init', async init() { @@ -104,7 +107,7 @@ export default async function registerPlugins() { editorInit.pluginName = 'editorInit'; await plugins.register(editorInit); - const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { + const builtinPluginRegistry = (ctx: any) => { return { name: 'builtin-plugin-registry', async init() { @@ -148,7 +151,7 @@ export default async function registerPlugins() { await plugins.register(builtinPluginRegistry); // 设置内置 setter 和事件绑定、插件绑定面板 - const setterRegistry = (ctx: IPublicModelPluginContext) => { + const setterRegistry = (ctx: any) => { const { setterMap, pluginMap } = AliLowCodeEngineExt; return { name: 'ext-setters-registry', @@ -186,7 +189,7 @@ export default async function registerPlugins() { // 注册中英文切换 await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: IPublicModelPluginContext) => { + const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', async init() { @@ -211,7 +214,7 @@ export default async function registerPlugins() { await plugins.register(loadAssetsSample); // 注册保存面板 - const saveSample = (ctx: IPublicModelPluginContext) => { + const saveSample = (ctx: any) => { return { name: 'saveSample', async init() { @@ -259,7 +262,7 @@ export default async function registerPlugins() { // CodeEditor.pluginName = 'CodeEditor'; // await plugins.register(CodeEditor); - const previewSample = (ctx: IPublicModelPluginContext) => { + const previewSample = (ctx: any) => { return { name: 'previewSample', async init() { @@ -286,7 +289,7 @@ export default async function registerPlugins() { previewSample.pluginName = 'previewSample'; await plugins.register(previewSample); - const customSetter = (ctx: IPublicModelPluginContext) => { + const customSetter = (ctx: any) => { return { name: '___registerCustomSetter___', async init() { diff --git a/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx b/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx index c55ddff..936fa1a 100644 --- a/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx +++ b/packages/plugin-multiple-editor/src/dev-config/universal/plugin.tsx @@ -1,15 +1,11 @@ import React from 'react'; import { plugins, - skeleton, project, - setters, } from '@alilc/lowcode-engine'; import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; import { Button } from '@alifd/next'; import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; -import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; -import SchemaPlugin from '@alilc/lowcode-plugin-schema'; import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; // 注册到引擎 @@ -36,10 +32,6 @@ export default async function registerPlugins() { await plugins.register(deleteHiddenTransducer); - // plugin API 见 https://yuque.antfin.com/ali-lowcode/docs/cdukce - SchemaPlugin.pluginName = 'SchemaPlugin'; - await plugins.register(SchemaPlugin); - const editorInit = (ctx: any) => { return { name: 'editor-init', @@ -141,9 +133,6 @@ export default async function registerPlugins() { setterRegistry.pluginName = 'setterRegistry'; await plugins.register(setterRegistry); - // 注册中英文切换 - await plugins.register(ZhEnPlugin); - const loadAssetsSample = (ctx: any) => { return { name: 'loadAssetsSample', diff --git a/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts b/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts index e6e3af7..a3f734d 100644 --- a/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts +++ b/packages/plugin-multiple-editor/src/dev-config/universal/utils.ts @@ -1,7 +1,7 @@ import { material, project } from '@alilc/lowcode-engine'; import { filterPackages } from '@alilc/lowcode-plugin-inject'; import { Message, Dialog } from '@alifd/next'; -import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; +import { TransformStage } from '@alilc/lowcode-types'; export const loadIncrementalAssets = () => { material?.onChangeAssets(() => { @@ -252,7 +252,7 @@ const setProjectSchemaToLocalStorage = (scenarioName: string) => { } window.localStorage.setItem( getLSName(scenarioName), - JSON.stringify(project.exportSchema(IPublicEnumTransformStage.Save)) + JSON.stringify(project.exportSchema(TransformStage.Save as any)) ); }; @@ -296,5 +296,6 @@ function request( headers?: object, otherProps?: any ): Promise { + // eslint-disable-next-line @typescript-eslint/no-var-requires return Promise.resolve(require('./schema.json')); } diff --git a/packages/plugin-multiple-editor/src/global.d.ts b/packages/plugin-multiple-editor/src/global.d.ts index e238d01..8da7e27 100644 --- a/packages/plugin-multiple-editor/src/global.d.ts +++ b/packages/plugin-multiple-editor/src/global.d.ts @@ -1,2 +1,8 @@ declare module '*.png'; declare module '*.svg'; + +interface Window { + less: any; + prettier: typeof import('prettier'); + prettierPlugins: any; +} diff --git a/packages/plugin-multiple-editor/src/index.dev.tsx b/packages/plugin-multiple-editor/src/index.dev.tsx index 02fe5b5..b544dcc 100644 --- a/packages/plugin-multiple-editor/src/index.dev.tsx +++ b/packages/plugin-multiple-editor/src/index.dev.tsx @@ -10,6 +10,8 @@ import codePlugin from './index'; import { EditorController } from './Controller'; import registerAllPlugin from './dev-config/universal/plugin'; import { SearchPlugin } from './plugins/search-plugin'; +import { EditorPluginInterface, Service } from './Service'; +import { PrettierPlugin } from './plugins/prettier-plugin'; controller.updateMeta({ singleton: true }); @@ -17,15 +19,40 @@ controller.updateMeta({ singleton: true }); console.log((await getMonaco()) === (await getMonaco())); })(); +class TestPlugin implements EditorPluginInterface { + apply(service: Service): void { + service.registerAction({ + icon: ( + 111 + ), + key: 'hello', + action() { + alert('111'); + }, + title: '111', + priority: 0, + }); + } +} + async function initEditor(el: any) { await registerAllPlugin(); await plugins.register( codePlugin({ softSave: true, + useLess: true, // mode: 'single', es6: true, defaultFiles: { 'aspect.js': 'export default {}', + 'utils/index.js': 'xxx', + 'utils/u.js': 'xxx', + 'config/life/index.js': 'xxx', + 'config/life/a.js': 'xxx', + 'util.js': '', }, plugins: [ new SearchPlugin({ @@ -33,6 +60,8 @@ async function initEditor(el: any) { console.log(name); }, }), + new TestPlugin(), + new PrettierPlugin(), ], onInstall(controller: EditorController) { (window as any).codeEditorController = controller; @@ -62,10 +91,17 @@ async function initEditor(el: any) { }, 1000); controller.onEditCodeChange((v) => { - console.log('value change', v); + // console.log('value change', v); }); + + setTimeout(() => { + controller.addFiles({ + 'extends/index.js': 'console.log(1)', + 'extends/util.js': 'console.log(2)', + }); + }, 3000); }, - }) + }) as any ); await init(el, { locale: 'zh-CN', @@ -73,7 +109,7 @@ async function initEditor(el: any) { enableCanvasLock: true, // 默认绑定变量 supportVariableGlobally: true, - }); + } as any); } const LowcodeRender = () => { diff --git a/packages/plugin-multiple-editor/src/index.tsx b/packages/plugin-multiple-editor/src/index.tsx index 6b7b7dc..3e6363c 100644 --- a/packages/plugin-multiple-editor/src/index.tsx +++ b/packages/plugin-multiple-editor/src/index.tsx @@ -1,13 +1,18 @@ -import { project, editor } from '@alilc/lowcode-engine'; +import { project, event } from '@alilc/lowcode-engine'; +import { IPublicTypePluginConfig, IPublicModelPluginContext } from '@alilc/lowcode-types'; import { controller as baseController } from '@alilc/lowcode-plugin-base-monaco-editor/es/controller'; import { EditorProvider } from './Context'; import MultipleFileEditor from './MultipleFileEditor'; import React from 'react'; import { EditorController, editorController } from './Controller'; import { EditorPluginInterface, Service } from './Service'; +import { loadLess, loadPrettier } from './utils/script-loader'; export { editorController }; +loadPrettier(); +loadLess(); + baseController.registerMethod('getSchema', () => { return editorController.getSchema(); }); @@ -20,14 +25,16 @@ const pluginCodeEditor = ( onInstall?: (controller: EditorController) => void; plugins?: EditorPluginInterface[]; defaultFiles?: Record; + useLess?: boolean; } = {} ) => { - const plugin = (ctx: any): any => { + const plugin = (ctx: IPublicModelPluginContext): IPublicTypePluginConfig => { return { exports: () => ({}), init() { options.onInstall?.(editorController); editorController.es6 = options.es6; + editorController.useLess = options.useLess; editorController.defaultFiles = options.defaultFiles || {}; const schemaDock = ctx.skeleton.add({ area: 'leftArea', @@ -62,9 +69,10 @@ const pluginCodeEditor = ( schemaDock && schemaDock.disable(); project.onSimulatorRendererReady(() => { schemaDock.enable(); + const finalEditor = event; const service = new Service(editorController, ctx.skeleton); service.init({ plugins: options.plugins }); - editorController.init(project, editor, service); + editorController.init(project, finalEditor, service); }); }, }; diff --git a/packages/plugin-multiple-editor/src/plugins/prettier-plugin/index.tsx b/packages/plugin-multiple-editor/src/plugins/prettier-plugin/index.tsx new file mode 100644 index 0000000..cab4de5 --- /dev/null +++ b/packages/plugin-multiple-editor/src/plugins/prettier-plugin/index.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { EditorPluginInterface, Service } from '@/Service'; +import icon from './prettier.png'; +import { HookKeys } from '@/EditorHook'; +import { Message } from '@alifd/next'; + +export class PrettierPlugin implements EditorPluginInterface { + private service!: Service; + + apply(service: Service): void { + this.service = service; + this.service.registerAction({ + key: 'format', + title: '格式化', + icon: , + action: () => { + const currentFile = service.controller.codeEditorCtx?.currentFile; + if (currentFile?.file && window.prettier) { + const { file } = currentFile; + const { ext, content } = file; + const parseMap: any = { + js: 'babel', + ts: 'babel-ts', + less: 'less', + css: 'css', + }; + const formatted = window.prettier.format(content, { + parser: parseMap[ext as string], + semi: true, + singleQuote: true, + bracketSpacing: true, + trailingComma: 'es5', + // endOfLine: false, + plugins: [ + window.prettierPlugins?.babel, + window.prettierPlugins?.postcss, + ].filter(Boolean), + }); + const editor = service.controller.codeEditor; + editor?.executeEdits('', [ + { + range: editor.getModel()!.getFullModelRange(), + text: formatted, + forceMoveMarkers: true, + }, + ]); + editor?.pushUndoStop(); + service.controller.triggerHook(HookKeys.onEditCodeChange, { + file: file?.fullPath, + content: formatted, + }); + Message.success('格式化代码成功'); + } + }, + priority: 1, + }); + } +} diff --git a/packages/plugin-multiple-editor/src/plugins/prettier-plugin/prettier.png b/packages/plugin-multiple-editor/src/plugins/prettier-plugin/prettier.png new file mode 100644 index 0000000000000000000000000000000000000000..2d8e9d4a84a130fbce5db30054665e0cc1a71630 GIT binary patch literal 3377 zcmV-14bJk3P)Px>>q$gGRCr$PU2BjWRTchD&nAQzOtvQvKtMsnijts~C`F+qf)t{q1c>+mveOfS zc}!0>JQ4*hQA-I_Wp`%tfROE336?zMp(tpHR4GM8(9#6Lqe>-(JS2gcNwPpT*_l38 z2ZFn^Ju}^Rx_j>I-2U6=e&;*i`O-V-?t7Y`j$^dPyK%1AZt^mpaZLUC@m#?k>$^c>t>`AWCZM$O*Vl@6uRA#10 z9Zyc%u%sxamb|NknpZITRssA|dCLli88fYj=Tbf4pf?BAw*dw(-7s@_!tl=K&~1L! z1H=2L9J%@GH=EBS7zVx#P)KG@2Gdi)q;EZxk{vs0=D^ZdTaURrW8VgFV2VceaRxp$ zUPSO(2ZQd5Td51Y#oi0Hnh2bEsF6>+)Ce7t-?ZA-yFpFJZ3&T zbQMBOKt%gk(|!}bb=lJ)rV)k~YF@#}J_O)g;jI5(xJ9?j(<^cEM&@e-x-$TLX&{Jb zUT1&merX83L&UcM_9WMxSmyFSgDQmV^2a*|y0?zRD;U{F0h|$34oPqx(k=5mNw~aA z!?yv7T|FOQEw&@5LSi)5+j?30C4!&d+q3sIcJ6cD}wh^14j zWK%#HK(>xV%tsj@V!>rgCuD%v7WEvZm13)iF;|ku!TUh;fZm^4?6ZD$O6dd%OTozg7r>D< z7rR`s!sF?V?ArhiOy20bPy?@HU{=(GtL7v8N}Je`aC>*ZkjO3u;RXQj4VdqC*z`@e z8(R59=5!+Z8GsYraxyTm*FIwL@dJsWfI0bs6EeV|48>&cXF)NcJAuAf)(I|`@apt| zRLy_ouPnM{^5OP@z+PmvZQ38VmTjq5hhqdSrcE3fN5BiyHl+f4o>GrPt@8~TppnFC ztsDv{1IW>brm;{4XqxnLBvuBHqYq7EA!LBv$;??c(;5JCy)oyP30U1}rTZ%5ogZh1 z4IfxfWM2T#5iWR-f%w~ce>(De4=>JNbNJ*b9czhreid%s%J&vk0C1~rnX9~o2NUJn z0K1l~o6<2rGXHt75xw)R~vm$b~WU3L+*_L^ zJ*fAmz7$y19)Su*W+^~xJ%$GoX0v_T^xX2t0|D~@;@bcYW`1GzG_uJ8c(#We0O3)M zX~i@v^*6Wpf|1<_@Ymh`&N6exrlIe-J#q7tyTPD>ky!`e(g=P7JjF~`$8)LQH%Qsn zav=lw%AkU!RzMj*>h^?BP8lG4jit_@3?OxT!Y3zefGEbqaf!>N$+3UTT)*^<@TI7p zVRvHfCpgAIKS~~zkW0wd+9wfK{XzzadQ2RHFRrzdI4p7UiFL;km7Q&BuFv#?&&!Vw zbxivF(HpOLD|l>oMBfHz(wMkcbjy5SRH7WplTT!Ni6|XuUd9qVXKsipr*8u^X-wQc z-7+UfCCZ^Zg=F>)FfNWb@3p#R{v@iLz760ID;U|w0F2q!A0p|Sbj!RZM0{81ypcVJ zfGBUw>}HP5t-Mo7&Ah5gPI&v`<3OsE_P z&y>osA4WZdQrG~YilM+GQ$QIYGO6WEqzoWuUm|0r3=o;rawZZsK(#S(&P0p}!xQg5 zV)No%ZYA&PT6g3Gtu$YB@&|zq*o23t_nS{tleC!ZJKtuU(!dD2u)DQ42K)YLR=2aq zvZ;rV0qTy4V-z`tx$#ZrOCzh>y&(HRJBGgpvqOiM=~mi#RzK<}7}*B_jM=Q&RF$hF zw+WxFW#lM0`!;~rF>wsOGH#`v7f0Vc@`>z^h;UsXg)yGibLPpT3}*D4U?cYLK=300 z;hS|Uy*QFoRg(BNfcG(Rv{<)NH;>Hg@dZ#%dJyo}PRks%)vK_m_c)Za7d!z-5X8Wm zxMg11Oe($&;E*jEnN19;wXONFHwQ~!sGN+ob7AkSiMF;afK8=)iSd=rocSl0KLHy7 zT;5DkJ?8$GT`GNU`fV#-_81>Zn2-S+CeAolK$~6pLrVj;bz15Bs5U+}8NEffU>KsCmW&Rp8rIo$L^*Z@sut_TF8fHFWJGPW*=GC=G0E)eF* z0D;KZx*$RZ2xUwhgPE|kq}eyj+O*vD!<2mDiYP)fY$;_o} z(|nNdc$u0b>>A|W@Nyvogghp0yKb3tDl5w;`UZ%2LBkbS1L&~duWwxbpOL2zHlOLX zKyngR>HX&FK(GP?@oj)8#>AC7%16)G*zHW&diTg1*_{N;46yb}s4*K?3r62B-rlm- z_`$#=yR_OS)A?k~sN>+3$1dLvrl98pyg}gax(%;* z` z=x(Fu1lBr^^8!~HQ$}g$^iAE*imZ)dO+yBVf}qL~t^&#c;p!_rx-x+DEee;QGC;Wc zN{=pNfZAi?_;r9b>Xvz}TlIxxW;K`=0??&bXCy)5tz^@3w|5X)s*Vb>z761YOq|=N zQj13RG6tl04ldZVJ-TI16I?6hGT#R9F(z)zCdYg-vxb1{Ha571_Y`Zj<=)_F6yWS3VH;Q|-(+ijqGx@A7> zR+#gE#b&yWfRmb8xIpgB6NV>TRc*h60G<>}gbW}Bb44N$1(X2-k+F3_lmS||cY!ch z1_(sP)&&tZKs$|zYu)zNXD(!bb{P{_U%u9l@NIy08WY$0?X6#dZv(W`n7I1#wSI(e z12`qO%b2*A>w&9 zaorC_#8~_Dv|P&h_>$}K_Gj8--vW*PC<8$o8rI6WY7;|RRdktn3mZVDA`};K1(X5A zwHp^Jl>x>@8^w!I1`yY7T&xr_KqzD4T;yb+OhjAC{MPCj*2=+gp}1s42pJ&cF>!7Z z{Z_ZkFH5G~xS-?P08xyIb5mBgOy69`MTbHz!nddqjEQqA`6=Bp=Z36BTf+M`z`>h9 z$?O$ijQSc#i0W+v@g;hHdV7dD+7?>K0FGMD>*1x2;n|3hFh)JqZSYWhllhl=aq7Id z0--feoRV4@r2@(TQK~IrE@c1-n-V1@Wq>HvmN1txfP_tnl9Dn&lxjnaQU;K)DN#~V28dE^33L4qgx3YV?INrR00000NkvXX Hu0mjfB { + if (!filepath) return; // 只需要初始化一次 if ( filepath.replace(/^\//, '') === 'index.js' && diff --git a/packages/plugin-multiple-editor/src/plugins/search-plugin/search.ts b/packages/plugin-multiple-editor/src/plugins/search-plugin/search.ts index 0a16eed..b3c3c6a 100644 --- a/packages/plugin-multiple-editor/src/plugins/search-plugin/search.ts +++ b/packages/plugin-multiple-editor/src/plugins/search-plugin/search.ts @@ -37,6 +37,9 @@ function getMethodFromNode(node: any): Methods { // 合并一个节点数组,例如 slot 的元素列表 const mergeNodeList = (list: any[]) => { + if (!isArray(list)) { + return; + } for (const item of list) { mergeMethod(methods, getMethodFromNode(item)); } diff --git a/packages/plugin-multiple-editor/src/types/index.ts b/packages/plugin-multiple-editor/src/types/index.ts index 4682325..9f07652 100644 --- a/packages/plugin-multiple-editor/src/types/index.ts +++ b/packages/plugin-multiple-editor/src/types/index.ts @@ -1,7 +1,9 @@ +import { IPublicTypeJSExpression } from '@alilc/lowcode-types'; + export type Monaco = typeof import('monaco-editor/esm/vs/editor/editor.api'); export type ObjectType = Record; -export interface IState { +export interface IState extends IPublicTypeJSExpression { originCode?: string; } diff --git a/packages/plugin-multiple-editor/src/utils/code.ts b/packages/plugin-multiple-editor/src/utils/code.ts index 796f89d..0f76a26 100644 --- a/packages/plugin-multiple-editor/src/utils/code.ts +++ b/packages/plugin-multiple-editor/src/utils/code.ts @@ -1,3 +1,4 @@ +import { IPublicTypeProjectSchema, IPublicTypeRootSchema } from '@alilc/lowcode-types'; // @ts-ignore import prettier from 'prettier/esm/standalone.mjs'; import parserBabel from 'prettier/parser-babel'; @@ -23,7 +24,9 @@ const prettierCssConfig = { printWidth: 120, // 超过120个字符强制换行 }; -export const initCode = (componentSchema: any | undefined) => { +export const initCode = ( + componentSchema: IPublicTypeRootSchema | undefined +) => { return ( (componentSchema as any)?.originCode || `export default class LowcodeComponent extends Component { @@ -72,6 +75,6 @@ export const beautifyCSS = (input: string, options: any): string => { }; // schema转换为CSS代码 -export const schema2CssCode = (schema: any, prettierOptions: any) => { +export const schema2CssCode = (schema: IPublicTypeProjectSchema, prettierOptions: any) => { return beautifyCSS(schema.componentsTree[0]?.css || '', prettierOptions); }; diff --git a/packages/plugin-multiple-editor/src/utils/constants.ts b/packages/plugin-multiple-editor/src/utils/constants.ts index 3e39b1c..76a7bdc 100644 --- a/packages/plugin-multiple-editor/src/utils/constants.ts +++ b/packages/plugin-multiple-editor/src/utils/constants.ts @@ -4,4 +4,6 @@ export const languageMap: ObjectType = { js: 'javascript', css: 'css', json: 'json', + ts: 'typescript', + less: 'less', }; diff --git a/packages/plugin-multiple-editor/src/utils/files.ts b/packages/plugin-multiple-editor/src/utils/files.ts index c9a5d09..3a3f1f2 100644 --- a/packages/plugin-multiple-editor/src/utils/files.ts +++ b/packages/plugin-multiple-editor/src/utils/files.ts @@ -4,7 +4,11 @@ export class File { public type = 'file'; - constructor(public name: string, public content: string) { + constructor( + public name: string, + public content: string, + public fullPath: string + ) { this.ext = name.match(/\.(\w+)$/)?.[1]; } } @@ -13,10 +17,17 @@ export class Dir { public dirs: Dir[]; public files: File[]; public type = 'dir'; - - constructor(public name: string, dirs?: Dir[], files?: File[]) { + public fullPath = ''; + + constructor( + public name: string, + dirs: Dir[], + files: File[], + fullPath: string + ) { this.dirs = dirs || []; this.files = files || []; + this.fullPath = fullPath || ''; } } @@ -25,9 +36,9 @@ export const getKey = (parent: string | undefined, cur: string) => { return `${finalParent}${cur}`; }; -export function getKeyByPath(path: string[], name: string) { - return ['', ...path, name].join('/'); -} +// export function getKeyByPath(path: string[], name: string) { +// return ['', ...path, name].join('/'); +// } export const parseKey = (key: string) => { const fragment = key.split('/').filter(Boolean); @@ -106,13 +117,13 @@ export function generateFile( for (const dir of path) { let found: Dir | undefined = nextDir.dirs.find((d) => d.name === dir); if (!found) { - found = new Dir(dir); + found = new Dir(dir, [], [], path.join('/')); nextDir.dirs.push(found); } nextDir = found; } // 添加文件 - nextDir.files.push(new File(filename, file.content)); + nextDir.files.push(new File(filename, file.content, file.name)); } /** @@ -124,7 +135,7 @@ export function generateFile( export function fileMapToTree(obj: any) { const { files } = compatGetSourceCodeMap(obj); const keys = Object.keys(files); - const dir = new Dir('/'); + const dir = new Dir('/', [], [], ''); for (const key of keys) { generateFile({ name: key, content: files[key] }, dir); } @@ -145,10 +156,14 @@ export function treeToMap(root: Dir, base = '') { return files; } -export function compatGetSourceCodeMap(origin: any = {}) { +export function compatGetSourceCodeMap(origin: any = {}, defaultFiles?: any) { const { meta, files, ...rest } = origin; + let finalFiles = files; + if (!finalFiles) { + finalFiles = Object.keys(rest).length ? rest : defaultFiles; + } return { - files: files || rest, + files: finalFiles || {}, meta: meta || {}, }; } diff --git a/packages/plugin-multiple-editor/src/utils/get-methods.ts b/packages/plugin-multiple-editor/src/utils/get-methods.ts index 4d3b760..6c1315b 100644 --- a/packages/plugin-multiple-editor/src/utils/get-methods.ts +++ b/packages/plugin-multiple-editor/src/utils/get-methods.ts @@ -111,7 +111,7 @@ export const getMethods = (fileContent: string) => { ?.code; const compiledCode = pureTranspile(codeStr, { esm: true }); state[ - (property.key as Identifier).name ?? property?.key?.extra?.rawValue as string + ((property.key as Identifier).name ?? (property?.key?.extra as any)?.rawValue) as string ] = { type: 'JSExpression', value: compiledCode.replace(/var *name *= */, '').replace(/;$/, ''), diff --git a/packages/plugin-multiple-editor/src/utils/ghostBabel.ts b/packages/plugin-multiple-editor/src/utils/ghostBabel.ts index 7ee0f79..d3e6883 100644 --- a/packages/plugin-multiple-editor/src/utils/ghostBabel.ts +++ b/packages/plugin-multiple-editor/src/utils/ghostBabel.ts @@ -2,7 +2,11 @@ * 使用 @babel/standalone 的能力实现 parse 和 traverse */ -import { transform, transformFromAst } from '@babel/standalone'; +import { + transform, + transformFromAst, + availablePlugins, +} from '@babel/standalone'; import type { Visitor, PluginItem, @@ -14,6 +18,10 @@ import { Node, File, file } from '@babel/types'; const defaultBabelOption: TransformOptions = { babelrc: false, sourceType: 'module', + plugins: [ + availablePlugins['syntax-jsx'], + availablePlugins['transform-react-jsx'], + ], }; export function traverse(code: string | ParseResult | Node, visitor: Visitor) { @@ -26,13 +34,13 @@ export function traverse(code: string | ParseResult | Node, visitor: Visitor) { if (typeof code === 'string') { transform(code, { ...defaultBabelOption, - plugins: [plugin], - }); + plugins: [...(defaultBabelOption.plugins || []), plugin], + } as any); } else { transformFromAst(code, undefined, { ...defaultBabelOption, - plugins: [plugin], - }); + plugins: [...(defaultBabelOption.plugins || []), plugin], + } as any); } } @@ -46,3 +54,62 @@ export function parse(code: string): File { // @ts-ignore return ast; } +export function generateOutline(ast: any) { + const outlineMap: any[] = []; + + function traverse(node: any, outline: any) { + if (!node) { + return; + } + if (!getName(node) && !node.type) return; + let outlineNode: any = {}; + if (getName(node)) { + outlineNode = { + name: getName(node), + type: node.type, + children: [], + }; + outline.push(outlineNode); + if ( + !(node?.type === 'ClassDeclaration' || node?.type === 'ObjectProperty') + ) + return; + } + for (const key in node) { + if (Object.prototype.hasOwnProperty.call(node, key)) { + const childNode = node[key]; + if (Array.isArray(childNode)) { + childNode.forEach((child) => + traverse(child, outlineNode?.children || outline) + ); + } else if (typeof childNode === 'object') { + traverse(childNode, outlineNode.children || outline); + } + } + } + } + + traverse(ast, outlineMap); + return outlineMap; +} + +export function getName(node: any) { + switch (node.type) { + case 'FunctionDeclaration': + return node.id.name; + case 'VariableDeclarator': + return node.id.name; + case 'ClassDeclaration': + return node.id.name; + case 'ClassProperty': + return node.key.name; + case 'ObjectProperty': + return node.key.name; + case 'ClassMethod': + return node.key.name; + case 'ObjectMethod': + return node.key.name; + default: + return null; + } +} diff --git a/packages/plugin-multiple-editor/src/utils/index.ts b/packages/plugin-multiple-editor/src/utils/index.ts index 3e3fcd0..8f90e59 100644 --- a/packages/plugin-multiple-editor/src/utils/index.ts +++ b/packages/plugin-multiple-editor/src/utils/index.ts @@ -4,3 +4,4 @@ export * from './tsUtils'; export * from './files'; export * from './codeLint'; export * from './ghostBabel'; +export * from './path'; diff --git a/packages/plugin-multiple-editor/src/utils/multipleFile/babel/compile.ts b/packages/plugin-multiple-editor/src/utils/multipleFile/babel/compile.ts index 3533e65..c5c5b02 100644 --- a/packages/plugin-multiple-editor/src/utils/multipleFile/babel/compile.ts +++ b/packages/plugin-multiple-editor/src/utils/multipleFile/babel/compile.ts @@ -37,7 +37,11 @@ export function pureTranspile( ]; let plugins: any[] = [modulePlugin]; if (es6) { - plugins.unshift(availablePlugins['transform-modules-commonjs']); + plugins.unshift( + availablePlugins['transform-modules-commonjs'], + availablePlugins['syntax-jsx'], + availablePlugins['transform-react-jsx'] + ); } if (options?.presets) { presets = presets.concat(options.presets); diff --git a/packages/plugin-multiple-editor/src/utils/path.ts b/packages/plugin-multiple-editor/src/utils/path.ts new file mode 100644 index 0000000..4ffd40c --- /dev/null +++ b/packages/plugin-multiple-editor/src/utils/path.ts @@ -0,0 +1,68 @@ +import uniqBy from 'lodash/uniqBy'; + +export const pathResolve: (...args: string[]) => string = function () { + function normalizeArray(parts: string[], allowAboveRoot: boolean) { + const res = []; + for (let i = 0; i < parts.length; i++) { + const p = parts[i]; + if (!p || p === '.') continue; + if (p === '..') { + if (res.length && res[res.length - 1] !== '..') { + res.pop(); + } else if (allowAboveRoot) { + res.push('..'); + } + } else { + res.push(p); + } + } + return res; + } + let resolvedPath = '', + resolvedAbsolute = false; + for (let i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + // eslint-disable-next-line prefer-rest-params + const path = i >= 0 ? arguments[i] : '/'; + if (!path) { + continue; + } + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path[0] === '/'; + } + resolvedPath = normalizeArray( + resolvedPath.split('/'), + !resolvedAbsolute + ).join('/'); + return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; +}; + +export function resolveFilePath(filepath: string) { + const list = filepath.replace(/^\//, '').split('/'); + return list.slice(0, list.length - 1).join('/'); +} + +export function getFilesByPath(files: Record, path: string) { + const fileKeys = Object.keys(files); + const getDirsFromList = (list: string[]) => + uniqBy( + list + .filter((f) => f.replace(/^\//, '').split('/').length > 1) + .map((f) => ({ type: 'dir', path: f.split('/')[0] })), + (i) => i.path + ); + if (!path || path === '/') { + const fileList = fileKeys + .filter((key) => key.replace(/^\//, '').split('/').length === 1) + .map((f) => ({ type: 'file', path: f.split('/')[0] })); + return [...getDirsFromList(fileKeys), ...fileList]; + } + + const normalizedList = fileKeys + .filter((key) => key.replace(/^\//, '').startsWith(path.replace(/^\//, ''))) + .map((f) => f.replace(`${path.replace(/(\/$)|(^\/)/g, '')}/`, '')); + const fileList = normalizedList + .filter((f) => f.split('/').length === 1) + .map((f) => ({ type: 'file', path: f })); + + return [...getDirsFromList(normalizedList), ...fileList]; +} diff --git a/packages/plugin-multiple-editor/src/utils/script-loader.ts b/packages/plugin-multiple-editor/src/utils/script-loader.ts new file mode 100644 index 0000000..08efeed --- /dev/null +++ b/packages/plugin-multiple-editor/src/utils/script-loader.ts @@ -0,0 +1,50 @@ +export function loadScript(url: string) { + return new Promise((resolve) => { + let script = document.getElementById(url) as HTMLScriptElement; + if (!script) { + script = document.createElement('script'); + // script.id = url; + script.src = url; + script.type = 'text/javascript'; + } + script.onload = () => { + resolve(script); + }; + script.addEventListener('error', () => { + console.error('load script error', url); + }); + document.body.appendChild(script); + }); +} + +export async function loadLess() { + if (window.less) { + return window.less; + } + await loadScript( + 'https://gw.alipayobjects.com/os/lib/less/4.2.0/dist/less.min.js' + ); + return window.less; +} + +export async function loadPrettier() { + await Promise.all([ + loadScript( + 'https://g.alicdn.com/code/lib/prettier/2.6.0/standalone.min.js' + ), + loadScript( + 'https://g.alicdn.com/code/lib/prettier/2.6.0/parser-postcss.min.js' + ), + loadScript( + 'https://g.alicdn.com/code/lib/prettier/2.6.0/parser-babel.min.js' + ), + ]); + return window.prettier; +} + +export async function loadBabel(): Promise { + const url = + 'https://gw.alipayobjects.com/os/lib/babel/standalone/7.22.13/babel.min.js'; + await loadScript(url); + return (window as any).Babel; +} diff --git a/packages/plugin-multiple-editor/src/utils/transformUMD.ts b/packages/plugin-multiple-editor/src/utils/transformUMD.ts index 844531b..001437f 100644 --- a/packages/plugin-multiple-editor/src/utils/transformUMD.ts +++ b/packages/plugin-multiple-editor/src/utils/transformUMD.ts @@ -88,7 +88,7 @@ function preprocessIndex(content: string) { export function getInitFuncContent(fileMap: ObjectType, es6?: boolean) { const finalFileMap = Object.entries(fileMap) - .filter(([k]) => !['index.css'].includes(k)) + .filter(([k]) => !['index.css', 'index.less'].includes(k)) .map(([key, content]) => { let realContent = content; if (key === 'index.js') { diff --git a/packages/plugin-multiple-editor/tsconfig.json b/packages/plugin-multiple-editor/tsconfig.json index c820ed9..99b6c71 100644 --- a/packages/plugin-multiple-editor/tsconfig.json +++ b/packages/plugin-multiple-editor/tsconfig.json @@ -1,109 +1,28 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "ES5" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - "jsx": "react" /* Specify what JSX code is generated. */, - "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - - /* Modules */ - "module": "ES2020" /* Specify what module code is generated. */, - "rootDir": "./src", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + "strict": false, + "rootDir": "./src", + "baseUrl": "./", + "outDir": "./es", + "moduleResolution": "node", + "declaration": true, + "resolveJsonModule": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "module": "es2020", + "target": "ESNext", + "jsx": "react", "paths": { "@/*": ["./src/*"], "utils": ["./src/utils"], "utils/*": ["./src/utils/*"], "types": ["./src/types"], - "types/*": ["./src/types/*"] - }, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - "resolveJsonModule": true /* Enable importing .json files */, - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./es", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": false /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "types/*": ["./src/types/*"], + "react": [ "./node_modules/@types/react" ] + } }, "include": ["src"], - "exclude": ["src/dev-config/*"] + "exclude": ["src/dev-config"] } From 50547c91d3043a71af88be43abb13738a3766dbc Mon Sep 17 00:00:00 2001 From: jingyu Date: Fri, 23 Feb 2024 10:08:18 +0800 Subject: [PATCH 31/36] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 053834e..1c0db21 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-multiple-editor", - "version": "0.1.0", + "version": "0.2.0", "main": "es/index.js", "license": "MIT", "private": false, From 55c72b9822a6fb325bbc91294ef88e9fdccccc45 Mon Sep 17 00:00:00 2001 From: carrot Date: Fri, 23 Feb 2024 10:22:49 +0800 Subject: [PATCH 32/36] =?UTF-8?q?Revert=20"feat:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/plugin-multiple-editor/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 1c0db21..053834e 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-multiple-editor", - "version": "0.2.0", + "version": "0.1.0", "main": "es/index.js", "license": "MIT", "private": false, From e0a6d55d929886be8f78c4989eb921c8948f96f1 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 23 Feb 2024 10:47:14 +0800 Subject: [PATCH 33/36] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/publish beta npm.yml | 1 + .github/workflows/publish npm.yml | 1 + packages/plugin-multiple-editor/package.json | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish beta npm.yml b/.github/workflows/publish beta npm.yml index ff4108b..d60d927 100644 --- a/.github/workflows/publish beta npm.yml +++ b/.github/workflows/publish beta npm.yml @@ -28,6 +28,7 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" + npm install echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc cd packages/${{ github.event.inputs.packagePath }} npm install --legacy-peer-deps diff --git a/.github/workflows/publish npm.yml b/.github/workflows/publish npm.yml index 10fe201..d8971d4 100644 --- a/.github/workflows/publish npm.yml +++ b/.github/workflows/publish npm.yml @@ -32,6 +32,7 @@ jobs: git config --local user.name "GitHub Action" echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc + npm install cd packages/${{ github.event.inputs.packagePath }} npm install --legacy-peer-deps npm version ${{ github.event.inputs.versionType }} diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 053834e..3b19ad0 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -179,5 +179,6 @@ ], "fastPublish": { "npmClient": "npm" - } + }, + "repository": "https://github.com/alibaba/lowcode-plugins.git" } From dce5a8c6e3aac34dcf22a02ce55cef60634bf223 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 23 Feb 2024 10:53:39 +0800 Subject: [PATCH 34/36] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/publish beta npm.yml | 2 +- .github/workflows/publish npm.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish beta npm.yml b/.github/workflows/publish beta npm.yml index d60d927..01ab685 100644 --- a/.github/workflows/publish beta npm.yml +++ b/.github/workflows/publish beta npm.yml @@ -28,7 +28,7 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - npm install + npm install --legacy-peer-deps echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc cd packages/${{ github.event.inputs.packagePath }} npm install --legacy-peer-deps diff --git a/.github/workflows/publish npm.yml b/.github/workflows/publish npm.yml index d8971d4..5ada959 100644 --- a/.github/workflows/publish npm.yml +++ b/.github/workflows/publish npm.yml @@ -32,7 +32,7 @@ jobs: git config --local user.name "GitHub Action" echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc - npm install + npm install --legacy-peer-deps cd packages/${{ github.event.inputs.packagePath }} npm install --legacy-peer-deps npm version ${{ github.event.inputs.versionType }} From 552fe53c35ffd1d0b2bffe048082aa15763b699a Mon Sep 17 00:00:00 2001 From: jingyu Date: Mon, 26 Feb 2024 09:56:51 +0800 Subject: [PATCH 35/36] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4ci=E6=8A=A5?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin-multiple-editor/scripts/build.js | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/packages/plugin-multiple-editor/scripts/build.js b/packages/plugin-multiple-editor/scripts/build.js index a15ed89..007f85e 100644 --- a/packages/plugin-multiple-editor/scripts/build.js +++ b/packages/plugin-multiple-editor/scripts/build.js @@ -155,26 +155,27 @@ function build(previousFileSizes) { } return reject(new Error(messages.errors.join('\n\n'))); } - if ( - process.env.CI && - (typeof process.env.CI !== 'string' || - process.env.CI.toLowerCase() !== 'false') && - messages.warnings.length - ) { - // Ignore sourcemap warnings in CI builds. See #8227 for more info. - const filteredWarnings = messages.warnings.filter( - w => !/Failed to parse source map/.test(w) - ); - if (filteredWarnings.length) { - console.log( - chalk.yellow( - '\nTreating warnings as errors because process.env.CI = true.\n' + - 'Most CI servers set it automatically.\n' - ) - ); - return reject(new Error(filteredWarnings.join('\n\n'))); - } - } + // process.env.CI=true; + // if ( + // process.env.CI && + // (typeof process.env.CI !== 'string' || + // process.env.CI.toLowerCase() !== 'false') && + // messages.warnings.length + // ) { + // // Ignore sourcemap warnings in CI builds. See #8227 for more info. + // const filteredWarnings = messages.warnings.filter( + // w => !/Failed to parse source map/.test(w) + // ); + // if (filteredWarnings.length) { + // console.log( + // chalk.yellow( + // '\nTreating warnings as errors because process.env.CI = true.\n' + + // 'Most CI servers set it automatically.\n' + // ) + // ); + // return reject(new Error(filteredWarnings.join('\n\n'))); + // } + // } const resolveArgs = { stats, @@ -192,4 +193,4 @@ function build(previousFileSizes) { return resolve(resolveArgs); }); }); -} \ No newline at end of file +} From bbf63cc40af9cf75b4e1dc59400eed728c23cad4 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 26 Feb 2024 02:53:07 +0000 Subject: [PATCH 36/36] Bump version to --- packages/plugin-multiple-editor/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-multiple-editor/package.json b/packages/plugin-multiple-editor/package.json index 3b19ad0..38e07c7 100644 --- a/packages/plugin-multiple-editor/package.json +++ b/packages/plugin-multiple-editor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-multiple-editor", - "version": "0.1.0", + "version": "0.2.0", "main": "es/index.js", "license": "MIT", "private": false,