From 19780739298bb36302361f75538036143a11c876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E5=8A=9B?= <3071730@qq.com> Date: Fri, 22 Mar 2019 12:25:58 +0800 Subject: [PATCH] feat: Add the `GGEditor` demo (#3810) * feat: Add the `GGEditor` demo * style: Update the size of the card * feat: Extract the `MenuItem` and `ToolbarButton` components * feat: Add the shape type of the line * feat: Extract the `DetailForm` components * feat: add PageHeader * fix: add all local laug * fix: Fix the height of the editor --- config/router.config.js | 23 ++++ package.json | 1 + public/ggeditor/flow/decision.svg | 29 ++++ public/ggeditor/flow/model.svg | 29 ++++ public/ggeditor/flow/normal.svg | 29 ++++ public/ggeditor/flow/start.svg | 29 ++++ public/ggeditor/koni/bank.svg | 29 ++++ public/ggeditor/koni/country.svg | 29 ++++ public/ggeditor/koni/icon.svg | 14 ++ public/ggeditor/koni/person.svg | 29 ++++ src/locales/en-US.js | 2 + src/locales/en-US/editor.js | 11 ++ src/locales/en-US/menu.js | 4 + src/locales/pt-BR.js | 2 + src/locales/pt-BR/editor.js | 11 ++ src/locales/pt-BR/menu.js | 4 + src/locales/zh-CN.js | 2 + src/locales/zh-CN/editor.js | 9 ++ src/locales/zh-CN/menu.js | 4 + src/locales/zh-TW.js | 2 + src/locales/zh-TW/editor.js | 9 ++ src/locales/zh-TW/menu.js | 4 + src/pages/Editor/GGEditor/Flow/index.js | 43 ++++++ src/pages/Editor/GGEditor/Flow/index.less | 41 ++++++ src/pages/Editor/GGEditor/Koni/index.js | 45 ++++++ .../Koni/shape/nodes/KoniCustomNode.js | 33 +++++ src/pages/Editor/GGEditor/Mind/index.js | 40 ++++++ .../Editor/GGEditor/common/IconFont/index.js | 7 + .../EditorContextMenu/FlowContextMenu.js | 36 +++++ .../EditorContextMenu/KoniContextMenu.js | 3 + .../components/EditorContextMenu/MenuItem.js | 20 +++ .../EditorContextMenu/MindContextMenu.js | 24 ++++ .../components/EditorContextMenu/index.js | 5 + .../components/EditorContextMenu/index.less | 39 ++++++ .../EditorDetailPanel/DetailForm.js | 129 ++++++++++++++++++ .../EditorDetailPanel/FlowDetailPanel.js | 29 ++++ .../EditorDetailPanel/KoniDetailPanel.js | 3 + .../EditorDetailPanel/MindDetailPanel.js | 20 +++ .../components/EditorDetailPanel/index.js | 5 + .../components/EditorDetailPanel/index.less | 10 ++ .../EditorItemPanel/FlowItemPanel.js | 55 ++++++++ .../EditorItemPanel/KoniItemPanel.js | 51 +++++++ .../components/EditorItemPanel/index.js | 4 + .../components/EditorItemPanel/index.less | 20 +++ .../components/EditorMinimap/index.js | 13 ++ .../components/EditorToolbar/FlowToolbar.js | 32 +++++ .../components/EditorToolbar/KoniToolbar.js | 3 + .../components/EditorToolbar/MindToolbar.js | 27 ++++ .../components/EditorToolbar/ToolbarButton.js | 24 ++++ .../components/EditorToolbar/index.js | 5 + .../components/EditorToolbar/index.less | 39 ++++++ .../Editor/GGEditor/mock/worldCup2018.json | 129 ++++++++++++++++++ 52 files changed, 1239 insertions(+) create mode 100644 public/ggeditor/flow/decision.svg create mode 100644 public/ggeditor/flow/model.svg create mode 100644 public/ggeditor/flow/normal.svg create mode 100644 public/ggeditor/flow/start.svg create mode 100644 public/ggeditor/koni/bank.svg create mode 100644 public/ggeditor/koni/country.svg create mode 100644 public/ggeditor/koni/icon.svg create mode 100644 public/ggeditor/koni/person.svg create mode 100644 src/locales/en-US/editor.js create mode 100644 src/locales/pt-BR/editor.js create mode 100644 src/locales/zh-CN/editor.js create mode 100644 src/locales/zh-TW/editor.js create mode 100644 src/pages/Editor/GGEditor/Flow/index.js create mode 100644 src/pages/Editor/GGEditor/Flow/index.less create mode 100644 src/pages/Editor/GGEditor/Koni/index.js create mode 100644 src/pages/Editor/GGEditor/Koni/shape/nodes/KoniCustomNode.js create mode 100644 src/pages/Editor/GGEditor/Mind/index.js create mode 100644 src/pages/Editor/GGEditor/common/IconFont/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/FlowContextMenu.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/KoniContextMenu.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/MenuItem.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/MindContextMenu.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorContextMenu/index.less create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/DetailForm.js create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/FlowDetailPanel.js create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/KoniDetailPanel.js create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/MindDetailPanel.js create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorDetailPanel/index.less create mode 100644 src/pages/Editor/GGEditor/components/EditorItemPanel/FlowItemPanel.js create mode 100644 src/pages/Editor/GGEditor/components/EditorItemPanel/KoniItemPanel.js create mode 100644 src/pages/Editor/GGEditor/components/EditorItemPanel/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorItemPanel/index.less create mode 100644 src/pages/Editor/GGEditor/components/EditorMinimap/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/FlowToolbar.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/KoniToolbar.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/MindToolbar.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/ToolbarButton.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/index.js create mode 100644 src/pages/Editor/GGEditor/components/EditorToolbar/index.less create mode 100644 src/pages/Editor/GGEditor/mock/worldCup2018.json diff --git a/config/router.config.js b/config/router.config.js index 2698abc9..32e8172c 100644 --- a/config/router.config.js +++ b/config/router.config.js @@ -93,6 +93,29 @@ export default [ }, ], }, + // editor + { + name: 'editor', + icon: 'highlight', + path: '/editor', + routes: [ + { + path: '/editor/flow', + name: 'flow', + component: './Editor/GGEditor/Flow', + }, + { + path: '/editor/mind', + name: 'mind', + component: './Editor/GGEditor/Mind', + }, + { + path: '/editor/koni', + name: 'koni', + component: './Editor/GGEditor/Koni', + }, + ], + }, // list { path: '/list', diff --git a/package.json b/package.json index 3990b358..7bc019c3 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "classnames": "^2.2.6", "dva": "^2.4.1", "enquire-js": "^0.2.1", + "gg-editor": "^2.0.2", "hash.js": "^1.1.7", "lodash": "^4.17.11", "lodash-decorators": "^6.0.1", diff --git a/public/ggeditor/flow/decision.svg b/public/ggeditor/flow/decision.svg new file mode 100644 index 00000000..7af317ce --- /dev/null +++ b/public/ggeditor/flow/decision.svg @@ -0,0 +1,29 @@ + + + + Group 3 + Created with Sketch. + + + + + + + + + + + + + + + + + + + Decision + + + + + \ No newline at end of file diff --git a/public/ggeditor/flow/model.svg b/public/ggeditor/flow/model.svg new file mode 100644 index 00000000..3fd8afaa --- /dev/null +++ b/public/ggeditor/flow/model.svg @@ -0,0 +1,29 @@ + + + + Group 4 + Created with Sketch. + + + + + + + + + + + + + + + + + + + Model + + + + + \ No newline at end of file diff --git a/public/ggeditor/flow/normal.svg b/public/ggeditor/flow/normal.svg new file mode 100644 index 00000000..53791e9f --- /dev/null +++ b/public/ggeditor/flow/normal.svg @@ -0,0 +1,29 @@ + + + + Group + Created with Sketch. + + + + + + + + + + + + + + + + + + + Normal + + + + + \ No newline at end of file diff --git a/public/ggeditor/flow/start.svg b/public/ggeditor/flow/start.svg new file mode 100644 index 00000000..3ab4c3cb --- /dev/null +++ b/public/ggeditor/flow/start.svg @@ -0,0 +1,29 @@ + + + + Group 2 + Created with Sketch. + + + + + + + + + + + + + + + + + + + Start + + + + + \ No newline at end of file diff --git a/public/ggeditor/koni/bank.svg b/public/ggeditor/koni/bank.svg new file mode 100644 index 00000000..7ec11643 --- /dev/null +++ b/public/ggeditor/koni/bank.svg @@ -0,0 +1,29 @@ + + + + Group 16 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/ggeditor/koni/country.svg b/public/ggeditor/koni/country.svg new file mode 100644 index 00000000..eeb861a7 --- /dev/null +++ b/public/ggeditor/koni/country.svg @@ -0,0 +1,29 @@ + + + + Group 18 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/ggeditor/koni/icon.svg b/public/ggeditor/koni/icon.svg new file mode 100644 index 00000000..0c3eba65 --- /dev/null +++ b/public/ggeditor/koni/icon.svg @@ -0,0 +1,14 @@ + + + + earth copy 53 + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/public/ggeditor/koni/person.svg b/public/ggeditor/koni/person.svg new file mode 100644 index 00000000..c9dcad00 --- /dev/null +++ b/public/ggeditor/koni/person.svg @@ -0,0 +1,29 @@ + + + + Group 17 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/locales/en-US.js b/src/locales/en-US.js index 25f2888c..a10691ce 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -10,6 +10,7 @@ import settingDrawer from './en-US/settingDrawer'; import settings from './en-US/settings'; import pwa from './en-US/pwa'; import component from './en-US/component'; +import editor from './en-US/editor'; export default { 'navBar.lang': 'Languages', @@ -32,4 +33,5 @@ export default { ...settings, ...pwa, ...component, + ...editor, }; diff --git a/src/locales/en-US/editor.js b/src/locales/en-US/editor.js new file mode 100644 index 00000000..81bd0f17 --- /dev/null +++ b/src/locales/en-US/editor.js @@ -0,0 +1,11 @@ +export default { + 'app.editor.flow.title': 'Flowchart Editor', + 'app.editor.flow.description': + 'The flow chart is an excellent way to represent the idea of the algorithm.', + 'app.editor.koni.title': 'Koni Editor', + 'app.editor.koni.description': + 'The topology diagram refers to the network structure diagram composed of network node devices and communication media.', + 'app.editor.mind.title': 'Mind Map Editor', + 'app.editor.mind.description': + 'The brain map is an effective graphical thinking tool for expressing divergent thinking. It is simple but effective and is a practical thinking tool.', +}; diff --git a/src/locales/en-US/menu.js b/src/locales/en-US/menu.js index 056c255e..1d673466 100644 --- a/src/locales/en-US/menu.js +++ b/src/locales/en-US/menu.js @@ -38,4 +38,8 @@ export default { 'menu.account.settings': 'Account Settings', 'menu.account.trigger': 'Trigger Error', 'menu.account.logout': 'Logout', + 'menu.editor': 'Editor', + 'menu.editor.flow': 'Flow Editor', + 'menu.editor.mind': 'Mind Editor', + 'menu.editor.koni': 'Koni Editor', }; diff --git a/src/locales/pt-BR.js b/src/locales/pt-BR.js index af8bcee5..19e82643 100644 --- a/src/locales/pt-BR.js +++ b/src/locales/pt-BR.js @@ -10,6 +10,7 @@ import settingDrawer from './pt-BR/settingDrawer'; import settings from './pt-BR/settings'; import pwa from './pt-BR/pwa'; import component from './pt-BR/component'; +import editor from './pt-BR/editor'; export default { 'navBar.lang': 'Idiomas', @@ -32,4 +33,5 @@ export default { ...settings, ...pwa, ...component, + ...editor, }; diff --git a/src/locales/pt-BR/editor.js b/src/locales/pt-BR/editor.js new file mode 100644 index 00000000..10237f9b --- /dev/null +++ b/src/locales/pt-BR/editor.js @@ -0,0 +1,11 @@ +export default { + 'app.editor.flow.title': 'Editor de diagrama de flujo', + 'app.editor.flow.description': + 'El diagrama de flujo es una excelente manera de representar la idea del algoritmo.', + 'app.editor.koni.title': 'Editor de topologia', + 'app.editor.koni.description': + 'El diagrama de topología se refiere al diagrama de estructura de red compuesto por dispositivos de nodo de red y medios de comunicación.', + 'app.editor.mind.title': 'Editor de mapas cerebrales', + 'app.editor.mind.description': + 'El mapa cerebral es una herramienta de pensamiento gráfico eficaz para expresar el pensamiento divergente. Es simple pero efectivo y es una herramienta de pensamiento práctico.', +}; diff --git a/src/locales/pt-BR/menu.js b/src/locales/pt-BR/menu.js index 77ee7fd7..ee82fb1e 100644 --- a/src/locales/pt-BR/menu.js +++ b/src/locales/pt-BR/menu.js @@ -38,4 +38,8 @@ export default { 'menu.account.settings': 'Configurar Conta', 'menu.account.trigger': 'Disparar Erro', 'menu.account.logout': 'Sair', + 'menu.editor': 'Editor', + 'menu.editor.flow': 'Flow Editor', + 'menu.editor.mind': 'Mind Editor', + 'menu.editor.koni': 'Koni Editor', }; diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index cf601f37..6cc85e4b 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -10,6 +10,7 @@ import settingDrawer from './zh-CN/settingDrawer'; import settings from './zh-CN/settings'; import pwa from './zh-CN/pwa'; import component from './zh-CN/component'; +import editor from './zh-CN/editor'; export default { 'navBar.lang': '语言', @@ -32,4 +33,5 @@ export default { ...settings, ...pwa, ...component, + ...editor, }; diff --git a/src/locales/zh-CN/editor.js b/src/locales/zh-CN/editor.js new file mode 100644 index 00000000..1688644e --- /dev/null +++ b/src/locales/zh-CN/editor.js @@ -0,0 +1,9 @@ +export default { + 'app.editor.flow.title': '流程图编辑器', + 'app.editor.flow.description': '千言万语不如一张图,流程图是表示算法思路的好方法', + 'app.editor.koni.title': '拓扑编辑器', + 'app.editor.koni.description': '拓扑结构图是指由网络节点设备和通信介质构成的网络结构图', + 'app.editor.mind.title': '脑图编辑器', + 'app.editor.mind.description': + '脑图是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。', +}; diff --git a/src/locales/zh-CN/menu.js b/src/locales/zh-CN/menu.js index 5657c6e0..0fb0069e 100644 --- a/src/locales/zh-CN/menu.js +++ b/src/locales/zh-CN/menu.js @@ -38,4 +38,8 @@ export default { 'menu.account.settings': '个人设置', 'menu.account.trigger': '触发报错', 'menu.account.logout': '退出登录', + 'menu.editor': '编辑页', + 'menu.editor.flow': '流程编辑器', + 'menu.editor.mind': '脑图编辑器', + 'menu.editor.koni': '拓扑编辑器', }; diff --git a/src/locales/zh-TW.js b/src/locales/zh-TW.js index c6217339..33351509 100644 --- a/src/locales/zh-TW.js +++ b/src/locales/zh-TW.js @@ -10,6 +10,7 @@ import settingDrawer from './zh-TW/settingDrawer'; import settings from './zh-TW/settings'; import pwa from './zh-TW/pwa'; import component from './zh-TW/component'; +import editor from './zh-TW/editor'; export default { 'navBar.lang': '語言', @@ -32,4 +33,5 @@ export default { ...settings, ...pwa, ...component, + ...editor, }; diff --git a/src/locales/zh-TW/editor.js b/src/locales/zh-TW/editor.js new file mode 100644 index 00000000..d1d13774 --- /dev/null +++ b/src/locales/zh-TW/editor.js @@ -0,0 +1,9 @@ +export default { + 'app.editor.flow.title': '流程圖編輯器', + 'app.editor.flow.description': '千言萬語不如一張圖,流程圖是表示算法思路的好方法', + 'app.editor.koni.title': '拓撲編輯器', + 'app.editor.koni.description': '拓撲結構圖是指由網絡節點設備和通信介質構成的網絡結構圖', + 'app.editor.mind.title': '腦圖編輯器', + 'app.editor.mind.description': + '腦圖是表達發散性思維的有效圖形思維工具 ,它簡單卻又很有效,是一種實用性的思維工具', +}; diff --git a/src/locales/zh-TW/menu.js b/src/locales/zh-TW/menu.js index 7bd71a7a..2cf5f9da 100644 --- a/src/locales/zh-TW/menu.js +++ b/src/locales/zh-TW/menu.js @@ -38,4 +38,8 @@ export default { 'menu.exception.not-find': '404', 'menu.exception.server-error': '500', 'menu.exception.trigger': '触发错误', + 'menu.editor': '編輯頁', + 'menu.editor.flow': '流程編輯器', + 'menu.editor.mind': '腦圖編輯器', + 'menu.editor.koni': '拓撲編輯器', }; diff --git a/src/pages/Editor/GGEditor/Flow/index.js b/src/pages/Editor/GGEditor/Flow/index.js new file mode 100644 index 00000000..6acac054 --- /dev/null +++ b/src/pages/Editor/GGEditor/Flow/index.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { Row, Col } from 'antd'; +import GGEditor, { Flow } from 'gg-editor'; +import EditorMinimap from '../components/EditorMinimap'; +import { FlowContextMenu } from '../components/EditorContextMenu'; +import { FlowToolbar } from '../components/EditorToolbar'; +import { FlowItemPanel } from '../components/EditorItemPanel'; +import { FlowDetailPanel } from '../components/EditorDetailPanel'; +import styles from './index.less'; +import { FormattedMessage } from 'umi/locale'; +import PageHeaderWrapper from '@/components/PageHeaderWrapper'; + +const FlowPage = () => { + return ( + } + content={} + > + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default FlowPage; diff --git a/src/pages/Editor/GGEditor/Flow/index.less b/src/pages/Editor/GGEditor/Flow/index.less new file mode 100644 index 00000000..aeffa829 --- /dev/null +++ b/src/pages/Editor/GGEditor/Flow/index.less @@ -0,0 +1,41 @@ +.editor { + display: flex; + flex: 1; + flex-direction: column; + width: 100%; + height: calc(100vh - 250px); + background: #fff; +} + +.editorHd { + padding: 8px; + border: 1px solid #e6e9ed; +} + +.editorBd { + flex: 1; +} + +.editorSidebar, +.editorContent { + display: flex; + flex-direction: column; +} + +.editorSidebar { + background: #fafafa; + + &:first-child { + border-right: 1px solid #e6e9ed; + } + + &:last-child { + border-left: 1px solid #e6e9ed; + } +} + +.flow, +.mind, +.koni { + flex: 1; +} diff --git a/src/pages/Editor/GGEditor/Koni/index.js b/src/pages/Editor/GGEditor/Koni/index.js new file mode 100644 index 00000000..5b46dfac --- /dev/null +++ b/src/pages/Editor/GGEditor/Koni/index.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { Row, Col } from 'antd'; +import GGEditor, { Koni } from 'gg-editor'; +import EditorMinimap from '../components/EditorMinimap'; +import { KoniContextMenu } from '../components/EditorContextMenu'; +import { KoniToolbar } from '../components/EditorToolbar'; +import { KoniItemPanel } from '../components/EditorItemPanel'; +import { KoniDetailPanel } from '../components/EditorDetailPanel'; +import KoniCustomNode from './shape/nodes/KoniCustomNode'; +import styles from '../Flow/index.less'; +import { FormattedMessage } from 'umi/locale'; +import PageHeaderWrapper from '@/components/PageHeaderWrapper'; + +const KoniPage = () => { + return ( + } + content={} + > + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default KoniPage; diff --git a/src/pages/Editor/GGEditor/Koni/shape/nodes/KoniCustomNode.js b/src/pages/Editor/GGEditor/Koni/shape/nodes/KoniCustomNode.js new file mode 100644 index 00000000..4c13bb4f --- /dev/null +++ b/src/pages/Editor/GGEditor/Koni/shape/nodes/KoniCustomNode.js @@ -0,0 +1,33 @@ +import React from 'react'; +import { RegisterNode } from 'gg-editor'; + +class KoniCustomNode extends React.Component { + render() { + const config = { + draw(item) { + const keyShape = this.drawKeyShape(item); + + // draw label + this.drawLabel(item); + + // draw image + const group = item.getGraphicGroup(); + const model = item.getModel(); + + group.addShape('image', { + attrs: { + x: -7, + y: -7, + img: model.icon, + }, + }); + + return keyShape; + }, + }; + + return ; + } +} + +export default KoniCustomNode; diff --git a/src/pages/Editor/GGEditor/Mind/index.js b/src/pages/Editor/GGEditor/Mind/index.js new file mode 100644 index 00000000..f33812d4 --- /dev/null +++ b/src/pages/Editor/GGEditor/Mind/index.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { Row, Col } from 'antd'; +import GGEditor, { Mind } from 'gg-editor'; +import EditorMinimap from '../components/EditorMinimap'; +import { MindContextMenu } from '../components/EditorContextMenu'; +import { MindToolbar } from '../components/EditorToolbar'; +import { MindDetailPanel } from '../components/EditorDetailPanel'; +import data from '../mock/worldCup2018.json'; +import styles from '../Flow/index.less'; +import { FormattedMessage } from 'umi/locale'; +import PageHeaderWrapper from '@/components/PageHeaderWrapper'; + +const MindPage = () => { + return ( + } + content={} + > + + + + + + + + + + + + + + + + + + + ); +}; + +export default MindPage; diff --git a/src/pages/Editor/GGEditor/common/IconFont/index.js b/src/pages/Editor/GGEditor/common/IconFont/index.js new file mode 100644 index 00000000..3bba8d2e --- /dev/null +++ b/src/pages/Editor/GGEditor/common/IconFont/index.js @@ -0,0 +1,7 @@ +import { Icon } from 'antd'; + +const IconFont = Icon.createFromIconfontCN({ + scriptUrl: 'https://at.alicdn.com/t/font_1101588_01zniftxm9yp.js', +}); + +export default IconFont; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/FlowContextMenu.js b/src/pages/Editor/GGEditor/components/EditorContextMenu/FlowContextMenu.js new file mode 100644 index 00000000..cbb7041f --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/FlowContextMenu.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { NodeMenu, EdgeMenu, GroupMenu, MultiMenu, CanvasMenu, ContextMenu } from 'gg-editor'; +import MenuItem from './MenuItem'; +import styles from './index.less'; + +const FlowContextMenu = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default FlowContextMenu; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/KoniContextMenu.js b/src/pages/Editor/GGEditor/components/EditorContextMenu/KoniContextMenu.js new file mode 100644 index 00000000..8b049a5e --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/KoniContextMenu.js @@ -0,0 +1,3 @@ +import FlowContextMenu from './FlowContextMenu'; + +export default FlowContextMenu; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/MenuItem.js b/src/pages/Editor/GGEditor/components/EditorContextMenu/MenuItem.js new file mode 100644 index 00000000..4cbde89e --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/MenuItem.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { Command } from 'gg-editor'; +import upperFirst from 'lodash/upperFirst'; +import IconFont from '../../common/IconFont'; +import styles from './index.less'; + +const MenuItem = props => { + const { command, icon, text } = props; + + return ( + +
+ + {text || upperFirst(command)} +
+
+ ); +}; + +export default MenuItem; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/MindContextMenu.js b/src/pages/Editor/GGEditor/components/EditorContextMenu/MindContextMenu.js new file mode 100644 index 00000000..2a9d43cd --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/MindContextMenu.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { NodeMenu, CanvasMenu, ContextMenu } from 'gg-editor'; +import MenuItem from './MenuItem'; +import styles from './index.less'; + +const MindContextMenu = () => { + return ( + + + + + + + + + + + + + + ); +}; + +export default MindContextMenu; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/index.js b/src/pages/Editor/GGEditor/components/EditorContextMenu/index.js new file mode 100644 index 00000000..16fcde01 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/index.js @@ -0,0 +1,5 @@ +import FlowContextMenu from './FlowContextMenu'; +import MindContextMenu from './MindContextMenu'; +import KoniContextMenu from './KoniContextMenu'; + +export { FlowContextMenu, MindContextMenu, KoniContextMenu }; diff --git a/src/pages/Editor/GGEditor/components/EditorContextMenu/index.less b/src/pages/Editor/GGEditor/components/EditorContextMenu/index.less new file mode 100644 index 00000000..8a2cdae3 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorContextMenu/index.less @@ -0,0 +1,39 @@ +.contextMenu { + display: none; + overflow: hidden; + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + + .item { + display: flex; + align-items: center; + padding: 5px 12px; + cursor: pointer; + transition: all 0.3s; + user-select: none; + + &:hover { + background: #e6f7ff; + } + + i { + margin-right: 8px; + } + } + + :global { + .disable { + :local { + .item { + color: rgba(0, 0, 0, 0.25); + cursor: auto; + + &:hover { + background: #fff; + } + } + } + } + } +} diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/DetailForm.js b/src/pages/Editor/GGEditor/components/EditorDetailPanel/DetailForm.js new file mode 100644 index 00000000..3d680115 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/DetailForm.js @@ -0,0 +1,129 @@ +import React, { Fragment } from 'react'; +import { Card, Form, Input, Select } from 'antd'; +import { withPropsAPI } from 'gg-editor'; +import upperFirst from 'lodash/upperFirst'; + +const { Item } = Form; +const { Option } = Select; + +const inlineFormItemLayout = { + labelCol: { + sm: { span: 8 }, + }, + wrapperCol: { + sm: { span: 16 }, + }, +}; + +class DetailForm extends React.Component { + get item() { + const { propsAPI } = this.props; + + return propsAPI.getSelected()[0]; + } + + handleSubmit = e => { + if (e && e.preventDefault) { + e.preventDefault(); + } + + const { form, propsAPI } = this.props; + const { getSelected, executeCommand, update } = propsAPI; + + setTimeout(() => { + form.validateFieldsAndScroll((err, values) => { + if (err) { + return; + } + + const item = getSelected()[0]; + + if (!item) { + return; + } + + executeCommand(() => { + update(item, { + ...values, + }); + }); + }); + }, 0); + }; + + renderEdgeShapeSelect = () => { + return ( + + ); + }; + + renderNodeDetail = () => { + const { form } = this.props; + const { label } = this.item.getModel(); + + return ( + + {form.getFieldDecorator('label', { + initialValue: label, + })()} + + ); + }; + + renderEdgeDetail = () => { + const { form } = this.props; + const { label = '', shape = 'flow-smooth' } = this.item.getModel(); + + return ( + + + {form.getFieldDecorator('label', { + initialValue: label, + })()} + + + {form.getFieldDecorator('shape', { + initialValue: shape, + })(this.renderEdgeShapeSelect())} + + + ); + }; + + renderGroupDetail = () => { + const { form } = this.props; + const { label = '新建分组' } = this.item.getModel(); + + return ( + + {form.getFieldDecorator('label', { + initialValue: label, + })()} + + ); + }; + + render() { + const { type } = this.props; + + if (!this.item) { + return null; + } + + return ( + +
+ {type === 'node' && this.renderNodeDetail()} + {type === 'edge' && this.renderEdgeDetail()} + {type === 'group' && this.renderGroupDetail()} +
+
+ ); + } +} + +export default Form.create()(withPropsAPI(DetailForm)); diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/FlowDetailPanel.js b/src/pages/Editor/GGEditor/components/EditorDetailPanel/FlowDetailPanel.js new file mode 100644 index 00000000..8d681618 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/FlowDetailPanel.js @@ -0,0 +1,29 @@ +import React from 'react'; +import { Card } from 'antd'; +import { NodePanel, EdgePanel, GroupPanel, MultiPanel, CanvasPanel, DetailPanel } from 'gg-editor'; +import DetailForm from './DetailForm'; +import styles from './index.less'; + +const FlowDetailPanel = () => { + return ( + + + + + + + + + + + + + + + + + + ); +}; + +export default FlowDetailPanel; diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/KoniDetailPanel.js b/src/pages/Editor/GGEditor/components/EditorDetailPanel/KoniDetailPanel.js new file mode 100644 index 00000000..18aea9a4 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/KoniDetailPanel.js @@ -0,0 +1,3 @@ +import FlowDetailPanel from './FlowDetailPanel'; + +export default FlowDetailPanel; diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/MindDetailPanel.js b/src/pages/Editor/GGEditor/components/EditorDetailPanel/MindDetailPanel.js new file mode 100644 index 00000000..6b4d5c9e --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/MindDetailPanel.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { Card } from 'antd'; +import { NodePanel, CanvasPanel, DetailPanel } from 'gg-editor'; +import DetailForm from './DetailForm'; +import styles from './index.less'; + +const MindDetailPanel = () => { + return ( + + + + + + + + + ); +}; + +export default MindDetailPanel; diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.js b/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.js new file mode 100644 index 00000000..8df063ef --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.js @@ -0,0 +1,5 @@ +import FlowDetailPanel from './FlowDetailPanel'; +import MindDetailPanel from './MindDetailPanel'; +import KoniDetailPanel from './KoniDetailPanel'; + +export { FlowDetailPanel, MindDetailPanel, KoniDetailPanel }; diff --git a/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.less b/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.less new file mode 100644 index 00000000..081945be --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorDetailPanel/index.less @@ -0,0 +1,10 @@ +.detailPanel { + flex: 1; + background: #fafafa; + + :global { + .ant-card { + background: #fafafa; + } + } +} diff --git a/src/pages/Editor/GGEditor/components/EditorItemPanel/FlowItemPanel.js b/src/pages/Editor/GGEditor/components/EditorItemPanel/FlowItemPanel.js new file mode 100644 index 00000000..b3b46930 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorItemPanel/FlowItemPanel.js @@ -0,0 +1,55 @@ +import React from 'react'; +import { Card } from 'antd'; +import { ItemPanel, Item } from 'gg-editor'; +import styles from './index.less'; + +const FlowItemPanel = () => { + return ( + + + + + + + + + ); +}; + +export default FlowItemPanel; diff --git a/src/pages/Editor/GGEditor/components/EditorItemPanel/KoniItemPanel.js b/src/pages/Editor/GGEditor/components/EditorItemPanel/KoniItemPanel.js new file mode 100644 index 00000000..655ea99a --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorItemPanel/KoniItemPanel.js @@ -0,0 +1,51 @@ +import React from 'react'; +import { Card } from 'antd'; +import { ItemPanel, Item } from 'gg-editor'; +import styles from './index.less'; + +const KoniItemPanel = () => { + return ( + + + + + + + + ); +}; + +export default KoniItemPanel; diff --git a/src/pages/Editor/GGEditor/components/EditorItemPanel/index.js b/src/pages/Editor/GGEditor/components/EditorItemPanel/index.js new file mode 100644 index 00000000..2ba03fbb --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorItemPanel/index.js @@ -0,0 +1,4 @@ +import FlowItemPanel from './FlowItemPanel'; +import KoniItemPanel from './KoniItemPanel'; + +export { FlowItemPanel, KoniItemPanel }; diff --git a/src/pages/Editor/GGEditor/components/EditorItemPanel/index.less b/src/pages/Editor/GGEditor/components/EditorItemPanel/index.less new file mode 100644 index 00000000..a7acc366 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorItemPanel/index.less @@ -0,0 +1,20 @@ +.itemPanel { + flex: 1; + background: #fafafa; + + :global { + .ant-card { + background: #fafafa; + } + + .ant-card-body { + display: flex; + flex-direction: column; + align-items: center; + + > div { + margin-bottom: 16px; + } + } + } +} diff --git a/src/pages/Editor/GGEditor/components/EditorMinimap/index.js b/src/pages/Editor/GGEditor/components/EditorMinimap/index.js new file mode 100644 index 00000000..8c86b242 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorMinimap/index.js @@ -0,0 +1,13 @@ +import React from 'react'; +import { Card } from 'antd'; +import { Minimap } from 'gg-editor'; + +const EditorMinimap = () => { + return ( + + + + ); +}; + +export default EditorMinimap; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/FlowToolbar.js b/src/pages/Editor/GGEditor/components/EditorToolbar/FlowToolbar.js new file mode 100644 index 00000000..374c1858 --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/FlowToolbar.js @@ -0,0 +1,32 @@ +import React from 'react'; +import { Divider } from 'antd'; +import { Toolbar } from 'gg-editor'; +import ToolbarButton from './ToolbarButton'; +import styles from './index.less'; + +const FlowToolbar = () => { + return ( + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default FlowToolbar; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/KoniToolbar.js b/src/pages/Editor/GGEditor/components/EditorToolbar/KoniToolbar.js new file mode 100644 index 00000000..f222007a --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/KoniToolbar.js @@ -0,0 +1,3 @@ +import FlowToolbar from './FlowToolbar'; + +export default FlowToolbar; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/MindToolbar.js b/src/pages/Editor/GGEditor/components/EditorToolbar/MindToolbar.js new file mode 100644 index 00000000..1c83286a --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/MindToolbar.js @@ -0,0 +1,27 @@ +import React from 'react'; +import { Divider } from 'antd'; +import { Toolbar } from 'gg-editor'; +import ToolbarButton from './ToolbarButton'; +import styles from './index.less'; + +const FlowToolbar = () => { + return ( + + + + + + + + + + + + + + + + ); +}; + +export default FlowToolbar; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/ToolbarButton.js b/src/pages/Editor/GGEditor/components/EditorToolbar/ToolbarButton.js new file mode 100644 index 00000000..eb5b4ffa --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/ToolbarButton.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Tooltip } from 'antd'; +import { Command } from 'gg-editor'; +import upperFirst from 'lodash/upperFirst'; +import IconFont from '../../common/IconFont'; +import styles from './index.less'; + +const ToolbarButton = props => { + const { command, icon, text } = props; + + return ( + + + + + + ); +}; + +export default ToolbarButton; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/index.js b/src/pages/Editor/GGEditor/components/EditorToolbar/index.js new file mode 100644 index 00000000..ac08e3dc --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/index.js @@ -0,0 +1,5 @@ +import FlowToolbar from './FlowToolbar'; +import MindToolbar from './MindToolbar'; +import KoniToolbar from './KoniToolbar'; + +export { FlowToolbar, MindToolbar, KoniToolbar }; diff --git a/src/pages/Editor/GGEditor/components/EditorToolbar/index.less b/src/pages/Editor/GGEditor/components/EditorToolbar/index.less new file mode 100644 index 00000000..a5cca37c --- /dev/null +++ b/src/pages/Editor/GGEditor/components/EditorToolbar/index.less @@ -0,0 +1,39 @@ +.toolbar { + display: flex; + align-items: center; + + :global { + .command i { + display: inline-block; + width: 27px; + height: 27px; + margin: 0 6px; + padding-top: 6px; + text-align: center; + border: 1px solid #fff; + cursor: pointer; + + &:hover { + border: 1px solid #e6e9ed; + } + } + + .disable i { + color: rgba(0, 0, 0, 0.25); + cursor: auto; + + &:hover { + border: 1px solid #fff; + } + } + } +} + +.tooltip { + :global { + .ant-tooltip-inner { + font-size: 12px; + border-radius: 0; + } + } +} diff --git a/src/pages/Editor/GGEditor/mock/worldCup2018.json b/src/pages/Editor/GGEditor/mock/worldCup2018.json new file mode 100644 index 00000000..44f3e63f --- /dev/null +++ b/src/pages/Editor/GGEditor/mock/worldCup2018.json @@ -0,0 +1,129 @@ +{ + "roots": [ + { + "label": "法国", + "children": [ + { + "label": "克罗地亚", + "side": "left", + "children": [ + { + "label": "克罗地亚", + "children": [ + { + "label": "克罗地亚", + "children": [ + { + "label": "克罗地亚" + }, + { + "label": "丹麦" + } + ] + }, + { + "label": "俄罗斯", + "children": [ + { + "label": "俄罗斯" + }, + { + "label": "西班牙" + } + ] + } + ] + }, + { + "label": "英格兰", + "children": [ + { + "label": "英格兰", + "children": [ + { + "label": "英格兰" + }, + { + "label": "哥伦比亚" + } + ] + }, + { + "label": "瑞典", + "children": [ + { + "label": "瑞士" + }, + { + "label": "瑞典" + } + ] + } + ] + } + ] + }, + { + "label": "法国", + "side": "right", + "children": [ + { + "label": "法国", + "children": [ + { + "label": "法国", + "children": [ + { + "label": "法国" + }, + { + "label": "阿根廷" + } + ] + }, + { + "label": "乌拉圭", + "children": [ + { + "label": "乌拉圭" + }, + { + "label": "葡萄牙" + } + ] + } + ] + }, + { + "label": "比利时", + "children": [ + { + "label": "比利时", + "children": [ + { + "label": "比利时" + }, + { + "label": "日本" + } + ] + }, + { + "label": "巴西", + "children": [ + { + "label": "巴西" + }, + { + "label": "墨西哥" + } + ] + } + ] + } + ] + } + ] + } + ] +} -- GitLab