UNPKG

hrw-certificate-editor

Version:

Design Editor Tools with React.js + ant.design + fabric.js

329 lines 17 kB
"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