chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
const global = {
|
||||
trackable: process.env.NODE_ENV === 'production',
|
||||
version: process.env.GG_EDITOR_VERSION,
|
||||
};
|
||||
|
||||
export default {
|
||||
get(key) {
|
||||
return global[key];
|
||||
},
|
||||
set(key, value) {
|
||||
global[key] = value;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
export const FLOW_CONTAINER = 'J_FlowContainer';
|
||||
export const MIND_CONTAINER = 'J_MindContainer';
|
||||
export const KONI_CONTAINER = 'J_KoniContainer';
|
||||
export const TOOLBAR_CONTAINER = 'J_ToolbarContainer';
|
||||
export const MINIMAP_CONTAINER = 'J_MinimapContainer';
|
||||
export const CONTEXT_MENU_CONTAINER = 'J_ContextMenuContainer';
|
||||
|
||||
export const FLOW_CLASS_NAME = 'Flow';
|
||||
export const MIND_CLASS_NAME = 'Mind';
|
||||
export const KONI_CLASS_NAME = 'Koni';
|
||||
|
||||
export const EVENT_BEFORE_ADD_PAGE = 'beforeAddPage';
|
||||
export const EVENT_AFTER_ADD_PAGE = 'afterAddPage';
|
||||
|
||||
export const STATUS_CANVAS_SELECTED = 'canvas-selected';
|
||||
export const STATUS_NODE_SELECTED = 'node-selected';
|
||||
export const STATUS_EDGE_SELECTED = 'edge-selected';
|
||||
export const STATUS_GROUP_SELECTED = 'group-selected';
|
||||
export const STATUS_MULTI_SELECTED = 'multi-selected';
|
||||
|
||||
export const GRAPH_MOUSE_REACT_EVENTS = {
|
||||
click: 'Click',
|
||||
contextmenu: 'ContextMenu',
|
||||
dblclick: 'DoubleClick',
|
||||
drag: 'Drag',
|
||||
dragend: 'DragEnd',
|
||||
dragenter: 'DragEnter',
|
||||
dragleave: 'DragLeave',
|
||||
dragstart: 'DragStart',
|
||||
drop: 'Drop',
|
||||
mousedown: 'MouseDown',
|
||||
mouseenter: 'MouseEnter',
|
||||
mouseleave: 'MouseLeave',
|
||||
mousemove: 'MouseMove',
|
||||
mouseup: 'MouseUp',
|
||||
};
|
||||
|
||||
export const GRAPH_OTHER_REACT_EVENTS = {
|
||||
afterchange: 'onAfterChange',
|
||||
afterchangesize: 'onAfterChangeSize',
|
||||
afterviewportchange: 'onAfterViewportChange',
|
||||
beforechange: 'onBeforeChange',
|
||||
beforechangesize: 'onBeforeChangeSize',
|
||||
beforeviewportchange: 'onBeforeViewportChange',
|
||||
keydown: 'onKeyDown',
|
||||
keyup: 'onKeyUp',
|
||||
mousewheel: 'onMouseWheel',
|
||||
};
|
||||
|
||||
export const PAGE_REACT_EVENTS = {
|
||||
afteritemactived: 'onAfterItemActived',
|
||||
afteriteminactivated: 'onAfterItemInactivated',
|
||||
afteritemselected: 'onAfterItemSelected',
|
||||
afteritemunactived: 'onAfterItemInactivated',
|
||||
afteritemunselected: 'onAfterItemUnselected',
|
||||
beforeitemactived: 'onBeforeItemActived',
|
||||
beforeiteminactivated: 'onBeforeItemInactivated',
|
||||
beforeitemselected: 'onBeforeItemSelected',
|
||||
beforeitemunactived: 'onBeforeItemInactivated',
|
||||
beforeitemunselected: 'onBeforeItemUnselected',
|
||||
keyUpEditLabel: 'onKeyUpEditLabel',
|
||||
};
|
||||
|
||||
export const EDITOR_REACT_EVENTS = {
|
||||
aftercommandexecute: 'onAfterCommandExecute',
|
||||
beforecommandexecute: 'onBeforeCommandExecute',
|
||||
};
|
||||
|
||||
export const GRAPH_MOUSE_EVENTS = Object.keys(GRAPH_MOUSE_REACT_EVENTS);
|
||||
export const GRAPH_OTHER_EVENTS = Object.keys(GRAPH_OTHER_REACT_EVENTS);
|
||||
export const PAGE_EVENTS = Object.keys(PAGE_REACT_EVENTS);
|
||||
export const EDITOR_EVENTS = Object.keys(EDITOR_REACT_EVENTS);
|
||||
@@ -0,0 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default React.createContext({});
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import GGEditorContext from '@common/context/GGEditorContext';
|
||||
|
||||
export default function (WrappedComponent) {
|
||||
class InjectGGEditorContext extends React.Component {
|
||||
render() {
|
||||
const { forwardRef, ...rest } = this.props;
|
||||
|
||||
return (
|
||||
<GGEditorContext.Consumer>
|
||||
{context => <WrappedComponent ref={forwardRef} {...rest} {...context} />}
|
||||
</GGEditorContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return React.forwardRef((props, ref) => <InjectGGEditorContext {...props} forwardRef={ref} />);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default React.createContext({});
|
||||
@@ -0,0 +1,21 @@
|
||||
class PropsAPI {
|
||||
editor = null;
|
||||
|
||||
constructor(editor) {
|
||||
this.editor = editor;
|
||||
|
||||
['executeCommand'].forEach((key) => {
|
||||
this[key] = (...params) => this.editor[key](...params);
|
||||
});
|
||||
|
||||
['read', 'save', 'add', 'find', 'update', 'remove', 'getSelected'].forEach((key) => {
|
||||
this[key] = (...params) => this.currentPage[key](...params);
|
||||
});
|
||||
}
|
||||
|
||||
get currentPage() {
|
||||
return this.editor.getCurrentPage();
|
||||
}
|
||||
}
|
||||
|
||||
export default PropsAPI;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import PropsAPIContext from '@common/context/PropsAPIContext';
|
||||
|
||||
export default function (WrappedComponent) {
|
||||
class InjectPropsAPI extends React.Component {
|
||||
render() {
|
||||
const { forwardRef, ...rest } = this.props;
|
||||
|
||||
return (
|
||||
<PropsAPIContext.Consumer>
|
||||
{propsAPI => <WrappedComponent ref={forwardRef} {...rest} propsAPI={propsAPI} />}
|
||||
</PropsAPIContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return React.forwardRef((props, ref) => <InjectPropsAPI {...props} forwardRef={ref} />);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import GGEditorCore from '@gg-editor-core/bundle';
|
||||
import { EVENT_BEFORE_ADD_PAGE } from '@common/constants';
|
||||
import track from '@helpers/track';
|
||||
import { uniqueId } from '@utils';
|
||||
|
||||
export default class Editor extends GGEditorCore {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.id = uniqueId();
|
||||
|
||||
this.on(EVENT_BEFORE_ADD_PAGE, ({ className }) => {
|
||||
track({ c1: className });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
class Command extends React.Component {
|
||||
render() {
|
||||
const { name, children } = this.props;
|
||||
|
||||
return (
|
||||
<div className="command" data-command={name}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Command;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
|
||||
class Menu extends React.Component {
|
||||
static create = function (type) {
|
||||
return class TypedMenu extends Menu {
|
||||
constructor(props) {
|
||||
super(props, type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props, type) {
|
||||
super(props);
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
const { type } = this;
|
||||
|
||||
return (
|
||||
<div className="menu" data-status={`${type}-selected`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Menu;
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { pick } from '@utils';
|
||||
import Editor from '@components/Base/Editor';
|
||||
import { CONTEXT_MENU_CONTAINER } from '@common/constants';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
import Menu from './Menu';
|
||||
|
||||
class ContextMenu extends React.Component {
|
||||
contextMenu = null;
|
||||
|
||||
get containerId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${CONTEXT_MENU_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { editor } = this.props;
|
||||
|
||||
this.contextMenu = new Editor.Contextmenu({
|
||||
container: this.containerId,
|
||||
});
|
||||
|
||||
editor.add(this.contextMenu);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div id={this.containerId} {...pick(this.props, ['style', 'className'])}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const NodeMenu = Menu.create('node');
|
||||
export const EdgeMenu = Menu.create('edge');
|
||||
export const GroupMenu = Menu.create('group');
|
||||
export const MultiMenu = Menu.create('multi');
|
||||
export const CanvasMenu = Menu.create('canvas');
|
||||
|
||||
export default withGGEditorContext(ContextMenu);
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { pick } from '@utils';
|
||||
|
||||
class Panel extends React.Component {
|
||||
static create = function (type) {
|
||||
return class TypedPanel extends Panel {
|
||||
constructor(props) {
|
||||
super(props, type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props, type) {
|
||||
super(props);
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { status, children } = this.props;
|
||||
const { type } = this;
|
||||
|
||||
if (`${type}-selected` !== status) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...pick(this.props, ['style', 'className'])}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Panel;
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { pick } from '@utils';
|
||||
import { STATUS_CANVAS_SELECTED } from '@common/constants';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
import Panel from './Panel';
|
||||
|
||||
class DetailPanel extends React.Component {
|
||||
state = {
|
||||
status: '',
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { onAfterAddPage } = this.props;
|
||||
|
||||
onAfterAddPage(({ page }) => {
|
||||
this.setState({
|
||||
status: STATUS_CANVAS_SELECTED,
|
||||
});
|
||||
|
||||
page.on('statuschange', ({ status }) => {
|
||||
this.setState({ status });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
const { status } = this.state;
|
||||
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...pick(this.props, ['style', 'className'])}>
|
||||
{
|
||||
React.Children.toArray(children).map(child => React.cloneElement(child, {
|
||||
status,
|
||||
}))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const NodePanel = Panel.create('node');
|
||||
export const EdgePanel = Panel.create('edge');
|
||||
export const GroupPanel = Panel.create('group');
|
||||
export const MultiPanel = Panel.create('multi');
|
||||
export const CanvasPanel = Panel.create('canvas');
|
||||
|
||||
export default withGGEditorContext(DetailPanel);
|
||||
@@ -0,0 +1,38 @@
|
||||
import Editor from '@components/Base/Editor';
|
||||
import {
|
||||
FLOW_CONTAINER,
|
||||
FLOW_CLASS_NAME,
|
||||
EVENT_BEFORE_ADD_PAGE,
|
||||
EVENT_AFTER_ADD_PAGE,
|
||||
} from '@common/constants';
|
||||
import Page from '@components/Page';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Flow extends Page {
|
||||
static defaultProps = {
|
||||
data: {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
},
|
||||
};
|
||||
|
||||
get pageId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${FLOW_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
initPage() {
|
||||
const { editor } = this.props;
|
||||
|
||||
editor.emit(EVENT_BEFORE_ADD_PAGE, { className: FLOW_CLASS_NAME });
|
||||
|
||||
this.page = new Editor.Flow(this.config);
|
||||
|
||||
editor.add(this.page);
|
||||
|
||||
editor.emit(EVENT_AFTER_ADD_PAGE, { page: this.page });
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Flow);
|
||||
@@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import Editor from '@components/Base/Editor';
|
||||
import {
|
||||
EDITOR_EVENTS,
|
||||
EDITOR_REACT_EVENTS,
|
||||
EVENT_BEFORE_ADD_PAGE,
|
||||
EVENT_AFTER_ADD_PAGE,
|
||||
} from '@common/constants';
|
||||
import { pick } from '@utils';
|
||||
import Global from '@common/Global';
|
||||
import GGEditorContext from '@common/context/GGEditorContext';
|
||||
import PropsAPIContext from '@common/context/PropsAPIContext';
|
||||
import PropsAPI from '@common/context/PropsAPIContext/propsAPI';
|
||||
|
||||
class GGEditor extends React.Component {
|
||||
static setTrackable(value) {
|
||||
Global.set('trackable', Boolean(value));
|
||||
}
|
||||
|
||||
editor = null;
|
||||
|
||||
get currentPage() {
|
||||
return this.editor.getCurrentPage();
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.init();
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
addListener = (target, eventName, handler) => {
|
||||
if (typeof handler === 'function') target.on(eventName, handler);
|
||||
};
|
||||
|
||||
handleBeforeAddPage = (func) => {
|
||||
this.editor.on(EVENT_BEFORE_ADD_PAGE, func);
|
||||
};
|
||||
|
||||
handleAfterAddPage = (func) => {
|
||||
const { currentPage: page } = this;
|
||||
|
||||
if (page) {
|
||||
func({ page });
|
||||
return;
|
||||
}
|
||||
|
||||
this.editor.on(EVENT_AFTER_ADD_PAGE, func);
|
||||
};
|
||||
|
||||
init() {
|
||||
this.editor = new Editor();
|
||||
this.ggEditor = {
|
||||
editor: this.editor,
|
||||
onBeforeAddPage: this.handleBeforeAddPage,
|
||||
onAfterAddPage: this.handleAfterAddPage,
|
||||
};
|
||||
this.propsAPI = new PropsAPI(this.editor);
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
EDITOR_EVENTS.forEach((event) => {
|
||||
this.addListener(this.editor, [event], this.props[EDITOR_REACT_EVENTS[event]]);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.editor.destroy();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<GGEditorContext.Provider value={this.ggEditor}>
|
||||
<PropsAPIContext.Provider value={this.propsAPI}>
|
||||
<div {...pick(this.props, ['style', 'className'])}>{children}</div>
|
||||
</PropsAPIContext.Provider>
|
||||
</GGEditorContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default GGEditor;
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Item extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
handleMouseDown = () => {
|
||||
const { type, size, shape, model } = this.props;
|
||||
|
||||
if (this.page) {
|
||||
this.page.beginAdd(type, {
|
||||
type,
|
||||
size,
|
||||
shape,
|
||||
...model,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { onAfterAddPage } = this.props;
|
||||
|
||||
onAfterAddPage(({ page }) => {
|
||||
this.page = page;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { src, shape, children } = this.props;
|
||||
|
||||
return (
|
||||
<div style={{ cursor: 'pointer' }} onMouseDown={this.handleMouseDown}>
|
||||
{src ? <img src={src} alt={shape} draggable={false} /> : children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Item);
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { pick } from '@utils';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
import Item from './Item';
|
||||
|
||||
class ItemPanel extends React.Component {
|
||||
page = null;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
handleMouseUp = () => {
|
||||
this.page.cancelAdd();
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { onAfterAddPage } = this.props;
|
||||
|
||||
onAfterAddPage(({ page }) => {
|
||||
this.page = page;
|
||||
|
||||
document.addEventListener('mouseup', this.handleMouseUp);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('mouseup', this.handleMouseUp);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div id={this.containerId} {...pick(this.props, ['style', 'className'])}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { Item };
|
||||
|
||||
export default withGGEditorContext(ItemPanel);
|
||||
@@ -0,0 +1,38 @@
|
||||
import Editor from '@components/Base/Editor';
|
||||
import {
|
||||
KONI_CONTAINER,
|
||||
KONI_CLASS_NAME,
|
||||
EVENT_BEFORE_ADD_PAGE,
|
||||
EVENT_AFTER_ADD_PAGE,
|
||||
} from '@common/constants';
|
||||
import Page from '@components/Page';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Koni extends Page {
|
||||
static defaultProps = {
|
||||
data: {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
},
|
||||
};
|
||||
|
||||
get pageId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${KONI_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
initPage() {
|
||||
const { editor } = this.props;
|
||||
|
||||
editor.emit(EVENT_BEFORE_ADD_PAGE, { className: KONI_CLASS_NAME });
|
||||
|
||||
this.page = new Editor.Koni(this.config);
|
||||
|
||||
editor.add(this.page);
|
||||
|
||||
editor.emit(EVENT_AFTER_ADD_PAGE, { page: this.page });
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Koni);
|
||||
@@ -0,0 +1,52 @@
|
||||
import Editor from '@components/Base/Editor';
|
||||
import {
|
||||
MIND_CONTAINER,
|
||||
MIND_CLASS_NAME,
|
||||
EVENT_BEFORE_ADD_PAGE,
|
||||
EVENT_AFTER_ADD_PAGE,
|
||||
} from '@common/constants';
|
||||
import Page from '@components/Page';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Mind extends Page {
|
||||
get pageId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${MIND_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
initPage() {
|
||||
const { editor } = this.props;
|
||||
|
||||
editor.emit(EVENT_BEFORE_ADD_PAGE, { className: MIND_CLASS_NAME });
|
||||
|
||||
this.page = new Editor.Mind(this.config);
|
||||
|
||||
editor.add(this.page);
|
||||
|
||||
editor.emit(EVENT_AFTER_ADD_PAGE, { page: this.page });
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
super.bindEvent();
|
||||
this.bindKeyUpEditLabel();
|
||||
}
|
||||
|
||||
bindKeyUpEditLabel() {
|
||||
const editLabel = this.page.get('labelTextArea');
|
||||
|
||||
editLabel.on('keyup', (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const item = editLabel.focusItem;
|
||||
const text = editLabel.textContent;
|
||||
|
||||
this.page.emit('keyUpEditLabel', {
|
||||
item,
|
||||
text,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Mind);
|
||||
@@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import G6 from '@antv/g6';
|
||||
import { pick } from '@utils';
|
||||
import { MINIMAP_CONTAINER } from '@common/constants';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
require('@antv/g6/build/plugin.tool.minimap');
|
||||
|
||||
const { Minimap: G6Minimap } = G6.Components;
|
||||
|
||||
class Minimap extends React.Component {
|
||||
minimap = null;
|
||||
|
||||
get containerId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${MINIMAP_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
get currentPage() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return editor.getCurrentPage();
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.init();
|
||||
this.bindPage();
|
||||
}
|
||||
|
||||
init() {
|
||||
const {
|
||||
container = this.containerId,
|
||||
width,
|
||||
height,
|
||||
viewportWindowStyle,
|
||||
viewportBackStyle,
|
||||
} = this.props;
|
||||
|
||||
const { clientWidth, clientHeight } = document.getElementById(container);
|
||||
|
||||
this.minimap = new G6Minimap({
|
||||
container,
|
||||
width: width || clientWidth,
|
||||
height: height || clientHeight,
|
||||
viewportWindowStyle,
|
||||
viewportBackStyle,
|
||||
});
|
||||
|
||||
this.minimap.getGraph = () => this.currentPage.getGraph();
|
||||
}
|
||||
|
||||
bindPage() {
|
||||
if (!this.minimap || !this.currentPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
const graph = this.currentPage.getGraph();
|
||||
|
||||
this.minimap.bindGraph(graph);
|
||||
this.minimap.debounceRender();
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { onAfterAddPage } = this.props;
|
||||
|
||||
onAfterAddPage(() => {
|
||||
this.bindPage();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { container } = this.props;
|
||||
|
||||
if (container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <div id={this.containerId} {...pick(this.props, ['style', 'className'])} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Minimap);
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
import { pick, merge } from '@utils';
|
||||
import {
|
||||
GRAPH_MOUSE_EVENTS,
|
||||
GRAPH_OTHER_EVENTS,
|
||||
PAGE_EVENTS,
|
||||
GRAPH_MOUSE_REACT_EVENTS,
|
||||
GRAPH_OTHER_REACT_EVENTS,
|
||||
PAGE_REACT_EVENTS,
|
||||
} from '@common/constants';
|
||||
|
||||
class Page extends React.Component {
|
||||
page;
|
||||
|
||||
get pageId() {
|
||||
return '';
|
||||
}
|
||||
|
||||
config = {};
|
||||
|
||||
componentDidMount() {
|
||||
this.init();
|
||||
this.bindEvent();
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(props) {
|
||||
const { data: newData } = props;
|
||||
const { data: oldData } = this.props;
|
||||
const { mode: newMode } = props.graph || {};
|
||||
const { mode: oldMode } = this.props.graph || {};
|
||||
|
||||
if (newMode !== oldMode) {
|
||||
this.page.changeMode(newMode);
|
||||
}
|
||||
|
||||
if (newData !== oldData) {
|
||||
// Remove the arrow after the connection point of the compensation type
|
||||
newData.edges.forEach((item) => {
|
||||
if (item.type === 'Compensation') {
|
||||
item.style = {
|
||||
...item.style,
|
||||
endArrow: false,
|
||||
};
|
||||
}
|
||||
});
|
||||
this.page.read(newData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (props.className !== this.props.className) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
get graph() {
|
||||
return this.page.getGraph();
|
||||
}
|
||||
|
||||
initPage() { }
|
||||
|
||||
readData() {
|
||||
const { data } = this.config;
|
||||
|
||||
if (data) {
|
||||
this.page.read(data);
|
||||
}
|
||||
}
|
||||
|
||||
addListener = (target, eventName, handler) => {
|
||||
if (typeof handler === 'function') target.on(eventName, handler);
|
||||
};
|
||||
|
||||
init() {
|
||||
merge(this.config, this.props, {
|
||||
graph: {
|
||||
container: this.pageId,
|
||||
},
|
||||
});
|
||||
|
||||
this.initPage();
|
||||
this.readData();
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { addListener } = this;
|
||||
|
||||
GRAPH_MOUSE_EVENTS.forEach((event) => {
|
||||
const eventName = GRAPH_MOUSE_REACT_EVENTS[event];
|
||||
|
||||
addListener(this.graph, `${event}`, this.props[`on${eventName}`]);
|
||||
addListener(this.graph, `node:${event}`, this.props[`onNode${eventName}`]);
|
||||
addListener(this.graph, `edge:${event}`, this.props[`onEdge${eventName}`]);
|
||||
addListener(this.graph, `group:${event}`, this.props[`onGroup${eventName}`]);
|
||||
addListener(this.graph, `guide:${event}`, this.props[`onGuide${eventName}`]);
|
||||
addListener(this.graph, `anchor:${event}`, this.props[`onAnchor${eventName}`]);
|
||||
});
|
||||
|
||||
GRAPH_OTHER_EVENTS.forEach((event) => {
|
||||
addListener(this.graph, [event], this.props[GRAPH_OTHER_REACT_EVENTS[event]]);
|
||||
});
|
||||
|
||||
PAGE_EVENTS.forEach((event) => {
|
||||
addListener(this.page, [event], this.props[PAGE_REACT_EVENTS[event]]);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { page, pageId } = this;
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div id={pageId} {...pick(this.props, ['style', 'className'])}>
|
||||
{page ? children : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import Editor from '@components/Base/Editor';
|
||||
import { upperFirst } from '@utils';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Register extends React.Component {
|
||||
static create = function (type) {
|
||||
class TypedRegister extends Register {
|
||||
constructor(props) {
|
||||
super(props, type);
|
||||
}
|
||||
}
|
||||
|
||||
return withGGEditorContext(TypedRegister);
|
||||
}
|
||||
|
||||
constructor(props, type) {
|
||||
super(props);
|
||||
|
||||
this.type = type;
|
||||
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
const { type } = this;
|
||||
const { onBeforeAddPage } = this.props;
|
||||
|
||||
onBeforeAddPage(({ className }) => {
|
||||
let host = Editor[className];
|
||||
let keys = ['name', 'config', 'extend'];
|
||||
|
||||
if (type === 'command') {
|
||||
host = Editor;
|
||||
}
|
||||
|
||||
if (type === 'behaviour') {
|
||||
keys = ['name', 'behaviour', 'dependences'];
|
||||
}
|
||||
|
||||
const args = keys.map(key => this.props[key]);
|
||||
|
||||
host[`register${upperFirst(type)}`](...args);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const RegisterNode = Register.create('node');
|
||||
export const RegisterEdge = Register.create('edge');
|
||||
export const RegisterGroup = Register.create('group');
|
||||
export const RegisterGuide = Register.create('guide');
|
||||
export const RegisterCommand = Register.create('command');
|
||||
export const RegisterBehaviour = Register.create('behaviour');
|
||||
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import Editor from '@components/Base/Editor';
|
||||
import { pick } from '@utils';
|
||||
import { TOOLBAR_CONTAINER } from '@common/constants';
|
||||
import withGGEditorContext from '@common/context/GGEditorContext/withGGEditorContext';
|
||||
|
||||
class Toolbar extends React.Component {
|
||||
toolbar = null;
|
||||
|
||||
get containerId() {
|
||||
const { editor } = this.props;
|
||||
|
||||
return `${TOOLBAR_CONTAINER}_${editor.id}`;
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const { editor, onAfterAddPage } = props;
|
||||
|
||||
onAfterAddPage(() => {
|
||||
this.toolbar = new Editor.Toolbar({
|
||||
container: this.containerId,
|
||||
});
|
||||
|
||||
editor.add(this.toolbar);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div id={this.containerId} {...pick(this.props, ['style', 'className'])}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withGGEditorContext(Toolbar);
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,34 @@
|
||||
import Global from '@common/Global';
|
||||
import { toQueryString } from '@utils';
|
||||
|
||||
const BASE_URL = 'http://gm.mmstat.com/fsp.1.1';
|
||||
|
||||
const track = (options) => {
|
||||
const trackable = Global.get('trackable');
|
||||
const version = Global.get('version');
|
||||
|
||||
if (!trackable) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { location, navigator } = window;
|
||||
const image = new Image();
|
||||
const params = toQueryString({
|
||||
pid: 'ggeditor',
|
||||
code: '11',
|
||||
msg: 'syslog',
|
||||
page: `${location.protocol}//${location.host}${location.pathname}`,
|
||||
hash: location.hash,
|
||||
ua: navigator.userAgent,
|
||||
rel: version,
|
||||
...options,
|
||||
});
|
||||
|
||||
image.src = `${BASE_URL}?${params}`;
|
||||
};
|
||||
|
||||
export default (options) => {
|
||||
setTimeout(() => {
|
||||
track(options);
|
||||
}, 1000);
|
||||
};
|
||||
63
saga/seata-saga-statemachine-designer/ggeditor/index.js
Normal file
63
saga/seata-saga-statemachine-designer/ggeditor/index.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import Flow from '@components/Flow';
|
||||
import Mind from '@components/Mind';
|
||||
import Koni from '@components/Koni';
|
||||
import {
|
||||
RegisterNode,
|
||||
RegisterEdge,
|
||||
RegisterGroup,
|
||||
RegisterGuide,
|
||||
RegisterCommand,
|
||||
RegisterBehaviour,
|
||||
} from '@components/Register';
|
||||
import Command from '@components/Command';
|
||||
import Minimap from '@components/Minimap';
|
||||
import ContextMenu, {
|
||||
NodeMenu,
|
||||
EdgeMenu,
|
||||
GroupMenu,
|
||||
MultiMenu,
|
||||
CanvasMenu,
|
||||
} from '@components/ContextMenu';
|
||||
import Toolbar from '@components/Toolbar';
|
||||
import ItemPanel, { Item } from '@components/ItemPanel';
|
||||
import DetailPanel, {
|
||||
NodePanel,
|
||||
EdgePanel,
|
||||
GroupPanel,
|
||||
MultiPanel,
|
||||
CanvasPanel,
|
||||
} from '@components/DetailPanel';
|
||||
import withPropsAPI from '@common/context/PropsAPIContext/withPropsAPI';
|
||||
import GGEditor from '@components/GGEditor';
|
||||
|
||||
export {
|
||||
Flow,
|
||||
Mind,
|
||||
Koni,
|
||||
RegisterNode,
|
||||
RegisterEdge,
|
||||
RegisterGroup,
|
||||
RegisterGuide,
|
||||
RegisterCommand,
|
||||
RegisterBehaviour,
|
||||
Command,
|
||||
Minimap,
|
||||
NodeMenu,
|
||||
EdgeMenu,
|
||||
GroupMenu,
|
||||
MultiMenu,
|
||||
CanvasMenu,
|
||||
ContextMenu,
|
||||
Toolbar,
|
||||
Item,
|
||||
ItemPanel,
|
||||
NodePanel,
|
||||
EdgePanel,
|
||||
GroupPanel,
|
||||
MultiPanel,
|
||||
CanvasPanel,
|
||||
DetailPanel,
|
||||
withPropsAPI,
|
||||
};
|
||||
|
||||
export default GGEditor;
|
||||
@@ -0,0 +1,14 @@
|
||||
import merge from 'lodash/merge';
|
||||
import pick from 'lodash/pick';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
|
||||
const toQueryString = obj => Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
|
||||
|
||||
export {
|
||||
merge,
|
||||
pick,
|
||||
toQueryString,
|
||||
uniqueId,
|
||||
upperFirst,
|
||||
};
|
||||
Reference in New Issue
Block a user