UNPKG

plot-plan-designer

Version:

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

280 lines (279 loc) 15.3 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 (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 react_1 = __importStar(require("react")); const prop_types_1 = __importDefault(require("prop-types")); const antd_1 = require("antd"); const uuid_1 = require("uuid"); const classnames_1 = __importDefault(require("classnames")); const i18next_1 = __importDefault(require("i18next")); const flex_1 = require("../flex"); const Icon_1 = __importDefault(require("../icon/Icon")); const Scrollbar_1 = __importDefault(require("../common/Scrollbar")); const CommonButton_1 = __importDefault(require("../common/CommonButton")); const common_1 = require("../common"); antd_1.notification.config({ top: 80, duration: 2, }); let ImageMapItems = /** @class */ (() => { class ImageMapItems extends react_1.Component { constructor() { super(...arguments); this.state = { activeKey: [], collapse: false, textSearch: '', descriptors: {}, filteredDescriptors: [], svgModalVisible: false, }; this.waitForCanvasRender = (canvas) => { setTimeout(() => { if (canvas) { this.attachEventListener(canvas); return; } const { canvasRef } = this.props; this.waitForCanvasRender(canvasRef); }, 5); }; this.attachEventListener = (canvas) => { canvas.canvas.wrapperEl.addEventListener('dragenter', this.events.onDragEnter, false); canvas.canvas.wrapperEl.addEventListener('dragover', this.events.onDragOver, false); canvas.canvas.wrapperEl.addEventListener('dragleave', this.events.onDragLeave, false); canvas.canvas.wrapperEl.addEventListener('drop', this.events.onDrop, false); }; this.detachEventListener = (canvas) => { canvas.canvas.wrapperEl.removeEventListener('dragenter', this.events.onDragEnter); canvas.canvas.wrapperEl.removeEventListener('dragover', this.events.onDragOver); canvas.canvas.wrapperEl.removeEventListener('dragleave', this.events.onDragLeave); canvas.canvas.wrapperEl.removeEventListener('drop', this.events.onDrop); }; /* eslint-disable react/sort-comp, react/prop-types */ this.handlers = { onAddItem: (item, centered) => { const { canvasRef } = this.props; if (canvasRef.handler.interactionMode === 'polygon') { antd_1.message.info('Already drawing'); return; } const id = uuid_1.v4(); const option = Object.assign({}, item.option, { id }); if (item.option.superType === 'svg' && item.type === 'default') { this.handlers.onSVGModalVisible(item.option); return; } canvasRef.handler.add(option, centered); }, onAddSVG: (option, centered) => { const { canvasRef } = this.props; canvasRef.handler.add(Object.assign(Object.assign({}, option), { type: 'svg', superType: 'svg', id: uuid_1.v4(), name: 'New SVG' }), centered); this.handlers.onSVGModalVisible(); }, onDrawingItem: (item) => { const { canvasRef } = this.props; if (canvasRef.handler.interactionMode === 'polygon') { antd_1.message.info('Already drawing'); return; } if (item.option.type === 'line') { canvasRef.handler.drawingHandler.line.init(); } else if (item.option.type === 'arrow') { canvasRef.handler.drawingHandler.arrow.init(); } else { canvasRef.handler.drawingHandler.polygon.init(); } }, onChangeActiveKey: (activeKey) => { this.setState({ activeKey, }); }, onCollapse: () => { this.setState({ collapse: !this.state.collapse, }); }, onSearchNode: (e) => { const filteredDescriptors = this.handlers .transformList() .filter((descriptor) => descriptor.name.toLowerCase().includes(e.target.value.toLowerCase())); this.setState({ textSearch: e.target.value, filteredDescriptors, }); }, transformList: () => { return Object.values(this.props.descriptors).reduce((prev, curr) => prev.concat(curr), []); }, onSVGModalVisible: () => { this.setState((prevState) => { return { svgModalVisible: !prevState.svgModalVisible, }; }); }, }; this.events = { onDragStart: (e, item) => { this.item = item; const { target } = e; target.classList.add('dragging'); }, onDragOver: (e) => { if (e.preventDefault) { e.preventDefault(); } e.dataTransfer.dropEffect = 'copy'; return false; }, onDragEnter: (e) => { const { target } = e; target.classList.add('over'); }, onDragLeave: (e) => { const { target } = e; target.classList.remove('over'); }, onDrop: (e) => { e = e || window.event; if (e.preventDefault) { e.preventDefault(); } if (e.stopPropagation) { e.stopPropagation(); } const { layerX, layerY } = e; const dt = e.dataTransfer; if (dt.types.length && dt.types[0] === 'Files') { const { files } = dt; Array.from(files).forEach((file) => { file.uid = uuid_1.v4(); const { type } = file; if (type === 'image/png' || type === 'image/jpeg' || type === 'image/jpg') { const item = { option: { type: 'image', file, left: layerX, top: layerY, }, }; this.handlers.onAddItem(item, false); } else { antd_1.notification.warn({ message: 'Not supported file type', }); } }); return false; } const option = Object.assign({}, this.item.option, { left: layerX, top: layerY }); const newItem = Object.assign({}, this.item, { option }); this.handlers.onAddItem(newItem, false); return false; }, onDragEnd: (e) => { this.item = null; e.target.classList.remove('dragging'); }, }; this.renderItems = (items) => { return (react_1.default.createElement(flex_1.Flex, { flexWrap: "wrap", flexDirection: "column", style: { width: '100%' } }, items.map((item) => this.renderItem(item)))); }; this.renderItem = (item, centered) => item.type === 'drawing' ? (react_1.default.createElement("div", { key: item.name, draggable: true, onClick: (e) => this.handlers.onDrawingItem(item), className: "rde-editor-items-item", style: { justifyContent: this.state.collapse ? 'center' : null } }, react_1.default.createElement("span", { className: "rde-editor-items-item-icon" }, react_1.default.createElement(Icon_1.default, { name: item.icon.name, prefix: item.icon.prefix, style: item.icon.style })), this.state.collapse ? null : react_1.default.createElement("div", { className: "rde-editor-items-item-text" }, item.trans ? i18next_1.default.t(`imagemap.descriptors.${item.trans}`) : item.name))) : (react_1.default.createElement("div", { key: item.name, draggable: true, onClick: (e) => this.handlers.onAddItem(item, centered), onDragStart: (e) => this.events.onDragStart(e, item), onDragEnd: (e) => this.events.onDragEnd(e, item), className: "rde-editor-items-item", style: { justifyContent: this.state.collapse ? 'center' : null } }, react_1.default.createElement("span", { className: "rde-editor-items-item-icon" }, react_1.default.createElement(Icon_1.default, { name: item.icon.name, prefix: item.icon.prefix, style: item.icon.style })), this.state.collapse ? null : react_1.default.createElement("div", { className: "rde-editor-items-item-text" }, item.trans ? i18next_1.default.t(`imagemap.descriptors.${item.trans}`) : item.name))); } componentDidMount() { const { canvasRef } = this.props; this.waitForCanvasRender(canvasRef); } UNSAFE_componentWillReceiveProps(nextProps) { if (JSON.stringify(this.props.descriptors) !== JSON.stringify(nextProps.descriptors)) { const descriptors = Object.keys(nextProps.descriptors).reduce((prev, key) => { return prev.concat(nextProps.descriptors[key]); }, []); this.setState({ descriptors, }); } } shouldComponentUpdate(nextProps, nextState) { if (JSON.stringify(this.state.descriptors) !== JSON.stringify(nextState.descriptors)) { return true; } else if (JSON.stringify(this.state.filteredDescriptors) !== JSON.stringify(nextState.filteredDescriptors)) { return true; } else if (this.state.textSearch !== nextState.textSearch) { return true; } else if (JSON.stringify(this.state.activeKey) !== JSON.stringify(nextState.activeKey)) { return true; } else if (this.state.collapse !== nextState.collapse) { return true; } else if (this.state.svgModalVisible !== nextState.svgModalVisible) { return true; } return false; } componentWillUnmount() { const { canvasRef } = this.props; this.detachEventListener(canvasRef); } render() { const { descriptors } = this.props; const { collapse, textSearch, filteredDescriptors, activeKey, svgModalVisible, svgOption } = this.state; const className = classnames_1.default('rde-editor-items', { minimize: collapse, }); return (react_1.default.createElement("div", { className: className }, react_1.default.createElement(flex_1.Flex, { flex: "1", flexDirection: "column", style: { height: '100%' } }, react_1.default.createElement(flex_1.Flex, { justifyContent: "center", alignItems: "center", style: { height: 40 } }, react_1.default.createElement(CommonButton_1.default, { icon: collapse ? 'angle-double-right' : 'angle-double-left', shape: "circle", className: "rde-action-btn", style: { margin: '0 4px' }, onClick: this.handlers.onCollapse, tooltipTitle: i18next_1.default.t('action.collapse') }), collapse ? null : (react_1.default.createElement(antd_1.Input, { style: { margin: '8px' }, placeholder: i18next_1.default.t('action.search-list'), onChange: this.handlers.onSearchNode, value: textSearch, allowClear: true }))), react_1.default.createElement(Scrollbar_1.default, null, react_1.default.createElement(flex_1.Flex, { flex: "1", style: { overflowY: 'hidden' } }, (textSearch.length && this.renderItems(filteredDescriptors)) || (collapse ? (react_1.default.createElement(flex_1.Flex, { flexWrap: "wrap", flexDirection: "column", style: { width: '100%' }, justifyContent: "center" }, this.handlers.transformList().map((item) => this.renderItem(item)))) : (react_1.default.createElement(antd_1.Collapse, { style: { width: '100%' }, bordered: false, activeKey: activeKey.length ? activeKey : Object.keys(descriptors), onChange: this.handlers.onChangeActiveKey }, Object.keys(descriptors).map((key) => (react_1.default.createElement(antd_1.Collapse.Panel, { key: key, header: i18next_1.default.t(`imagemap.descriptors.${key.toLowerCase()}`), showArrow: !collapse }, this.renderItems(descriptors[key])))))))))), react_1.default.createElement(common_1.SVGModal, { visible: svgModalVisible, onOk: this.handlers.onAddSVG, onCancel: this.handlers.onSVGModalVisible, option: svgOption }))); } } ImageMapItems.propTypes = { canvasRef: prop_types_1.default.any, descriptors: prop_types_1.default.object, }; return ImageMapItems; })(); exports.default = ImageMapItems;