Merged in feature/model_to_typescript (pull request #22)

Feature/model to typescript

Approved-by: Matias Arriola
This commit is contained in:
Paulo Veiga 2022-01-03 14:13:38 +00:00 committed by Matias Arriola
commit b1809816b0
35 changed files with 908 additions and 972 deletions

View File

@ -59,7 +59,7 @@ class CommandContext {
/** */
createModel() {
const mindmap = this._designer.getMindmap();
return mindmap.createNode(NodeModel.MAIN_TOPIC_TYPE);
return mindmap.createNode('MainTopic');
}
/** */

View File

@ -34,7 +34,7 @@ class ConnectionLine {
let line;
const ctrlPoints = this._getCtrlPoints(sourceNode, targetNode);
if (targetNode.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (targetNode.getType() === 'CentralTopic') {
line = this._createLine(lineType, ConnectionLine.CURVED);
line.setSrcControlPoint(ctrlPoints[0]);
line.setDestControlPoint(ctrlPoints[1]);

View File

@ -243,7 +243,7 @@ class Designer extends Events {
});
// Register node listeners ...
if (topic.getType() !== INodeModel.CENTRAL_TOPIC_TYPE) {
if (topic.getType() !== 'CentralTopic') {
// Central Topic doesn't support to be dragged
this._dragManager.add(topic);
}
@ -443,7 +443,7 @@ class Designer extends Events {
}
// Execute event ...
const topic = nodes[0];
if (topic.getType() !== INodeModel.CENTRAL_TOPIC_TYPE) {
if (topic.getType() !== 'CentralTopic') {
this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken());
}
}
@ -476,7 +476,7 @@ class Designer extends Events {
*/
_copyNodeProps(sourceModel, targetModel) {
// I don't copy the font size if the target is the source is the central topic.
if (sourceModel.getType() !== INodeModel.CENTRAL_TOPIC_TYPE) {
if (sourceModel.getType() !== 'CentralTopic') {
const fontSize = sourceModel.getFontSize();
if (fontSize) {
targetModel.setFontSize(fontSize);
@ -586,7 +586,7 @@ class Designer extends Events {
// Hack: if parent is central topic, add node below not on opposite side.
// This should be done in the layout
if (parentTopic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (parentTopic.getType() === 'CentralTopic') {
siblingModel.setOrder(topic.getOrder() + 2);
}
@ -954,7 +954,7 @@ class Designer extends Events {
/** */
changeTopicShape(shape) {
const validateFunc = (topic) => !(
topic.getType() === INodeModel.CENTRAL_TOPIC_TYPE && shape === TopicShape.LINE
topic.getType() === 'CentralTopic' && shape === TopicShape.LINE
);
const validateError = 'Central Topic shape can not be changed to line figure.';

View File

@ -145,7 +145,7 @@ class DragPivot {
let result = null;
const parentTopic = this._targetTopic;
if (parentTopic) {
if (parentTopic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (parentTopic.getType() === 'CentralTopic') {
result = this._straightLine;
} else {
result = this._curvedLine;

View File

@ -25,15 +25,12 @@ import {
} from '@wisemapping/web2d';
import IconGroupRemoveTip from './IconGroupRemoveTip';
import NoteModel from './model/NoteModel';
import LinkModel from './model/LinkModel';
import IconModel from './model/IconModel';
import Icon from './Icon';
const ORDER_BY_TYPE = new Map();
ORDER_BY_TYPE.set(IconModel.FEATURE_TYPE, 0);
ORDER_BY_TYPE.set(NoteModel.FEATURE_TYPE, 1);
ORDER_BY_TYPE.set(LinkModel.FEATURE_TYPE, 2);
ORDER_BY_TYPE.set('icon', 0);
ORDER_BY_TYPE.set('note', 1);
ORDER_BY_TYPE.set('link', 2);
class IconGroup {
constructor(topicId, iconSize) {

View File

@ -22,9 +22,9 @@ export const create = (nodeModel, options) => {
$assert(type, 'Node model type can not be null');
let result;
if (type === INodeModel.CENTRAL_TOPIC_TYPE) {
if (type === 'CentralTopic') {
result = new CentralTopic(nodeModel, options);
} else if (type === INodeModel.MAIN_TOPIC_TYPE) {
} else if (type === 'MainTopic') {
result = new MainTopic(nodeModel, options);
} else {
$assert(false, `unsupported node type:${type}`);

View File

@ -86,7 +86,7 @@ class Relationship extends ConnectionLine {
const targetTopic = this._targetTopic;
let targetPosition = targetTopic.getPosition();
if (targetTopic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (targetTopic.getType() === 'CentralTopic') {
targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition);
}

View File

@ -131,7 +131,7 @@ class RelationshipPivot {
_calculateFromPosition(toPosition) {
// Calculate origin position ...
let sourcePosition = this._sourceTopic.getPosition();
if (this._sourceTopic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (this._sourceTopic.getType() === 'CentralTopic') {
sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
}
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);

View File

@ -1337,7 +1337,7 @@ class Topic extends NodeGraph {
/** @return {Boolean} true if the topic is the central topic of the map */
isCentralTopic() {
return this.getModel().getType() === INodeModel.CENTRAL_TOPIC_TYPE;
return this.getModel().getType() === 'CentralTopic';
}
}

View File

@ -17,29 +17,26 @@
*/
import { $assert } from '@wisemapping/core-js';
import IconModel from './model/IconModel';
import ImageIcon from './ImageIcon';
import LinkModel from './model/LinkModel';
import LinkIcon from './LinkIcon';
import NoteModel from './model/NoteModel';
import NoteIcon from './NoteIcon';
const TopicFeatureFactory = {
/** the icon object */
Icon: {
id: IconModel.FEATURE_TYPE,
id: 'icon',
icon: ImageIcon,
},
/** the link object */
Link: {
id: LinkModel.FEATURE_TYPE,
id: 'link',
icon: LinkIcon,
},
/** the note object */
Note: {
id: NoteModel.FEATURE_TYPE,
id: 'note',
icon: NoteIcon,
},

View File

@ -16,6 +16,8 @@
* limitations under the License.
*/
import { Mindmap } from "../..";
import INodeModel from "../model/INodeModel";
import LinkModel from "../model/LinkModel";
import NodeModel from "../model/NodeModel";
import Exporter from "./Exporter";
@ -37,17 +39,20 @@ class TxtExporter implements Exporter {
return Promise.resolve(retult);
}
private traverseBranch(prefix: string, branches: Array<NodeModel>) {
private traverseBranch(prefix: string, branches: Array<INodeModel>) {
let result = '';
branches.forEach((node, index) => {
result = result + `${prefix}${index+1} ${node.getText()}`;
node.getFeatures().forEach((f)=>{
const type = f.getType();
if(type === 'link'){
result = result + ` [link: ${(f as LinkModel).getUrl()}]`
}
});
result = result + '\n';
if (node.getChildren().length > 0) {
result = result + this.traverseBranch(`${prefix}${index+1}.`, node.getChildren());
result = result + this.traverseBranch(`\t${prefix}${index+1}.`, node.getChildren());
}
});
return result;

View File

@ -15,16 +15,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import { $assert } from '@wisemapping/core-js';
export type FeatureType = 'note' | 'link' | 'icon';
class FeatureModel {
static _next_id = 0;
private _id: number;
private _type: FeatureType;
private _attributes: {};
/**
* @constructs
* @param type
* @throws will throw an exception if type is null or undefined
* assigns a unique id and the given type to the new model
*/
constructor(type) {
constructor(type: FeatureType) {
$assert(type, 'type can not be null');
this._id = FeatureModel._nextUUID();
@ -77,19 +84,15 @@ class FeatureModel {
this._id = id;
}
/** */
getType() {
getType(): FeatureType {
return this._type;
}
}
FeatureModel._nextUUID = function _nextUUID() {
if (!$defined(FeatureModel._uuid)) {
FeatureModel._uuid = 0;
static _nextUUID(): number {
const result = FeatureModel._next_id + 1;
FeatureModel._next_id = result;
return result;
}
}
FeatureModel._uuid += 1;
return FeatureModel._uuid;
};
export default FeatureModel;

View File

@ -2,20 +2,25 @@ import { $assert } from '@wisemapping/core-js';
import IconModel from './IconModel';
import LinkModel from './LinkModel';
import NoteModel from './NoteModel';
import FeatureModel from './FeatureModel';
import FeatureModel, { FeatureType } from './FeatureModel';
interface NodeById {
id: FeatureType,
model: typeof FeatureModel;
}
class FeatureModelFactory {
private static modelById = [{
id: IconModel.FEATURE_TYPE,
static modelById: Array<NodeById> = [{
id: 'icon',
model: IconModel,
}, {
id: LinkModel.FEATURE_TYPE,
id: 'link',
model: LinkModel,
}, {
id: NoteModel.FEATURE_TYPE,
id: 'note',
model: NoteModel,
}] as const;
}];
static createModel(type: string, attributes): FeatureModel {
$assert(type, 'type can not be null');

View File

@ -18,35 +18,36 @@
* limitations under the License.
*/
import { $assert } from '@wisemapping/core-js';
import INodeModel, { NodeModelType as NodeType } from './INodeModel';
import NodeModel from './NodeModel';
import RelationshipModel from './RelationshipModel';
abstract class IMindmap {
getCentralTopic(): NodeModel {
getCentralTopic(): INodeModel {
return this.getBranches()[0];
}
abstract getDescription(): string;
abstract setDescription(value: string);
abstract setDescription(value: string): void;
abstract getId(): string
abstract setId(id: string);
abstract setId(id: string): void;
abstract getVersion(): string;
abstract setVersion(version: string): void;
abstract addBranch(nodeModel: NodeModel): void;
abstract addBranch(nodeModel: INodeModel): void;
abstract getBranches(): Array<NodeModel>;
abstract getBranches(): Array<INodeModel>;
abstract removeBranch(node: NodeModel): void;
abstract removeBranch(node: INodeModel): void;
abstract getRelationships(): Array<RelationshipModel>;
connect(parent: NodeModel, child: NodeModel): void {
connect(parent: INodeModel, child: INodeModel): void {
// Child already has a parent ?
$assert(!child.getParent(), 'Child model seems to be already connected');
@ -62,7 +63,7 @@ abstract class IMindmap {
* @throws will throw an error if child is null or undefined
* @throws will throw an error if child's parent cannot be found
*/
disconnect(child: NodeModel): void {
disconnect(child: INodeModel): void {
const parent = child.getParent();
$assert(child, 'Child can not be null.');
$assert(parent, 'Child model seems to be already connected');
@ -71,23 +72,15 @@ abstract class IMindmap {
this.addBranch(child);
}
/** @abstract */
hasAlreadyAdded(node) {
throw new Error('Unsupported operation');
}
abstract hasAlreadyAdded(node: INodeModel): boolean;
/** @abstract */
createNode(type, id) {
throw new Error('Unsupported operation');
}
abstract createNode(type: NodeType, id: number):void;
abstract createRelationship(fromNode: NodeModel, toNode: NodeModel): void;
abstract addRelationship(rel: RelationshipModel): void;
deleteRelationship(relationship: RelationshipModel): void {
throw new Error('Unsupported operation');
}
abstract deleteRelationship(relationship: RelationshipModel): void;
/** */
inspect() {

View File

@ -17,47 +17,53 @@
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import FeatureModel from './FeatureModel';
import Mindmap from './Mindmap';
// regex taken from https://stackoverflow.com/a/34763398/58128
const parseJsObject = (str) => JSON.parse(str.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '));
const parseJsObject = (str: string) => JSON.parse(str.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '));
class INodeModel {
constructor(mindmap) {
abstract class INodeModel {
static MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE: number = 220;
static _next_uuid: number = 0;
protected _mindmap: Mindmap;
constructor(mindmap: Mindmap) {
$assert(mindmap && mindmap.getBranches, 'mindmap can not be null');
this._mindmap = mindmap;
}
/** */
getId() {
getId(): number {
return this.getProperty('id');
}
abstract getFeatures(): Array<FeatureModel>;
/** */
setId(id) {
setId(id: number): void {
if (!$defined(id)) {
const newId = INodeModel._nextUUID();
this.putProperty('id', newId);
} else {
if (id > INodeModel._uuid) {
if (id > INodeModel._next_uuid) {
$assert(Number.isFinite(id));
INodeModel._uuid = id;
INodeModel._next_uuid = id;
}
this.putProperty('id', id);
}
}
/** */
getType() {
getType(): NodeModelType {
return this.getProperty('type');
}
/** */
setType(type) {
setType(type: NodeModelType): void {
this.putProperty('type', type);
}
/** */
setText(text) {
setText(text: string): void {
this.putProperty('text', text);
}
@ -315,39 +321,55 @@ class INodeModel {
// console.log("After:" + mindmap.inspect());
}
/** @abstract */
getPropertiesKeys() {
throw new Error('Unsupported operation');
abstract getPropertiesKeys(): string[];
abstract getProperty(key: string);
abstract putProperty(key: string, value: any): void;
abstract setParent(parent: INodeModel): void;
abstract getChildren(): INodeModel[];
abstract getParent(): INodeModel;
abstract clone(): INodeModel;
isChildNode(node: INodeModel): boolean {
let result = false;
if (node === this) {
result = true;
} else {
const children = this.getChildren();
for (let i = 0; i < children.length; i++) {
const child = children[i];
result = child.isChildNode(node);
if (result) {
break;
}
}
}
return result;
}
/** @abstract */
// eslint-disable-next-line no-unused-vars
putProperty(key, value) {
throw new Error('Unsupported operation');
findNodeById(id: number): INodeModel {
$assert(Number.isFinite(id));
let result = null;
if (this.getId() === id) {
result = this;
} else {
const children = this.getChildren();
for (let i = 0; i < children.length; i++) {
const child = children[i];
result = child.findNodeById(id);
if (result) {
break;
}
}
}
return result;
}
/** @abstract */
// eslint-disable-next-line no-unused-vars
setParent(parent) {
throw new Error('Unsupported operation');
}
/** @abstract */
getChildren() {
throw new Error('Unsupported operation');
}
/** @abstract */
getParent() {
throw new Error('Unsupported operation');
}
/** @abstract */
clone() {
throw new Error('Unsupported operation');
}
/** */
inspect() {
let result = `{ type: ${this.getType()} , id: ${this.getId()} , text: ${this.getText()}`;
@ -369,16 +391,14 @@ class INodeModel {
return result;
}
/** @abstract */
// eslint-disable-next-line no-unused-vars
removeChild(child) {
throw new Error('Unsupported operation');
}
abstract removeChild(child: INodeModel);
static _nextUUID(): number {
INodeModel._next_uuid += 1;
return INodeModel._next_uuid;
};
}
/**
* @enum {String}
*/
const TopicShape = {
RECTANGLE: 'rectagle',
ROUNDED_RECT: 'rounded rectagle',
@ -387,38 +407,10 @@ const TopicShape = {
IMAGE: 'image',
};
/**
* @constant
* @type {String}
* @default
*/
INodeModel.CENTRAL_TOPIC_TYPE = 'CentralTopic';
/**
* @constant
* @type {String}
* @default
*/
INodeModel.MAIN_TOPIC_TYPE = 'MainTopic';
/**
* @constant
* @type {Number}
* @default
*/
INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
export type NodeModelType = 'CentralTopic' | 'MainTopic';
/**
* @todo: This method must be implemented. (unascribed)
*/
INodeModel._nextUUID = () => {
if (!$defined(INodeModel._uuid)) {
INodeModel._uuid = 0;
}
INodeModel._uuid += 1;
return INodeModel._uuid;
};
INodeModel._uuid = 0;
export { TopicShape };
export default INodeModel;

View File

@ -20,27 +20,17 @@ import FeatureModel from './FeatureModel';
class IconModel extends FeatureModel {
constructor(attributes) {
super(IconModel.FEATURE_TYPE);
super('icon');
this.setIconType(attributes.id);
}
/** @return the icon type id */
getIconType() {
getIconType(): string {
return this.getAttribute('id');
}
/** @param {String} iconType the icon type id */
setIconType(iconType) {
setIconType(iconType: string) {
$assert(iconType, 'iconType id can not be null');
this.setAttribute('id', iconType);
}
}
/**
* @constant
* @type {String}
* @default
*/
IconModel.FEATURE_TYPE = 'icon';
export default IconModel;

View File

@ -20,12 +20,12 @@ import FeatureModel from './FeatureModel';
class LinkModel extends FeatureModel {
constructor(attributes) {
super(LinkModel.FEATURE_TYPE);
super('link');
this.setUrl(attributes.url);
}
/** @return {String} the url attribute value */
getUrl() {
getUrl():string {
return this.getAttribute('url');
}
@ -33,7 +33,7 @@ class LinkModel extends FeatureModel {
* @param {String} url a URL provided by the user to set the link to
* @throws will throw an error if url is null or undefined
*/
setUrl(url) {
setUrl(url: string): void {
$assert(url, 'url can not be null');
const fixedUrl = LinkModel._fixUrl(url);
@ -44,7 +44,7 @@ class LinkModel extends FeatureModel {
}
// url format is already checked in LinkEditor.checkUrl
static _fixUrl(url) {
static _fixUrl(url: string): string {
let result = url;
if (!result.includes('http://') && !result.includes('https://') && !result.includes('mailto://')) {
result = `http://${result}`;
@ -61,12 +61,4 @@ class LinkModel extends FeatureModel {
this.setAttribute('urlType', urlType);
}
}
/**
* @constant
* @type {String}
* @default
*/
LinkModel.FEATURE_TYPE = 'link';
export default LinkModel;

View File

@ -17,17 +17,17 @@
*/
import { $assert, $defined } from '@wisemapping/core-js';
import IMindmap from './IMindmap';
import INodeModel from './INodeModel';
import INodeModel, { NodeModelType } from './INodeModel';
import NodeModel from './NodeModel';
import RelationshipModel from './RelationshipModel';
import ModelCodeName from '../persistence/ModelCodeName';
class Mindmap extends IMindmap {
_description: string;
_version: string;
_id: string;
_branches: Array<NodeModel>;
_relationships: Array<RelationshipModel>;
private _description: string;
private _version: string;
private _id: string;
private _branches: Array<NodeModel>;
private _relationships: Array<RelationshipModel>;
constructor(id: string, version: string = ModelCodeName.TANGO) {
super();
@ -79,10 +79,10 @@ class Mindmap extends IMindmap {
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
const branches = this.getBranches();
if (branches.length === 0) {
$assert(nodeModel.getType() === INodeModel.CENTRAL_TOPIC_TYPE, 'First element must be the central topic');
$assert(nodeModel.getType() === 'CentralTopic', 'First element must be the central topic');
nodeModel.setPosition(0, 0);
} else {
$assert(nodeModel.getType() !== INodeModel.CENTRAL_TOPIC_TYPE, 'Mindmaps only have one cental topic');
$assert(nodeModel.getType() !== 'CentralTopic', 'Mindmaps only have one cental topic');
}
this._branches.push(nodeModel);
@ -91,7 +91,7 @@ class Mindmap extends IMindmap {
/**
* @param nodeModel
*/
removeBranch(nodeModel: NodeModel): void {
removeBranch(nodeModel: INodeModel): void {
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
this._branches = this._branches.filter((b) => b !== nodeModel);
}
@ -104,29 +104,22 @@ class Mindmap extends IMindmap {
return this._relationships;
}
/**
* @param node
* @return {Boolean} true if node already exists
*/
hasAlreadyAdded(node: any) {
hasAlreadyAdded(node: NodeModel): boolean {
let result = false;
// Check in not connected nodes.
const branches = this._branches;
for (let i = 0; i < branches.length; i++) {
result = branches[i]._isChildNode(node);
result = branches[i].isChildNode(node);
if (result) {
break;
}
}
return result;
}
/**
* @param type
* @param id
* @return the node model created
*/
createNode(type = INodeModel.MAIN_TOPIC_TYPE, id: number) {
createNode(type: NodeModelType = 'MainTopic', id: number) {
return new NodeModel(type, this, id);
}
@ -172,7 +165,7 @@ class Mindmap extends IMindmap {
static buildEmpty = (mapId: string) => {
const result = new Mindmap(mapId);
const node = result.createNode(INodeModel.CENTRAL_TOPIC_TYPE, 0);
const node = result.createNode('CentralTopic', 0);
result.addBranch(node);
return result;
};

View File

@ -17,21 +17,28 @@
*/
import { $assert, $defined } from '@wisemapping/core-js';
import cloneDeep from 'lodash/cloneDeep';
import INodeModel from './INodeModel';
import INodeModel, { NodeModelType } from './INodeModel';
import FeatureModelFactory from './FeatureModelFactory';
import FeatureModel from './FeatureModel';
import Mindmap from './Mindmap';
class NodeModel extends INodeModel {
constructor(type, mindmap, id) {
private _properties: {};
private _children: INodeModel[];
private _features: FeatureModel[];
private _parent: INodeModel;
constructor(type: NodeModelType, mindmap: Mindmap, id: number) {
$assert(type, 'Node type can not be null');
$assert(mindmap, 'mindmap can not be null');
super(mindmap);
this._properties = {};
this.setId(id);
this.setType(type);
this.areChildrenShrunken(false);
this.areChildrenShrunken();
this._children = [];
this._feature = [];
this._features = [];
}
/**
@ -49,12 +56,12 @@ class NodeModel extends INodeModel {
*/
addFeature(feature) {
$assert(feature, 'feature can not be null');
this._feature.push(feature);
this._features.push(feature);
}
/** */
getFeatures() {
return this._feature;
return this._features;
}
/**
@ -64,9 +71,9 @@ class NodeModel extends INodeModel {
*/
removeFeature(feature) {
$assert(feature, 'feature can not be null');
const size = this._feature.length;
this._feature = this._feature.filter((f) => feature.getId() !== f.getId());
$assert(size - 1 === this._feature.length, 'Could not be removed ...');
const size = this._features.length;
this._features = this._features.filter((f) => feature.getId() !== f.getId());
$assert(size - 1 === this._features.length, 'Could not be removed ...');
}
/**
@ -75,7 +82,7 @@ class NodeModel extends INodeModel {
*/
findFeatureByType(type) {
$assert(type, 'type can not be null');
return this._feature.filter((feature) => feature.getType() === type);
return this._features.filter((feature) => feature.getType() === type);
}
/**
@ -86,7 +93,7 @@ class NodeModel extends INodeModel {
*/
findFeatureById(id) {
$assert($defined(id), 'id can not be null');
const result = this._feature.filter((feature) => feature.getId() === id);
const result = this._features.filter((feature) => feature.getId() === id);
$assert(result.length === 1, `Feature could not be found:${id}`);
return result[0];
}
@ -112,7 +119,7 @@ class NodeModel extends INodeModel {
}
/** */
getProperty(key) {
getProperty(key: string) {
$defined(key, 'key can not be null');
const result = this._properties[key];
return !$defined(result) ? null : result;
@ -122,15 +129,15 @@ class NodeModel extends INodeModel {
* @return {mindplot.model.NodeModel} an identical clone of the NodeModel
*/
clone() {
const result = new NodeModel(this.getType(), this._mindmap);
const result = new NodeModel(this.getType(), this._mindmap, -1);
result._children = this._children.map((node) => {
const cnode = node.clone();
const cnode = node.clone() as NodeModel;
cnode._parent = result;
return cnode;
});
result._properties = cloneDeep(this._properties);
result._feature = cloneDeep(this._feature);
result._features = cloneDeep(this._features);
return result;
}
@ -138,19 +145,19 @@ class NodeModel extends INodeModel {
* Similar to clone, assign new id to the elements ...
* @return {mindplot.model.NodeModel}
*/
deepCopy() {
const result = new NodeModel(this.getType(), this._mindmap);
deepCopy(): NodeModel {
const result = new NodeModel(this.getType(), this._mindmap, -1);
result._children = this._children.map((node) => {
const cnode = node.deepCopy();
const cnode = (node as NodeModel).deepCopy();
cnode._parent = result;
return cnode;
});
const id = result.getId();
result._properties = Object.clone(this._properties);
result._properties = Object.assign({}, this._properties);
result.setId(id);
result._feature = this._feature.clone();
result._features = cloneDeep(this._features);
return result;
}
@ -158,7 +165,7 @@ class NodeModel extends INodeModel {
* @param {mindplot.model.NodeModel} child
* @throws will throw an error if child is null, undefined or not a NodeModel object
*/
append(child) {
append(child: NodeModel) {
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object');
this._children.push(child);
// eslint-disable-next-line no-param-reassign
@ -169,7 +176,7 @@ class NodeModel extends INodeModel {
* @param {mindplot.model.NodeModel} child
* @throws will throw an error if child is null, undefined or not a NodeModel object
*/
removeChild(child) {
removeChild(child): void {
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.');
this._children = this._children.filter((c) => c !== child);
// eslint-disable-next-line no-param-reassign
@ -192,44 +199,6 @@ class NodeModel extends INodeModel {
this._parent = parent;
}
_isChildNode(node) {
let result = false;
if (node === this) {
result = true;
} else {
const children = this.getChildren();
for (let i = 0; i < children.length; i++) {
const child = children[i];
result = child._isChildNode(node);
if (result) {
break;
}
}
}
return result;
}
/**
* @id
* @return {mindplot.model.NodeModel} the node with the respective id
*/
findNodeById(id) {
$assert(Number.isFinite(id));
let result = null;
if (this.getId() === id) {
result = this;
} else {
const children = this.getChildren();
for (let i = 0; i < children.length; i++) {
const child = children[i];
result = child.findNodeById(id);
if (result) {
break;
}
}
}
return result;
}
}
export default NodeModel;

View File

@ -20,7 +20,7 @@ import FeatureModel from './FeatureModel';
class NoteModel extends FeatureModel {
constructor(attributes) {
super(NoteModel.FEATURE_TYPE);
super('note');
const noteText = attributes.text ? attributes.text : ' ';
this.setText(noteText);
}
@ -37,11 +37,4 @@ class NoteModel extends FeatureModel {
}
}
/**
* @constant
* @type {String}
* @default
*/
NoteModel.FEATURE_TYPE = 'note';
export default NoteModel;

View File

@ -16,10 +16,21 @@
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import ConnectionLine from '../ConnectionLine';
class RelationshipModel {
constructor(sourceTopicId, targetTopicId) {
static _next_uuid: number = 0;
private _id: number;
private _sourceTargetId: number;
private _targetTopicId: number;
private _lineType: number;
private _srcCtrlPoint: Point;
private _destCtrlPoint: Point;
private _endArrow: boolean;
private _startArrow: boolean;
constructor(sourceTopicId: number, targetTopicId: number) {
$assert($defined(sourceTopicId), 'from node type can not be null');
$assert($defined(targetTopicId), 'to node type can not be null');
$assert(Number.isFinite(sourceTopicId), 'sourceTopicId is not a number');
@ -46,7 +57,7 @@ class RelationshipModel {
}
/** */
getId() {
getId():number {
$assert(this._id, 'id is null');
return this._id;
}
@ -57,27 +68,27 @@ class RelationshipModel {
}
/** */
setLineType(lineType) {
setLineType(lineType: number) {
this._lineType = lineType;
}
/** */
getSrcCtrlPoint() {
getSrcCtrlPoint(): Point {
return this._srcCtrlPoint;
}
/** */
setSrcCtrlPoint(srcCtrlPoint) {
setSrcCtrlPoint(srcCtrlPoint: Point) {
this._srcCtrlPoint = srcCtrlPoint;
}
/** */
getDestCtrlPoint() {
getDestCtrlPoint(): Point {
return this._destCtrlPoint;
}
/** */
setDestCtrlPoint(destCtrlPoint) {
setDestCtrlPoint(destCtrlPoint: Point) {
this._destCtrlPoint = destCtrlPoint;
}
@ -87,7 +98,7 @@ class RelationshipModel {
}
/** */
setEndArrow(endArrow) {
setEndArrow(endArrow: boolean) {
this._endArrow = endArrow;
}
@ -97,7 +108,7 @@ class RelationshipModel {
}
/** */
setStartArrow(startArrow) {
setStartArrow(startArrow: boolean) {
this._startArrow = startArrow;
}
@ -118,23 +129,19 @@ class RelationshipModel {
/**
* @return {String} textual information about the relationship's source and target node
*/
inspect() {
inspect(): string {
return (
`(fromNode:${this.getFromNode().getId()
} , toNode: ${this.getToNode().getId()
`(fromNode:${this.getFromNode()
} , toNode: ${this.getToNode()
})`
);
}
static _nextUUID() {
RelationshipModel._next_uuid += 1;
return RelationshipModel._next_uuid;
}
}
function _nextUUID() {
if (!$defined(RelationshipModel._uuid)) {
RelationshipModel._uuid = 0;
}
RelationshipModel._uuid += 1;
return RelationshipModel._uuid;
}
RelationshipModel._nextUUID = _nextUUID;
export default RelationshipModel;

View File

@ -51,11 +51,11 @@ class XMLSerializerBeta {
const parentTopic = document.createElement('topic');
// Set topic attributes...
if (topic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (topic.getType() === 'CentralTopic') {
parentTopic.setAttribute('central', true);
} else {
const parent = topic.getParent();
if (parent == null || parent.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (parent == null || parent.getType() === 'CentralTopic') {
const pos = topic.getPosition();
parentTopic.setAttribute('position', `${pos.x},${pos.y}`);
} else {
@ -206,8 +206,8 @@ class XMLSerializerBeta {
_deserializeNode(domElem, mindmap) {
const type = domElem.getAttribute('central') != null
? INodeModel.CENTRAL_TOPIC_TYPE
: INodeModel.MAIN_TOPIC_TYPE;
? 'CentralTopic'
: 'MainTopic';
const topic = mindmap.createNode(type);
// Load attributes...

View File

@ -68,7 +68,7 @@ class XMLSerializerPela {
const parentTopic = document.createElement('topic');
// Set topic attributes...
if (topic.getType() === INodeModel.CENTRAL_TOPIC_TYPE) {
if (topic.getType() === 'CentralTopic') {
parentTopic.setAttribute('central', 'true');
} else {
const pos = topic.getPosition();
@ -96,7 +96,7 @@ class XMLSerializerPela {
}
}
if (topic.areChildrenShrunken() && topic.getType() !== INodeModel.CENTRAL_TOPIC_TYPE) {
if (topic.areChildrenShrunken() && topic.getType() !== 'CentralTopic') {
parentTopic.setAttribute('shrink', 'true');
}
@ -268,8 +268,8 @@ class XMLSerializerPela {
_deserializeNode(domElem, mindmap) {
const type = domElem.getAttribute('central') != null
? INodeModel.CENTRAL_TOPIC_TYPE
: INodeModel.MAIN_TOPIC_TYPE;
? 'CentralTopic'
: 'MainTopic';
// Load attributes...
let id = domElem.getAttribute('id');
@ -349,7 +349,7 @@ class XMLSerializerPela {
const isShrink = domElem.getAttribute('shrink');
// Hack: Some production maps has been stored with the central topic collapsed. This is a bug.
if ($defined(isShrink) && type !== INodeModel.CENTRAL_TOPIC_TYPE) {
if ($defined(isShrink) && type !== 'CentralTopic') {
topic.setChildrenShrunken(isShrink);
}

View File

@ -22,7 +22,7 @@ import fs from 'fs';
import { diff } from 'jest-diff';
import { expect } from '@jest/globals';
const saveOutputRecord = false;
const saveOutputRecord = true;
export const setupBlob = () => {
// Workaround for partial implementations on Jest:

View File

@ -1,6 +1,6 @@
1 PPM Plan
1.1 Business Development
1.2 Backlog Management
1.2 Backlog Management [link: https://docs.google.com/a/freeform.ca/drawings/d/1mrtkVAN3_XefJJCgfxw4Va6xk9TVDBKXDt_uzyIF4Us/edit]
1.3 Freeform IT
1.4 Client Project Management
1.5 Governance & Executive
@ -81,7 +81,7 @@
11.1.1 null
11.2 Strategic Priority 3b: Health Promotion
11.2.1 Health and Wellness Committee
11.2.2 Work-life Balance Initiative
11.2.2 Work-life Balance Initiative [link: http://hrcouncil.ca/hr-toolkit/workplaces-health-safety.cfm]
11.3 So that...
12 Benefits
12.1 As Freeform Staff
@ -98,8 +98,8 @@
13.3 Drupal Community
13.4 CiviCRM
13.5 Other
14 Backlog Plan
14.1 Go To Backlog Plan
14 Backlog Plan [link: https://docs.google.com/a/freeform.ca/drawings/d/1mrtkVAN3_XefJJCgfxw4Va6xk9TVDBKXDt_uzyIF4Us/edit]
14.1 Go To Backlog Plan [link: https://docs.google.com/a/freeform.ca/drawings/d/1mrtkVAN3_XefJJCgfxw4Va6xk9TVDBKXDt_uzyIF4Us/edit]
15 Strategy Prospecting
15.1 null
15.2 null

View File

@ -3,11 +3,11 @@
2.1 Normas aplicables a problemas de determinación de resultados
3 CIRCULANTES
3.1 Adquisición temporal de acciones propias
4 NIF A
4 NIF A [link: http://www.youtube.com/watch?v=7YN-sOlkQp0]
4.1 Marco conceptual
5 NIF C
5 NIF C [link: https://sites.google.com/site/contabilidadimcpnif/estructura-de-las-nif]
5.1 Normas aplicables a conceptos específicos de los estados financieros
6 NIF E
6.1 Normas aplicables alas actividades especializadas de distintos sectores
7 NIF B
7 NIF B [link: http://www.contaduria.uady.mx/files/cuerpo-acad/caef/aief/resumen_NIF_marco_conceptual.pdf]
7.1 Normas aplicables a los estados financieros en su conjunto

View File

@ -29,7 +29,7 @@
1.5.1.1 Orange County Eye and Transplant Bank
1.5.1.2 Northern California Transplant Bank
1.5.1.2.1 In 2010, 2,500 referrals forwarded to OneLegacy
1.5.1.3 Doheny Eye and Tissue Transplant Bank
1.5.1.3 Doheny Eye and Tissue Transplant Bank [link: http://www.dohenyeyebank.org/]
1.5.2 OneLegacy
1.5.2.1 In 2010, 11,828 referrals
1.5.3 San Diego Eye Bank

View File

@ -1,13 +1,13 @@
1 Welcome To WiseMapping
1.1 5 min tutorial video ?
Follow the link !
Follow the link ! [link: https://www.youtube.com/tv?vq=medium#/watch?v=rKxZwNKs9cE]
1.2 Try it Now!
1.2.1 Double Click
1.2.2 Press "enter" to add a
Sibling
1.2.3 Drag map to move
1.3 Features
1.3.1 Links to Sites
1.3.1 Links to Sites [link: http://www.digg.com]
1.3.2 Styles
1.3.2.1 Fonts
1.3.2.2 Topic Shapes
@ -24,8 +24,8 @@ Sibling
1.5.2 Brainstorming
1.5.3 Visual
1.6 Install In Your Server
1.6.1 Open Source
1.6.2 Download
1.6.1 Open Source [link: http://www.wisemapping.org/]
1.6.2 Download [link: http://www.wisemapping.com/inyourserver.html]
1.7 Collaborate
1.7.1 Embed
1.7.2 Publish