mirror of
https://github.com/NetEase/tango.git
synced 2026-09-01 15:03:03 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2919c1aa0 | |||
| 5dd5ab62a8 | |||
| 5e7e285452 | |||
| b3a458a914 | |||
| 1acfa6864b | |||
| baf071f130 | |||
| 6b1d55a11f | |||
| a8357f45b8 | |||
| 9db6358588 | |||
| 5bc2fb2d5a | |||
| 05a0f8f490 | |||
| c884712331 | |||
| e35ff792a0 | |||
| 138cbe9b20 | |||
| 979aa34259 | |||
| 76a5a2c659 |
@@ -1,2 +0,0 @@
|
|||||||
PORT=6006
|
|
||||||
HOST=local.netease.com
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/node_modules
|
||||||
|
/.env.local
|
||||||
|
/.umirc.local.ts
|
||||||
|
/config/config.local.ts
|
||||||
|
/src/.umi
|
||||||
|
/src/.umi-production
|
||||||
|
/src/.umi-test
|
||||||
|
/dist
|
||||||
|
.swc
|
||||||
@@ -1,33 +1,17 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { defineConfig } from 'umi';
|
||||||
|
|
||||||
const resolvePackageIndex = (relativeEntry: string) =>
|
const resolvePackageIndex = (relativeEntry: string) =>
|
||||||
path.resolve(__dirname, '../../../packages/', relativeEntry);
|
path.resolve(__dirname, '../../packages/', relativeEntry);
|
||||||
|
|
||||||
export default {
|
export default defineConfig({
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{ path: '/', component: 'index' },
|
||||||
exact: true,
|
{ path: '/docs', component: 'docs' },
|
||||||
path: '/',
|
|
||||||
component: 'index',
|
|
||||||
name: '首页',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
devServer: {
|
npmClient: 'yarn',
|
||||||
host: 'local.netease.com',
|
mfsu: false,
|
||||||
port: 8008,
|
codeSplitting: false,
|
||||||
https: {
|
|
||||||
key: path.resolve(__dirname, 'local.netease.com-key.pem'),
|
|
||||||
cert: path.resolve(__dirname, 'local.netease.com.pem'),
|
|
||||||
},
|
|
||||||
headers: { 'Origin-Agent-Cluster': '?0' },
|
|
||||||
},
|
|
||||||
targets: {
|
|
||||||
chrome: 79,
|
|
||||||
firefox: false,
|
|
||||||
safari: false,
|
|
||||||
edge: false,
|
|
||||||
ios: false,
|
|
||||||
},
|
|
||||||
alias: {
|
alias: {
|
||||||
'@music163/tango-helpers': resolvePackageIndex('helpers/src/index.ts'),
|
'@music163/tango-helpers': resolvePackageIndex('helpers/src/index.ts'),
|
||||||
'@music163/tango-core': resolvePackageIndex('core/src/index.ts'),
|
'@music163/tango-core': resolvePackageIndex('core/src/index.ts'),
|
||||||
@@ -44,6 +28,21 @@ export default {
|
|||||||
moment: 'moment',
|
moment: 'moment',
|
||||||
antd: 'antd',
|
antd: 'antd',
|
||||||
},
|
},
|
||||||
|
headScripts: [
|
||||||
|
'https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.development.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.development.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/react-is@18.2.0/umd/react-is.production.min.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/moment/min/moment-with-locales.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/styled-components@5.3.11/dist/styled-components.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/antd@4.24.13/dist/antd-with-locales.min.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/prettier@2.6.0/standalone.js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/prettier@2.6.0/parser-babel.js',
|
||||||
|
],
|
||||||
|
https: {
|
||||||
|
key: path.resolve(__dirname, 'local.netease.com-key.pem'),
|
||||||
|
cert: path.resolve(__dirname, 'local.netease.com.pem'),
|
||||||
|
http2: false,
|
||||||
|
},
|
||||||
chainWebpack: (config: any) => {
|
chainWebpack: (config: any) => {
|
||||||
// @see https://github.com/graphql/graphql-js/issues/1272#issuecomment-393903706
|
// @see https://github.com/graphql/graphql-js/issues/1272#issuecomment-393903706
|
||||||
config.module
|
config.module
|
||||||
@@ -61,4 +60,5 @@ export default {
|
|||||||
config.module.rule('js').include.add(resolvePackageIndex('ui/src'));
|
config.module.rule('js').include.add(resolvePackageIndex('ui/src'));
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
};
|
monorepoRedirect: {},
|
||||||
|
});
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# `playground`
|
|
||||||
|
|
||||||
搭建平台演示示例
|
|
||||||
|
|
||||||
## 说明
|
|
||||||
@@ -2,24 +2,23 @@
|
|||||||
"name": "playground",
|
"name": "playground",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "playground of tango-apps",
|
"author": "Wells <ww.sun@outlook.com>",
|
||||||
"license": "MIT",
|
|
||||||
"author": "wwsun <ww.sun@outlook.com>",
|
|
||||||
"files": [
|
|
||||||
"lib"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "COMPRESS=none umi build",
|
"dev": "HOST=local.netease.com PORT=8001 umi dev",
|
||||||
"start": "umi dev"
|
"build": "umi build",
|
||||||
|
"postinstall": "umi setup",
|
||||||
|
"setup": "umi setup",
|
||||||
|
"start": "npm run dev"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@music163/tango-designer": "*",
|
|
||||||
"@music163/tango-helpers": "*",
|
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"coral-system": "^1.0.5"
|
"coral-system": "^1.0.5",
|
||||||
|
"umi": "^4.0.89"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"umi": "^3.5.24"
|
"@types/react": "^18.0.33",
|
||||||
|
"@types/react-dom": "^18.0.11",
|
||||||
|
"typescript": "^5.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { IApi } from 'umi';
|
||||||
|
|
||||||
|
export default (api: IApi) => {
|
||||||
|
api.addMiddlewares(() => {
|
||||||
|
return (req, res, next) => {
|
||||||
|
res.setHeader('Origin-Agent-Cluster', '?0');
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 177 KiB |
@@ -6,29 +6,30 @@ import { registerSetter } from '@music163/tango-designer';
|
|||||||
import type { ComponentPrototypeType } from '@music163/tango-helpers';
|
import type { ComponentPrototypeType } from '@music163/tango-helpers';
|
||||||
import { FooSetter } from '../components';
|
import { FooSetter } from '../components';
|
||||||
|
|
||||||
|
export * from './mock-files';
|
||||||
|
|
||||||
export const bootHelperVariables = [
|
export const bootHelperVariables = [
|
||||||
{
|
{
|
||||||
key: '$helpers',
|
key: '$helpers',
|
||||||
title: '工具函数',
|
title: '工具函数',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: 'setStoreValue',
|
title: '设置变量值',
|
||||||
key: '() => tango.setStoreValue("variableName", "variableValue")',
|
key: '() => tango.setStoreValue("variableName", "variableValue")',
|
||||||
type: 'function',
|
type: 'function',
|
||||||
|
help: '设置状态值,tango.setStoreValue("variableName", "variableValue")',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'getStoreValue',
|
title: '获取变量值',
|
||||||
key: '() => tango.getStoreValue("variableName")',
|
key: '() => tango.getStoreValue("variableName")',
|
||||||
type: 'function',
|
type: 'function',
|
||||||
|
help: '获取状态值',
|
||||||
},
|
},
|
||||||
{ title: 'openModal', key: '() => tango.openModal("")', type: 'function' },
|
{ title: '打开弹窗', key: '() => tango.openModal("")', type: 'function' },
|
||||||
{ title: 'closeModal', key: '() => tango.closeModal("")', type: 'function' },
|
{ title: '关闭弹窗', key: '() => tango.closeModal("")', type: 'function' },
|
||||||
{ title: 'navigateTo', key: '() => tango.navigateTo("/")', type: 'function' },
|
{ title: '切换路由', key: '() => tango.navigateTo("/")', type: 'function' },
|
||||||
{ title: 'showToast', key: '() => tango.showToast("hello")', type: 'function' },
|
|
||||||
{ title: 'formatDate', key: '() => tango.formatDate("2022-12-12")', type: 'function' },
|
|
||||||
{ title: 'formatNumber', key: '() => tango.formatDate(9999)', type: 'function' },
|
|
||||||
{
|
{
|
||||||
title: 'copyToClipboard',
|
title: '拷贝到剪贴板',
|
||||||
key: '() => tango.copyToClipboard("hello")',
|
key: '() => tango.copyToClipboard("hello")',
|
||||||
type: 'function',
|
type: 'function',
|
||||||
},
|
},
|
||||||
@@ -143,6 +143,8 @@ import {
|
|||||||
FormilyForm,
|
FormilyForm,
|
||||||
} from "@music163/antd";
|
} from "@music163/antd";
|
||||||
import { Space } from '@music163/antd';
|
import { Space } from '@music163/antd';
|
||||||
|
import { MyButton } from '../components/button';
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@@ -151,6 +153,7 @@ class App extends React.Component {
|
|||||||
</Section>
|
</Section>
|
||||||
<Section>
|
<Section>
|
||||||
<Space>
|
<Space>
|
||||||
|
<MyButton />
|
||||||
<Button>button</Button>
|
<Button>button</Button>
|
||||||
<Input />
|
<Input />
|
||||||
</Space>
|
</Space>
|
||||||
@@ -162,6 +165,16 @@ class App extends React.Component {
|
|||||||
export default definePage(App);
|
export default definePage(App);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const componentsButtonCode = `
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export function MyButton() {
|
||||||
|
return <button>my button</button>
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const componentsPrototypeCode = ``;
|
||||||
|
|
||||||
const storeApp = `
|
const storeApp = `
|
||||||
import { defineStore } from '@music163/tango-boot';
|
import { defineStore } from '@music163/tango-boot';
|
||||||
|
|
||||||
@@ -246,6 +259,8 @@ export const sampleFiles = [
|
|||||||
{ filename: '/src/style.css', code: cssCode },
|
{ filename: '/src/style.css', code: cssCode },
|
||||||
{ filename: '/src/index.js', code: entryCode },
|
{ filename: '/src/index.js', code: entryCode },
|
||||||
{ filename: '/src/pages/list.js', code: viewHomeCode },
|
{ filename: '/src/pages/list.js', code: viewHomeCode },
|
||||||
|
{ filename: '/src/components/button.js', code: componentsButtonCode },
|
||||||
|
{ filename: '/src/components/prototype.js', code: componentsPrototypeCode },
|
||||||
{ filename: '/src/routes.js', code: routesCode },
|
{ filename: '/src/routes.js', code: routesCode },
|
||||||
{ filename: '/src/stores/index.js', code: storeIndexCode },
|
{ filename: '/src/stores/index.js', code: storeIndexCode },
|
||||||
{ filename: '/src/stores/app.js', code: storeApp },
|
{ filename: '/src/stores/app.js', code: storeApp },
|
||||||
@@ -3,3 +3,4 @@
|
|||||||
|
|
||||||
@primary-color: #2f54eb;
|
@primary-color: #2f54eb;
|
||||||
@border-radius-base: 2px;
|
@border-radius-base: 2px;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Outlet } from 'umi';
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const DocsPage = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>This is umi docs.</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DocsPage;
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Tango Playground</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="root"></div>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/react@16.14.0/umd/react.development.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/react-dom@16.14.0/umd/react-dom.development.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/react-is@16.13.1/umd/react-is.production.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/moment/min/moment-with-locales.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/styled-components@5.3.11/dist/styled-components.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.15.6/babel.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/prettier@2.6.0/standalone.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/prettier@2.6.0/parser-babel.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/antd@4.24.13/dist/antd-with-locales.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -15,9 +15,7 @@ import {
|
|||||||
themeLight,
|
themeLight,
|
||||||
} from '@music163/tango-designer';
|
} from '@music163/tango-designer';
|
||||||
import { createEngine, Workspace } from '@music163/tango-core';
|
import { createEngine, Workspace } from '@music163/tango-core';
|
||||||
import { Logo, ProjectDetail, bootHelperVariables } from './share';
|
import { Logo, ProjectDetail, bootHelperVariables, sampleFiles } from '../helpers';
|
||||||
import { sampleFiles } from '../mock/project';
|
|
||||||
import './index.less';
|
|
||||||
import {
|
import {
|
||||||
ApiOutlined,
|
ApiOutlined,
|
||||||
AppstoreAddOutlined,
|
AppstoreAddOutlined,
|
||||||
@@ -68,6 +66,7 @@ export default function App() {
|
|||||||
<Box px="l">
|
<Box px="l">
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Toolbar.Item key="routeSwitch" placement="left" />
|
<Toolbar.Item key="routeSwitch" placement="left" />
|
||||||
|
<Toolbar.Item key="history" placement="left" />
|
||||||
<Toolbar.Item key="preview" placement="left" />
|
<Toolbar.Item key="preview" placement="left" />
|
||||||
<Toolbar.Item key="modeSwitch" placement="right" />
|
<Toolbar.Item key="modeSwitch" placement="right" />
|
||||||
<Toolbar.Item key="togglePanel" placement="right" />
|
<Toolbar.Item key="togglePanel" placement="right" />
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json"
|
"extends": "./src/.umi/tsconfig.json"
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
import 'umi/typings';
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@music163/tango-setting-form": "*",
|
"@music163/tango-setting-form": "*",
|
||||||
"@music163/tango-ui": "*",
|
"@music163/tango-ui": "*",
|
||||||
"mobx": "6.9.0",
|
"mobx": "6.12.0",
|
||||||
"mobx-react-lite": "4.0.2"
|
"mobx-react-lite": "4.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@storybook/addon-actions": "^6.5.14",
|
"@storybook/addon-actions": "^6.5.14",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { EditableVariableTree, FormModel, SettingForm } from '@music163/tango-setting-form';
|
import { FormModel, SettingForm } from '@music163/tango-setting-form';
|
||||||
import { ComponentPrototypeType, getValue } from '@music163/tango-helpers';
|
import { ComponentPrototypeType } from '@music163/tango-helpers';
|
||||||
import { createServices } from '@music163/request';
|
|
||||||
import { Box } from 'coral-system';
|
import { Box } from 'coral-system';
|
||||||
import { JsonView } from '@music163/tango-ui';
|
import { JsonView } from '@music163/tango-ui';
|
||||||
import { toJS } from 'mobx';
|
import { toJS } from 'mobx';
|
||||||
@@ -9,51 +8,9 @@ import { observer } from 'mobx-react-lite';
|
|||||||
import { Card } from 'antd';
|
import { Card } from 'antd';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'SettingForm/ Setters',
|
title: 'SettingForm',
|
||||||
};
|
};
|
||||||
|
|
||||||
const modelVariables = [
|
|
||||||
{
|
|
||||||
title: 'stores',
|
|
||||||
key: 'stores',
|
|
||||||
selectable: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'app',
|
|
||||||
key: 'stores.app',
|
|
||||||
selectable: false,
|
|
||||||
children: [
|
|
||||||
{ title: 'app.title', key: 'stores.app.title', raw: '"hello"' },
|
|
||||||
{ title: 'app.age', key: 'stores.app.age', raw: '20' },
|
|
||||||
{ title: 'app.detail', key: 'stores.app.detail', raw: '{ foo: "foo" }' },
|
|
||||||
{ title: 'app.list', key: 'stores.app.list', type: 'function', raw: '() => {}' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'user',
|
|
||||||
key: 'stores.user',
|
|
||||||
selectable: false,
|
|
||||||
children: [
|
|
||||||
{ title: 'name', key: 'stores.user.name' },
|
|
||||||
{ title: 'age', key: 'stores.user.age' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'services',
|
|
||||||
key: 'services',
|
|
||||||
selectable: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: 'listUsers',
|
|
||||||
key: 'services.listUsers',
|
|
||||||
type: 'function',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const prototype: ComponentPrototypeType = {
|
const prototype: ComponentPrototypeType = {
|
||||||
name: 'Test',
|
name: 'Test',
|
||||||
exportType: 'namedExport',
|
exportType: 'namedExport',
|
||||||
@@ -257,47 +214,6 @@ const prototype: ComponentPrototypeType = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const deerService = createServices(
|
|
||||||
{
|
|
||||||
listMy: {
|
|
||||||
url: '/my/upload/list',
|
|
||||||
},
|
|
||||||
listFav: {
|
|
||||||
url: '/my/star/list',
|
|
||||||
},
|
|
||||||
listPub: {
|
|
||||||
url: '/list',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
baseURL: 'https://febase-openapi.fn.netease.com/deer/api/deer/pic',
|
|
||||||
withCredentials: false, // 解决跨域时必须非*问题
|
|
||||||
headers: {
|
|
||||||
'Febase-Auth': 'dskPVkIRnQ2dEn1DbyxURmUj4rl4BsCh53xFAsJnvVs=',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const context = {
|
|
||||||
stores: {
|
|
||||||
app: {
|
|
||||||
title: 'Sample App',
|
|
||||||
age: 20,
|
|
||||||
detail: {
|
|
||||||
foo: 'foo',
|
|
||||||
bar: 'bar',
|
|
||||||
biz: {
|
|
||||||
x: 'xxx',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
newKey: 'xxx',
|
|
||||||
},
|
|
||||||
foo: {
|
|
||||||
test: 'test string',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单值预览
|
* 表单值预览
|
||||||
*/
|
*/
|
||||||
@@ -310,9 +226,7 @@ export function Basic() {
|
|||||||
const model = new FormModel(
|
const model = new FormModel(
|
||||||
{
|
{
|
||||||
router: 'www.163.com',
|
router: 'www.163.com',
|
||||||
expression: {
|
expression: `{ foo: 'foo' }`,
|
||||||
foo: 'foo',
|
|
||||||
},
|
|
||||||
object: {
|
object: {
|
||||||
name: 'Alice',
|
name: 'Alice',
|
||||||
},
|
},
|
||||||
@@ -324,19 +238,7 @@ export function Basic() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display="flex">
|
<Box display="flex">
|
||||||
<SettingForm
|
<SettingForm model={model} prototype={prototype} />
|
||||||
model={model}
|
|
||||||
remoteServices={{
|
|
||||||
ImageService: deerService as any,
|
|
||||||
}}
|
|
||||||
prototype={prototype}
|
|
||||||
evaluateContext={{
|
|
||||||
tango: context,
|
|
||||||
__UNSAFE_TANGO_CURRENT_PAGE_RENDER_RUNTIME__: { routeData: { params: {}, query: {} } },
|
|
||||||
}}
|
|
||||||
modelVariables={modelVariables}
|
|
||||||
expressionVariables={modelVariables}
|
|
||||||
/>
|
|
||||||
<Box position="relative">
|
<Box position="relative">
|
||||||
<Card title="表单状态预览" style={{ position: 'sticky', top: 0 }}>
|
<Card title="表单状态预览" style={{ position: 'sticky', top: 0 }}>
|
||||||
<FormValuePreview model={model} />
|
<FormValuePreview model={model} />
|
||||||
@@ -346,6 +248,14 @@ export function Basic() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Lite() {
|
||||||
|
return (
|
||||||
|
<Box width={320} border="solid">
|
||||||
|
<SettingForm showSearch={false} showGroups={false} prototype={prototype} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function NoExpressionSwitch() {
|
export function NoExpressionSwitch() {
|
||||||
const model = new FormModel({});
|
const model = new FormModel({});
|
||||||
return (
|
return (
|
||||||
@@ -354,30 +264,3 @@ export function NoExpressionSwitch() {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Binding() {
|
|
||||||
const [data, setData] = useState<any>({});
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Box as="code" bg="highlight" color="white" fontSize="24px">
|
|
||||||
selected: {data?.key}
|
|
||||||
</Box>
|
|
||||||
<EditableVariableTree
|
|
||||||
dataSource={modelVariables as any}
|
|
||||||
getPreviewValue={(node) => {
|
|
||||||
if (!node || !node.key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (node.type === 'function') {
|
|
||||||
return node.raw;
|
|
||||||
}
|
|
||||||
const keyPath = node.key.replaceAll('?', '');
|
|
||||||
return getValue(context, keyPath);
|
|
||||||
}}
|
|
||||||
onSelect={setData}
|
|
||||||
onAddVariable={console.log}
|
|
||||||
onSave={console.log}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ToggleButton, IconFont } from '@music163/tango-ui';
|
import { ToggleButton, UndoOutlined, RedoOutlined } from '@music163/tango-ui';
|
||||||
import { Box, Flex } from 'coral-system';
|
import { Box, Group, Flex } from 'coral-system';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'UI/ToggleButton',
|
title: 'UI/ToggleButton',
|
||||||
@@ -9,28 +9,73 @@ export default {
|
|||||||
export function Basic() {
|
export function Basic() {
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Flex gap="l" bg="#efefef" p="l">
|
<Box display="flex" columnGap="l" p="l">
|
||||||
<ToggleButton>
|
<ToggleButton>
|
||||||
<IconFont type="icon-undo" />
|
<UndoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton selected>
|
<ToggleButton selected>
|
||||||
<IconFont type="icon-redo" />
|
<RedoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton disabled>
|
<ToggleButton disabled>
|
||||||
<IconFont type="icon-redo" />
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
</Box>
|
||||||
|
<Box display="flex" columnGap="l" p="l">
|
||||||
|
<ToggleButton type="primary">
|
||||||
|
<UndoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton type="primary" selected>
|
||||||
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton type="primary" disabled>
|
||||||
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DarkMode() {
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Flex gap="l" bg="#222" p="l">
|
||||||
|
<ToggleButton shape="ghost">
|
||||||
|
<UndoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton shape="ghost" selected>
|
||||||
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton shape="ghost" disabled>
|
||||||
|
<UndoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex gap="l" bg="#222" p="l">
|
<Flex gap="l" bg="#222" p="l">
|
||||||
<ToggleButton shape="ghost">
|
<ToggleButton shape="text">
|
||||||
<IconFont type="icon-undo" />
|
<UndoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton shape="ghost" selected>
|
<ToggleButton shape="text" selected>
|
||||||
<IconFont type="icon-redo" />
|
<RedoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton shape="ghost" disabled>
|
<ToggleButton shape="text" disabled>
|
||||||
<IconFont type="icon-undo" />
|
<RedoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ButtonGroup() {
|
||||||
|
return (
|
||||||
|
<Group attached>
|
||||||
|
<ToggleButton>
|
||||||
|
<UndoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton selected>
|
||||||
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton disabled>
|
||||||
|
<RedoOutlined />
|
||||||
|
</ToggleButton>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
||||||
"useWorkspaces": true,
|
|
||||||
"version": "independent",
|
"version": "independent",
|
||||||
"packages": ["packages/*"],
|
"packages": ["packages/*"],
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
|
|||||||
+22
-18
@@ -6,7 +6,7 @@
|
|||||||
"apps/*"
|
"apps/*"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "yarn workspace playground start",
|
"start": "yarn workspace playground dev",
|
||||||
"start:docs": "yarn workspace storybook storybook",
|
"start:docs": "yarn workspace storybook storybook",
|
||||||
"start:site": "yarn workspace website start",
|
"start:site": "yarn workspace website start",
|
||||||
"deploy:site": "yarn workspace website deploy",
|
"deploy:site": "yarn workspace website deploy",
|
||||||
@@ -18,18 +18,19 @@
|
|||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"eslint": "eslint packages/**/src/*.{ts,tsx} --cache",
|
"eslint": "eslint packages/**/src/*.{ts,tsx} --cache",
|
||||||
"publish": "lerna publish",
|
"publish": "lerna publish",
|
||||||
"ver": "lerna version --no-private --conventional-commits",
|
"ver": "lerna version --no-private",
|
||||||
"release": "yarn eslint && yarn build && yarn run ver && lerna publish from-git",
|
"release": "yarn eslint && yarn build && lerna version --no-private --conventional-commits && lerna publish from-git",
|
||||||
|
"release:npm": "yarn eslint && yarn build && yarn run ver && lerna publish from-git",
|
||||||
"release:beta": "yarn eslint && yarn build && yarn run ver && lerna publish from-package --dist-tag beta",
|
"release:beta": "yarn eslint && yarn build && yarn run ver && lerna publish from-package --dist-tag beta",
|
||||||
"up": "yarn upgrade-interactive --latest",
|
"up": "yarn upgrade-interactive --latest",
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/preset-env": "^7.23.2",
|
"@babel/preset-env": "^7.23.6",
|
||||||
"@babel/preset-react": "^7.22.15",
|
"@babel/preset-react": "^7.23.3",
|
||||||
"@babel/preset-typescript": "^7.23.2",
|
"@babel/preset-typescript": "^7.23.3",
|
||||||
"@commitlint/cli": "^17.5.0",
|
"@commitlint/cli": "^18.4.3",
|
||||||
"@commitlint/config-conventional": "^17.3.0",
|
"@commitlint/config-conventional": "^18.4.3",
|
||||||
"@types/jest": "^29.5.7",
|
"@types/jest": "^29.5.7",
|
||||||
"@types/lodash-es": "^4.17.10",
|
"@types/lodash-es": "^4.17.10",
|
||||||
"@types/lodash.get": "^4.4.8",
|
"@types/lodash.get": "^4.4.8",
|
||||||
@@ -38,13 +39,13 @@
|
|||||||
"@types/react": "^18.2.34",
|
"@types/react": "^18.2.34",
|
||||||
"@types/react-dom": "^18.2.14",
|
"@types/react-dom": "^18.2.14",
|
||||||
"@types/styled-components": "^5.1.29",
|
"@types/styled-components": "^5.1.29",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||||
"@typescript-eslint/parser": "^6.9.1",
|
"@typescript-eslint/parser": "^6.13.2",
|
||||||
"conventional-changelog-cli": "^2.2.2",
|
"conventional-changelog-cli": "^4.1.0",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"eslint": "^8.52.0",
|
"eslint": "^8.55.0",
|
||||||
"eslint-config-ali": "^14.0.2",
|
"eslint-config-ali": "^14.0.2",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-import-resolver-typescript": "^3.6.1",
|
"eslint-import-resolver-typescript": "^3.6.1",
|
||||||
"eslint-plugin-import": "^2.29.0",
|
"eslint-plugin-import": "^2.29.0",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
@@ -53,14 +54,17 @@
|
|||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"lerna": "^6.6.1",
|
"lerna": "^8.0.0",
|
||||||
"lint-staged": "^14.0.1",
|
"lint-staged": "^15.2.0",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^3.1.0",
|
||||||
"react": "^17.0.0",
|
"react": "^17.0.0",
|
||||||
"react-dom": "^17.0.0",
|
"react-dom": "^17.0.0",
|
||||||
"styled-components": "^5.3.6",
|
"styled-components": "^5.3.6",
|
||||||
"typedoc": "^0.25.3",
|
"typedoc": "^0.25.4",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.3.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,jsx,ts,tsx}": [
|
"*.{js,jsx,ts,tsx}": [
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-context@0.2.12...@music163/tango-context@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-context
|
||||||
|
|
||||||
|
## [0.2.12](https://github.com/netease/tango/compare/@music163/tango-context@0.2.11...@music163/tango-context@0.2.12) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-context
|
||||||
|
|
||||||
|
## [0.2.11](https://github.com/netease/tango/compare/@music163/tango-context@0.2.10...@music163/tango-context@0.2.11) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-context
|
||||||
|
|
||||||
|
## [0.2.10](https://github.com/netease/tango/compare/@music163/tango-context@0.2.9...@music163/tango-context@0.2.10) (2023-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-context
|
||||||
|
|
||||||
## [0.2.9](https://github.com/netease/tango/compare/@music163/tango-context@0.2.8...@music163/tango-context@0.2.9) (2023-11-29)
|
## [0.2.9](https://github.com/netease/tango/compare/@music163/tango-context@0.2.8...@music163/tango-context@0.2.9) (2023-11-29)
|
||||||
|
|
||||||
**Note:** Version bump only for package @music163/tango-context
|
**Note:** Version bump only for package @music163/tango-context
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-context",
|
"name": "@music163/tango-context",
|
||||||
"version": "0.2.9",
|
"version": "1.0.0-alpha.1",
|
||||||
"description": "react context for tango-apps",
|
"description": "react context for tango-apps",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
@@ -31,9 +31,9 @@
|
|||||||
"react": ">= 16.8"
|
"react": ">= 16.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@music163/tango-core": "^0.2.8",
|
"@music163/tango-core": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"mobx-react-lite": "4.0.2"
|
"mobx-react-lite": "4.0.5"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|||||||
@@ -3,6 +3,28 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-core@0.2.11...@music163/tango-core@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-core
|
||||||
|
|
||||||
|
## [0.2.11](https://github.com/netease/tango/compare/@music163/tango-core@0.2.10...@music163/tango-core@0.2.11) (2023-12-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- update FileType ([c884712](https://github.com/netease/tango/commit/c8847123312bc47ea06575f4e714dfd596893e39))
|
||||||
|
|
||||||
|
## [0.2.10](https://github.com/netease/tango/compare/@music163/tango-core@0.2.9...@music163/tango-core@0.2.10) (2023-12-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- add filesFormatter to sandbox & fix update props with imports ([#71](https://github.com/netease/tango/issues/71)) ([138cbe9](https://github.com/netease/tango/commit/138cbe9b203b370aff42c1ae8086d69edacf35e9))
|
||||||
|
|
||||||
|
## [0.2.9](https://github.com/netease/tango/compare/@music163/tango-core@0.2.8...@music163/tango-core@0.2.9) (2023-11-30)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- fix render components tree ([76a5a2c](https://github.com/netease/tango/commit/76a5a2c65920bc42b019cd1f32a3cacd0d888638))
|
||||||
|
|
||||||
## [0.2.8](https://github.com/netease/tango/compare/@music163/tango-core@0.2.7...@music163/tango-core@0.2.8) (2023-11-29)
|
## [0.2.8](https://github.com/netease/tango/compare/@music163/tango-core@0.2.7...@music163/tango-core@0.2.8) (2023-11-29)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-core",
|
"name": "@music163/tango-core",
|
||||||
"version": "0.2.8",
|
"version": "1.0.0-alpha.1",
|
||||||
"description": "tango core",
|
"description": "tango core",
|
||||||
"author": "wwsun <ww.sun@outlook.com>",
|
"author": "wwsun <ww.sun@outlook.com>",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -24,14 +24,14 @@
|
|||||||
"prepublishOnly": "yarn build"
|
"prepublishOnly": "yarn build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/generator": "^7.23.0",
|
"@babel/generator": "^7.23.5",
|
||||||
"@babel/parser": "^7.23.0",
|
"@babel/parser": "^7.23.5",
|
||||||
"@babel/traverse": "^7.23.2",
|
"@babel/traverse": "^7.23.5",
|
||||||
"@babel/types": "^7.23.0",
|
"@babel/types": "^7.23.5",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"@types/babel__generator": "^7.6.6",
|
"@types/babel__generator": "^7.6.7",
|
||||||
"@types/babel__traverse": "^7.20.3",
|
"@types/babel__traverse": "^7.20.4",
|
||||||
"mobx": "6.9.0",
|
"mobx": "6.12.0",
|
||||||
"path-browserify": "^1.0.1"
|
"path-browserify": "^1.0.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ export * from './helpers';
|
|||||||
export * from './types';
|
export * from './types';
|
||||||
|
|
||||||
export { default as generator } from '@babel/generator';
|
export { default as generator } from '@babel/generator';
|
||||||
export { default as traverse } from '@babel/types';
|
export { default as traverse } from '@babel/traverse';
|
||||||
export * from '@babel/parser';
|
export * from '@babel/parser';
|
||||||
|
|||||||
@@ -307,10 +307,24 @@ export class TangoViewModule extends TangoModule implements IViewFile {
|
|||||||
updateNodeAttributes(nodeId: string, config: Record<string, any>, relatedImports?: string[]) {
|
updateNodeAttributes(nodeId: string, config: Record<string, any>, relatedImports?: string[]) {
|
||||||
if (relatedImports && relatedImports.length) {
|
if (relatedImports && relatedImports.length) {
|
||||||
// 导入依赖的组件
|
// 导入依赖的组件
|
||||||
relatedImports.forEach((name: string) => {
|
const newImportData = relatedImports.reduce((prev, name) => {
|
||||||
const proto = this.workspace.getPrototype(name);
|
const proto = this.workspace.getPrototype(name);
|
||||||
const { source, specifiers } = prototype2importDeclarationData(proto, this.filename);
|
const { source, specifiers } = prototype2importDeclarationData(proto, this.filename);
|
||||||
this.addImportSpecifiers(source, specifiers);
|
const existSpecifiers: IImportSpecifierData[] = prev[source];
|
||||||
|
if (existSpecifiers) {
|
||||||
|
// merge specifiers
|
||||||
|
specifiers.forEach((item) => {
|
||||||
|
if (!existSpecifiers.find((existItem) => existItem.localName === item.localName)) {
|
||||||
|
existSpecifiers.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
prev[source] = specifiers;
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}, {});
|
||||||
|
Object.keys(newImportData).forEach((source) => {
|
||||||
|
this.addImportSpecifiers(source, newImportData[source]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.ast = updateJSXAttributes(this.ast, nodeId, config);
|
this.ast = updateJSXAttributes(this.ast, nodeId, config);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { action, computed, makeObservable, observable } from 'mobx';
|
import { action, computed, makeObservable, observable } from 'mobx';
|
||||||
import { JSXElement } from '@babel/types';
|
import { JSXElement } from '@babel/types';
|
||||||
import {
|
import {
|
||||||
array2object,
|
|
||||||
ComponentPrototypeType,
|
ComponentPrototypeType,
|
||||||
hasFileExtension,
|
hasFileExtension,
|
||||||
isString,
|
isString,
|
||||||
@@ -16,7 +15,6 @@ import {
|
|||||||
getJSXElementChildrenNames,
|
getJSXElementChildrenNames,
|
||||||
namesToImportDeclarations,
|
namesToImportDeclarations,
|
||||||
getBlockNameByFilename,
|
getBlockNameByFilename,
|
||||||
getPrivilegeCode,
|
|
||||||
prototype2importDeclarationData,
|
prototype2importDeclarationData,
|
||||||
} from '../helpers';
|
} from '../helpers';
|
||||||
import { DropMethod } from './drop-target';
|
import { DropMethod } from './drop-target';
|
||||||
@@ -96,7 +94,7 @@ export class Workspace extends EventTarget implements IWorkspace {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地区块 { [blockName]: filePath }
|
* 本地区块 { [blockName]: filePath }
|
||||||
* FIXME: 修正类型 Record<string, TangoBlockModule>
|
* TODO: 废弃这个,不再支持
|
||||||
*/
|
*/
|
||||||
localBlocks: Record<string, string>;
|
localBlocks: Record<string, string>;
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,20 @@ export enum FileType {
|
|||||||
Module = 'module',
|
Module = 'module',
|
||||||
StoreEntryModule = 'storeEntryModule',
|
StoreEntryModule = 'storeEntryModule',
|
||||||
RouteModule = 'routeModule',
|
RouteModule = 'routeModule',
|
||||||
BlockEntryModule = 'blockEntryModule',
|
|
||||||
ServiceModule = 'serviceModule',
|
ServiceModule = 'serviceModule',
|
||||||
StoreModule = 'storeModule',
|
StoreModule = 'storeModule',
|
||||||
|
|
||||||
|
// 组件配置文件
|
||||||
|
ComponentPrototypeModule = 'componentPrototypeModule',
|
||||||
|
// 组件运行调试入口文件,一般为 `/app.js`
|
||||||
|
ComponentDemoEntryModule = 'componentDemoEntryModule',
|
||||||
|
|
||||||
|
// 区块入口文件 FIXME: 是否移除
|
||||||
|
BlockEntryModule = 'blockEntryModule',
|
||||||
|
|
||||||
|
// jsx 类型视图文件
|
||||||
JsxViewModule = 'jsxViewModule',
|
JsxViewModule = 'jsxViewModule',
|
||||||
|
// json 类型视图文件
|
||||||
JsonViewModule = 'jsonViewModule',
|
JsonViewModule = 'jsonViewModule',
|
||||||
|
|
||||||
// 非 js 文件
|
// 非 js 文件
|
||||||
|
|||||||
@@ -3,6 +3,35 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.2](https://github.com/netease/tango/compare/@music163/tango-designer@1.0.0-alpha.1...@music163/tango-designer@1.0.0-alpha.2) (2023-12-13)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- update variable tree with help messages and styling & add tangoConfig schema ([5e7e285](https://github.com/netease/tango/commit/5e7e285452b46888b447991b0e8548b6392acb3a))
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.14...@music163/tango-designer@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
|
||||||
|
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
|
||||||
|
|
||||||
|
## [0.5.14](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.13...@music163/tango-designer@0.5.14) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-designer
|
||||||
|
|
||||||
|
## [0.5.13](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.12...@music163/tango-designer@0.5.13) (2023-12-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- add filesFormatter to sandbox & fix update props with imports ([#71](https://github.com/netease/tango/issues/71)) ([138cbe9](https://github.com/netease/tango/commit/138cbe9b203b370aff42c1ae8086d69edacf35e9))
|
||||||
|
|
||||||
|
## [0.5.12](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.11...@music163/tango-designer@0.5.12) (2023-11-30)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- fix render components tree ([76a5a2c](https://github.com/netease/tango/commit/76a5a2c65920bc42b019cd1f32a3cacd0d888638))
|
||||||
|
|
||||||
## [0.5.11](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.10...@music163/tango-designer@0.5.11) (2023-11-29)
|
## [0.5.11](https://github.com/netease/tango/compare/@music163/tango-designer@0.5.10...@music163/tango-designer@0.5.11) (2023-11-29)
|
||||||
|
|
||||||
**Note:** Version bump only for package @music163/tango-designer
|
**Note:** Version bump only for package @music163/tango-designer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-designer",
|
"name": "@music163/tango-designer",
|
||||||
"version": "0.5.11",
|
"version": "1.0.0-alpha.2",
|
||||||
"description": "lowcode designer",
|
"description": "lowcode designer",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react"
|
"react"
|
||||||
@@ -33,12 +33,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@music163/request": "^0.1.2",
|
"@music163/request": "^0.1.2",
|
||||||
"@music163/tango-context": "^0.2.9",
|
"@music163/tango-context": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-core": "^0.2.8",
|
"@music163/tango-core": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"@music163/tango-sandbox": "^0.1.13",
|
"@music163/tango-sandbox": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-setting-form": "^0.2.13",
|
"@music163/tango-setting-form": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-ui": "^0.1.12",
|
"@music163/tango-ui": "^1.0.0-alpha.1",
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"cash-dom": "^8.1.2",
|
"cash-dom": "^8.1.2",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Empty,
|
Empty,
|
||||||
Popconfirm,
|
Popconfirm,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Alert,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { Box, Text, css } from 'coral-system';
|
import { Box, Text, css } from 'coral-system';
|
||||||
import {
|
import {
|
||||||
@@ -166,7 +167,7 @@ export function EditableVariableTree({
|
|||||||
height={height}
|
height={height}
|
||||||
position="relative"
|
position="relative"
|
||||||
>
|
>
|
||||||
<Box p="l" width="40%" borderRight="solid" borderColor="line.normal">
|
<Box p="l" width="40%">
|
||||||
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
|
<Box mb="m" position="sticky" top="0" bg="white" zIndex={2}>
|
||||||
<Input.Group compact>
|
<Input.Group compact>
|
||||||
<Search
|
<Search
|
||||||
@@ -201,7 +202,17 @@ export function EditableVariableTree({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{node ? (
|
{node ? (
|
||||||
|
<Box width="60%" position="sticky" top="0">
|
||||||
|
{node.help && (
|
||||||
|
<Alert
|
||||||
|
type="info"
|
||||||
|
message={`使用说明:${node.help}`}
|
||||||
|
closable
|
||||||
|
style={{ marginBottom: 12 }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Panel
|
<Panel
|
||||||
|
shape="solid"
|
||||||
title={
|
title={
|
||||||
{
|
{
|
||||||
preview: '变量值预览',
|
preview: '变量值预览',
|
||||||
@@ -221,10 +232,6 @@ export function EditableVariableTree({
|
|||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
width="60%"
|
|
||||||
borderRadius="m"
|
|
||||||
position="sticky"
|
|
||||||
top="0"
|
|
||||||
bodyProps={{ px: 'm' }}
|
bodyProps={{ px: 'm' }}
|
||||||
>
|
>
|
||||||
{mode === 'preview' && (
|
{mode === 'preview' && (
|
||||||
@@ -261,8 +268,9 @@ export function EditableVariableTree({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Panel>
|
</Panel>
|
||||||
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Panel title="提示" flex="1" position="sticky" top="0">
|
<Panel shape="solid" title="提示" flex="1" position="sticky" top="0">
|
||||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请从左侧列表中选择一个变量" />
|
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请从左侧列表中选择一个变量" />
|
||||||
</Panel>
|
</Panel>
|
||||||
)}
|
)}
|
||||||
@@ -469,11 +477,11 @@ interface NodePreviewProps {
|
|||||||
|
|
||||||
export function ValuePreview({ value, onSelect }: NodePreviewProps) {
|
export function ValuePreview({ value, onSelect }: NodePreviewProps) {
|
||||||
if (isNil(value)) {
|
if (isNil(value)) {
|
||||||
return <span>暂时没有可预览的数据</span>;
|
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂时没有可预览的数据" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFunction(value)) {
|
if (isFunction(value)) {
|
||||||
return <span>暂不支持预览函数</span>;
|
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂不支持预览函数" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
@@ -503,7 +511,7 @@ function NodeDefineForm({ node, onSave = noop, onDelete = noop }: NodeDefineProp
|
|||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
const [editable, { on, off }] = useBoolean();
|
const [editable, { on, off }] = useBoolean();
|
||||||
if (isNil(node.raw)) {
|
if (isNil(node.raw)) {
|
||||||
return <Empty description="缺失定义数据" />;
|
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="缺失定义数据" />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ export type SandboxProps = Omit<CodeSandboxProps, 'files' | 'eventHandlers' | 'o
|
|||||||
* tangoConfigJson 处理器
|
* tangoConfigJson 处理器
|
||||||
*/
|
*/
|
||||||
configFormatter?: IMergeTangoConfigJsonConfig['formatter'];
|
configFormatter?: IMergeTangoConfigJsonConfig['formatter'];
|
||||||
|
/**
|
||||||
|
* 文件格式化器
|
||||||
|
* @param files 沙箱文件列表
|
||||||
|
* @returns 修改后的文件列表
|
||||||
|
*/
|
||||||
|
filesFormatter?: (files: CodeSandboxProps['files']) => CodeSandboxProps['files'];
|
||||||
sandboxType?: 'design' | 'preview';
|
sandboxType?: 'design' | 'preview';
|
||||||
mode?: 'single' | 'combined';
|
mode?: 'single' | 'combined';
|
||||||
injectScript?: string;
|
injectScript?: string;
|
||||||
@@ -41,6 +47,7 @@ const LANDING_PAGE_PATH = '/__background_landing_page__';
|
|||||||
function useSandbox({
|
function useSandbox({
|
||||||
isPreview: isPreviewProp,
|
isPreview: isPreviewProp,
|
||||||
configFormatter,
|
configFormatter,
|
||||||
|
filesFormatter,
|
||||||
onViewChange,
|
onViewChange,
|
||||||
onMessage: onMessageProp,
|
onMessage: onMessageProp,
|
||||||
onLoad: onLoadProp,
|
onLoad: onLoadProp,
|
||||||
@@ -79,7 +86,12 @@ function useSandbox({
|
|||||||
prev[filename] = { code };
|
prev[filename] = { code };
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
files = fixSandboxFiles(files, workspace.entry);
|
files = fixSandboxFiles(files, workspace.entry);
|
||||||
|
if (filesFormatter) {
|
||||||
|
// 支持用户对传入的文件进行修改
|
||||||
|
files = filesFormatter(files);
|
||||||
|
}
|
||||||
|
|
||||||
const onMessage = (data: any) => onMessageProp && onMessageProp(data, getSandboxConfig());
|
const onMessage = (data: any) => onMessageProp && onMessageProp(data, getSandboxConfig());
|
||||||
const onLoad = () => onLoadProp && onLoadProp(getSandboxConfig());
|
const onLoad = () => onLoadProp && onLoadProp(getSandboxConfig());
|
||||||
@@ -413,6 +425,7 @@ function fixSandboxFiles(files: Record<string, { code: string }>, entry = '/src/
|
|||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,4 +168,6 @@ const setters: IFormItemCreateOptions[] = [
|
|||||||
{ name: 'borderSetter', component: BorderSetter },
|
{ name: 'borderSetter', component: BorderSetter },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export function registerBuiltinSetters() {
|
||||||
setters.forEach(register);
|
setters.forEach(register);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import { SettingForm, FormModel, SettingFormProps } from '@music163/tango-settin
|
|||||||
import { Panel } from '@music163/tango-ui';
|
import { Panel } from '@music163/tango-ui';
|
||||||
import { clone } from '@music163/tango-helpers';
|
import { clone } from '@music163/tango-helpers';
|
||||||
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
|
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
|
||||||
import './setters';
|
import { registerBuiltinSetters } from './setters';
|
||||||
|
|
||||||
|
registerBuiltinSetters();
|
||||||
|
|
||||||
export interface SettingPanelProps extends SettingFormProps {
|
export interface SettingPanelProps extends SettingFormProps {
|
||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo } from 'react';
|
||||||
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
||||||
import { Box, css } from 'coral-system';
|
import { Box, css } from 'coral-system';
|
||||||
import { Button, FormProps, Empty, Space, Dropdown } from 'antd';
|
import { Button, FormProps, Empty, Space, Dropdown, Form, Select, Input } from 'antd';
|
||||||
import { PlayCircleOutlined } from '@ant-design/icons';
|
import { PlayCircleOutlined } from '@ant-design/icons';
|
||||||
import { Form, InputCode, Panel, JsonView, Search } from '@music163/tango-ui';
|
import { InputCode, Panel, JsonView, Search } from '@music163/tango-ui';
|
||||||
import {
|
import {
|
||||||
isNil,
|
isNil,
|
||||||
getVariableContent,
|
getVariableContent,
|
||||||
@@ -37,15 +37,6 @@ enum ServiceFunctionMethodType {
|
|||||||
// DELETE = 'DELETE',
|
// DELETE = 'DELETE',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* requestType
|
|
||||||
* headers: Content-Type
|
|
||||||
*/
|
|
||||||
enum DataServiceRequestType {
|
|
||||||
'application/json' = 'json',
|
|
||||||
'application/x-www-form-urlencoded' = 'x-www-form-urlencoded',
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 api 路径转换为默认的驼峰方法名
|
* 将 api 路径转换为默认的驼峰方法名
|
||||||
*/
|
*/
|
||||||
@@ -79,12 +70,6 @@ const httpMethods = Object.keys(ServiceFunctionMethodType).map((key) => ({
|
|||||||
value: key,
|
value: key,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// requestType 类型
|
|
||||||
const requestTypes = Object.keys(DataServiceRequestType).map((key) => ({
|
|
||||||
label: key,
|
|
||||||
value: DataServiceRequestType[key],
|
|
||||||
}));
|
|
||||||
|
|
||||||
const detailFormStyle = css`
|
const detailFormStyle = css`
|
||||||
.ant-form-item {
|
.ant-form-item {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
@@ -261,8 +246,8 @@ function ServiceDetailForm({
|
|||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
labelCol={6}
|
labelCol={{ span: 6 }}
|
||||||
wrapperCol={17}
|
wrapperCol={{ span: 17 }}
|
||||||
colon={false}
|
colon={false}
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
@@ -285,12 +270,9 @@ function ServiceDetailForm({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
component="select"
|
>
|
||||||
componentProps={{
|
<Select options={serviceModules} disabled={disabled || isModifyMode} />
|
||||||
options: serviceModules,
|
</Form.Item>
|
||||||
disabled: disabled || isModifyMode,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="方法名"
|
label="方法名"
|
||||||
name="name"
|
name="name"
|
||||||
@@ -308,11 +290,6 @@ function ServiceDetailForm({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
component="input"
|
|
||||||
componentProps={{
|
|
||||||
placeholder: '请输入数据服务调用名称',
|
|
||||||
disabled: disabled || isModifyMode,
|
|
||||||
}}
|
|
||||||
extra={
|
extra={
|
||||||
!disabled &&
|
!disabled &&
|
||||||
!isModifyMode && (
|
!isModifyMode && (
|
||||||
@@ -331,38 +308,15 @@ function ServiceDetailForm({
|
|||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
<Form.Item
|
<Input placeholder="请输入数据服务调用名称" disabled={disabled || isModifyMode} />
|
||||||
label="路径"
|
</Form.Item>
|
||||||
name="url"
|
<Form.Item label="路径" name="url" rules={[{ required: true, type: 'url' }]}>
|
||||||
rules={[{ required: true, type: 'url' }]}
|
<Input placeholder="请输入数据服务调用名称" disabled={disabled || isModifyMode} />
|
||||||
component="input"
|
</Form.Item>
|
||||||
componentProps={{
|
<Form.Item label="方法" name="method">
|
||||||
placeholder: '请输入数据服务调用名称',
|
<Select options={httpMethods} placeholder="请选择 HTTP 请求方法" disabled={disabled} />
|
||||||
disabled: disabled || isModifyMode,
|
</Form.Item>
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Form.Item
|
|
||||||
label="方法"
|
|
||||||
name="method"
|
|
||||||
component="select"
|
|
||||||
componentProps={{
|
|
||||||
options: httpMethods,
|
|
||||||
placeholder: '请选择 HTTP 请求方法',
|
|
||||||
disabled,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Form.Item
|
|
||||||
label="编码类型"
|
|
||||||
name="requestType"
|
|
||||||
tooltip="设置请求头的 Content-Type,若不设置,则默认变为为 JSON"
|
|
||||||
component="select"
|
|
||||||
componentProps={{
|
|
||||||
options: requestTypes,
|
|
||||||
placeholder: '请求头Content-Type,默认为JSON',
|
|
||||||
disabled,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="格式化响应"
|
label="格式化响应"
|
||||||
name="formatter"
|
name="formatter"
|
||||||
|
|||||||
@@ -148,6 +148,12 @@ export const ComponentsTree: React.FC<ComponentsTreeProps> = observer(
|
|||||||
setSelectedKeys(workspace.selectSource.selected.map((item) => item.id));
|
setSelectedKeys(workspace.selectSource.selected.map((item) => item.id));
|
||||||
}, [workspace.selectSource.selected]);
|
}, [workspace.selectSource.selected]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setExpandedKeys(getNodeKeys(nodesTree));
|
||||||
|
// nodeTree 更新后重新计算expandKeys
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [nodesTree?.[0]?.id]);
|
||||||
|
|
||||||
if (!nodesTree.length) {
|
if (!nodesTree.length) {
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
@@ -156,12 +162,6 @@ export const ComponentsTree: React.FC<ComponentsTreeProps> = observer(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setExpandedKeys(getNodeKeys(nodesTree));
|
|
||||||
// nodeTree 更新后重新计算expandKeys
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [nodesTree?.[0]?.id]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box css={outlineStyle}>
|
<Box css={outlineStyle}>
|
||||||
<Tree
|
<Tree
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button, Space } from 'antd';
|
import { Button, Space, Form, Input } from 'antd';
|
||||||
import { useBoolean } from '@music163/tango-helpers';
|
|
||||||
import { Panel, Form, IconButton } from '@music163/tango-ui';
|
|
||||||
import { FileAddOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
import { FileAddOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
|
import { useBoolean } from '@music163/tango-helpers';
|
||||||
|
import { Panel, IconButton } from '@music163/tango-ui';
|
||||||
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
import { observer, useWorkspace, useWorkspaceData } from '@music163/tango-context';
|
||||||
import { EditableVariableTree, EditableVariableTreeProps } from '../components';
|
import { EditableVariableTree, EditableVariableTreeProps } from '../components';
|
||||||
|
|
||||||
@@ -90,9 +90,10 @@ interface AddStoreFormProps {
|
|||||||
|
|
||||||
function AddStoreForm({ existNames = [], onCancel, onSubmit }: AddStoreFormProps) {
|
function AddStoreForm({ existNames = [], onCancel, onSubmit }: AddStoreFormProps) {
|
||||||
return (
|
return (
|
||||||
<Panel title="添加模型" subTitle="模型可以用来组织一组变量">
|
<Panel title="添加模型" subTitle="模型可以用来组织一组变量" bodyProps={{ p: 'l' }}>
|
||||||
<Form
|
<Form
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
colon={false}
|
||||||
onFinish={(values) => {
|
onFinish={(values) => {
|
||||||
onSubmit && onSubmit(values);
|
onSubmit && onSubmit(values);
|
||||||
}}
|
}}
|
||||||
@@ -112,11 +113,9 @@ function AddStoreForm({ existNames = [], onCancel, onSubmit }: AddStoreFormProps
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
component="input"
|
>
|
||||||
componentProps={{
|
<Input placeholder="请输入模型名称" />
|
||||||
placeholder: '请输入模型名称',
|
</Form.Item>
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Form.Item label=" ">
|
<Form.Item label=" ">
|
||||||
<Space>
|
<Space>
|
||||||
<Button onClick={onCancel}>取消</Button>
|
<Button onClick={onCancel}>取消</Button>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box } from 'coral-system';
|
import { Box } from 'coral-system';
|
||||||
import { ToggleButton, IconFont } from '@music163/tango-ui';
|
import { ToggleButton, RedoOutlined, UndoOutlined } from '@music163/tango-ui';
|
||||||
import { observer, useWorkspace } from '@music163/tango-context';
|
import { observer, useWorkspace } from '@music163/tango-context';
|
||||||
|
|
||||||
export const HistoryTool = observer(() => {
|
export const HistoryTool = observer(() => {
|
||||||
@@ -16,7 +16,7 @@ export const HistoryTool = observer(() => {
|
|||||||
workspace.selectSource.clear();
|
workspace.selectSource.clear();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconFont type="icon-undo" />
|
<UndoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
shape="ghost"
|
shape="ghost"
|
||||||
@@ -27,7 +27,7 @@ export const HistoryTool = observer(() => {
|
|||||||
workspace.selectSource.clear();
|
workspace.selectSource.clear();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconFont type="icon-redo" />
|
<RedoOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Group } from 'coral-system';
|
import { Group } from 'coral-system';
|
||||||
import { Modal } from 'antd';
|
import { Modal } from 'antd';
|
||||||
import { ToggleButton } from '@music163/tango-ui';
|
import { ToggleButton, CodeOutlined } from '@music163/tango-ui';
|
||||||
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
|
import { observer, useDesigner, useWorkspace } from '@music163/tango-context';
|
||||||
|
import { BorderOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
export const ModeSwitchTool = observer(() => {
|
export const ModeSwitchTool = observer(() => {
|
||||||
const workspace = useWorkspace();
|
const workspace = useWorkspace();
|
||||||
@@ -17,7 +18,7 @@ export const ModeSwitchTool = observer(() => {
|
|||||||
}}
|
}}
|
||||||
tooltip="设计视图"
|
tooltip="设计视图"
|
||||||
>
|
>
|
||||||
设计
|
<BorderOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
shape="ghost"
|
shape="ghost"
|
||||||
@@ -36,7 +37,7 @@ export const ModeSwitchTool = observer(() => {
|
|||||||
}}
|
}}
|
||||||
tooltip="源码视图"
|
tooltip="源码视图"
|
||||||
>
|
>
|
||||||
源码
|
<CodeOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { Button, Popconfirm, Modal, ModalProps } from 'antd';
|
import { Button, Popconfirm, Modal, ModalProps, Form, Input } from 'antd';
|
||||||
import { Box, css, Group, Text } from 'coral-system';
|
import { Box, css, Group, Text } from 'coral-system';
|
||||||
import { FileOutlined, DeleteOutlined, CopyOutlined, SettingOutlined } from '@ant-design/icons';
|
import { FileOutlined, DeleteOutlined, CopyOutlined, SettingOutlined } from '@ant-design/icons';
|
||||||
import { array2object, callAll } from '@music163/tango-helpers';
|
import { array2object, callAll } from '@music163/tango-helpers';
|
||||||
import { IPageConfigData } from '@music163/tango-core';
|
import { IPageConfigData } from '@music163/tango-core';
|
||||||
import { Form, ToggleButton } from '@music163/tango-ui';
|
import { ToggleButton } from '@music163/tango-ui';
|
||||||
import { observer, useWorkspace } from '@music163/tango-context';
|
import { observer, useWorkspace } from '@music163/tango-context';
|
||||||
|
|
||||||
export const RouteSwitchTool = observer(() => {
|
export const RouteSwitchTool = observer(() => {
|
||||||
@@ -250,17 +250,13 @@ function CopyViewModalForm({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Form
|
<Form
|
||||||
wrapperCol={20}
|
wrapperCol={{ span: 20 }}
|
||||||
form={form}
|
form={form}
|
||||||
initialValues={{ name: current?.name, path: current?.path }}
|
initialValues={{ name: current?.name, path: current?.path }}
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item label="页面标题" name="name" required>
|
||||||
label="页面标题"
|
<Input placeholder="请输入标题" />
|
||||||
name="name"
|
</Form.Item>
|
||||||
required
|
|
||||||
component="input"
|
|
||||||
componentProps={{ placeholder: '请输入标题' }}
|
|
||||||
/>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="页面路由"
|
label="页面路由"
|
||||||
name="path"
|
name="path"
|
||||||
@@ -281,11 +277,9 @@ function CopyViewModalForm({
|
|||||||
message: '非法的路由地址',
|
message: '非法的路由地址',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
component="input"
|
>
|
||||||
componentProps={{
|
<Input placeholder="请输入页面路由" />
|
||||||
placeholder: '输入页面路由',
|
</Form.Item>
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer, useDesigner } from '@music163/tango-context';
|
import { observer, useDesigner } from '@music163/tango-context';
|
||||||
import { Box } from 'coral-system';
|
import { Box } from 'coral-system';
|
||||||
import { IconFont, ToggleButton } from '@music163/tango-ui';
|
import {
|
||||||
|
OpenPanelFilledLeftOutlined,
|
||||||
|
OpenPanelFilledRightOutlined,
|
||||||
|
OpenPanelLeftOutlined,
|
||||||
|
OpenPanelRightOutlined,
|
||||||
|
ToggleButton,
|
||||||
|
} from '@music163/tango-ui';
|
||||||
|
|
||||||
export const TogglePanelTool = observer(() => {
|
export const TogglePanelTool = observer(() => {
|
||||||
const designer = useDesigner();
|
const designer = useDesigner();
|
||||||
@@ -14,20 +20,15 @@ export const TogglePanelTool = observer(() => {
|
|||||||
designer.setActiveSidebarPanel(designer.activeSidebarPanel ? '' : 'outline');
|
designer.setActiveSidebarPanel(designer.activeSidebarPanel ? '' : 'outline');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconFont
|
{designer.activeSidebarPanel ? <OpenPanelFilledLeftOutlined /> : <OpenPanelLeftOutlined />}
|
||||||
type={
|
|
||||||
designer.activeSidebarPanel ? 'icon-open-panel-filled-left' : 'icon-open-panel-left'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
tooltip="隐藏/显示右侧面板"
|
tooltip="隐藏/显示右侧面板"
|
||||||
shape="ghost"
|
shape="ghost"
|
||||||
onClick={() => designer.toggleRightPanel()}
|
onClick={() => designer.toggleRightPanel()}
|
||||||
|
disabled={designer.activeView === 'code'}
|
||||||
>
|
>
|
||||||
<IconFont
|
{designer.showRightPanel ? <OpenPanelFilledRightOutlined /> : <OpenPanelRightOutlined />}
|
||||||
type={designer.showRightPanel ? 'icon-open-panel-filled-right' : 'icon-open-panel-right'}
|
|
||||||
/>
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.16...@music163/tango-sandbox@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-sandbox
|
||||||
|
|
||||||
|
## [0.1.16](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.15...@music163/tango-sandbox@0.1.16) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-sandbox
|
||||||
|
|
||||||
|
## [0.1.15](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.14...@music163/tango-sandbox@0.1.15) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-sandbox
|
||||||
|
|
||||||
|
## [0.1.14](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.13...@music163/tango-sandbox@0.1.14) (2023-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-sandbox
|
||||||
|
|
||||||
## [0.1.13](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.12...@music163/tango-sandbox@0.1.13) (2023-11-29)
|
## [0.1.13](https://github.com/netease/tango/compare/@music163/tango-sandbox@0.1.12...@music163/tango-sandbox@0.1.13) (2023-11-29)
|
||||||
|
|
||||||
**Note:** Version bump only for package @music163/tango-sandbox
|
**Note:** Version bump only for package @music163/tango-sandbox
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-sandbox",
|
"name": "@music163/tango-sandbox",
|
||||||
"version": "0.1.13",
|
"version": "1.0.0-alpha.1",
|
||||||
"description": "sandbox of tango apps",
|
"description": "sandbox of tango apps",
|
||||||
"author": "wwsun <ww.sun@outlook.com>",
|
"author": "wwsun <ww.sun@outlook.com>",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@music163/tango-core": "^0.2.8",
|
"@music163/tango-core": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"lodash.isequal": "4.5.0",
|
"lodash.isequal": "4.5.0",
|
||||||
|
|||||||
@@ -3,6 +3,25 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.16...@music163/tango-setting-form@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
|
||||||
|
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
|
||||||
|
|
||||||
|
## [0.2.16](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.15...@music163/tango-setting-form@0.2.16) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
|
## [0.2.15](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.14...@music163/tango-setting-form@0.2.15) (2023-12-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
|
## [0.2.14](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.13...@music163/tango-setting-form@0.2.14) (2023-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @music163/tango-setting-form
|
||||||
|
|
||||||
## [0.2.13](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.12...@music163/tango-setting-form@0.2.13) (2023-11-29)
|
## [0.2.13](https://github.com/netease/tango/compare/@music163/tango-setting-form@0.2.12...@music163/tango-setting-form@0.2.13) (2023-11-29)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-setting-form",
|
"name": "@music163/tango-setting-form",
|
||||||
"version": "0.2.13",
|
"version": "1.0.0-alpha.1",
|
||||||
"description": "setting form of tango-apps",
|
"description": "setting form of tango-apps",
|
||||||
"author": "wwsun <ww.sun@outlook.com>",
|
"author": "wwsun <ww.sun@outlook.com>",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@music163/tango-core": "^0.2.8",
|
"@music163/tango-core": "^1.0.0-alpha.1",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"@music163/tango-ui": "^0.1.12",
|
"@music163/tango-ui": "^1.0.0-alpha.1",
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"coral-system": "^1.0.5",
|
"coral-system": "^1.0.5",
|
||||||
"mobx": "6.9.0",
|
"mobx": "6.12.0",
|
||||||
"mobx-react-lite": "4.0.2"
|
"mobx-react-lite": "4.0.5"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|||||||
@@ -8,14 +8,15 @@ import {
|
|||||||
useBoolean,
|
useBoolean,
|
||||||
} from '@music163/tango-helpers';
|
} from '@music163/tango-helpers';
|
||||||
import { isWrappedByExpressionContainer } from '@music163/tango-core';
|
import { isWrappedByExpressionContainer } from '@music163/tango-core';
|
||||||
import { IconFont, ToggleButton } from '@music163/tango-ui';
|
import { ToggleButton, CodeOutlined } from '@music163/tango-ui';
|
||||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
import { InputProps } from 'antd';
|
||||||
import { InputProps, Tooltip } from 'antd';
|
|
||||||
import { useFormModel, useFormVariable } from './context';
|
import { useFormModel, useFormVariable } from './context';
|
||||||
import { FormControl } from './form-ui';
|
import { FormControl } from './form-ui';
|
||||||
|
import { Box, Text } from 'coral-system';
|
||||||
|
|
||||||
export interface FormItemProps extends ComponentPropType {
|
export interface FormItemProps extends ComponentPropType {
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
|
footer?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormItemComponentProps<T = any> {
|
export interface FormItemComponentProps<T = any> {
|
||||||
@@ -76,6 +77,7 @@ export function createFormItem(options: IFormItemCreateOptions) {
|
|||||||
getVisible: getVisibleProp,
|
getVisible: getVisibleProp,
|
||||||
getSetterProps: getSetterPropsProp,
|
getSetterProps: getSetterPropsProp,
|
||||||
extra,
|
extra,
|
||||||
|
footer,
|
||||||
}: FormItemProps) {
|
}: FormItemProps) {
|
||||||
const { disableSwitchExpressionSetter } = useFormVariable();
|
const { disableSwitchExpressionSetter } = useFormVariable();
|
||||||
const model = useFormModel();
|
const model = useFormModel();
|
||||||
@@ -106,7 +108,7 @@ export function createFormItem(options: IFormItemCreateOptions) {
|
|||||||
|
|
||||||
let expProps = {};
|
let expProps = {};
|
||||||
|
|
||||||
// FIXME: 重新考虑这段代码的位置
|
// FIXME: 重新考虑这段代码的位置,外置这个逻辑
|
||||||
if (['expressionSetter', 'actionSetter', 'eventSetter'].includes(setter) || isVariable) {
|
if (['expressionSetter', 'actionSetter', 'eventSetter'].includes(setter) || isVariable) {
|
||||||
expProps = {
|
expProps = {
|
||||||
modalTitle: title,
|
modalTitle: title,
|
||||||
@@ -141,7 +143,8 @@ export function createFormItem(options: IFormItemCreateOptions) {
|
|||||||
docs={docs}
|
docs={docs}
|
||||||
error={field.error}
|
error={field.error}
|
||||||
extra={
|
extra={
|
||||||
<>
|
<Box>
|
||||||
|
{extra}
|
||||||
{!disableVariableSetter ? (
|
{!disableVariableSetter ? (
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
borderRadius="s"
|
borderRadius="s"
|
||||||
@@ -153,12 +156,12 @@ export function createFormItem(options: IFormItemCreateOptions) {
|
|||||||
selected={isVariable}
|
selected={isVariable}
|
||||||
onClick={() => toggleIsVariable()}
|
onClick={() => toggleIsVariable()}
|
||||||
>
|
>
|
||||||
<IconFont type="icon-brackets-curly" />
|
<CodeOutlined />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
) : null}
|
) : null}
|
||||||
{extra}
|
</Box>
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
|
footer={footer}
|
||||||
data-setter={setterName}
|
data-setter={setterName}
|
||||||
data-field={name}
|
data-field={name}
|
||||||
>
|
>
|
||||||
@@ -187,10 +190,6 @@ export function register(config: IFormItemCreateOptions) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
color: 'red',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function SettingFormItem(props: FormItemProps) {
|
export function SettingFormItem(props: FormItemProps) {
|
||||||
const { setter } = props;
|
const { setter } = props;
|
||||||
const Comp = REGISTERED_FORM_ITEM_MAP[setter];
|
const Comp = REGISTERED_FORM_ITEM_MAP[setter];
|
||||||
@@ -199,10 +198,10 @@ export function SettingFormItem(props: FormItemProps) {
|
|||||||
return (
|
return (
|
||||||
<Fallback
|
<Fallback
|
||||||
{...props}
|
{...props}
|
||||||
extra={
|
footer={
|
||||||
<Tooltip title={`${props.name}: invalid setter ${props.setter}`}>
|
<Text color="red" mt="m">
|
||||||
<QuestionCircleOutlined color="red" style={iconStyle} />
|
{props.setter} is invalid
|
||||||
</Tooltip>
|
</Text>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { isNil, isString } from '@music163/tango-helpers';
|
|||||||
export interface FormControlProps extends Omit<FormLabelProps, 'type'> {
|
export interface FormControlProps extends Omit<FormLabelProps, 'type'> {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
|
footer?: React.ReactNode;
|
||||||
error?: string;
|
error?: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
@@ -18,6 +19,7 @@ export function FormControl({
|
|||||||
tip,
|
tip,
|
||||||
docs,
|
docs,
|
||||||
extra,
|
extra,
|
||||||
|
footer,
|
||||||
error,
|
error,
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
@@ -29,6 +31,7 @@ export function FormControl({
|
|||||||
{extra}
|
{extra}
|
||||||
</Box>
|
</Box>
|
||||||
<Box>{children}</Box>
|
<Box>{children}</Box>
|
||||||
|
{footer}
|
||||||
{!!error && (
|
{!!error && (
|
||||||
<Box mt="m" color="red">
|
<Box mt="m" color="red">
|
||||||
{error}
|
{error}
|
||||||
|
|||||||
@@ -83,7 +83,15 @@ export interface SettingFormProps {
|
|||||||
*/
|
*/
|
||||||
prototype?: ComponentPrototypeType;
|
prototype?: ComponentPrototypeType;
|
||||||
/**
|
/**
|
||||||
* 选项分组信息
|
* 是否显示搜索框
|
||||||
|
*/
|
||||||
|
showSearch?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否显示分组导航
|
||||||
|
*/
|
||||||
|
showGroups?: boolean;
|
||||||
|
/**
|
||||||
|
* 选项分组信息,用于对表单项进行分组展示,如未提供,则使用内置的分组信息
|
||||||
*/
|
*/
|
||||||
groupOptions?: IFormTabsGroupOption[];
|
groupOptions?: IFormTabsGroupOption[];
|
||||||
/**
|
/**
|
||||||
@@ -98,6 +106,8 @@ export function SettingForm({
|
|||||||
model: modelProp,
|
model: modelProp,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
onChange = noop,
|
onChange = noop,
|
||||||
|
showSearch = true,
|
||||||
|
showGroups = true,
|
||||||
groupOptions = internalGroups,
|
groupOptions = internalGroups,
|
||||||
}: SettingFormProps) {
|
}: SettingFormProps) {
|
||||||
const [keyword, setKeyword] = useState('');
|
const [keyword, setKeyword] = useState('');
|
||||||
@@ -107,10 +117,8 @@ export function SettingForm({
|
|||||||
const componentPropGroups = useMemo(() => {
|
const componentPropGroups = useMemo(() => {
|
||||||
return normalizeComponentProps(componentProps);
|
return normalizeComponentProps(componentProps);
|
||||||
}, [componentProps]);
|
}, [componentProps]);
|
||||||
|
|
||||||
const filterProps = useMemo(() => {
|
const filterProps = useMemo(() => {
|
||||||
if (!keyword) {
|
|
||||||
return componentPropGroups[tabKey] || [];
|
|
||||||
}
|
|
||||||
const computedProps = mapTreeData(componentProps, (node) => {
|
const computedProps = mapTreeData(componentProps, (node) => {
|
||||||
const { getProp, ...rest } = node;
|
const { getProp, ...rest } = node;
|
||||||
return {
|
return {
|
||||||
@@ -118,8 +126,19 @@ export function SettingForm({
|
|||||||
...getProp?.(model),
|
...getProp?.(model),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 没有进行搜索的情况
|
||||||
|
if (!keyword) {
|
||||||
|
if (showGroups) {
|
||||||
|
return componentPropGroups[tabKey] || [];
|
||||||
|
} else {
|
||||||
|
return computedProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户进行搜索的情况
|
||||||
return filterComponentProps(computedProps, keyword);
|
return filterComponentProps(computedProps, keyword);
|
||||||
}, [keyword, componentProps, tabKey, model]);
|
}, [keyword, componentProps, tabKey, model, showGroups, componentPropGroups]);
|
||||||
|
|
||||||
const renderProps = useCallback(
|
const renderProps = useCallback(
|
||||||
(props: ComponentPropType[]) =>
|
(props: ComponentPropType[]) =>
|
||||||
@@ -129,15 +148,7 @@ export function SettingForm({
|
|||||||
...rest,
|
...rest,
|
||||||
...getProp?.(model),
|
...getProp?.(model),
|
||||||
};
|
};
|
||||||
const FormChild = isValidNestProps(childProto.props)
|
const FormChild = isValidNestProps(childProto.props) ? SettingFormObject : SettingFormItem;
|
||||||
? SettingFormObject
|
|
||||||
: childProto.setter
|
|
||||||
? SettingFormItem
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (!FormChild) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return <FormChild key={item.name} {...childProto} />;
|
return <FormChild key={item.name} {...childProto} />;
|
||||||
}),
|
}),
|
||||||
[model],
|
[model],
|
||||||
@@ -155,6 +166,7 @@ export function SettingForm({
|
|||||||
<FormModelProvider value={model}>
|
<FormModelProvider value={model}>
|
||||||
<Box className="SettingForm" mb="xl" css={formStyle}>
|
<Box className="SettingForm" mb="xl" css={formStyle}>
|
||||||
<Box className="SettingFormHeader" position="sticky" top="0" bg="white" zIndex="2">
|
<Box className="SettingFormHeader" position="sticky" top="0" bg="white" zIndex="2">
|
||||||
|
{showSearch && (
|
||||||
<Box className="SettingFormSearch" px="l" py="m">
|
<Box className="SettingFormSearch" px="l" py="m">
|
||||||
<Search
|
<Search
|
||||||
placeholder="搜索属性"
|
placeholder="搜索属性"
|
||||||
@@ -163,7 +175,8 @@ export function SettingForm({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{!keyword && (
|
)}
|
||||||
|
{!keyword && showGroups && (
|
||||||
<Box className="SettingFormNav">
|
<Box className="SettingFormNav">
|
||||||
<Tabs activeKey={tabKey} onChange={setTabKey}>
|
<Tabs activeKey={tabKey} onChange={setTabKey}>
|
||||||
{groupOptions.map((group) => (
|
{groupOptions.map((group) => (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { register } from './form-item';
|
import { register } from './form-item';
|
||||||
import { ExpressionSetter } from './setter';
|
import { ExpressionSetter, TextSetter } from './setter';
|
||||||
|
|
||||||
// 预注册基础 Setter
|
// 预注册基础 Setter
|
||||||
register({
|
register({
|
||||||
@@ -7,6 +7,11 @@ register({
|
|||||||
component: ExpressionSetter,
|
component: ExpressionSetter,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
register({
|
||||||
|
name: 'textSetter',
|
||||||
|
component: TextSetter,
|
||||||
|
});
|
||||||
|
|
||||||
export * from './form';
|
export * from './form';
|
||||||
export * from './form-item';
|
export * from './form-item';
|
||||||
export * from './form-object';
|
export * from './form-object';
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Input } from 'antd';
|
||||||
|
import { InputCode } from '@music163/tango-ui';
|
||||||
import { FormItemComponentProps } from './form-item';
|
import { FormItemComponentProps } from './form-item';
|
||||||
|
|
||||||
// TODO: 内置基本的 ExpressionSetter,默认全部 fallback 到此 setter
|
export function ExpressionSetter({ value, onChange, ...rest }: FormItemComponentProps<string>) {
|
||||||
export function ExpressionSetter(props: FormItemComponentProps<string>) {
|
return <InputCode onChange={(val) => onChange?.(val)} value={value || ''} {...rest} />;
|
||||||
return <div>exp setter</div>;
|
}
|
||||||
|
|
||||||
|
export function TextSetter({ onChange, ...rest }: FormItemComponentProps<string>) {
|
||||||
|
return <Input onChange={(e) => onChange?.(e.target.value)} {...rest} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## 1.0.2 (2023-12-13)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- update variable tree with help messages and styling & add tangoConfig schema ([5e7e285](https://github.com/NetEase/tango/commit/5e7e285452b46888b447991b0e8548b6392acb3a))
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Tango Config Spec
|
||||||
|
|
||||||
|
This is the specification for the Tango Config format.
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "tango-spec",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "tango config spec",
|
||||||
|
"keywords": [
|
||||||
|
"json",
|
||||||
|
"schema"
|
||||||
|
],
|
||||||
|
"author": "wwsun <ww.sww@outlook.com>",
|
||||||
|
"homepage": "https://github.com/NetEase/tango#readme",
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "index.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/NetEase/tango.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ./__tests__/spec.test.js"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/NetEase/tango/issues"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public",
|
||||||
|
"registry": "https://registry.npmjs.org/"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://unpkg.com/tango-spec/tango-config.json",
|
||||||
|
"title": "JSON Schema of tango.config.json",
|
||||||
|
"description": "tango.config.json is a configuration file for NetEase Tango apps",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"packages": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
"^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "package description"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "package version"
|
||||||
|
},
|
||||||
|
"library": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "package library"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "package type",
|
||||||
|
"enum": ["dependency", "bizDependency", "baseDependency"]
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "package resources"
|
||||||
|
},
|
||||||
|
"designerResources": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "package designer resources"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["version", "library"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"dataSource": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ox": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "music ox data provider",
|
||||||
|
"properties": {
|
||||||
|
"key": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "dataSource provider name"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"app": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "app name"
|
||||||
|
},
|
||||||
|
"branch": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "branch name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["app", "branch"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"key": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "the path of proxy rule"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"target": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "the target of proxy rule"
|
||||||
|
},
|
||||||
|
"changeOrigin": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "whether change origin of proxy rule"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["target"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externalResources": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": true,
|
||||||
|
"required": ["packages"]
|
||||||
|
}
|
||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-alpha.1](https://github.com/netease/tango/compare/@music163/tango-ui@0.1.12...@music163/tango-ui@1.0.0-alpha.1) (2023-12-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- add showSearch and showGroups to SettingForm & update internal icons ([#73](https://github.com/netease/tango/issues/73)) ([a8357f4](https://github.com/netease/tango/commit/a8357f45b8b0c1f2b91a856918f6bdecdc65aa73))
|
||||||
|
- disable search keymap of InputCode ([#72](https://github.com/netease/tango/issues/72)) ([9db6358](https://github.com/netease/tango/commit/9db635858876ee0b9612e4b2ccd996280fc35d3b))
|
||||||
|
- render form item without setter & enhance tools ([#76](https://github.com/netease/tango/issues/76)) ([1acfa68](https://github.com/netease/tango/commit/1acfa6864b1faad1a441facc426d8d94b6b090b5))
|
||||||
|
|
||||||
## [0.1.12](https://github.com/netease/tango/compare/@music163/tango-ui@0.1.11...@music163/tango-ui@0.1.12) (2023-11-28)
|
## [0.1.12](https://github.com/netease/tango/compare/@music163/tango-ui@0.1.11...@music163/tango-ui@0.1.12) (2023-11-28)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@music163/tango-ui",
|
"name": "@music163/tango-ui",
|
||||||
"version": "0.1.12",
|
"version": "1.0.0-alpha.1",
|
||||||
"description": "ui widgets of tango",
|
"description": "ui widgets of tango",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
@@ -34,14 +34,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.8.0",
|
"@ant-design/icons": "^4.8.0",
|
||||||
"@codemirror/autocomplete": "^6.10.2",
|
"@codemirror/autocomplete": "^6.11.1",
|
||||||
"@codemirror/lang-javascript": "^6.2.1",
|
"@codemirror/lang-javascript": "^6.2.1",
|
||||||
"@codemirror/lint": "^6.4.2",
|
"@codemirror/lint": "^6.4.2",
|
||||||
"@codemirror/search": "^6.5.4",
|
"@codemirror/search": "^6.5.5",
|
||||||
"@music163/tango-helpers": "^0.1.8",
|
"@music163/tango-helpers": "^0.1.8",
|
||||||
"@uiw/react-codemirror": "^4.21.20",
|
"@uiw/react-codemirror": "^4.21.21",
|
||||||
"antd": "^4.24.2",
|
"antd": "^4.24.2",
|
||||||
"antd-easy-form": "^1.1.3",
|
|
||||||
"coral-system": "^1.0.5",
|
"coral-system": "^1.0.5",
|
||||||
"eslint-linter-browserify": "^8.51.0",
|
"eslint-linter-browserify": "^8.51.0",
|
||||||
"react-json-view": "^1.21.3",
|
"react-json-view": "^1.21.3",
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const CodeOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path d="m31 16-7 7-1.41-1.41 5.58-5.59-5.58-5.59 1.41-1.41z" />
|
||||||
|
<path d="m1 16 7-7 1.41 1.41-5.58 5.59 5.58 5.59-1.41 1.41z" />
|
||||||
|
<path
|
||||||
|
d="m5.91 15h20.17v2h-20.17z"
|
||||||
|
transform="matrix(.25881905 -.96592583 .96592583 .25881905 -3.6 27.31)"
|
||||||
|
/>
|
||||||
|
<path d="m0 0h32v32h-32z" fill="none" transform="matrix(0 -1 1 0 0 32)" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const CodeOutlined = createIcon(CodeOutlinedSvg, 'CodeOutlined');
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Icon from '@ant-design/icons';
|
||||||
|
import type { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
|
||||||
|
|
||||||
|
export function createIcon(component: React.ComponentType<any>, displayName?: string) {
|
||||||
|
const CustomIcon = (props: Partial<CustomIconComponentProps>) => (
|
||||||
|
<Icon component={component} {...props} />
|
||||||
|
);
|
||||||
|
if (displayName) {
|
||||||
|
CustomIcon.displayName = displayName;
|
||||||
|
}
|
||||||
|
return CustomIcon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export * from './create-icon';
|
||||||
|
export * from './code-outlined';
|
||||||
|
export * from './open-panel-filled-left-outlined';
|
||||||
|
export * from './open-panel-filled-right-outlined';
|
||||||
|
export * from './open-panel-left-outlined';
|
||||||
|
export * from './open-panel-right-outlined';
|
||||||
|
export * from './undo-outlined';
|
||||||
|
export * from './redo-outlined';
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const OpenPanelFilledLeftOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm0 22h-16v-20h16z" />
|
||||||
|
<path d="m0 0h32v32h-32z" fill="none" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const OpenPanelFilledLeftOutlined = createIcon(
|
||||||
|
OpenPanelFilledLeftOutlinedSvg,
|
||||||
|
'OpenPanelFilledLeftOutlined',
|
||||||
|
);
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const OpenPanelFilledRightOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h16v20h-16z" />
|
||||||
|
<path d="m0 0h32v32h-32z" fill="none" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const OpenPanelFilledRightOutlined = createIcon(
|
||||||
|
OpenPanelFilledRightOutlinedSvg,
|
||||||
|
'OpenPanelFilledRightOutlined',
|
||||||
|
);
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const OpenPanelLeftOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h6v20h-6zm24 20h-16v-20h16z" />
|
||||||
|
<path d="m0 0h32v32h-32z" fill="none" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const OpenPanelLeftOutlined = createIcon(OpenPanelLeftOutlinedSvg, 'OpenPanelLeftOutlined');
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const OpenPanelRightOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m28 4h-24a2 2 0 0 0 -2 2v20a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2v-20a2 2 0 0 0 -2-2zm-24 2h16v20h-16zm24 20h-6v-20h6z" />
|
||||||
|
<path d="m0 0h32v32h-32z" fill="none" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const OpenPanelRightOutlined = createIcon(
|
||||||
|
OpenPanelRightOutlinedSvg,
|
||||||
|
'OpenPanelRightOutlined',
|
||||||
|
);
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const RedoOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m12 10h12.1851l-3.5874-3.5859 1.4023-1.4141 6 6-6 6-1.4023-1.4146 3.5844-3.5854h-12.1821a6 6 0 0 0 0 12h8v2h-8a8 8 0 0 1 0-16z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const RedoOutlined = createIcon(RedoOutlinedSvg, 'RedoOutlined');
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createIcon } from './create-icon';
|
||||||
|
|
||||||
|
const UndoOutlinedSvg = () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="m20 10h-12.1851l3.5874-3.5859-1.4023-1.4141-6 6 6 6 1.4023-1.4146-3.5844-3.5854h12.1821a6 6 0 0 1 0 12h-8v2h8a8 8 0 0 0 0-16z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const UndoOutlined = createIcon(UndoOutlinedSvg, 'UndoOutlined');
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './icons';
|
||||||
export * from './action-select';
|
export * from './action-select';
|
||||||
export * from './code-editor';
|
export * from './code-editor';
|
||||||
export * from './chat-input';
|
export * from './chat-input';
|
||||||
@@ -19,4 +20,3 @@ export * from './tabs';
|
|||||||
export * from './select-action';
|
export * from './select-action';
|
||||||
export * from './copy-clipboard';
|
export * from './copy-clipboard';
|
||||||
export * from './tag-select';
|
export * from './tag-select';
|
||||||
export { Form } from 'antd-easy-form';
|
|
||||||
@@ -153,12 +153,12 @@ export function InputCode({
|
|||||||
autocomplete: buildAutoComplete(autoCompleteContext, options),
|
autocomplete: buildAutoComplete(autoCompleteContext, options),
|
||||||
});
|
});
|
||||||
}, [autoCompleteContext, autoCompleteOptions]);
|
}, [autoCompleteContext, autoCompleteOptions]);
|
||||||
const { rootStyle, codeSetup } = useInputCode({ shape, status, showLineNumbers, showFoldGutter });
|
|
||||||
const extensions = [javascript({ jsx: true }), globalJavaScriptCompletions];
|
const extensions = [javascript({ jsx: true }), globalJavaScriptCompletions];
|
||||||
if (enableESLint) {
|
if (enableESLint) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
extensions.push(lintGutter(), linter(esLint(new eslint.Linter(), eslintConfig)));
|
extensions.push(lintGutter(), linter(esLint(new eslint.Linter(), eslintConfig)));
|
||||||
}
|
}
|
||||||
|
const { rootStyle, codeSetup } = useInputCode({ shape, status, showLineNumbers, showFoldGutter });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className="InputCode" display="flex" alignItems="center" overflow="hidden" {...rootStyle}>
|
<Box className="InputCode" display="flex" alignItems="center" overflow="hidden" {...rootStyle}>
|
||||||
@@ -194,6 +194,7 @@ function useInputCode({
|
|||||||
codeSetup: {
|
codeSetup: {
|
||||||
lineNumbers: showLineNumbers ?? lineNumbers,
|
lineNumbers: showLineNumbers ?? lineNumbers,
|
||||||
foldGutter: showFoldGutter ?? foldGutter,
|
foldGutter: showFoldGutter ?? foldGutter,
|
||||||
|
searchKeymap: false, // 默认关闭搜索快捷键,原因:https://github.com/uiwjs/react-codemirror/issues/280
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,18 +64,18 @@ const buttonStyle = css`
|
|||||||
|
|
||||||
&.shape-outline {
|
&.shape-outline {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid var(--tango-colors-line2);
|
||||||
border-radius: var(--tango-radii-s);
|
border-radius: var(--tango-radii-s);
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
color: rgba(0, 0, 0, 0.25);
|
color: var(--tango-colors-text4);
|
||||||
background-color: #f5f5f5;
|
background-color: var(--tango-colors-fill1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected.type-normal {
|
&.selected.type-normal {
|
||||||
color: var(--tango-colors-gray-100);
|
color: var(--tango-colors-gray-100);
|
||||||
background-color: var(--tango-colors-gray-30);
|
background-color: var(--tango-colors-fill3);
|
||||||
border-color: var(--tango-colors-gray-30);
|
border-color: var(--tango-colors-line2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected.type-primary {
|
&.selected.type-primary {
|
||||||
|
|||||||
Reference in New Issue
Block a user