Fix cycle dependency

This commit is contained in:
Paulo Gustavo Veiga 2021-12-29 08:38:37 -08:00
parent 45ad796c3b
commit ef3984cfd0
10 changed files with 77 additions and 60 deletions

View File

@ -37,7 +37,7 @@ import RelationshipPivot from './RelationshipPivot';
import Relationship from './Relationship'; import Relationship from './Relationship';
import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher'; import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
import TopicFeature from './TopicFeature'; import TopicFeatureFactory from './TopicFeature';
import { create } from './NodeGraphUtils'; import { create } from './NodeGraphUtils';
@ -952,7 +952,7 @@ class Designer extends Events {
addIconType(iconType) { addIconType(iconType) {
const topicsIds = this.getModel().filterTopicsIds(); const topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) { if (topicsIds.length > 0) {
this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeature.Icon.id, { this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeatureFactory.Icon.id, {
id: iconType, id: iconType,
}); });
} }

View File

@ -31,7 +31,7 @@ import {
import NodeGraph from './NodeGraph'; import NodeGraph from './NodeGraph';
import TopicConfig from './TopicConfig'; import TopicConfig from './TopicConfig';
import TopicStyle from './TopicStyle'; import TopicStyle from './TopicStyle';
import TopicFeature from './TopicFeature'; import TopicFeatureFactory from './TopicFeature';
import ConnectionLine from './ConnectionLine'; import ConnectionLine from './ConnectionLine';
import IconGroup from './IconGroup'; import IconGroup from './IconGroup';
import FadeEffect from './util/FadeEffect'; import FadeEffect from './util/FadeEffect';
@ -311,8 +311,8 @@ class Topic extends NodeGraph {
const model = this.getModel(); const model = this.getModel();
const featuresModel = model.getFeatures(); const featuresModel = model.getFeatures();
featuresModel.forEach((f) => { featuresModel.forEach((f) => {
const icon = TopicFeature.createIcon(this, f, this.isReadOnly()); const icon = TopicFeatureFactory.createIcon(this, f, this.isReadOnly());
result.addIcon(icon, f.getType() === TopicFeature.Icon.id && !this.isReadOnly()); result.addIcon(icon, f.getType() === TopicFeatureFactory.Icon.id && !this.isReadOnly());
}); });
return result; return result;
@ -331,10 +331,10 @@ class Topic extends NodeGraph {
const model = this.getModel(); const model = this.getModel();
model.addFeature(featureModel); model.addFeature(featureModel);
const result = TopicFeature.createIcon(this, featureModel, this.isReadOnly()); const result = TopicFeatureFactory.createIcon(this, featureModel, this.isReadOnly());
iconGroup.addIcon( iconGroup.addIcon(
result, result,
featureModel.getType() === TopicFeature.Icon.id && !this.isReadOnly(), featureModel.getType() === TopicFeatureFactory.Icon.id && !this.isReadOnly(),
); );
this._adjustShapes(); this._adjustShapes();
@ -764,7 +764,7 @@ class Topic extends NodeGraph {
const model = this.getModel(); const model = this.getModel();
const editorModel = { const editorModel = {
getValue() { getValue() {
const notes = model.findFeatureByType(TopicFeature.Note.id); const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
let result; let result;
if (notes.length > 0) result = notes[0].getText(); if (notes.length > 0) result = notes[0].getText();
@ -773,7 +773,7 @@ class Topic extends NodeGraph {
setValue(value) { setValue(value) {
const dispatcher = ActionDispatcher.getInstance(); const dispatcher = ActionDispatcher.getInstance();
const notes = model.findFeatureByType(TopicFeature.Note.id); const notes = model.findFeatureByType(TopicFeatureFactory.Note.id);
if (!$defined(value)) { if (!$defined(value)) {
const featureId = notes[0].getId(); const featureId = notes[0].getId();
dispatcher.removeFeatureFromTopic(topicId, featureId); dispatcher.removeFeatureFromTopic(topicId, featureId);
@ -782,7 +782,7 @@ class Topic extends NodeGraph {
text: value, text: value,
}); });
} else { } else {
dispatcher.addFeatureToTopic(topicId, TopicFeature.Note.id, { dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Note.id, {
text: value, text: value,
}); });
} }
@ -800,7 +800,7 @@ class Topic extends NodeGraph {
const editorModel = { const editorModel = {
getValue() { getValue() {
// @param {mindplot.model.LinkModel[]} links // @param {mindplot.model.LinkModel[]} links
const links = model.findFeatureByType(TopicFeature.Link.id); const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
let result; let result;
if (links.length > 0) result = links[0].getUrl(); if (links.length > 0) result = links[0].getUrl();
@ -809,7 +809,7 @@ class Topic extends NodeGraph {
setValue(value) { setValue(value) {
const dispatcher = ActionDispatcher.getInstance(); const dispatcher = ActionDispatcher.getInstance();
const links = model.findFeatureByType(TopicFeature.Link.id); const links = model.findFeatureByType(TopicFeatureFactory.Link.id);
if (!$defined(value)) { if (!$defined(value)) {
const featureId = links[0].getId(); const featureId = links[0].getId();
dispatcher.removeFeatureFromTopic(topicId, featureId); dispatcher.removeFeatureFromTopic(topicId, featureId);
@ -818,7 +818,7 @@ class Topic extends NodeGraph {
url: value, url: value,
}); });
} else { } else {
dispatcher.addFeatureToTopic(topicId, TopicFeature.Link.id, { dispatcher.addFeatureToTopic(topicId, TopicFeatureFactory.Link.id, {
url: value, url: value,
}); });
} }

View File

@ -24,53 +24,25 @@ import LinkIcon from './LinkIcon';
import NoteModel from './model/NoteModel'; import NoteModel from './model/NoteModel';
import NoteIcon from './NoteIcon'; import NoteIcon from './NoteIcon';
const TopicFeature = { const TopicFeatureFactory = {
/** the icon object */ /** the icon object */
Icon: { Icon: {
id: IconModel.FEATURE_TYPE, id: IconModel.FEATURE_TYPE,
model: IconModel,
icon: ImageIcon, icon: ImageIcon,
}, },
/** the link object */ /** the link object */
Link: { Link: {
id: LinkModel.FEATURE_TYPE, id: LinkModel.FEATURE_TYPE,
model: LinkModel,
icon: LinkIcon, icon: LinkIcon,
}, },
/** the note object */ /** the note object */
Note: { Note: {
id: NoteModel.FEATURE_TYPE, id: NoteModel.FEATURE_TYPE,
model: NoteModel,
icon: NoteIcon, icon: NoteIcon,
}, },
/**
* @param id the feature metadata id
* @return {Boolean} returns true if the given id is contained in the metadata array
*/
isSupported(id) {
return TopicFeature._featuresMetadataById.some((elem) => elem.id === id);
},
/**
* @param type
* @param attributes
* @throws will throw an error if type is null or undefined
* @throws will throw an error if attributes is null or undefined
* @return {mindplot.model.FeatureModel} a new instance of the feature model subclass matching
* the topic feature
*/
createModel(type, attributes) {
$assert(type, 'type can not be null');
$assert(attributes, 'attributes can not be null');
const { model: Model } = TopicFeature._featuresMetadataById
.filter((elem) => elem.id === type)[0];
return new Model(attributes);
},
/** /**
* @param {mindplot.Topic} topic * @param {mindplot.Topic} topic
* @param {mindplot.model.FeatureModel} model * @param {mindplot.model.FeatureModel} model
@ -83,12 +55,12 @@ const TopicFeature = {
$assert(topic, 'topic can not be null'); $assert(topic, 'topic can not be null');
$assert(model, 'model can not be null'); $assert(model, 'model can not be null');
const { icon: Icon } = TopicFeature._featuresMetadataById const { icon: Icon } = TopicFeatureFactory._featuresMetadataById
.filter((elem) => elem.id === model.getType())[0]; .filter((elem) => elem.id === model.getType())[0];
return new Icon(topic, model, readOnly); return new Icon(topic, model, readOnly);
}, },
}; };
TopicFeature._featuresMetadataById = [TopicFeature.Icon, TopicFeature.Link, TopicFeature.Note]; TopicFeatureFactory._featuresMetadataById = [TopicFeatureFactory.Icon, TopicFeatureFactory.Link, TopicFeatureFactory.Note];
export default TopicFeature; export default TopicFeatureFactory;

View File

@ -4,10 +4,7 @@ import Mindmap from "src/components/model/Mindmap";
class TextExporter implements Exporter { class TextExporter implements Exporter {
export(mindplot: Mindmap): string { export(mindplot: Mindmap): string {
return "some value";
throw new Error("Method not implemented.");
} }
} }
export default TextExporter; export default TextExporter;

View File

@ -0,0 +1,42 @@
import { $assert } from '@wisemapping/core-js';
import IconModel from './IconModel';
import LinkModel from './LinkModel';
import NoteModel from './NoteModel';
const FeatureModelFactory = {
Icon: {
id: IconModel.FEATURE_TYPE,
model: IconModel,
},
Link: {
id: LinkModel.FEATURE_TYPE,
model: LinkModel,
},
/** the note object */
Note: {
id: NoteModel.FEATURE_TYPE,
model: NoteModel,
},
createModel(type, attributes) {
$assert(type, 'type can not be null');
$assert(attributes, 'attributes can not be null');
const { model: Model } = FeatureModelFactory._featuresMetadataById
.filter((elem) => elem.id === type)[0];
return new Model(attributes);
},
/**
* @param id the feature metadata id
* @return {Boolean} returns true if the given id is contained in the metadata array
*/
isSupported(id) {
return FeatureModelFactory._featuresMetadataById.some((elem) => elem.id === id);
},
};
FeatureModelFactory._featuresMetadataById = [FeatureModelFactory.Icon, FeatureModelFactory.Link, FeatureModelFactory.Note];
export default FeatureModelFactory;

View File

@ -18,7 +18,7 @@
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';
import INodeModel from './INodeModel'; import INodeModel from './INodeModel';
import TopicFeature from '../TopicFeature'; import FeatureModelFactory from './FeatureModelFactory';
class NodeModel extends INodeModel { class NodeModel extends INodeModel {
constructor(type, mindmap, id) { constructor(type, mindmap, id) {
@ -40,7 +40,7 @@ class NodeModel extends INodeModel {
* @return {mindplot.model.FeatureModel} the created feature model * @return {mindplot.model.FeatureModel} the created feature model
*/ */
createFeature(type, attributes) { createFeature(type, attributes) {
return TopicFeature.createModel(type, attributes); return FeatureModelFactory.createModel(type, attributes);
} }
/** /**

View File

@ -20,7 +20,7 @@ import {
import ModelCodeName from './ModelCodeName'; import ModelCodeName from './ModelCodeName';
import Mindmap from '../model/Mindmap'; import Mindmap from '../model/Mindmap';
import INodeModel from '../model/INodeModel'; import INodeModel from '../model/INodeModel';
import TopicFeature from '../TopicFeature'; import FeatureModelFactory from '../model/FeatureModelFactory';
class XMLSerializerBeta { class XMLSerializerBeta {
toXML(mindmap) { toXML(mindmap) {
@ -306,16 +306,16 @@ class XMLSerializerBeta {
_deserializeIcon(domElem) { _deserializeIcon(domElem) {
let icon = domElem.getAttribute('id'); let icon = domElem.getAttribute('id');
icon = icon.replace('images/', 'icons/legacy/'); icon = icon.replace('images/', 'icons/legacy/');
return TopicFeature.createModel(TopicFeature.Icon.id, { id: icon }); return FeatureModelFactory.createModel(FeatureModelFactory.Icon.id, { id: icon });
} }
_deserializeLink(domElem) { _deserializeLink(domElem) {
return TopicFeature.createModel(TopicFeature.Link.id, { url: domElem.getAttribute('url') }); return FeatureModelFactory.createModel(FeatureModelFactory.Link.id, { url: domElem.getAttribute('url') });
} }
_deserializeNote(domElem) { _deserializeNote(domElem) {
const text = domElem.getAttribute('text'); const text = domElem.getAttribute('text');
return TopicFeature.createModel(TopicFeature.Note.id, { text: text == null ? ' ' : text }); return FeatureModelFactory.createModel(FeatureModelFactory.Note.id, { text: text == null ? ' ' : text });
} }
} }

View File

@ -19,8 +19,8 @@ import { $assert, $defined, createDocument } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d'; import { Point } from '@wisemapping/web2d';
import Mindmap from '../model/Mindmap'; import Mindmap from '../model/Mindmap';
import INodeModel, { TopicShape } from '../model/INodeModel'; import INodeModel, { TopicShape } from '../model/INodeModel';
import TopicFeature from '../TopicFeature';
import ConnectionLine from '../ConnectionLine'; import ConnectionLine from '../ConnectionLine';
import FeatureModelFactory from '../model/FeatureModelFactory';
class XMLSerializerPela { class XMLSerializerPela {
toXML(mindmap) { toXML(mindmap) {
@ -371,7 +371,7 @@ class XMLSerializerPela {
if (child.tagName === 'topic') { if (child.tagName === 'topic') {
const childTopic = this._deserializeNode(child, mindmap); const childTopic = this._deserializeNode(child, mindmap);
childTopic.connectTo(topic); childTopic.connectTo(topic);
} else if (TopicFeature.isSupported(child.tagName)) { } else if (FeatureModelFactory.isSupported(child.tagName)) {
// Load attributes ... // Load attributes ...
const namedNodeMap = child.attributes; const namedNodeMap = child.attributes;
const attributes = {}; const attributes = {};
@ -388,7 +388,7 @@ class XMLSerializerPela {
// Create a new element .... // Create a new element ....
const featureType = child.tagName; const featureType = child.tagName;
const feature = TopicFeature.createModel(featureType, attributes); const feature = FeatureModelFactory.createModel(featureType, attributes);
topic.addFeature(feature); topic.addFeature(feature);
} else if (child.tagName === 'text') { } else if (child.tagName === 'text') {
const nodeText = XMLSerializerPela._deserializeNodeText(child); const nodeText = XMLSerializerPela._deserializeNodeText(child);

View File

@ -22,6 +22,7 @@ import Mindmap from './components/model/Mindmap';
import PersistenceManager from './components/PersistenceManager'; import PersistenceManager from './components/PersistenceManager';
import Designer from './components/Designer'; import Designer from './components/Designer';
import LocalStorageManager from './components/LocalStorageManager'; import LocalStorageManager from './components/LocalStorageManager';
import TxtExporter from './components/export/TxtExporter';
import Menu from './components/widget/Menu'; import Menu from './components/widget/Menu';
@ -36,4 +37,5 @@ export {
LocalStorageManager, LocalStorageManager,
Menu, Menu,
DesignerBuilder, DesignerBuilder,
TxtExporter,
}; };

View File

@ -1,5 +1,9 @@
import TxtExporter from '../../src/components/export/TxtExporter'; import TxtExporter from '../../src/components/export/TxtExporter';
import Mindmap from '../../src/components/model/Mindmap';
test('adds 1 + 2 to equal 3', () => { test('adds 1 + 2 to equal 3', () => {
const m = new Mindmap();
const exporter = new TxtExporter();
console.log(exporter.export(m));
}); });