mirror of
https://github.com/NetEase/tango.git
synced 2026-09-05 23:48:19 +08:00
Compare commits
2 Commits
@music163/
...
@music163/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e258b32a | ||
|
|
62d403f80a |
49
.github/workflows/ci.yml
vendored
Normal file
49
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: CI
|
||||
# Event设置为main分支的pull request事件,
|
||||
# 这里的main分支相当于master分支,github项目新建是把main设置为默认分支,我懒得改了所以就保持这样吧
|
||||
on:
|
||||
pull_request:
|
||||
branches: main
|
||||
jobs:
|
||||
# 只需要定义一个job并命名为CI
|
||||
CI:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# 拉取项目代码
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
# 给当前环境下载node
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
# 检查缓存
|
||||
# 如果key命中缓存则直接将缓存的文件还原到 path 目录,从而减少流水线运行时间
|
||||
# 若 key 没命中缓存时,在当前Job成功完成时将自动创建一个新缓存
|
||||
- name: Cache
|
||||
# 缓存命中结果会存储在steps.[id].outputs.cache-hit里,该变量在继后的step中可读
|
||||
id: cache-dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# 缓存文件目录的路径
|
||||
path: |
|
||||
**/node_modules
|
||||
# key中定义缓存标志位的生成方式。runner.OS指当前环境的系统。外加对yarn.lock内容生成哈希码作为key值,如果yarn.lock改变则代表依赖有变化。
|
||||
# 这里用yarn.lock而不是package.json是因为package.json中还有version和description之类的描述项目但和依赖无关的属性
|
||||
key: ${{runner.OS}}-${{hashFiles('**/yarn.lock')}}
|
||||
# 安装依赖
|
||||
- name: Installing Dependencies
|
||||
# 如果缓存标志位没命中,则执行该step。否则就跳过该step
|
||||
if: steps.cache-dependencies.outputs.cache-hit != 'true'
|
||||
run: yarn install
|
||||
# 预构建
|
||||
- name: Prebuild
|
||||
run: yarn build
|
||||
# 运行代码扫描
|
||||
- name: Running Lint
|
||||
# 通过前面章节定义的命令行执行代码扫描
|
||||
run: yarn eslint
|
||||
# 运行自动化测试
|
||||
- name: Running Test
|
||||
# 通过前面章节定义的命令行执行自动化测试
|
||||
run: yarn test
|
||||
20
README.md
20
README.md
@@ -31,26 +31,28 @@ You can view the detailed usage guide through the following links:
|
||||
- Out-of-the-box front-end low-code designer, providing flexible and easy-to-use designer React components
|
||||
- Developed using TypeScript, providing complete type definition files
|
||||
|
||||
## 🌐 Compatibility
|
||||
|
||||
- Modern browsers(Chrome >= 80, Edge >= 80, last 2 safari versions, last 2 firefox versions)
|
||||
|
||||
## 🎯 Milestone
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Tango Release Milestone
|
||||
title Tango 1.0 Milestones
|
||||
excludes weekends
|
||||
%% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)
|
||||
|
||||
section Builder Release
|
||||
Alpha version :active, m1, 2023-08-10, 2023-08-30
|
||||
Beta version : m2, 2023-09-01, 2023-09-30
|
||||
1.0 RC : m3, 2023-10-01, 2023-12-15
|
||||
1.0 version : m4, after m3, 10d
|
||||
1.0 Alpha : m1, 2023-10-01, 2024-01-31
|
||||
1.0 RC : m2, 2024-02-01, 2024-04-30
|
||||
1.0 Stable : m3, 2024-04-30, 2024-12-31
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Alpha versions will continue to optimize some implementation protocols and continuously integrate new features from the internal version of NetEase; RC versions will provide a stable parsing protocol and implementation; The 1.0 official version is planned to be released in Q2 2024. After the release of the 1.0 official version, we will continue to iterate on versions and gradually incorporate core capabilities such as process design, component library, and AIGC from the internal version.
|
||||
|
||||
## 🌐 Compatibility
|
||||
|
||||
- Modern browsers(Chrome >= 80, Edge >= 80, last 2 safari versions, last 2 firefox versions)
|
||||
|
||||
## 💻 Development
|
||||
|
||||
### Environment
|
||||
|
||||
@@ -31,26 +31,28 @@
|
||||
- 开箱即用的前端低代码设计器,提供灵活易用的设计器 React 组件
|
||||
- 使用 TypeScript 开发,提供完整的类型定义文件
|
||||
|
||||
## 🌐 兼容环境
|
||||
|
||||
- 现代浏览器(Chrome >= 80, Edge >= 80, last 2 safari versions, last 2 firefox versions)
|
||||
|
||||
## 🎯 里程碑
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Tango Release Milestone
|
||||
title Tango 1.0 Milestones
|
||||
excludes weekends
|
||||
%% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)
|
||||
|
||||
section Builder Release
|
||||
Alpha version :active, m1, 2023-08-10, 2023-08-30
|
||||
Beta version : m2, 2023-09-01, 2023-09-30
|
||||
1.0 RC : m3, 2023-10-01, 2023-12-15
|
||||
1.0 version : m4, after m3, 10d
|
||||
1.0 Alpha : m1, 2023-10-01, 2024-01-31
|
||||
1.0 RC : m2, 2024-02-01, 2024-04-30
|
||||
1.0 Stable : m3, 2024-04-30, 2024-12-31
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Alpha 版本会持续对一些实现协议进行优化,并持续融合网易内网版本中的新增特性;RC 版本将会提供基本稳定的解析协议和实现;1.0 正式版本计划在 2024 年Q2发布。1.0 正式版发布后我们将会持续进行版本迭代,并逐步融入内网版本中的流程设计、组件库、AIGC 等核心基础能力。
|
||||
|
||||
## 🌐 兼容环境
|
||||
|
||||
- 现代浏览器(Chrome >= 80, Edge >= 80, last 2 safari versions, last 2 firefox versions)
|
||||
|
||||
## 💻 开发
|
||||
|
||||
### 推荐开发环境
|
||||
|
||||
@@ -62,13 +62,13 @@ const config = {
|
||||
({
|
||||
// Replace with your project's social card
|
||||
image: 'img/social-card.png',
|
||||
announcementBar: {
|
||||
id: 'notion_alert',
|
||||
content: '🏗 当前版本为测试版,请暂时不要用于生产环境,正式版将于2023年Q4发布!',
|
||||
backgroundColor: 'var(--ifm-color-primary-contrast-background)',
|
||||
textColor: 'var(--ifm-color-primary-contrast-foreground)',
|
||||
isCloseable: false,
|
||||
},
|
||||
// announcementBar: {
|
||||
// id: 'notion_alert',
|
||||
// content: '🏗 当前版本为测试版,请暂时不要用于生产环境,正式版将于2023年Q4发布!',
|
||||
// backgroundColor: 'var(--ifm-color-primary-contrast-background)',
|
||||
// textColor: 'var(--ifm-color-primary-contrast-foreground)',
|
||||
// isCloseable: false,
|
||||
// },
|
||||
navbar: {
|
||||
title: '',
|
||||
logo: {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/netease/tango/compare/@music163/tango-context@1.0.0-alpha.5...@music163/tango-context@1.0.0-alpha.6) (2024-01-16)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-context
|
||||
|
||||
# [1.0.0-alpha.5](https://github.com/netease/tango/compare/@music163/tango-context@1.0.0-alpha.4...@music163/tango-context@1.0.0-alpha.5) (2023-12-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-context",
|
||||
"version": "1.0.0-alpha.5",
|
||||
"version": "1.0.0-alpha.6",
|
||||
"description": "react context for tango-apps",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -31,8 +31,8 @@
|
||||
"react": ">= 16.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@music163/tango-core": "^1.0.0-alpha.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-core": "^1.0.0-alpha.6",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"mobx-react-lite": "4.0.5"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/netease/tango/compare/@music163/tango-core@1.0.0-alpha.5...@music163/tango-core@1.0.0-alpha.6) (2024-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 优化变量树实现 ([#90](https://github.com/netease/tango/issues/90)) ([62d403f](https://github.com/netease/tango/commit/62d403f80a5ad08c216bc0c035ffc12c2cf329d2))
|
||||
|
||||
# [1.0.0-alpha.5](https://github.com/netease/tango/compare/@music163/tango-core@1.0.0-alpha.4...@music163/tango-core@1.0.0-alpha.5) (2023-12-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-core",
|
||||
"version": "1.0.0-alpha.5",
|
||||
"version": "1.0.0-alpha.6",
|
||||
"description": "tango core",
|
||||
"author": "wwsun <ww.sun@outlook.com>",
|
||||
"homepage": "",
|
||||
@@ -28,7 +28,7 @@
|
||||
"@babel/parser": "^7.23.5",
|
||||
"@babel/traverse": "^7.23.5",
|
||||
"@babel/types": "^7.23.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"@types/babel__generator": "^7.6.7",
|
||||
"@types/babel__traverse": "^7.20.4",
|
||||
"mobx": "6.12.0",
|
||||
|
||||
@@ -1006,7 +1006,7 @@ export function serviceConfig2Node(payload: object) {
|
||||
});
|
||||
}
|
||||
|
||||
export function updateServiceConfigToServiceFile(ast: t.File, config: object) {
|
||||
export function updateServiceConfigToServiceFile(ast: t.File, config: Dict<object>) {
|
||||
traverse(ast, {
|
||||
CallExpression(path) {
|
||||
const calleeName = keyNode2value(path.node.callee) as string;
|
||||
|
||||
@@ -206,14 +206,14 @@ export interface IWorkspace {
|
||||
getServiceFunction?: (serviceKey: string) => {
|
||||
name: string;
|
||||
moduleName: string;
|
||||
config: object;
|
||||
config: Dict<object>;
|
||||
};
|
||||
listServiceFunctions?: () => Record<string, object>;
|
||||
listServiceFunctions?: () => Dict<object>;
|
||||
removeServiceFunction?: (serviceKey: string) => void;
|
||||
addServiceFunction?: (serviceName: string, config: object, modName?: string) => void;
|
||||
addServiceFunctions?: (configs: object, modName?: string) => void;
|
||||
updateServiceFunction?: (serviceName: string, payload: object, modName?: string) => void;
|
||||
updateServiceBaseConfig?: (config: object, modName?: string) => void;
|
||||
addServiceFunction?: (serviceName: string, config: Dict, modName?: string) => void;
|
||||
addServiceFunctions?: (configs: Dict<object>, modName?: string) => void;
|
||||
updateServiceFunction?: (serviceName: string, payload: Dict, modName?: string) => void;
|
||||
updateServiceBaseConfig?: (config: Dict, modName?: string) => void;
|
||||
|
||||
// ----------------- 状态管理文件操作 -----------------
|
||||
addStoreState?: (storeName: string, stateName: string, initValue: string) => void;
|
||||
|
||||
@@ -77,7 +77,7 @@ export class TangoServiceModule extends TangoModule {
|
||||
* @param configs { [name: string]: object }
|
||||
* @returns
|
||||
*/
|
||||
addServiceFunctions(configs: object) {
|
||||
addServiceFunctions(configs: Dict<object>) {
|
||||
this.ast = updateServiceConfigToServiceFile(this.ast, configs);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { action, computed, makeObservable, observable } from 'mobx';
|
||||
import { JSXElement } from '@babel/types';
|
||||
import {
|
||||
ComponentPrototypeType,
|
||||
Dict,
|
||||
hasFileExtension,
|
||||
isStoreVariablePath,
|
||||
isString,
|
||||
@@ -637,9 +638,10 @@ export class Workspace extends EventTarget implements IWorkspace {
|
||||
|
||||
/**
|
||||
* 获取服务函数的列表
|
||||
* @returns 返回服务函数的列表 { [serviceKey: string]: Dict }
|
||||
*/
|
||||
listServiceFunctions() {
|
||||
const ret: Record<string, object> = {};
|
||||
const ret: Record<string, Dict> = {};
|
||||
Object.keys(this.serviceModules).forEach((moduleName) => {
|
||||
const module = this.serviceModules[moduleName];
|
||||
Object.keys(module.serviceFunctions).forEach((name) => {
|
||||
@@ -653,18 +655,18 @@ export class Workspace extends EventTarget implements IWorkspace {
|
||||
/**
|
||||
* 更新服务函数
|
||||
*/
|
||||
updateServiceFunction(serviceName: string, payload: object, moduleName = 'index') {
|
||||
updateServiceFunction(serviceName: string, payload: Dict, moduleName = 'index') {
|
||||
this.serviceModules[moduleName].updateServiceFunction(serviceName, payload).update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增服务函数,支持批量添加
|
||||
*/
|
||||
addServiceFunction(name: string, config: object, moduleName = 'index') {
|
||||
addServiceFunction(name: string, config: Dict, moduleName = 'index') {
|
||||
this.serviceModules[moduleName]?.addServiceFunction(name, config).update();
|
||||
}
|
||||
|
||||
addServiceFunctions(configs: object, modName = 'index') {
|
||||
addServiceFunctions(configs: Dict<Dict>, modName = 'index') {
|
||||
this.serviceModules[modName]?.addServiceFunctions(configs).update();
|
||||
}
|
||||
|
||||
@@ -680,7 +682,7 @@ export class Workspace extends EventTarget implements IWorkspace {
|
||||
/**
|
||||
* 更新服务的基础配置
|
||||
*/
|
||||
updateServiceBaseConfig(config: object, moduleName = 'index') {
|
||||
updateServiceBaseConfig(config: Dict, moduleName = 'index') {
|
||||
this.serviceModules[moduleName]?.updateBaseConfig(config).update();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.7](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.0-alpha.6...@music163/tango-designer@1.0.0-alpha.7) (2024-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 优化变量树实现 ([#90](https://github.com/netease/tango/issues/90)) ([62d403f](https://github.com/netease/tango/commit/62d403f80a5ad08c216bc0c035ffc12c2cf329d2))
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.0-alpha.5...@music163/tango-designer@1.0.0-alpha.6) (2023-12-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-designer",
|
||||
"version": "1.0.0-alpha.6",
|
||||
"version": "1.0.0-alpha.7",
|
||||
"description": "lowcode designer",
|
||||
"keywords": [
|
||||
"react"
|
||||
@@ -33,12 +33,12 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@music163/request": "^0.1.2",
|
||||
"@music163/tango-context": "^1.0.0-alpha.5",
|
||||
"@music163/tango-core": "^1.0.0-alpha.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-sandbox": "^1.0.0-alpha.5",
|
||||
"@music163/tango-setting-form": "^1.0.0-alpha.5",
|
||||
"@music163/tango-ui": "^1.0.0-alpha.3",
|
||||
"@music163/tango-context": "^1.0.0-alpha.6",
|
||||
"@music163/tango-core": "^1.0.0-alpha.6",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"@music163/tango-sandbox": "^1.0.0-alpha.6",
|
||||
"@music163/tango-setting-form": "^1.0.0-alpha.6",
|
||||
"@music163/tango-ui": "^1.0.0-alpha.4",
|
||||
"antd": "^4.24.2",
|
||||
"cash-dom": "^8.1.2",
|
||||
"classnames": "^2.3.2",
|
||||
|
||||
@@ -55,6 +55,21 @@ const varTreeStyle = css`
|
||||
|
||||
type SelectNodeCallback = (data: IVariableTreeNode) => void;
|
||||
|
||||
type DetailModeType =
|
||||
| 'detail'
|
||||
| 'storeVariableDetail'
|
||||
| 'serviceDetail'
|
||||
| 'addVariable'
|
||||
| 'addStore'
|
||||
| 'addService';
|
||||
|
||||
interface IVariableTreeRenderDetailState {
|
||||
mode: DetailModeType;
|
||||
setMode: (mode: DetailModeType) => void;
|
||||
activeNode: IVariableTreeNode;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
export interface VariableTreeProps {
|
||||
defaultValueDetailMode?: ValueDetailProps['defaultMode'];
|
||||
dataSource: IVariableTreeNode[];
|
||||
@@ -66,43 +81,63 @@ export interface VariableTreeProps {
|
||||
getStoreNames?: () => string[];
|
||||
onSelect?: SelectNodeCallback;
|
||||
onAddStoreVariable?: (storeName: string, data: any) => void;
|
||||
onUpdateStoreVariable?: ValueDefineProps['onSave'];
|
||||
onRemoveStoreVariable?: (variableKey: string) => void;
|
||||
onAddStore?: (newStoreName: string) => void;
|
||||
onAddService?: (data: object) => void;
|
||||
onRemoveVariable?: (variableKey: string) => void;
|
||||
onUpdateVariable?: ValueDefineProps['onSave'];
|
||||
onUpdateService?: (data: object) => void;
|
||||
onRemoveService?: (variableKey: string) => void;
|
||||
onCopy?: (data: IVariableTreeNode) => void;
|
||||
onView?: SelectNodeCallback;
|
||||
height?: number | string;
|
||||
showViewButton?: boolean;
|
||||
/**
|
||||
* 自定义头部
|
||||
*/
|
||||
renderHeaderExtra?: (
|
||||
props: VariableTreeProps,
|
||||
state: IVariableTreeRenderDetailState,
|
||||
) => React.ReactNode;
|
||||
/**
|
||||
* 自定义变量详情渲染
|
||||
* @param props
|
||||
* @param state
|
||||
* @returns
|
||||
*/
|
||||
renderDetail?: (
|
||||
props: VariableTreeProps,
|
||||
state: IVariableTreeRenderDetailState,
|
||||
) => React.ReactNode;
|
||||
}
|
||||
|
||||
export function VariableTree({
|
||||
dataSource = [],
|
||||
serviceModules = [],
|
||||
appContext = {},
|
||||
defaultValueDetailMode,
|
||||
onSelect = noop,
|
||||
onAddStoreVariable = noop,
|
||||
onAddStore = noop,
|
||||
onAddService = noop,
|
||||
onRemoveVariable = noop,
|
||||
onUpdateVariable = noop,
|
||||
onUpdateService = noop,
|
||||
onCopy = noop,
|
||||
onView = noop,
|
||||
getServiceData,
|
||||
getServiceNames,
|
||||
getStoreNames,
|
||||
getPreviewValue = noop,
|
||||
showViewButton,
|
||||
...rest
|
||||
}: VariableTreeProps) {
|
||||
export function VariableTree(props: VariableTreeProps) {
|
||||
const {
|
||||
dataSource = [],
|
||||
serviceModules = [],
|
||||
appContext = {},
|
||||
defaultValueDetailMode,
|
||||
onSelect = noop,
|
||||
onAddStoreVariable = noop,
|
||||
onAddStore = noop,
|
||||
onAddService = noop,
|
||||
onUpdateStoreVariable = noop,
|
||||
onUpdateService = noop,
|
||||
onRemoveStoreVariable,
|
||||
onRemoveService,
|
||||
onCopy = noop,
|
||||
onView = noop,
|
||||
getServiceData,
|
||||
getServiceNames,
|
||||
getStoreNames,
|
||||
getPreviewValue = noop,
|
||||
showViewButton,
|
||||
renderHeaderExtra,
|
||||
renderDetail: renderDetailProp,
|
||||
...rest
|
||||
} = props;
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [activeNode, setActiveNode] = useState<IVariableTreeNode>();
|
||||
const [mode, setMode] = useState<
|
||||
'detail' | 'storeVariableDetail' | 'serviceDetail' | 'addVariable' | 'addStore' | 'addService'
|
||||
>();
|
||||
const [mode, setMode] = useState<DetailModeType>();
|
||||
const clear = useCallback(() => {
|
||||
setActiveNode(null);
|
||||
setMode(null);
|
||||
@@ -127,9 +162,12 @@ export function VariableTree({
|
||||
: dataSource;
|
||||
}, [keyword, dataSource]);
|
||||
|
||||
const state = { activeNode, mode, setMode, clear };
|
||||
|
||||
return (
|
||||
<Box display="flex" columnGap="l" className="VariableTree" css={varTreeStyle} {...rest}>
|
||||
<Box className="VariableList" width="40%">
|
||||
{renderHeaderExtra?.(props, state)}
|
||||
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
|
||||
<Search placeholder="请输入变量名" onChange={(val) => setKeyword(val?.trim())} />
|
||||
</Box>
|
||||
@@ -161,7 +199,11 @@ export function VariableTree({
|
||||
<Popconfirm
|
||||
title={`确认删除吗 ${node.title}?该操作会导致引用此模型的代码报错,请谨慎操作!`}
|
||||
onConfirm={() => {
|
||||
onRemoveVariable(node.key);
|
||||
if (isStoreVariablePath(node.key)) {
|
||||
onRemoveStoreVariable(node.key);
|
||||
} else {
|
||||
onRemoveService(node.key);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
@@ -263,97 +305,114 @@ export function VariableTree({
|
||||
/>
|
||||
</Box>
|
||||
<Box className="VariableDetail" flex="1" position="sticky" top="0" overflow="auto">
|
||||
{mode === 'detail' && <NodeCommonDetail data={activeNode} />}
|
||||
{mode === 'storeVariableDetail' && (
|
||||
<ValueDetail key={activeNode.key} defaultMode={defaultValueDetailMode}>
|
||||
{(previewMode) =>
|
||||
previewMode === 'runtime' ? (
|
||||
<ValuePreview
|
||||
value={getPreviewValue(activeNode)}
|
||||
onCopy={(valuePath) => {
|
||||
return ['tango', activeNode.key.replaceAll('.', '?.'), valuePath].join('.');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<ValueDefine data={activeNode} onSave={onUpdateVariable} />
|
||||
)
|
||||
}
|
||||
</ValueDetail>
|
||||
)}
|
||||
{mode === 'serviceDetail' && (
|
||||
<>
|
||||
<Panel shape="solid" title="服务函数配置">
|
||||
<AddServiceForm
|
||||
key={activeNode.key}
|
||||
serviceModules={serviceModules}
|
||||
serviceNames={(function () {
|
||||
const { moduleName } = parseServiceVariablePath(activeNode.key);
|
||||
return getServiceNames?.(moduleName) || [];
|
||||
})()}
|
||||
initialValues={{
|
||||
...getServiceData?.(activeNode.key),
|
||||
{(function renderDetail() {
|
||||
const customRenderer = renderDetailProp?.(props, state);
|
||||
if (customRenderer) {
|
||||
return customRenderer;
|
||||
}
|
||||
|
||||
if (mode === 'detail') {
|
||||
return <NodeCommonDetail data={activeNode} />;
|
||||
}
|
||||
if (mode === 'storeVariableDetail') {
|
||||
return (
|
||||
<ValueDetail key={activeNode.key} defaultMode={defaultValueDetailMode}>
|
||||
{(previewMode) =>
|
||||
previewMode === 'runtime' ? (
|
||||
<ValuePreview
|
||||
value={getPreviewValue(activeNode)}
|
||||
onCopy={(valuePath) => {
|
||||
return ['tango', activeNode.key.replaceAll('.', '?.'), valuePath].join('.');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<ValueDefine data={activeNode} onSave={onUpdateStoreVariable} />
|
||||
)
|
||||
}
|
||||
</ValueDetail>
|
||||
);
|
||||
}
|
||||
if (mode === 'serviceDetail') {
|
||||
return (
|
||||
<>
|
||||
<Panel shape="solid" title="服务函数配置">
|
||||
<AddServiceForm
|
||||
key={activeNode.key}
|
||||
serviceModules={serviceModules}
|
||||
serviceNames={(function () {
|
||||
const { moduleName } = parseServiceVariablePath(activeNode.key);
|
||||
return getServiceNames?.(moduleName) || [];
|
||||
})()}
|
||||
initialValues={{
|
||||
...getServiceData?.(activeNode.key),
|
||||
}}
|
||||
onCancel={clear}
|
||||
onSubmit={(values) => {
|
||||
onUpdateService(values);
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
<Panel shape="solid" title="服务函数预览" mt="l">
|
||||
<ServicePreview
|
||||
key={activeNode.key}
|
||||
appContext={appContext}
|
||||
functionKey={activeNode.key}
|
||||
/>
|
||||
</Panel>
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (mode === 'addVariable') {
|
||||
return (
|
||||
<AddStoreVariableForm
|
||||
parentNode={activeNode}
|
||||
onSubmit={(storeName, data) => {
|
||||
onAddStoreVariable(storeName, data);
|
||||
clear();
|
||||
}}
|
||||
onCancel={clear}
|
||||
onSubmit={(values) => {
|
||||
onUpdateService(values);
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
<Panel shape="solid" title="服务函数预览" mt="l">
|
||||
<ServicePreview
|
||||
key={activeNode.key}
|
||||
appContext={appContext}
|
||||
functionKey={activeNode.key}
|
||||
);
|
||||
}
|
||||
if (mode === 'addStore') {
|
||||
return (
|
||||
<AddStoreForm
|
||||
storeNames={getStoreNames?.() || []}
|
||||
onSubmit={({ name }) => {
|
||||
onAddStore(name);
|
||||
clear();
|
||||
}}
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
</>
|
||||
)}
|
||||
{mode === 'addVariable' && (
|
||||
<Panel shape="solid" title="添加变量">
|
||||
<AddStoreVariableForm
|
||||
parentNode={activeNode}
|
||||
onSubmit={(storeName, data) => {
|
||||
onAddStoreVariable(storeName, data);
|
||||
clear();
|
||||
}}
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
)}
|
||||
{mode === 'addStore' && (
|
||||
<AddStoreForm
|
||||
storeNames={getStoreNames?.() || []}
|
||||
onSubmit={({ name }) => {
|
||||
onAddStore(name);
|
||||
clear();
|
||||
}}
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{mode === 'addService' && (
|
||||
<Panel shape="solid" title="创建服务函数">
|
||||
<AddServiceForm
|
||||
key={activeNode.key}
|
||||
serviceModules={serviceModules}
|
||||
serviceNames={activeNode.children?.map((item) => item.title) || []}
|
||||
initialValues={{
|
||||
moduleName: activeNode.title,
|
||||
}}
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
onSubmit={(values) => {
|
||||
onAddService(values);
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
)}
|
||||
);
|
||||
}
|
||||
if (mode === 'addService') {
|
||||
return (
|
||||
<Panel shape="solid" title="创建服务函数">
|
||||
<AddServiceForm
|
||||
key={activeNode.key}
|
||||
serviceModules={serviceModules}
|
||||
serviceNames={activeNode.children?.map((item) => item.title) || []}
|
||||
initialValues={{
|
||||
moduleName: activeNode.title,
|
||||
}}
|
||||
onCancel={() => {
|
||||
clear();
|
||||
}}
|
||||
onSubmit={(values) => {
|
||||
onAddService(values);
|
||||
clear();
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
noop,
|
||||
useBoolean,
|
||||
getValue,
|
||||
isStoreVariablePath,
|
||||
IVariableTreeNode,
|
||||
} from '@music163/tango-helpers';
|
||||
import { CloseCircleFilled, ExpandAltOutlined } from '@ant-design/icons';
|
||||
@@ -288,18 +287,17 @@ export function ExpressionModal({
|
||||
onAddStoreVariable={(storeName, data) => {
|
||||
workspace.addStoreState(storeName, data.name, data.initialValue);
|
||||
}}
|
||||
onUpdateVariable={(variableKey, code) => {
|
||||
onUpdateStoreVariable={(variableKey, code) => {
|
||||
workspace.updateStoreVariable(variableKey, code);
|
||||
}}
|
||||
onAddStore={(storeName) => {
|
||||
workspace.addStoreFile(storeName, newStoreTemplate);
|
||||
}}
|
||||
onRemoveVariable={(variablePath) => {
|
||||
if (isStoreVariablePath(variablePath)) {
|
||||
workspace.removeStoreVariable(variablePath);
|
||||
} else {
|
||||
workspace.removeServiceFunction(variablePath);
|
||||
}
|
||||
onRemoveStoreVariable={(variableKey) => {
|
||||
workspace.removeStoreVariable(variableKey);
|
||||
}}
|
||||
onRemoveService={(serviceKey) => {
|
||||
workspace.removeServiceFunction(serviceKey);
|
||||
}}
|
||||
onAddService={(data) => {
|
||||
const { name, moduleName, ...payload } = shapeServiceValues(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Box } from 'coral-system';
|
||||
import { Input, Tooltip } from 'antd';
|
||||
import { getValue, isFunction, isStoreVariablePath } from '@music163/tango-helpers';
|
||||
import { getValue, isFunction } from '@music163/tango-helpers';
|
||||
import { FormItemComponentProps } from '@music163/tango-setting-form';
|
||||
import { MenuOutlined } from '@ant-design/icons';
|
||||
import { useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
||||
@@ -135,18 +135,17 @@ export function ModelSetter({
|
||||
onAddStoreVariable={(storeName, data) => {
|
||||
workspace.addStoreState(storeName, data.name, data.initialValue);
|
||||
}}
|
||||
onUpdateVariable={(variableKey, code) => {
|
||||
onUpdateStoreVariable={(variableKey, code) => {
|
||||
workspace.updateStoreVariable(variableKey, code);
|
||||
}}
|
||||
onAddStore={(storeName) => {
|
||||
workspace.addStoreFile(storeName, newStoreTemplate);
|
||||
}}
|
||||
onRemoveVariable={(variablePath) => {
|
||||
if (isStoreVariablePath(variablePath)) {
|
||||
workspace.removeStoreVariable(variablePath);
|
||||
} else {
|
||||
workspace.removeServiceFunction(variablePath);
|
||||
}
|
||||
onRemoveStoreVariable={(variablePath) => {
|
||||
workspace.removeStoreVariable(variablePath);
|
||||
}}
|
||||
onRemoveService={(serviceKey) => {
|
||||
workspace.removeServiceFunction(serviceKey);
|
||||
}}
|
||||
getStoreNames={() => Object.keys(workspace.storeModules)}
|
||||
getPreviewValue={(node) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
||||
import { Box } from 'coral-system';
|
||||
import { getVariableContent, parseServiceVariablePath } from '@music163/tango-helpers';
|
||||
import { getVariableContent } from '@music163/tango-helpers';
|
||||
import { isWrappedByExpressionContainer } from '@music163/tango-core';
|
||||
import { VariableTree } from '../../components';
|
||||
import { useSandboxQuery } from '../../context';
|
||||
@@ -32,7 +32,7 @@ const DataSourceView = observer(() => {
|
||||
dataSource={serviceVariables}
|
||||
appContext={sandbox?.window['tango']}
|
||||
serviceModules={serviceModules}
|
||||
onRemoveVariable={(variableKey) => {
|
||||
onRemoveService={(variableKey) => {
|
||||
workspace.removeServiceFunction(variableKey);
|
||||
}}
|
||||
onAddService={(data) => {
|
||||
|
||||
@@ -47,10 +47,10 @@ export const VariablePanel = observer(
|
||||
onAddStoreVariable={(storeName, data) => {
|
||||
workspace.addStoreState(storeName, data.name, data.initialValue);
|
||||
}}
|
||||
onRemoveVariable={(variableKey) => {
|
||||
onRemoveStoreVariable={(variableKey) => {
|
||||
workspace.removeStoreVariable(variableKey);
|
||||
}}
|
||||
onUpdateVariable={(variableKey, code) => {
|
||||
onUpdateStoreVariable={(variableKey, code) => {
|
||||
workspace.updateStoreVariable(variableKey, code);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.2](https://github.com/netease/tango/compare/@music163/tango-helpers@1.0.0-alpha.1...@music163/tango-helpers@1.0.0-alpha.2) (2024-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 优化变量树实现 ([#90](https://github.com/netease/tango/issues/90)) ([62d403f](https://github.com/netease/tango/commit/62d403f80a5ad08c216bc0c035ffc12c2cf329d2))
|
||||
|
||||
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-helpers@1.0.0-alpha.0...@music163/tango-helpers@1.0.0-alpha.1) (2023-12-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-helpers",
|
||||
"version": "1.0.0-alpha.1",
|
||||
"version": "1.0.0-alpha.2",
|
||||
"description": "Shared types, helpers, and hooks of tango-apps",
|
||||
"keywords": [
|
||||
"shared",
|
||||
|
||||
@@ -73,6 +73,10 @@ export interface IVariableTreeNode {
|
||||
* 定义的原始值
|
||||
*/
|
||||
raw?: any;
|
||||
/**
|
||||
* 是否禁用
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 子结点
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/netease/tango/compare/@music163/tango-sandbox@1.0.0-alpha.5...@music163/tango-sandbox@1.0.0-alpha.6) (2024-01-16)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-sandbox
|
||||
|
||||
# [1.0.0-alpha.5](https://github.com/netease/tango/compare/@music163/tango-sandbox@1.0.0-alpha.4...@music163/tango-sandbox@1.0.0-alpha.5) (2023-12-29)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-sandbox
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-sandbox",
|
||||
"version": "1.0.0-alpha.5",
|
||||
"version": "1.0.0-alpha.6",
|
||||
"description": "sandbox of tango apps",
|
||||
"author": "wwsun <ww.sun@outlook.com>",
|
||||
"homepage": "",
|
||||
@@ -29,8 +29,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@music163/tango-core": "^1.0.0-alpha.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-core": "^1.0.0-alpha.6",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"crypto-js": "^4.1.1",
|
||||
"lodash.isequal": "4.5.0",
|
||||
"react-frame-component": "^5.2.4"
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.0.0-alpha.5...@music163/tango-setting-form@1.0.0-alpha.6) (2024-01-16)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-setting-form
|
||||
|
||||
# [1.0.0-alpha.5](https://github.com/netease/tango/compare/@music163/tango-setting-form@1.0.0-alpha.4...@music163/tango-setting-form@1.0.0-alpha.5) (2023-12-29)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-setting-form
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-setting-form",
|
||||
"version": "1.0.0-alpha.5",
|
||||
"version": "1.0.0-alpha.6",
|
||||
"description": "setting form of tango-apps",
|
||||
"author": "wwsun <ww.sun@outlook.com>",
|
||||
"homepage": "",
|
||||
@@ -28,9 +28,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@music163/tango-core": "^1.0.0-alpha.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-ui": "^1.0.0-alpha.3",
|
||||
"@music163/tango-core": "^1.0.0-alpha.6",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"@music163/tango-ui": "^1.0.0-alpha.4",
|
||||
"antd": "^4.24.2",
|
||||
"coral-system": "^1.0.5",
|
||||
"mobx": "6.12.0",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.0.0-alpha.4](https://github.com/netease/tango/compare/@music163/tango-ui@1.0.0-alpha.3...@music163/tango-ui@1.0.0-alpha.4) (2024-01-16)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-ui
|
||||
|
||||
# [1.0.0-alpha.3](https://github.com/netease/tango/compare/@music163/tango-ui@1.0.0-alpha.2...@music163/tango-ui@1.0.0-alpha.3) (2023-12-29)
|
||||
|
||||
**Note:** Version bump only for package @music163/tango-ui
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@music163/tango-ui",
|
||||
"version": "1.0.0-alpha.3",
|
||||
"version": "1.0.0-alpha.4",
|
||||
"description": "ui widgets of tango",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -38,7 +38,7 @@
|
||||
"@codemirror/lang-javascript": "^6.2.1",
|
||||
"@codemirror/lint": "^6.4.2",
|
||||
"@codemirror/search": "^6.5.5",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.1",
|
||||
"@music163/tango-helpers": "^1.0.0-alpha.2",
|
||||
"@uiw/react-codemirror": "^4.21.21",
|
||||
"antd": "^4.24.2",
|
||||
"coral-system": "^1.0.5",
|
||||
|
||||
Reference in New Issue
Block a user