@logicflow/extension
Version:
LogicFlow Extensions
161 lines (160 loc) • 8.11 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { jsx as _jsx } from "preact/jsx-runtime";
import { Component, observer } from '@logicflow/core';
import { forEach, merge } from 'lodash-es';
import Label from './Label';
import LabelModel from './LabelModel';
import { MediumEditor, defaultOptions, ColorPickerButton } from './mediumEditor';
// const { createUuid } = LogicFlowUtil
// DONE: 解决问题,如果 LabelOverlay 设置为 Observer,拖拽 Label 时会导致 LabelOverlay 组件重新渲染,不知道为何
// 目前解决了。流程是 拖动 -> 更新 label 的数据信息到 element model -> 重新渲染 LabelOverlay
// 这种目前存在的问题,会全量重新渲染,是否会影响性能 ❓❓❓
// 另一种解决方案是,在此组件中监听一些事件,当这些事件触发时,再重新渲染 LabelOverlay
// 讨论一下
var LabelOverlay = /** @class */ (function (_super) {
__extends(LabelOverlay, _super);
function LabelOverlay(props) {
var _this = _super.call(this, props) || this;
_this.labelMap = new Map();
var lf = props.lf, graphModel = props.graphModel;
_this.lf = lf;
_this.graphModel = graphModel;
_this.state = { tick: 0 };
return _this;
}
LabelOverlay.prototype.componentDidMount = function () {
var _this = this;
var graphModel = this.props.graphModel;
// 1. 直接在此处初始化 RichTextEdit 工具
this.editor = new MediumEditor('.lf-label-editor', merge(defaultOptions, {
autoLink: true,
extensions: {
colorPicker: new ColorPickerButton(),
},
}));
// TODO: 2. 在此处监听一些事件,当 node、edge 数据变化时,主动触发重新渲染,保证同步更新
// TODO: 3. 整理哪些事件应该触发 Label 的更新
// 不需要了,将当前组件设置成 @observer 后,graphModel 更新会自动触发更新
graphModel.eventCenter.on('text:update,node:mousemove,node:resize,node:rotate,node:drag,label:drop,node:drop', function () {
// this.setState({ tick: this.state.tick + 1 })
});
graphModel.eventCenter.on('node:properties-change,node:properties-delete', function () {
_this.setState({ tick: _this.state.tick + 1 });
});
};
LabelOverlay.prototype.componentDidUpdate = function () {
var _a;
// 在组件更新后,将新增的 label 元素添加到富文本编辑器中
if (this.editor && this.editor.elements.length > 0) {
this.editor.addElements('.lf-label-editor');
}
else {
// FIX: 如果初始化的数据中没有 properties._label,需要重新初始化富文本编辑器
(_a = this.editor) === null || _a === void 0 ? void 0 : _a.destroy();
this.editor = new MediumEditor('.lf-label-editor', merge(defaultOptions, {
autoLink: true,
extensions: {
colorPicker: new ColorPickerButton(),
},
}));
}
};
LabelOverlay.prototype.componentWillUnmount = function () {
var _a;
// 组件销毁时,同时将富文本编辑器注销
(_a = this.editor) === null || _a === void 0 ? void 0 : _a.destroy();
};
/**
* 获取当前画布上所有的 label
* 1. 第一步,先把当前所有的 text 转换为 label 进行展示
* 2. 数据同步,text 编辑后,同步更新 label,并重新渲染
*/
LabelOverlay.prototype.getLabels = function () {
var _this = this;
// 1. 通过 graphModel 获取当前画布上所有的 label 配置数据
var _a = this.props, extension = _a.lf.extension, graphModel = _a.graphModel;
var elements = __spreadArray(__spreadArray([], __read(graphModel.nodes), false), __read(graphModel.edges), false);
var curExtension = extension['label'];
if (curExtension) {
var labels_1 = []; // 保存所有的 Label 元素
// TODO: 筛选出当前画布上,textMode 为 TextMode.LABEL 的元素(在支持元素级别的 textMode 时,需要做这个筛选)
// REMIND: 本期先只支持全局配置,所以判断全局的 textMode 即可
forEach(elements, function (element) {
var _a, _b;
var elementData = element.getData();
var labelConfig = (_b = (_a = elementData.properties) === null || _a === void 0 ? void 0 : _a._label) !== null && _b !== void 0 ? _b : [];
forEach(labelConfig, function (config) {
var labelMap = _this.labelMap;
// 查找 labelModel 实例,如果是实例化过的,直接复用;如果是新的,创建实例
// let label: LabelModel
// if (config.id && labelMap.has(config.id)) {
// label = labelMap.get(config.id)!
// } else {
// label = new LabelModel(config, element, graphModel)
// labelMap.set(label.id, label)
// }
var label = new LabelModel(config, element, graphModel);
labelMap.set(label.id, label);
labels_1.push(_jsx(Label, { label: label, element: element, graphModel: graphModel }, label.id));
});
});
return labels_1;
}
return null;
};
LabelOverlay.prototype.render = function () {
return (_jsx("foreignObject", { id: "lf-label-overlay", class: "lf-label-overlay", children: this.getLabels() }));
};
LabelOverlay.toolName = 'label-edit-tool';
LabelOverlay = __decorate([
observer
], LabelOverlay);
return LabelOverlay;
}(Component));
export { LabelOverlay };
export default LabelOverlay;