From 8e455ce184115c837698d04ad167472c6b5dec55 Mon Sep 17 00:00:00 2001 From: MrWindlike Date: Mon, 23 May 2022 21:32:02 +0800 Subject: [PATCH] feat: add the module mock properties --- package.json | 2 +- .../src/components/Form/RecordEditor.tsx | 42 ++++++++++--------- .../Explorer/ExplorerForm/ExplorerForm.tsx | 13 +++++- .../ExplorerForm/ModuleMetaDataForm.tsx | 12 ++++++ .../src/components/Explorer/ExplorerTree.tsx | 7 +++- packages/editor/src/services/AppStorage.ts | 3 ++ packages/editor/src/services/EditorStore.ts | 27 ++++++++---- packages/runtime/src/services/StateManager.ts | 20 ++++++--- yarn.lock | 5 +++ 9 files changed, 96 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 6993aeb4..fe4566c4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "husky": "^6.0.0", "lerna": "^4.0.0", "lint-staged": "^11.0.0", - "prettier": "^2.3.2" + "prettier": "^2.5.0" }, "workspaces": [ "packages/*" diff --git a/packages/editor-sdk/src/components/Form/RecordEditor.tsx b/packages/editor-sdk/src/components/Form/RecordEditor.tsx index aade1be5..3d7c7277 100644 --- a/packages/editor-sdk/src/components/Form/RecordEditor.tsx +++ b/packages/editor-sdk/src/components/Form/RecordEditor.tsx @@ -1,21 +1,19 @@ import { CloseIcon } from '@chakra-ui/icons'; -import { Button, Text, HStack, IconButton, Input, VStack } from '@chakra-ui/react'; +import { Box, Button, Text, HStack, IconButton, Input, VStack } from '@chakra-ui/react'; import produce from 'immer'; import { fromPairs, toPairs } from 'lodash-es'; import React, { useState, useMemo, useEffect, useCallback } from 'react'; import { Type } from '@sinclair/typebox'; import { SpecWidget } from '../Widgets/SpecWidget'; import { ExpressionWidget } from '../Widgets/ExpressionWidget'; +import { ExpressionEditor } from '../Form/ExpressionEditor'; import { WidgetProps } from '../../types/widget'; import { mergeWidgetOptionsIntoSpec } from '../../utils/widget'; import { ExpressionEditorProps } from './ExpressionEditor'; const IGNORE_SPEC_TYPES = ['array', 'object']; -type RecordEditorProps = Omit< - WidgetProps, - 'component' | 'spec' | 'level' | 'path' -> & { +type RecordEditorProps = Omit & { component?: WidgetProps['component']; spec?: WidgetProps['spec']; path?: WidgetProps['path']; @@ -45,10 +43,8 @@ const RowItem = (props: RowItemProps) => { onRemoveRow, emitDataChange, } = props; - const { minNum = 0, onlySetValue } = useMemo( - () => spec?.widgetOptions || {}, - [spec] - ); + const { stateManager } = services; + const { minNum = 0, onlySetValue } = useMemo(() => spec?.widgetOptions || {}, [spec]); const expressionOptions = useMemo<{ compactOptions: ExpressionEditorProps['compactOptions']; }>( @@ -152,16 +148,24 @@ const RowItem = (props: RowItemProps) => { )} ) : ( - + (() => { + const evaledResult = stateManager.maskedEval(value); + + return ( + + + + ); + })() )} {onlySetValue ? null : ( = observer( name, version, }; - form = ; + form = ( + + ); break; case 'module': const moduleSpec = editorStore.appStorage.modules.find( @@ -40,8 +42,15 @@ export const ExplorerForm: React.FC = observer( name, version, stateMap: moduleSpec?.spec.stateMap || {}, + properties: moduleSpec?.spec.properties || {}, }; - form = ; + form = ( + + ); break; } return ( diff --git a/packages/editor/src/components/Explorer/ExplorerForm/ModuleMetaDataForm.tsx b/packages/editor/src/components/Explorer/ExplorerForm/ModuleMetaDataForm.tsx index e45885cd..128d4404 100644 --- a/packages/editor/src/components/Explorer/ExplorerForm/ModuleMetaDataForm.tsx +++ b/packages/editor/src/components/Explorer/ExplorerForm/ModuleMetaDataForm.tsx @@ -9,6 +9,7 @@ export type ModuleMetaDataFormData = { name: string; version: string; stateMap: Record; + properties: Record; }; type ModuleMetaDataFormProps = { @@ -62,6 +63,17 @@ export const ModuleMetaDataForm: React.FC = observer( }} /> + + Module Mock Properties + { + formik.setFieldValue('properties', json); + formik.submitForm(); + }} + /> + ); } diff --git a/packages/editor/src/components/Explorer/ExplorerTree.tsx b/packages/editor/src/components/Explorer/ExplorerTree.tsx index 716929e2..22d86a6a 100644 --- a/packages/editor/src/components/Explorer/ExplorerTree.tsx +++ b/packages/editor/src/components/Explorer/ExplorerTree.tsx @@ -55,7 +55,12 @@ export const ExplorerTree: React.FC = observer( const moduleItemId = genItemId('module', module.version, module.metadata.name); const onClickModule = () => { setSelectedItem(moduleItemId); - updateCurrentEditingTarget('module', module.version, module.metadata.name); + updateCurrentEditingTarget( + 'module', + module.version, + module.metadata.name, + module.spec + ); }; const onEditModule = () => { onEdit('module', module.version, module.metadata.name); diff --git a/packages/editor/src/services/AppStorage.ts b/packages/editor/src/services/AppStorage.ts index 4f52329e..77db41d7 100644 --- a/packages/editor/src/services/AppStorage.ts +++ b/packages/editor/src/services/AppStorage.ts @@ -113,10 +113,12 @@ export class AppStorage { version, name, stateMap, + properties, }: { version: string; name: string; stateMap: Record; + properties: Record; } ) { const i = this.modules.findIndex( @@ -125,6 +127,7 @@ export class AppStorage { const newModules = produce(toJS(this.modules), draft => { draft[i].metadata.name = name; draft[i].spec.stateMap = stateMap; + draft[i].spec.properties = properties; draft[i].version = version; }); diff --git a/packages/editor/src/services/EditorStore.ts b/packages/editor/src/services/EditorStore.ts index 5bfe6059..e21ad862 100644 --- a/packages/editor/src/services/EditorStore.ts +++ b/packages/editor/src/services/EditorStore.ts @@ -13,19 +13,20 @@ import { import { genOperation } from '../operations'; import { ExplorerMenuTabs, ToolMenuTabs } from '../constants/enum'; -import { - CORE_VERSION, - CoreComponentName, -} from '@sunmao-ui/shared'; +import { CORE_VERSION, CoreComponentName } from '@sunmao-ui/shared'; import { isEqual } from 'lodash-es'; type EditingTarget = { kind: 'app' | 'module'; version: string; name: string; + spec?: { + properties?: Record; + }; }; export class EditorStore { + globalDependencies: Record = {}; components: ComponentSchema[] = []; // currentEditingComponents, it could be app's or module's components _selectedComponentId = ''; @@ -57,6 +58,7 @@ export class EditorStore { private stateManager: StateManagerInterface, public appStorage: AppStorage ) { + this.globalDependencies = this.stateManager.dependencies; this.schemaValidator = new SchemaValidator(this.registry); makeAutoObservable(this, { eleMap: false, @@ -79,7 +81,6 @@ export class EditorStore { reaction( () => this.currentEditingTarget, (target, prevTarget) => { - if (isEqual(prevTarget, target)) { return; } @@ -92,6 +93,14 @@ export class EditorStore { this.setComponents(this.originComponents); this.setSelectedComponentId(this.originComponents[0]?.id || ''); + const evaledDependencies = stateManager.deepEval( + target.spec?.properties || {}, + { fallbackWhenError: () => undefined } + ); + this.stateManager.setDependencies({ + ...this.globalDependencies, + ...evaledDependencies, + }); } } ); @@ -181,7 +190,9 @@ export class EditorStore { } get activeDataSource(): ComponentSchema | null { - return this.components.find((component) => component.id === this.activeDataSourceId) || null; + return ( + this.components.find(component => component.id === this.activeDataSourceId) || null + ); } get activeDataSourceType(): DataSourceType | null { @@ -224,12 +235,14 @@ export class EditorStore { updateCurrentEditingTarget = ( kind: 'app' | 'module', version: string, - name: string + name: string, + spec?: EditingTarget['spec'] ) => { this.currentEditingTarget = { kind, name, version, + spec, }; }; diff --git a/packages/runtime/src/services/StateManager.ts b/packages/runtime/src/services/StateManager.ts index b6f18ae3..60a3b38f 100644 --- a/packages/runtime/src/services/StateManager.ts +++ b/packages/runtime/src/services/StateManager.ts @@ -7,7 +7,13 @@ import relativeTime from 'dayjs/plugin/relativeTime'; import LocalizedFormat from 'dayjs/plugin/localizedFormat'; import { isProxy, reactive, toRaw } from '@vue/reactivity'; import { watch } from '../utils/watchReactivity'; -import { isNumeric, parseExpression, consoleError, ConsoleType, type ExpChunk } from '@sunmao-ui/shared'; +import { + isNumeric, + parseExpression, + consoleError, + ConsoleType, + type ExpChunk, +} from '@sunmao-ui/shared'; dayjs.extend(relativeTime); dayjs.extend(isLeapYear); @@ -19,7 +25,7 @@ type EvalOptions = { scopeObject?: Record; overrideScope?: boolean; fallbackWhenError?: (exp: string) => any; - noConsoleError?: boolean + noConsoleError?: boolean; }; // TODO: use web worker @@ -35,7 +41,7 @@ export class ExpressionError extends Error { } } -export type StateManagerInterface = InstanceType +export type StateManagerInterface = InstanceType; export class StateManager { store = reactive>({}); @@ -105,9 +111,9 @@ export class StateManager { } catch (error) { if (error instanceof Error) { const expressionError = new ExpressionError(error.message); - + if (!noConsoleError) { - consoleError(ConsoleType.Expression, '', expressionError.message); + consoleError(ConsoleType.Expression, '', expressionError.message); } return fallbackWhenError ? fallbackWhenError(raw) : expressionError; @@ -194,4 +200,8 @@ export class StateManager { stop: () => stops.forEach(s => s()), }; } + + setDependencies(dependencies: Record = {}) { + this.dependencies = { ...DefaultDependencies, ...dependencies }; + } } diff --git a/yarn.lock b/yarn.lock index ddf1a7b2..78bcb830 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9057,6 +9057,11 @@ prettier@^2.3.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier@^2.5.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" + integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== + pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"