hrw-certificate-editor
Version:
Design Editor Tools with React.js + ant.design + fabric.js
329 lines • 17 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const antd_1 = require("antd");
const i18next_1 = __importDefault(require("i18next"));
const React = __importStar(require("react"));
const Canvas_1 = __importDefault(require("../../canvas/Canvas"));
const common_1 = require("../../components/common");
const layout_1 = require("../../components/layout");
const NodeConfiguration_1 = require("./configuration/NodeConfiguration");
const constants_1 = require("./constant/constants");
const NodeConfigurationError_1 = __importDefault(require("./error/NodeConfigurationError"));
const link_1 = __importDefault(require("./link"));
const node_1 = __importDefault(require("./node"));
const WorkflowConfigurations_1 = __importDefault(require("./WorkflowConfigurations"));
const WorkflowItems_1 = __importDefault(require("./WorkflowItems"));
const WorkflowNodeConfigurations_1 = __importDefault(require("./WorkflowNodeConfigurations"));
const WorkflowTitle_1 = __importDefault(require("./WorkflowTitle"));
const WorkflowToolbar_1 = __importDefault(require("./WorkflowToolbar"));
class WorkflowEditor extends React.Component {
constructor() {
super(...arguments);
this.state = {
loading: true,
zoomRatio: 1,
workflow: {},
selectedItem: null,
descriptors: {},
editing: false,
};
this.canvasHandlers = {
onZoom: zoom => {
this.setState({
zoomRatio: zoom,
});
},
onAdd: (target) => {
if (target.type === 'activeSelection') {
this.canvasHandlers.onSelect(null);
return;
}
if (target.superType === 'node') {
this.canvasRef.handler.nodeHandler.highlightingNode(target);
this.canvasRef.handler.select(target);
}
},
onSelect: target => {
this.nodeConfigurationRef.props.form.validateFields(err => {
if (this.state.selectedItem) {
if (err || (this.state.selectedItem.errors && this.state.selectedItem.errors.length)) {
this.state.selectedItem.setErrors(true);
}
else {
this.state.selectedItem.setErrors(false);
}
}
});
if (target &&
target.id &&
target.id !== 'workarea' &&
target.type !== 'activeSelection' &&
target.superType !== 'link' &&
target.superType !== 'port') {
this.setState({
selectedItem: target,
});
return;
}
this.setState({
selectedItem: null,
}, () => {
this.canvasRef.handler.nodeHandler.deselect();
});
},
onRemove: () => {
if (!this.state.editing) {
this.changeEditing(true);
}
},
onModified: () => {
if (!this.state.editing) {
this.changeEditing(true);
}
},
};
this.handlers = {
onImport: files => {
if (files) {
this.showLoading();
const reader = new FileReader();
reader.onload = e => {
const result = JSON.parse(e.target.result);
this.setState({
workflow: result,
});
this.canvasRef.handler.clear();
const nodes = result.nodes.map(node => {
return {
...node,
type: NodeConfiguration_1.getNode(node.nodeClazz),
left: node.properties ? node.properties.left : 0,
top: node.properties ? node.properties.top : 0,
};
});
const links = result.links.map(link => {
return {
fromNodeId: link.fromNode,
fromPortId: link.fromPort,
toNodeId: link.toNode,
type: 'curvedLink',
superType: 'link',
left: link.properties ? link.properties.left : 0,
top: link.properties ? link.properties.top : 0,
};
});
const objects = nodes.concat(links);
const { viewportTransform } = result.properties;
if (viewportTransform) {
this.canvasRef.canvas.setViewportTransform(viewportTransform);
}
this.canvasRef.handler.importJSON(objects, () => {
this.hideLoading();
this.canvasRef.canvas.setZoom(this.state.zoomRatio);
});
};
reader.readAsText(files[0]);
}
},
onUpload: () => {
const inputEl = document.createElement('input');
inputEl.accept = '.json';
inputEl.type = 'file';
inputEl.hidden = true;
inputEl.onchange = (e) => {
this.handlers.onImport(e.target.files);
};
document.body.appendChild(inputEl); // required for firefox
inputEl.click();
inputEl.remove();
},
onDownload: () => {
this.showLoading();
const workflow = this.handlers.exportJsonCode();
if (workflow) {
const anchorEl = document.createElement('a');
anchorEl.href = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(workflow, null, '\t'))}`;
anchorEl.download = `${workflow.name}.json`;
document.body.appendChild(anchorEl); // required for firefox
anchorEl.click();
anchorEl.remove();
this.hideLoading();
}
},
exportJsonCode: () => {
const workflow = Object.assign({}, this.state.workflow);
const nodes = [];
const links = [];
try {
this.canvasRef.handler.exportJSON().forEach(obj => {
if (obj.superType === 'node') {
if (obj.errors) {
throw new NodeConfigurationError_1.default(i18next_1.default.t('workflow.validate-fields-error'), obj.id, obj.name);
}
const node = {
id: obj.id,
name: obj.name,
description: obj.description,
nodeClazz: obj.nodeClazz,
configuration: obj.configuration,
properties: {
left: obj.left || 0,
top: obj.top || 0,
icon: obj.icon,
},
};
nodes.push(node);
}
else if (obj.superType === 'link') {
const link = {
fromNode: obj.fromNode.id,
fromPort: obj.fromPort.id,
toNode: obj.toNode.id,
properties: {
left: obj.left || 0,
top: obj.top || 0,
},
};
links.push(link);
}
});
workflow.nodes = nodes;
workflow.links = links;
const properties = {
viewportTransform: this.canvasRef.canvas.viewportTransform,
};
workflow.properties = properties;
return workflow;
}
catch (error) {
console.error(`[ERROR] ${this.constructor.name} exportJsonCode()`, error);
this.canvasRef.handler.selectById(error.nodeId);
antd_1.message.error(error.message);
this.hideLoading();
}
},
onChange: (selectedItem, changedValues, allValues) => {
if (!this.state.editing) {
this.changeEditing(true);
}
if (changedValues.workflow) {
const workflow = Object.assign({}, this.state.workflow, changedValues.workflow);
this.setState({
workflow,
});
}
else {
setTimeout(() => {
const configurationList = Object.keys(allValues.configuration).map(key => `configuration.${key}`);
const errors = this.nodeConfigurationRef.props.form.getFieldsError(configurationList.concat(['name']));
if (Object.values(errors.configuration).filter(error => error).length || errors.name) {
selectedItem.setErrors(true);
}
else {
selectedItem.setErrors(false);
}
this.canvasRef.canvas.renderAll();
}, 0);
const configuration = Object.assign({}, selectedItem.configuration, changedValues.configuration);
this.canvasRef.handler.setObject({
configuration,
name: allValues.name,
description: allValues.description,
});
selectedItem.label.set({
text: NodeConfiguration_1.getEllipsis(allValues.name, 18),
});
if (selectedItem.descriptor.outPortType === constants_1.OUT_PORT_TYPE.DYNAMIC) {
this.canvasRef.handler.portHandler.recreate(selectedItem);
}
}
},
};
this.showLoading = () => {
this.setState({
loading: true,
});
};
this.hideLoading = () => {
this.setState({
loading: false,
});
};
this.changeEditing = editing => {
this.setState({
editing,
});
};
}
componentDidMount() {
new Promise(require('./Descriptors.json')).then(descriptors => {
this.setState({
descriptors,
}, () => {
this.hideLoading();
});
});
}
render() {
const { zoomRatio, workflow, selectedItem, descriptors, loading, editing } = this.state;
const { onChange, onDownload, onUpload } = this.handlers;
const { onZoom, onAdd, onSelect, onRemove, onModified } = this.canvasHandlers;
const nodes = node_1.default(descriptors);
const action = (React.createElement(React.Fragment, null,
React.createElement(common_1.CommonButton, { className: "rde-action-btn", shape: "circle", icon: "file-download", disabled: !editing, tooltipTitle: i18next_1.default.t('action.download'), onClick: onDownload, tooltipPlacement: "bottomRight" }),
editing ? (React.createElement(antd_1.Popconfirm, { title: i18next_1.default.t('workflow.workflow-editing-confirm'), okText: i18next_1.default.t('action.ok'), cancelText: i18next_1.default.t('action.cancel'), onConfirm: onUpload, placement: "bottomRight" },
React.createElement(common_1.CommonButton, { className: "rde-action-btn", shape: "circle", icon: "file-upload", tooltipTitle: i18next_1.default.t('action.upload'), tooltipPlacement: "bottomRight" }))) : (React.createElement(common_1.CommonButton, { className: "rde-action-btn", shape: "circle", icon: "file-upload", tooltipTitle: i18next_1.default.t('action.upload'), tooltipPlacement: "bottomRight", onClick: onUpload }))));
const titleContent = (React.createElement(React.Fragment, null,
React.createElement("span", null, i18next_1.default.t('workflow.workflow-editor')),
React.createElement("span", { style: { width: 40, textAlign: 'center' } }, "/"),
React.createElement("span", { style: { color: workflow.enabled ? '#49a9ee' : 'rgba(0, 0, 0, 0.65)' } }, workflow.name)));
const title = React.createElement(WorkflowTitle_1.default, { title: titleContent, action: action });
const content = (React.createElement("div", { className: "rde-editor" },
React.createElement(WorkflowItems_1.default, { canvasRef: this.canvasRef, descriptors: descriptors }),
React.createElement("div", { ref: c => {
this.container = c;
}, className: "rde-editor-canvas" },
React.createElement(Canvas_1.default, { ref: c => {
this.canvasRef = c;
}, className: "rde-canvas", fabricObjects: { ...nodes, ...link_1.default }, workareaOption: {
width: 0,
height: 0,
}, gridOption: { enabled: true, grid: 20, snapToGrid: true }, activeSelectionOption: {
hasControls: false,
hasBorders: false,
perPixelTargetFind: true,
}, minZoom: 50, maxZoom: 150, onZoom: onZoom, onSelect: onSelect, onAdd: onAdd, onRemove: onRemove, onModified: onModified, keyEvent: { move: false, transaction: true, clipboard: true } }),
React.createElement("div", { className: "rde-editor-properties", style: { display: selectedItem ? 'block' : 'none' } },
React.createElement(WorkflowNodeConfigurations_1.default, { wrappedComponentRef: c => {
this.nodeConfigurationRef = c;
}, selectedItem: selectedItem, workflow: workflow, canvasRef: this.canvasRef, descriptors: descriptors, onChange: onChange })),
React.createElement("div", { className: "rde-editor-toolbar" },
React.createElement(WorkflowToolbar_1.default, { canvasRef: this.canvasRef, zoomRatio: zoomRatio }))),
React.createElement(WorkflowConfigurations_1.default, { workflow: workflow, selectedItem: selectedItem, canvasRef: this.canvasRef, onChange: onChange })));
return React.createElement(layout_1.Content, { title: title, content: content, loading: loading, className: "" });
}
}
exports.default = WorkflowEditor;
//# sourceMappingURL=WorkflowEditor.js.map