mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-21 22:27:56 +01:00
Format all files with prettier
This commit is contained in:
parent
ae02780a1a
commit
cf29f4f953
2
packages/editor/src/@types/index.d.ts
vendored
2
packages/editor/src/@types/index.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
declare module "*.svg" {
|
||||
declare module '*.svg' {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
@ -5,7 +5,6 @@ import DE from './../../compiled-lang/de.json';
|
||||
import RU from './../../compiled-lang/ru.json';
|
||||
import ZH from './../../compiled-lang/zh.json';
|
||||
|
||||
|
||||
class I18nMsg {
|
||||
static loadLocaleData(locale: string) {
|
||||
switch (locale) {
|
||||
|
@ -48,9 +48,9 @@ class Events {
|
||||
if (!events) return this;
|
||||
|
||||
const args = Array.isArray(eventArgs) ? eventArgs : [eventArgs];
|
||||
events.forEach(((fn) => {
|
||||
events.forEach((fn) => {
|
||||
fn.apply(this, args);
|
||||
}));
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,9 @@ const ActionButton = styled.div`
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
||||
box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
||||
border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -26,7 +26,7 @@ export const ToolbarButton = styled.div`
|
||||
padding-left: 2px;
|
||||
margin-left: 3px;
|
||||
display: inline-block;
|
||||
`;
|
||||
`;
|
||||
|
||||
export const ToolbarButtonExt = styled(ToolbarButton)`
|
||||
width: 40px;
|
||||
|
@ -33,10 +33,12 @@
|
||||
"?": "ignore",
|
||||
">": "ignore",
|
||||
"||": "ignore",
|
||||
"&&": "ignore"
|
||||
"&&": "ignore",
|
||||
"(": "ignore"
|
||||
}
|
||||
}
|
||||
],
|
||||
"object-curly-newline": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-plusplus": "off",
|
||||
"no-param-reassign": "off",
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright [2021] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
* Copyright [2021] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { $defined } from '@wisemapping/core-js';
|
||||
import CommandContext from './CommandContext';
|
||||
|
||||
|
@ -47,9 +47,9 @@ class CommandContext {
|
||||
|
||||
if (result.length !== topicsIds.length) {
|
||||
const ids = designerTopics.map((topic) => topic.getId());
|
||||
throw new Error(`Could not find topic. Result:${result
|
||||
} Filter Criteria:${topicsIds
|
||||
} Current Topics: [${ids}])`);
|
||||
throw new Error(
|
||||
`Could not find topic. Result:${result} Filter Criteria:${topicsIds} Current Topics: [${ids}])`,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -17,9 +17,7 @@
|
||||
*/
|
||||
|
||||
import { $assert, $defined } from '@wisemapping/core-js';
|
||||
import {
|
||||
Point, CurvedLine, PolyLine, Line,
|
||||
} from '@wisemapping/web2d';
|
||||
import { Point, CurvedLine, PolyLine, Line } from '@wisemapping/web2d';
|
||||
import { TopicShape } from './model/INodeModel';
|
||||
import RelationshipModel from './model/RelationshipModel';
|
||||
import Topic from './Topic';
|
||||
|
@ -33,7 +33,22 @@ class DesignerKeyboard extends Keyboard {
|
||||
|
||||
private static _disabled: boolean;
|
||||
|
||||
private static excludeFromEditor = ['Enter', 'CapsLock', 'Escape', 'F1', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'];
|
||||
private static excludeFromEditor = [
|
||||
'Enter',
|
||||
'CapsLock',
|
||||
'Escape',
|
||||
'F1',
|
||||
'F3',
|
||||
'F4',
|
||||
'F5',
|
||||
'F6',
|
||||
'F7',
|
||||
'F8',
|
||||
'F9',
|
||||
'F10',
|
||||
'F11',
|
||||
'F12',
|
||||
];
|
||||
|
||||
constructor(designer: Designer) {
|
||||
super();
|
||||
@ -53,9 +68,13 @@ class DesignerKeyboard extends Keyboard {
|
||||
private _registerEvents(designer: Designer) {
|
||||
// Try with the keyboard ..
|
||||
const model = designer.getModel();
|
||||
this.addShortcut(['backspace', 'del'], () => { designer.deleteSelectedEntities(); });
|
||||
this.addShortcut(['backspace', 'del'], () => {
|
||||
designer.deleteSelectedEntities();
|
||||
});
|
||||
|
||||
this.addShortcut('space', () => { designer.shrinkSelectedBranch(); });
|
||||
this.addShortcut('space', () => {
|
||||
designer.shrinkSelectedBranch();
|
||||
});
|
||||
|
||||
this.addShortcut('f2', () => {
|
||||
const node = model.selectedTopic();
|
||||
@ -64,39 +83,68 @@ class DesignerKeyboard extends Keyboard {
|
||||
}
|
||||
});
|
||||
|
||||
this.addShortcut(['insert', 'tab', 'meta+enter'], () => { designer.createChildForSelectedNode(); });
|
||||
this.addShortcut(['insert', 'tab', 'meta+enter'], () => {
|
||||
designer.createChildForSelectedNode();
|
||||
});
|
||||
|
||||
this.addShortcut('enter', () => { designer.createSiblingForSelectedNode(); });
|
||||
this.addShortcut('enter', () => {
|
||||
designer.createSiblingForSelectedNode();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+z', 'meta+z'], () => { designer.undo(); });
|
||||
this.addShortcut(['ctrl+z', 'meta+z'], () => {
|
||||
designer.undo();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+shift+z', 'meta+shift+z'], () => { designer.redo(); });
|
||||
this.addShortcut(['ctrl+shift+z', 'meta+shift+z'], () => {
|
||||
designer.redo();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+c', 'meta+c'], () => { designer.copyToClipboard(); });
|
||||
this.addShortcut(['ctrl+c', 'meta+c'], () => {
|
||||
designer.copyToClipboard();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+l', 'meta+l'], () => { designer.addLink(); });
|
||||
this.addShortcut(['ctrl+l', 'meta+l'], () => {
|
||||
designer.addLink();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+k', 'meta+k'], () => { designer.addNote(); });
|
||||
this.addShortcut(['ctrl+k', 'meta+k'], () => {
|
||||
designer.addNote();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+v', 'meta+v'], () => { designer.pasteClipboard(); });
|
||||
this.addShortcut(['ctrl+v', 'meta+v'], () => {
|
||||
designer.pasteClipboard();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+a', 'meta+a'], () => { designer.selectAll(); });
|
||||
this.addShortcut(['ctrl+a', 'meta+a'], () => {
|
||||
designer.selectAll();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+b', 'meta+b'], () => { designer.changeFontWeight(); });
|
||||
this.addShortcut(['ctrl+b', 'meta+b'], () => {
|
||||
designer.changeFontWeight();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+s', 'meta+s'], () => { $(document).find('#save').trigger('click'); });
|
||||
this.addShortcut(['ctrl+s', 'meta+s'], () => {
|
||||
$(document).find('#save').trigger('click');
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+i', 'meta+i'], () => { designer.changeFontStyle(); });
|
||||
this.addShortcut(['ctrl+i', 'meta+i'], () => {
|
||||
designer.changeFontStyle();
|
||||
});
|
||||
|
||||
this.addShortcut(['ctrl+shift+a', 'meta+shift+a'], () => { designer.deselectAll(); });
|
||||
this.addShortcut(['ctrl+shift+a', 'meta+shift+a'], () => {
|
||||
designer.deselectAll();
|
||||
});
|
||||
|
||||
this.addShortcut(['meta+=', 'ctrl+='], () => { designer.zoomIn(); });
|
||||
this.addShortcut(['meta+=', 'ctrl+='], () => {
|
||||
designer.zoomIn();
|
||||
});
|
||||
|
||||
this.addShortcut(['meta+-', 'ctrl+-'], () => { designer.zoomOut(); });
|
||||
this.addShortcut(['meta+-', 'ctrl+-'], () => {
|
||||
designer.zoomOut();
|
||||
});
|
||||
|
||||
const me = this;
|
||||
this.addShortcut(
|
||||
'right', () => {
|
||||
this.addShortcut('right', () => {
|
||||
const node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (node.isCentralTopic()) {
|
||||
@ -110,11 +158,9 @@ class DesignerKeyboard extends Keyboard {
|
||||
const centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
this.addShortcut(
|
||||
'left', () => {
|
||||
this.addShortcut('left', () => {
|
||||
const node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (node.isCentralTopic()) {
|
||||
@ -128,11 +174,9 @@ class DesignerKeyboard extends Keyboard {
|
||||
const centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
this.addShortcut(
|
||||
'up', () => {
|
||||
this.addShortcut('up', () => {
|
||||
const node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (!node.isCentralTopic()) {
|
||||
@ -142,10 +186,8 @@ class DesignerKeyboard extends Keyboard {
|
||||
const centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
},
|
||||
);
|
||||
this.addShortcut(
|
||||
'down', () => {
|
||||
});
|
||||
this.addShortcut('down', () => {
|
||||
const node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (!node.isCentralTopic()) {
|
||||
@ -155,12 +197,14 @@ class DesignerKeyboard extends Keyboard {
|
||||
const centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
$(document).on('keypress', (event) => {
|
||||
// Needs to be ignored ?
|
||||
if (DesignerKeyboard.isDisabled() || DesignerKeyboard.excludeFromEditor.includes(event.code)) {
|
||||
if (
|
||||
DesignerKeyboard.isDisabled() ||
|
||||
DesignerKeyboard.excludeFromEditor.includes(event.code)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -189,14 +233,14 @@ class DesignerKeyboard extends Keyboard {
|
||||
const { x } = node.getPosition();
|
||||
let dist = null;
|
||||
for (let i = 0; i < brothers.length; i++) {
|
||||
const sameSide = (x * brothers[i].getPosition().x) >= 0;
|
||||
const sameSide = x * brothers[i].getPosition().x >= 0;
|
||||
if (brothers[i] !== node && sameSide) {
|
||||
const brother = brothers[i];
|
||||
const brotherY = brother.getPosition().y;
|
||||
if (direction === 'DOWN' && brotherY > y) {
|
||||
let distancia = y - brotherY;
|
||||
if (distancia < 0) {
|
||||
distancia *= (-1);
|
||||
distancia *= -1;
|
||||
}
|
||||
if (dist == null || dist > distancia) {
|
||||
dist = distancia;
|
||||
@ -205,7 +249,7 @@ class DesignerKeyboard extends Keyboard {
|
||||
} else if (direction === 'UP' && brotherY < y) {
|
||||
let distance = y - brotherY;
|
||||
if (distance < 0) {
|
||||
distance *= (-1);
|
||||
distance *= -1;
|
||||
}
|
||||
if (dist == null || dist > distance) {
|
||||
dist = distance;
|
||||
|
@ -117,7 +117,7 @@ class DesignerModel extends Events {
|
||||
|
||||
selectedTopic(): Topic | undefined {
|
||||
const topics = this.filterSelectedTopics();
|
||||
return (topics.length > 0) ? topics[0] : undefined;
|
||||
return topics.length > 0 ? topics[0] : undefined;
|
||||
}
|
||||
|
||||
findTopicById(id: number): Topic | undefined {
|
||||
|
@ -85,7 +85,7 @@ class DesignerUndoManager {
|
||||
result = false;
|
||||
} else if (undoLength > 0) {
|
||||
const command = this._undoQueue[undoLength - 1];
|
||||
result = (this._baseId !== command.getId());
|
||||
result = this._baseId !== command.getId();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class DragConnector {
|
||||
// That's why i need to divide it by two...
|
||||
const txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
|
||||
const distance = (sPos.x - txborder) * Math.sign(sPos.x);
|
||||
return distance > 0 && (distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
|
||||
return distance > 0 && distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE;
|
||||
});
|
||||
|
||||
// Assign a priority based on the distance:
|
||||
@ -99,19 +99,34 @@ class DragConnector {
|
||||
|
||||
const av = me._isVerticallyAligned(a.getSize(), aPos, sPos);
|
||||
const bv = me._isVerticallyAligned(b.getSize(), bPos, sPos);
|
||||
return me._proximityWeight(av, a, sPos, currentConnection)
|
||||
- me._proximityWeight(bv, b, sPos, currentConnection);
|
||||
return (
|
||||
me._proximityWeight(av, a, sPos, currentConnection) -
|
||||
me._proximityWeight(bv, b, sPos, currentConnection)
|
||||
);
|
||||
});
|
||||
return topics;
|
||||
}
|
||||
|
||||
private _proximityWeight(isAligned: boolean, target: Topic, sPos: Point, currentConnection: Topic): number {
|
||||
private _proximityWeight(
|
||||
isAligned: boolean,
|
||||
target: Topic,
|
||||
sPos: Point,
|
||||
currentConnection: Topic,
|
||||
): number {
|
||||
const tPos = target.getPosition();
|
||||
return (isAligned ? 0 : 200) + Math.abs(tPos.x - sPos.x)
|
||||
+ Math.abs(tPos.y - sPos.y) + (currentConnection === target ? 0 : 100);
|
||||
return (
|
||||
(isAligned ? 0 : 200) +
|
||||
Math.abs(tPos.x - sPos.x) +
|
||||
Math.abs(tPos.y - sPos.y) +
|
||||
(currentConnection === target ? 0 : 100)
|
||||
);
|
||||
}
|
||||
|
||||
private _isVerticallyAligned(targetSize: SizeType, targetPosition: Point, sourcePosition: Point): boolean {
|
||||
private _isVerticallyAligned(
|
||||
targetSize: SizeType,
|
||||
targetPosition: Point,
|
||||
sourcePosition: Point,
|
||||
): boolean {
|
||||
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
|
||||
}
|
||||
|
||||
|
@ -59,14 +59,14 @@ class DragManager {
|
||||
|
||||
// Register mouse move listener ...
|
||||
const mouseMoveListener = dragManager._buildMouseMoveListener(
|
||||
workspace, dragNode, dragManager,
|
||||
workspace,
|
||||
dragNode,
|
||||
dragManager,
|
||||
);
|
||||
screen.addEvent('mousemove', mouseMoveListener);
|
||||
|
||||
// Register mouse up listeners ...
|
||||
const mouseUpListener = dragManager._buildMouseUpListener(
|
||||
workspace, dragNode, dragManager,
|
||||
);
|
||||
const mouseUpListener = dragManager._buildMouseUpListener(workspace, dragNode, dragManager);
|
||||
screen.addEvent('mouseup', mouseUpListener);
|
||||
|
||||
// Change cursor.
|
||||
|
@ -1,2 +1,7 @@
|
||||
type EditorRenderMode = 'viewonly' | 'edition-owner' | 'edition-editor' | 'edition-viewer' | 'showcase';
|
||||
type EditorRenderMode =
|
||||
| 'viewonly'
|
||||
| 'edition-owner'
|
||||
| 'edition-editor'
|
||||
| 'edition-viewer'
|
||||
| 'showcase';
|
||||
export default EditorRenderMode;
|
||||
|
@ -48,9 +48,9 @@ class Events {
|
||||
if (!events) return this;
|
||||
|
||||
const args = Array.isArray(eventArgs) ? eventArgs : [eventArgs];
|
||||
events.forEach(((fn) => {
|
||||
events.forEach((fn) => {
|
||||
fn.apply(this, args);
|
||||
}));
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,7 @@ class Keyboard {
|
||||
addShortcut(shortcuts: string[] | string, callback: () => void) {
|
||||
const shortcutsArray = Array.isArray(shortcuts) ? shortcuts : [shortcuts];
|
||||
shortcutsArray.forEach((shortcut) => {
|
||||
$(document).bind('keydown', shortcut,
|
||||
(e) => {
|
||||
$(document).bind('keydown', shortcut, (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
callback();
|
||||
|
@ -55,7 +55,11 @@ class LocalStorageManager extends PersistenceManager {
|
||||
if (xml == null || this.forceLoad) {
|
||||
$.ajax({
|
||||
url: this.documentUrl.replace('{id}', mapId),
|
||||
headers: { 'Content-Type': 'text/plain', Accept: 'application/xml', 'X-CSRF-Token': this.getCSRFToken() },
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
Accept: 'application/xml',
|
||||
'X-CSRF-Token': this.getCSRFToken(),
|
||||
},
|
||||
type: 'get',
|
||||
dataType: 'text',
|
||||
async: false,
|
||||
|
@ -26,7 +26,7 @@ import Workspace from './Workspace';
|
||||
import SizeType from './SizeType';
|
||||
|
||||
class MainTopic extends Topic {
|
||||
private INNER_RECT_ATTRIBUTES: { stroke: string; };
|
||||
private INNER_RECT_ATTRIBUTES: { stroke: string };
|
||||
|
||||
constructor(model: NodeModel, options) {
|
||||
super(model, options);
|
||||
|
@ -33,16 +33,13 @@ class MultilineTextEditor extends Events {
|
||||
}
|
||||
|
||||
private static _buildEditor() {
|
||||
const result = $('<div></div>')
|
||||
.attr('id', 'textContainer')
|
||||
.css({
|
||||
const result = $('<div></div>').attr('id', 'textContainer').css({
|
||||
display: 'none',
|
||||
zIndex: '8',
|
||||
border: '0 none',
|
||||
});
|
||||
|
||||
const textareaElem = $('<textarea tabindex="-1" value="" wrap="off" ></textarea>')
|
||||
.css({
|
||||
const textareaElem = $('<textarea tabindex="-1" value="" wrap="off" ></textarea>').css({
|
||||
border: '1px gray dashed',
|
||||
background: 'rgba(98, 135, 167, .4)',
|
||||
outline: '0 none',
|
||||
|
@ -77,8 +77,7 @@ class NoteIcon extends Icon {
|
||||
}
|
||||
const result = $('<div id="textPopoverNote"></div>').css({ padding: '5px' });
|
||||
|
||||
const text = $('<div></div>').text(this._linksModel.getText())
|
||||
.css({
|
||||
const text = $('<div></div>').text(this._linksModel.getText()).css({
|
||||
'white-space': 'pre-wrap',
|
||||
'word-wrap': 'break-word',
|
||||
});
|
||||
|
@ -15,6 +15,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
type PositionType = { x: number, y: number };
|
||||
type PositionType = { x: number; y: number };
|
||||
|
||||
export default PositionType;
|
||||
|
@ -118,10 +118,7 @@ class Relationship extends ConnectionLine {
|
||||
this._line2d.setStroke(2);
|
||||
const ctrlPoints = this._line2d.getControlPoints();
|
||||
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
|
||||
const defaultPoints = Shape.calculateDefaultControlPoints(
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
);
|
||||
const defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
|
||||
ctrlPoints[0].x = defaultPoints[0].x;
|
||||
ctrlPoints[0].y = defaultPoints[0].y;
|
||||
|
||||
|
@ -31,7 +31,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
||||
|
||||
private clearTimeout;
|
||||
|
||||
constructor(options: { documentUrl: string, revertUrl: string, lockUrl: string }) {
|
||||
constructor(options: { documentUrl: string; revertUrl: string; lockUrl: string }) {
|
||||
$assert(options.documentUrl, 'documentUrl can not be null');
|
||||
$assert(options.revertUrl, 'revertUrl can not be null');
|
||||
$assert(options.lockUrl, 'lockUrl can not be null');
|
||||
@ -60,22 +60,28 @@ class RESTPersistenceManager extends PersistenceManager {
|
||||
}, 10000);
|
||||
|
||||
const persistence = this;
|
||||
fetch(
|
||||
`${this.documentUrl.replace('{id}', mapId)}?${query}`,
|
||||
{
|
||||
fetch(`${this.documentUrl.replace('{id}', mapId)}?${query}`, {
|
||||
method: 'PUT',
|
||||
// Blob helps to resuce the memory on large payload.
|
||||
body: new Blob([JSON.stringify(data)], { type: 'text/plain' }),
|
||||
headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json', 'X-CSRF-Token': this.getCSRFToken() },
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
Accept: 'application/json',
|
||||
'X-CSRF-Token': this.getCSRFToken(),
|
||||
},
|
||||
).then(async (response: Response) => {
|
||||
})
|
||||
.then(async (response: Response) => {
|
||||
if (response.ok) {
|
||||
events.onSuccess();
|
||||
} else {
|
||||
console.log(`Saving error: ${response.status}`);
|
||||
let userMsg;
|
||||
if (response.status === 405) {
|
||||
userMsg = { severity: 'SEVERE', message: $msg('SESSION_EXPIRED'), errorType: 'session-expired' };
|
||||
userMsg = {
|
||||
severity: 'SEVERE',
|
||||
message: $msg('SESSION_EXPIRED'),
|
||||
errorType: 'session-expired',
|
||||
};
|
||||
} else {
|
||||
const responseText = await response.text();
|
||||
const contentType = response.headers['Content-Type'];
|
||||
@ -99,9 +105,12 @@ class RESTPersistenceManager extends PersistenceManager {
|
||||
clearTimeout(persistence.clearTimeout);
|
||||
}
|
||||
persistence.onSave = false;
|
||||
}).catch(() => {
|
||||
})
|
||||
.catch(() => {
|
||||
const userMsg: PersistenceError = {
|
||||
severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED'), errorType: 'generic',
|
||||
severity: 'SEVERE',
|
||||
message: $msg('SAVE_COULD_NOT_BE_COMPLETED'),
|
||||
errorType: 'generic',
|
||||
};
|
||||
this.triggerError(userMsg);
|
||||
events.onError(userMsg);
|
||||
@ -116,22 +125,22 @@ class RESTPersistenceManager extends PersistenceManager {
|
||||
}
|
||||
|
||||
discardChanges(mapId: string) {
|
||||
fetch(this.revertUrl.replace('{id}', mapId),
|
||||
{
|
||||
fetch(this.revertUrl.replace('{id}', mapId), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json', 'X-CSRF-Token': this.getCSRFToken() },
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
Accept: 'application/json',
|
||||
'X-CSRF-Token': this.getCSRFToken(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
unlockMap(mapId: string): void {
|
||||
fetch(
|
||||
this.lockUrl.replace('{id}', mapId),
|
||||
{
|
||||
fetch(this.lockUrl.replace('{id}', mapId), {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'text/plain', 'X-CSRF-Token': this.getCSRFToken() },
|
||||
body: 'false',
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private _buildError(jsonSeverResponse) {
|
||||
@ -154,7 +163,11 @@ class RESTPersistenceManager extends PersistenceManager {
|
||||
url: `${this.documentUrl.replace('{id}', mapId)}/xml`,
|
||||
method: 'get',
|
||||
async: false,
|
||||
headers: { 'Content-Type': 'text/plain', Accept: 'application/xml', 'X-CSRF-Token': this.getCSRFToken() },
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
Accept: 'application/xml',
|
||||
'X-CSRF-Token': this.getCSRFToken(),
|
||||
},
|
||||
success(responseText) {
|
||||
xml = responseText;
|
||||
},
|
||||
|
@ -18,9 +18,7 @@
|
||||
import $ from 'jquery';
|
||||
import { $assert, $defined } from '@wisemapping/core-js';
|
||||
|
||||
import {
|
||||
Rect, Image, Line, Text, Group, ElementClass, Point,
|
||||
} from '@wisemapping/web2d';
|
||||
import { Rect, Image, Line, Text, Group, ElementClass, Point } from '@wisemapping/web2d';
|
||||
|
||||
import NodeGraph from './NodeGraph';
|
||||
import TopicConfig from './TopicConfig';
|
||||
@ -177,10 +175,7 @@ abstract class Topic extends NodeGraph {
|
||||
getInnerShape(): ElementClass {
|
||||
if (!$defined(this._innerShape)) {
|
||||
// Create inner box.
|
||||
this._innerShape = this._buildShape(
|
||||
TopicConfig.INNER_RECT_ATTRIBUTES,
|
||||
this.getShapeType(),
|
||||
);
|
||||
this._innerShape = this._buildShape(TopicConfig.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
||||
|
||||
// Update bgcolor ...
|
||||
const bgColor = this.getBackgroundColor();
|
||||
@ -246,7 +241,9 @@ abstract class Topic extends NodeGraph {
|
||||
result.setStroke(1, 'solid', stokeColor);
|
||||
};
|
||||
|
||||
result.getSize = function getSize() { return this.size; };
|
||||
result.getSize = function getSize() {
|
||||
return this.size;
|
||||
};
|
||||
|
||||
result.setPosition = () => {
|
||||
// Overwrite behaviour ...
|
||||
@ -279,10 +276,7 @@ abstract class Topic extends NodeGraph {
|
||||
|
||||
getOuterShape(): ElementClass {
|
||||
if (!$defined(this._outerShape)) {
|
||||
const rect = this._buildShape(
|
||||
TopicConfig.OUTER_SHAPE_ATTRIBUTES,
|
||||
TopicShape.ROUNDED_RECT,
|
||||
);
|
||||
const rect = this._buildShape(TopicConfig.OUTER_SHAPE_ATTRIBUTES, TopicShape.ROUNDED_RECT);
|
||||
rect.setPosition(-2, -3);
|
||||
rect.setOpacity(0);
|
||||
this._outerShape = rect;
|
||||
@ -953,9 +947,9 @@ abstract class Topic extends NodeGraph {
|
||||
const targetParent = targetTopic.getModel().getParent();
|
||||
const sourceParent = sourceTopic.getModel().getParent();
|
||||
relationship.setVisibility(
|
||||
value
|
||||
&& (targetParent == null || !targetParent.areChildrenShrunken())
|
||||
&& (sourceParent == null || !sourceParent.areChildrenShrunken()),
|
||||
value &&
|
||||
(targetParent == null || !targetParent.areChildrenShrunken()) &&
|
||||
(sourceParent == null || !sourceParent.areChildrenShrunken()),
|
||||
fade,
|
||||
);
|
||||
});
|
||||
@ -1027,7 +1021,8 @@ abstract class Topic extends NodeGraph {
|
||||
};
|
||||
|
||||
const oldSize = this.getSize();
|
||||
const hasSizeChanged = oldSize.width !== roundedSize.width || oldSize.height !== roundedSize.height;
|
||||
const hasSizeChanged =
|
||||
oldSize.width !== roundedSize.width || oldSize.height !== roundedSize.height;
|
||||
if (hasSizeChanged || force) {
|
||||
NodeGraph.prototype.setSize.call(this, roundedSize);
|
||||
|
||||
@ -1259,10 +1254,13 @@ abstract class Topic extends NodeGraph {
|
||||
const iconGroupWith = iconGroup.getSize().width;
|
||||
const topicWith = iconGroupWith + 2 * textIconSpacing + textWidth + padding * 2;
|
||||
|
||||
this.setSize({
|
||||
this.setSize(
|
||||
{
|
||||
width: topicWith,
|
||||
height: topicHeight,
|
||||
}, false);
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
// Adjust all topic elements positions ...
|
||||
const yPosition = Math.round((topicHeight - textHeight) / 2);
|
||||
|
@ -65,9 +65,9 @@ class TopicEventDispatcher extends Events {
|
||||
// Open the new editor ...
|
||||
const model = topic.getModel();
|
||||
if (
|
||||
model.getShapeType() !== TopicShape.IMAGE
|
||||
&& !this._readOnly
|
||||
&& eventType === TopicEvent.EDIT
|
||||
model.getShapeType() !== TopicShape.IMAGE &&
|
||||
!this._readOnly &&
|
||||
eventType === TopicEvent.EDIT
|
||||
) {
|
||||
this._multilineEditor.show(topic, options ? options.text : null);
|
||||
this._activeEditor = this._multilineEditor;
|
||||
|
@ -31,7 +31,10 @@ class AddTopicCommand extends Command {
|
||||
*/
|
||||
constructor(models: NodeModel[], parentTopicsId: number[]) {
|
||||
$assert(models, 'models can not be null');
|
||||
$assert(parentTopicsId == null || parentTopicsId.length === models.length, 'parents and models must have the same size');
|
||||
$assert(
|
||||
parentTopicsId == null || parentTopicsId.length === models.length,
|
||||
'parents and models must have the same size',
|
||||
);
|
||||
|
||||
super();
|
||||
this._models = models;
|
||||
|
@ -53,7 +53,7 @@ class DeleteCommand extends Command {
|
||||
const topics = this._filterChildren(this._topicIds, commandContext);
|
||||
|
||||
if (topics.length > 0) {
|
||||
topics.forEach(((topic) => {
|
||||
topics.forEach((topic) => {
|
||||
// In case that it's editing text node, force close without update ...
|
||||
topic.closeEditors();
|
||||
|
||||
@ -81,15 +81,15 @@ class DeleteCommand extends Command {
|
||||
|
||||
// Finally, delete the topic from the workspace...
|
||||
commandContext.deleteTopic(topic);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
const rels = commandContext.findRelationships(this._relIds);
|
||||
if (rels.length > 0) {
|
||||
rels.forEach(((rel) => {
|
||||
rels.forEach((rel) => {
|
||||
this._deletedRelModel.push(rel.getModel().clone());
|
||||
commandContext.deleteRelationship(rel);
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ class DeleteCommand extends Command {
|
||||
});
|
||||
|
||||
// Do they need to be connected ?
|
||||
this._deletedTopicModels.forEach(((topicModel, index) => {
|
||||
this._deletedTopicModels.forEach((topicModel, index) => {
|
||||
const topics = commandContext.findTopics([topicModel.getId()]);
|
||||
|
||||
const parentId = this._parentTopicIds[index];
|
||||
@ -112,7 +112,7 @@ class DeleteCommand extends Command {
|
||||
const parentTopics = commandContext.findTopics([parentId]);
|
||||
commandContext.connect(topics[0], parentTopics[0]);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// Add rebuild relationships ...
|
||||
this._deletedRelModel.forEach((model) => {
|
||||
@ -165,11 +165,10 @@ class DeleteCommand extends Command {
|
||||
result = result.concat(topic.getRelationships());
|
||||
|
||||
const children = topic.getChildren();
|
||||
const rels: (Relationship[])[] = children
|
||||
.map(((t: Topic) => this._collectInDepthRelationships(t)));
|
||||
const rels: Relationship[][] = children.map((t: Topic) => this._collectInDepthRelationships(t));
|
||||
|
||||
// flatten and concact
|
||||
result = result.concat(([].concat(...rels)));
|
||||
result = result.concat([].concat(...rels));
|
||||
|
||||
if (result.length > 0) {
|
||||
// Filter for unique ...
|
||||
|
@ -29,11 +29,15 @@ class GenericFunctionCommand extends Command {
|
||||
|
||||
private _commandFunc: (topic: Topic, value: CommandTypes) => CommandTypes;
|
||||
|
||||
private _oldValues: (CommandTypes)[];
|
||||
private _oldValues: CommandTypes[];
|
||||
|
||||
private _applied: boolean;
|
||||
|
||||
constructor(commandFunc: (topic: Topic, value: CommandTypes) => CommandTypes, topicsIds: number[], value: CommandTypes = undefined) {
|
||||
constructor(
|
||||
commandFunc: (topic: Topic, value: CommandTypes) => CommandTypes,
|
||||
topicsIds: number[],
|
||||
value: CommandTypes = undefined,
|
||||
) {
|
||||
$assert(commandFunc, 'commandFunc must be defined');
|
||||
$assert($defined(topicsIds), 'topicsIds must be defined');
|
||||
|
||||
@ -68,9 +72,9 @@ class GenericFunctionCommand extends Command {
|
||||
if (this._applied) {
|
||||
const topics = commandContext.findTopics(this._topicsIds);
|
||||
|
||||
topics.forEach(((topic: Topic, index: number) => {
|
||||
topics.forEach((topic: Topic, index: number) => {
|
||||
this._commandFunc(topic, this._oldValues[index]);
|
||||
}));
|
||||
});
|
||||
|
||||
this._applied = false;
|
||||
this._oldValues = [];
|
||||
|
@ -29,7 +29,13 @@ class BinaryImageExporter extends Exporter {
|
||||
|
||||
private adjustToFit: boolean;
|
||||
|
||||
constructor(svgElement: Element, width: number, height: number, imgFormat: 'image/png' | 'image/jpeg', adjustToFit = true) {
|
||||
constructor(
|
||||
svgElement: Element,
|
||||
width: number,
|
||||
height: number,
|
||||
imgFormat: 'image/png' | 'image/jpeg',
|
||||
adjustToFit = true,
|
||||
) {
|
||||
super(imgFormat.split('/')[0], imgFormat);
|
||||
this.svgElement = svgElement;
|
||||
this.adjustToFit = adjustToFit;
|
||||
@ -55,12 +61,12 @@ class BinaryImageExporter extends Exporter {
|
||||
if (this.adjustToFit) {
|
||||
// Size must match with SVG image size ...
|
||||
const size = svgExporter.getImgSize();
|
||||
width = (size.width * dpr);
|
||||
height = (size.height * dpr);
|
||||
width = size.width * dpr;
|
||||
height = size.height * dpr;
|
||||
} else {
|
||||
// Use screensize as size ..
|
||||
width = (this.width * dpr);
|
||||
height = (this.height * dpr);
|
||||
width = this.width * dpr;
|
||||
height = this.height * dpr;
|
||||
}
|
||||
|
||||
console.log(`Export size: ${width}:${height}`);
|
||||
|
@ -77,7 +77,11 @@ class FreemindExporter extends Exporter {
|
||||
|
||||
if (centralTopic) {
|
||||
this.nodeMap.set(centralTopic.getId(), main);
|
||||
this.setTopicPropertiesToNode({ freemindNode: main, mindmapTopic: centralTopic, isRoot: true });
|
||||
this.setTopicPropertiesToNode({
|
||||
freemindNode: main,
|
||||
mindmapTopic: centralTopic,
|
||||
isRoot: true,
|
||||
});
|
||||
this.addNodeFromTopic(centralTopic, main);
|
||||
}
|
||||
|
||||
@ -91,9 +95,13 @@ class FreemindExporter extends Exporter {
|
||||
|
||||
arrowlink.setDestination(destNode.getId());
|
||||
|
||||
if (relationship.getEndArrow() && relationship.getEndArrow()) arrowlink.setEndarrow('Default');
|
||||
if (relationship.getEndArrow() && relationship.getEndArrow()) {
|
||||
arrowlink.setEndarrow('Default');
|
||||
}
|
||||
|
||||
if (relationship.getStartArrow() && relationship.getStartArrow()) arrowlink.setStartarrow('Default');
|
||||
if (relationship.getStartArrow() && relationship.getStartArrow()) {
|
||||
arrowlink.setStartarrow('Default');
|
||||
}
|
||||
|
||||
srcNode.setArrowlinkOrCloudOrEdge(arrowlink);
|
||||
}
|
||||
@ -110,7 +118,15 @@ class FreemindExporter extends Exporter {
|
||||
return Promise.resolve(formatXml);
|
||||
}
|
||||
|
||||
private setTopicPropertiesToNode({ freemindNode, mindmapTopic, isRoot }: { freemindNode: FreeminNode; mindmapTopic: INodeModel; isRoot: boolean; }): void {
|
||||
private setTopicPropertiesToNode({
|
||||
freemindNode,
|
||||
mindmapTopic,
|
||||
isRoot,
|
||||
}: {
|
||||
freemindNode: FreeminNode;
|
||||
mindmapTopic: INodeModel;
|
||||
isRoot: boolean;
|
||||
}): void {
|
||||
freemindNode.setId(`ID_${mindmapTopic.getId()}`);
|
||||
|
||||
const text = mindmapTopic.getText();
|
||||
@ -154,7 +170,11 @@ class FreemindExporter extends Exporter {
|
||||
const newNode: FreeminNode = this.objectFactory.createNode();
|
||||
this.nodeMap.set(currentTopic.getId(), newNode);
|
||||
|
||||
this.setTopicPropertiesToNode({ freemindNode: newNode, mindmapTopic: currentTopic, isRoot: false });
|
||||
this.setTopicPropertiesToNode({
|
||||
freemindNode: newNode,
|
||||
mindmapTopic: currentTopic,
|
||||
isRoot: false,
|
||||
});
|
||||
|
||||
destNode.setArrowlinkOrCloudOrEdge(newNode);
|
||||
|
||||
@ -163,7 +183,7 @@ class FreemindExporter extends Exporter {
|
||||
const position: PositionNodeType = currentTopic.getPosition();
|
||||
if (position) {
|
||||
const xPos: number = position.x;
|
||||
newNode.setPosition((xPos < 0 ? 'left' : 'right'));
|
||||
newNode.setPosition(xPos < 0 ? 'left' : 'right');
|
||||
} else newNode.setPosition('left');
|
||||
});
|
||||
}
|
||||
@ -193,8 +213,7 @@ class FreemindExporter extends Exporter {
|
||||
private addFeautreNode(freemindNode: FreeminNode, mindmapTopic: INodeModel): void {
|
||||
const branches: Array<FeatureModel> = mindmapTopic.getFeatures();
|
||||
|
||||
branches
|
||||
.forEach((feature: FeatureModel) => {
|
||||
branches.forEach((feature: FeatureModel) => {
|
||||
const type = feature.getType();
|
||||
|
||||
if (type === 'link') {
|
||||
@ -286,7 +305,9 @@ class FreemindExporter extends Exporter {
|
||||
const g: string = rgb[1].trim();
|
||||
const b: string = rgb[2].trim();
|
||||
|
||||
result = `#${r.length === 1 ? `0${r}` : r}${g.length === 1 ? `0${g}` : g}${b.length === 1 ? `0${b}` : b}`;
|
||||
result = `#${r.length === 1 ? `0${r}` : r}${g.length === 1 ? `0${g}` : g}${
|
||||
b.length === 1 ? `0${b}` : b
|
||||
}`;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -21,7 +21,13 @@ import SVGExporter from './SVGExporter';
|
||||
|
||||
type imageType = 'svg' | 'png' | 'jpg';
|
||||
class ImageExpoterFactory {
|
||||
static create(type: imageType, svgElement: Element, width: number, height: number, adjustToFit = true): Exporter {
|
||||
static create(
|
||||
type: imageType,
|
||||
svgElement: Element,
|
||||
width: number,
|
||||
height: number,
|
||||
adjustToFit = true,
|
||||
): Exporter {
|
||||
let result: Exporter;
|
||||
switch (type) {
|
||||
case 'svg': {
|
||||
|
@ -39,8 +39,7 @@ class SVGExporter extends Exporter {
|
||||
|
||||
export(): Promise<string> {
|
||||
// Replace all images for in-line images ...
|
||||
let svgTxt: string = new XMLSerializer()
|
||||
.serializeToString(this.svgElement);
|
||||
let svgTxt: string = new XMLSerializer().serializeToString(this.svgElement);
|
||||
svgTxt = SVGExporter.prolog + svgTxt;
|
||||
|
||||
// Are namespace declared ?. Otherwise, force the declaration ...
|
||||
@ -59,17 +58,15 @@ class SVGExporter extends Exporter {
|
||||
svgDoc = this._normalizeToFit(svgDoc);
|
||||
}
|
||||
|
||||
const result = new XMLSerializer()
|
||||
.serializeToString(svgDoc);
|
||||
const result = new XMLSerializer().serializeToString(svgDoc);
|
||||
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
private _calcualteDimensions(): { minX: number, maxX: number, minY: number, maxY: number } {
|
||||
private _calcualteDimensions(): { minX: number; maxX: number; minY: number; maxY: number } {
|
||||
// Collect all group elements ...
|
||||
const rectElems = Array.from(document.querySelectorAll('g>rect'));
|
||||
const translates: SizeType[] = rectElems
|
||||
.map((rect: Element) => {
|
||||
const translates: SizeType[] = rectElems.map((rect: Element) => {
|
||||
const g = rect.parentElement;
|
||||
const transformStr = g.getAttribute('transform');
|
||||
|
||||
@ -104,14 +101,15 @@ class SVGExporter extends Exporter {
|
||||
const maxY = heights[heights.length - 1] + SVGExporter.padding;
|
||||
|
||||
return {
|
||||
minX, maxX, minY, maxY,
|
||||
minX,
|
||||
maxX,
|
||||
minY,
|
||||
maxY,
|
||||
};
|
||||
}
|
||||
|
||||
getImgSize(): SizeType {
|
||||
const {
|
||||
minX, maxX, minY, maxY,
|
||||
} = this._calcualteDimensions();
|
||||
const { minX, maxX, minY, maxY } = this._calcualteDimensions();
|
||||
|
||||
let width: number = maxX + Math.abs(minX);
|
||||
let height: number = maxY + Math.abs(minY);
|
||||
@ -127,9 +125,7 @@ class SVGExporter extends Exporter {
|
||||
}
|
||||
|
||||
private _normalizeToFit(document: Document): Document {
|
||||
const {
|
||||
minX, maxX, minY, maxY,
|
||||
} = this._calcualteDimensions();
|
||||
const { minX, maxX, minY, maxY } = this._calcualteDimensions();
|
||||
const svgElem = document.firstChild as Element;
|
||||
|
||||
const width = maxX + Math.abs(minX);
|
||||
|
@ -39,9 +39,10 @@ class TxtExporter extends Exporter {
|
||||
|
||||
private traverseBranch(indent: string, prefix: string, branches: INodeModel[]) {
|
||||
let result = '';
|
||||
branches
|
||||
.forEach((node, index) => {
|
||||
result = `${result}${indent}${prefix}${index + 1} ${node.getText() !== undefined ? node.getText() : ''}`;
|
||||
branches.forEach((node, index) => {
|
||||
result = `${result}${indent}${prefix}${index + 1} ${
|
||||
node.getText() !== undefined ? node.getText() : ''
|
||||
}`;
|
||||
node.getFeatures().forEach((f) => {
|
||||
const type = f.getType();
|
||||
if (type === 'link') {
|
||||
|
@ -29,12 +29,10 @@ class WiseXMLExporter extends Exporter {
|
||||
|
||||
export(): Promise<string> {
|
||||
const { mindmap } = this;
|
||||
const serializer = XMLSerializerFactory
|
||||
.createInstanceFromMindmap(mindmap);
|
||||
const serializer = XMLSerializerFactory.createInstanceFromMindmap(mindmap);
|
||||
const document: Document = serializer.toXML(mindmap);
|
||||
|
||||
const xmlStr: string = new XMLSerializer()
|
||||
.serializeToString(document);
|
||||
const xmlStr: string = new XMLSerializer().serializeToString(document);
|
||||
return Promise.resolve(xmlStr);
|
||||
}
|
||||
}
|
||||
|
@ -75,11 +75,21 @@ export default class Arrowlink {
|
||||
arrowlinkElem.setAttribute('DESTINATION', this.DESTINATION);
|
||||
arrowlinkElem.setAttribute('STARTARROW', this.STARTARROW);
|
||||
|
||||
if (this.COLOR) arrowlinkElem.setAttribute('COLOR', this.COLOR);
|
||||
if (this.ENDINCLINATION) arrowlinkElem.setAttribute('ENDINCLINATION', this.ENDINCLINATION);
|
||||
if (this.ENDARROW) arrowlinkElem.setAttribute('ENDARROW', this.ENDARROW);
|
||||
if (this.ID) arrowlinkElem.setAttribute('ID', this.ID);
|
||||
if (this.STARTINCLINATION) arrowlinkElem.setAttribute('STARTINCLINATION', this.STARTINCLINATION);
|
||||
if (this.COLOR) {
|
||||
arrowlinkElem.setAttribute('COLOR', this.COLOR);
|
||||
}
|
||||
if (this.ENDINCLINATION) {
|
||||
arrowlinkElem.setAttribute('ENDINCLINATION', this.ENDINCLINATION);
|
||||
}
|
||||
if (this.ENDARROW) {
|
||||
arrowlinkElem.setAttribute('ENDARROW', this.ENDARROW);
|
||||
}
|
||||
if (this.ID) {
|
||||
arrowlinkElem.setAttribute('ID', this.ID);
|
||||
}
|
||||
if (this.STARTINCLINATION) {
|
||||
arrowlinkElem.setAttribute('STARTINCLINATION', this.STARTINCLINATION);
|
||||
}
|
||||
|
||||
return arrowlinkElem;
|
||||
}
|
||||
|
@ -65,10 +65,7 @@ export default class Freemap {
|
||||
|
||||
// Verify that the version attribute exists
|
||||
console.log(rootElem.getAttribute('version'));
|
||||
$assert(
|
||||
rootElem.getAttribute('version') !== null,
|
||||
'Freemind version not found',
|
||||
);
|
||||
$assert(rootElem.getAttribute('version') !== null, 'Freemind version not found');
|
||||
|
||||
// Start the loading process...
|
||||
const version = rootElem.getAttribute('version') || '1.0.1';
|
||||
@ -81,9 +78,7 @@ export default class Freemap {
|
||||
|
||||
const childNodes = Array.from(mainTopicElement.childNodes);
|
||||
const childsNodes = childNodes
|
||||
.filter(
|
||||
(child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node',
|
||||
)
|
||||
.filter((child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node')
|
||||
.map((c) => c as Element);
|
||||
|
||||
childsNodes.forEach((child: Element) => {
|
||||
@ -98,14 +93,16 @@ export default class Freemap {
|
||||
let element: Element;
|
||||
if (child.nodeType === 1) {
|
||||
if (
|
||||
(child as Element).tagName === 'node'
|
||||
|| (child as Element).tagName === 'richcontent'
|
||||
|| (child as Element).tagName === 'font'
|
||||
|| (child as Element).tagName === 'edge'
|
||||
|| (child as Element).tagName === 'arrowlink'
|
||||
|| (child as Element).tagName === 'clud'
|
||||
|| (child as Element).tagName === 'icon'
|
||||
) element = child as Element;
|
||||
(child as Element).tagName === 'node' ||
|
||||
(child as Element).tagName === 'richcontent' ||
|
||||
(child as Element).tagName === 'font' ||
|
||||
(child as Element).tagName === 'edge' ||
|
||||
(child as Element).tagName === 'arrowlink' ||
|
||||
(child as Element).tagName === 'clud' ||
|
||||
(child as Element).tagName === 'icon'
|
||||
) {
|
||||
element = child as Element;
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
@ -132,44 +129,78 @@ export default class Freemap {
|
||||
|
||||
if (nodeElem.tagName === 'font') {
|
||||
node = new Font();
|
||||
if (nodeElem.getAttribute('NAME')) node.setName(nodeElem.getAttribute('NAME'));
|
||||
if (nodeElem.getAttribute('BOLD')) node.setBold(nodeElem.getAttribute('BOLD'));
|
||||
if (nodeElem.getAttribute('ITALIC')) node.setItalic(nodeElem.getAttribute('ITALIC'));
|
||||
if (nodeElem.getAttribute('SIZE')) node.setSize(nodeElem.getAttribute('SIZE'));
|
||||
if (nodeElem.getAttribute('NAME')) {
|
||||
node.setName(nodeElem.getAttribute('NAME'));
|
||||
}
|
||||
if (nodeElem.getAttribute('BOLD')) {
|
||||
node.setBold(nodeElem.getAttribute('BOLD'));
|
||||
}
|
||||
if (nodeElem.getAttribute('ITALIC')) {
|
||||
node.setItalic(nodeElem.getAttribute('ITALIC'));
|
||||
}
|
||||
if (nodeElem.getAttribute('SIZE')) {
|
||||
node.setSize(nodeElem.getAttribute('SIZE'));
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeElem.tagName === 'edge') {
|
||||
node = new Edge();
|
||||
if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
if (nodeElem.getAttribute('STYLE')) node.setStyle(nodeElem.getAttribute('STYLE'));
|
||||
if (nodeElem.getAttribute('WIDTH')) node.setWidth(nodeElem.getAttribute('WIDTH'));
|
||||
if (nodeElem.getAttribute('COLOR')) {
|
||||
node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
}
|
||||
if (nodeElem.getAttribute('STYLE')) {
|
||||
node.setStyle(nodeElem.getAttribute('STYLE'));
|
||||
}
|
||||
if (nodeElem.getAttribute('WIDTH')) {
|
||||
node.setWidth(nodeElem.getAttribute('WIDTH'));
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeElem.tagName === 'arrowlink') {
|
||||
node = new Arrowlink();
|
||||
if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
if (nodeElem.getAttribute('DESTINATION')) node.setDestination(nodeElem.getAttribute('DESTINATION'));
|
||||
if (nodeElem.getAttribute('ENDARROW')) node.setEndarrow(nodeElem.getAttribute('ENDARROW'));
|
||||
if (nodeElem.getAttribute('ENDINCLINATION')) node.setEndinclination(nodeElem.getAttribute('ENDINCLINATION'));
|
||||
if (nodeElem.getAttribute('ID')) node.setId(nodeElem.getAttribute('ID'));
|
||||
if (nodeElem.getAttribute('STARTARROW')) node.setStartarrow(nodeElem.getAttribute('STARTARROW'));
|
||||
if (nodeElem.getAttribute('STARTINCLINATION')) node.setStartinclination(nodeElem.getAttribute('STARTINCLINATION'));
|
||||
if (nodeElem.getAttribute('COLOR')) {
|
||||
node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
}
|
||||
if (nodeElem.getAttribute('DESTINATION')) {
|
||||
node.setDestination(nodeElem.getAttribute('DESTINATION'));
|
||||
}
|
||||
if (nodeElem.getAttribute('ENDARROW')) {
|
||||
node.setEndarrow(nodeElem.getAttribute('ENDARROW'));
|
||||
}
|
||||
if (nodeElem.getAttribute('ENDINCLINATION')) {
|
||||
node.setEndinclination(nodeElem.getAttribute('ENDINCLINATION'));
|
||||
}
|
||||
if (nodeElem.getAttribute('ID')) {
|
||||
node.setId(nodeElem.getAttribute('ID'));
|
||||
}
|
||||
if (nodeElem.getAttribute('STARTARROW')) {
|
||||
node.setStartarrow(nodeElem.getAttribute('STARTARROW'));
|
||||
}
|
||||
if (nodeElem.getAttribute('STARTINCLINATION')) {
|
||||
node.setStartinclination(nodeElem.getAttribute('STARTINCLINATION'));
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeElem.tagName === 'cloud') {
|
||||
node = new Cloud();
|
||||
if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
if (nodeElem.getAttribute('COLOR')) {
|
||||
node.setColor(nodeElem.getAttribute('COLOR'));
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeElem.tagName === 'icon') {
|
||||
node = new Icon();
|
||||
if (nodeElem.getAttribute('BUILTIN')) node.setBuiltin(nodeElem.getAttribute('BUILTIN'));
|
||||
if (nodeElem.getAttribute('BUILTIN')) {
|
||||
node.setBuiltin(nodeElem.getAttribute('BUILTIN'));
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeElem.tagName === 'richcontent') {
|
||||
node = new Richcontent();
|
||||
|
||||
if (nodeElem.getAttribute('TYPE')) node.setType(nodeElem.getAttribute('TYPE'));
|
||||
if (nodeElem.getAttribute('TYPE')) {
|
||||
node.setType(nodeElem.getAttribute('TYPE'));
|
||||
}
|
||||
if (nodeElem.firstChild && nodeElem.getElementsByTagName('html')) {
|
||||
const content = nodeElem.getElementsByTagName('html');
|
||||
const html = content[0] ? content[0].outerHTML : '';
|
||||
|
@ -7,7 +7,9 @@ import Icon from './Icon';
|
||||
import Richcontent from './Richcontent';
|
||||
|
||||
class Node {
|
||||
protected arrowlinkOrCloudOrEdge: Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this>;
|
||||
protected arrowlinkOrCloudOrEdge: Array<
|
||||
Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this
|
||||
>;
|
||||
|
||||
protected BACKGROUND_COLOR: string;
|
||||
|
||||
@ -43,9 +45,14 @@ class Node {
|
||||
|
||||
private centralTopic: boolean;
|
||||
|
||||
getArrowlinkOrCloudOrEdge(): Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node> {
|
||||
getArrowlinkOrCloudOrEdge(): Array<
|
||||
/* eslint-disable */
|
||||
Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node
|
||||
> {
|
||||
if (!this.arrowlinkOrCloudOrEdge) {
|
||||
this.arrowlinkOrCloudOrEdge = new Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this>();
|
||||
this.arrowlinkOrCloudOrEdge = new Array<
|
||||
Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this
|
||||
>();
|
||||
}
|
||||
return this.arrowlinkOrCloudOrEdge;
|
||||
}
|
||||
@ -118,7 +125,9 @@ class Node {
|
||||
return this.centralTopic;
|
||||
}
|
||||
|
||||
setArrowlinkOrCloudOrEdge(value: Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this): void {
|
||||
setArrowlinkOrCloudOrEdge(
|
||||
value: Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this,
|
||||
): void {
|
||||
this.getArrowlinkOrCloudOrEdge().push(value);
|
||||
}
|
||||
|
||||
@ -268,6 +277,6 @@ class Node {
|
||||
}
|
||||
}
|
||||
|
||||
export type Choise = Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node
|
||||
export type Choise = Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node;
|
||||
|
||||
export default Node;
|
||||
|
@ -26,7 +26,9 @@ export default class Richcontent {
|
||||
richcontentElem.setAttribute('TYPE', this.type);
|
||||
|
||||
if (this.html) {
|
||||
const htmlElement: DocumentFragment = document.createRange().createContextualFragment(this.html);
|
||||
const htmlElement: DocumentFragment = document
|
||||
.createRange()
|
||||
.createContextualFragment(this.html);
|
||||
richcontentElem.appendChild(htmlElement);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,9 @@ export default class FreemindImporter extends Importer {
|
||||
const version: string = this.freemindMap.getVersion();
|
||||
|
||||
if (!version || version.startsWith('freeplane')) {
|
||||
throw new Error('You seems to be be trying to import a Freeplane map. FreePlane is not supported format.');
|
||||
throw new Error(
|
||||
'You seems to be be trying to import a Freeplane map. FreePlane is not supported format.',
|
||||
);
|
||||
} else {
|
||||
const mapVersion: VersionNumber = new VersionNumber(version);
|
||||
if (mapVersion.isGreaterThan(FreemindConstant.SUPPORTED_FREEMIND_VERSION)) {
|
||||
@ -144,7 +146,11 @@ export default class FreemindImporter extends Importer {
|
||||
}
|
||||
}
|
||||
|
||||
private convertNodeProperties(freeNode: FreemindNode, wiseTopic: NodeModel, centralTopic: boolean): void {
|
||||
private convertNodeProperties(
|
||||
freeNode: FreemindNode,
|
||||
wiseTopic: NodeModel,
|
||||
centralTopic: boolean,
|
||||
): void {
|
||||
const text: string = freeNode.getText();
|
||||
if (text) {
|
||||
if (!centralTopic && text.length > 100) {
|
||||
@ -177,7 +183,12 @@ export default class FreemindImporter extends Importer {
|
||||
if (folded) wiseTopic.setChildrenShrunken(folded);
|
||||
}
|
||||
|
||||
private convertChildNodes(freeParent: FreemindNode, wiseParent: NodeModel, mindmap: Mindmap, depth: number): void {
|
||||
private convertChildNodes(
|
||||
freeParent: FreemindNode,
|
||||
wiseParent: NodeModel,
|
||||
mindmap: Mindmap,
|
||||
depth: number,
|
||||
): void {
|
||||
const freeChilden = freeParent.getArrowlinkOrCloudOrEdge();
|
||||
let currentWiseTopic: NodeModel = wiseParent;
|
||||
let order = 0;
|
||||
@ -206,7 +217,13 @@ export default class FreemindImporter extends Importer {
|
||||
|
||||
// Convert node position...
|
||||
const childrenCountSameSide = this.getChildrenCountSameSide(freeChilden, child);
|
||||
const position: {x: number, y: number} = this.convertPosition(wiseParent, child, depth, norder, childrenCountSameSide);
|
||||
const position: { x: number; y: number } = this.convertPosition(
|
||||
wiseParent,
|
||||
child,
|
||||
depth,
|
||||
norder,
|
||||
childrenCountSameSide,
|
||||
);
|
||||
wiseChild.setPosition(position.x, position.y);
|
||||
|
||||
// Convert the rest of the node properties...
|
||||
@ -239,7 +256,9 @@ export default class FreemindImporter extends Importer {
|
||||
const iconId: string = freeIcon.getBuiltin();
|
||||
const wiseIconId = FreemindIconConverter.toWiseId(iconId);
|
||||
if (wiseIconId) {
|
||||
const mindmapIcon: FeatureModel = FeatureModelFactory.createModel('icon', { id: wiseIconId });
|
||||
const mindmapIcon: FeatureModel = FeatureModelFactory.createModel('icon', {
|
||||
id: wiseIconId,
|
||||
});
|
||||
currentWiseTopic.addFeature(mindmapIcon);
|
||||
}
|
||||
}
|
||||
@ -263,7 +282,9 @@ export default class FreemindImporter extends Importer {
|
||||
|
||||
switch (type) {
|
||||
case 'NOTE': {
|
||||
const noteModel: FeatureModel = FeatureModelFactory.createModel('note', { text: text || FreemindConstant.EMPTY_NOTE });
|
||||
const noteModel: FeatureModel = FeatureModelFactory.createModel('note', {
|
||||
text: text || FreemindConstant.EMPTY_NOTE,
|
||||
});
|
||||
currentWiseTopic.addFeature(noteModel);
|
||||
break;
|
||||
}
|
||||
@ -274,7 +295,9 @@ export default class FreemindImporter extends Importer {
|
||||
}
|
||||
|
||||
default: {
|
||||
const noteModel: FeatureModel = FeatureModelFactory.createModel('note', { text: text || FreemindConstant.EMPTY_NOTE });
|
||||
const noteModel: FeatureModel = FeatureModelFactory.createModel('note', {
|
||||
text: text || FreemindConstant.EMPTY_NOTE,
|
||||
});
|
||||
currentWiseTopic.addFeature(noteModel);
|
||||
}
|
||||
}
|
||||
@ -381,7 +404,10 @@ export default class FreemindImporter extends Importer {
|
||||
|
||||
// Font Size
|
||||
if (font) {
|
||||
const fontSize: number = ((!font.getSize() || parseInt(font.getSize(), 10) < 8) ? FreemindConstant.FONT_SIZE_NORMAL : parseInt(font.getSize(), 10));
|
||||
const fontSize: number =
|
||||
!font.getSize() || parseInt(font.getSize(), 10) < 8
|
||||
? FreemindConstant.FONT_SIZE_NORMAL
|
||||
: parseInt(font.getSize(), 10);
|
||||
let wiseFontSize: number = FreemindConstant.FONT_SIZE_SMALL;
|
||||
if (fontSize >= 24) {
|
||||
wiseFontSize = FreemindConstant.FONT_SIZE_HUGE;
|
||||
@ -414,11 +440,19 @@ export default class FreemindImporter extends Importer {
|
||||
return result;
|
||||
}
|
||||
|
||||
private convertPosition(wiseParent: NodeModel, freeChild: FreemindNode, depth: number, order: number, childrenCount: number): {x: number, y: number} {
|
||||
let x: number = FreemindConstant.CENTRAL_TO_TOPIC_DISTANCE + ((depth - 1) * FreemindConstant.TOPIC_TO_TOPIC_DISTANCE);
|
||||
private convertPosition(
|
||||
wiseParent: NodeModel,
|
||||
freeChild: FreemindNode,
|
||||
depth: number,
|
||||
order: number,
|
||||
childrenCount: number,
|
||||
): { x: number; y: number } {
|
||||
let x: number =
|
||||
FreemindConstant.CENTRAL_TO_TOPIC_DISTANCE +
|
||||
(depth - 1) * FreemindConstant.TOPIC_TO_TOPIC_DISTANCE;
|
||||
if (depth === 1) {
|
||||
const side: string = freeChild.getPosition();
|
||||
x *= (side && FreemindConstant.POSITION_LEFT === side ? -1 : 1);
|
||||
x *= side && FreemindConstant.POSITION_LEFT === side ? -1 : 1;
|
||||
} else {
|
||||
const position = wiseParent.getPosition();
|
||||
x *= position.x < 0 ? 1 : -1;
|
||||
@ -427,7 +461,7 @@ export default class FreemindImporter extends Importer {
|
||||
let y: number;
|
||||
if (depth === 1) {
|
||||
if (order % 2 === 0) {
|
||||
const multiplier = ((order + 1) - childrenCount) * 2;
|
||||
const multiplier = (order + 1 - childrenCount) * 2;
|
||||
y = multiplier * FreemindConstant.ROOT_LEVEL_TOPIC_HEIGHT;
|
||||
} else {
|
||||
const multiplier = (order - childrenCount) * 2;
|
||||
@ -435,7 +469,11 @@ export default class FreemindImporter extends Importer {
|
||||
}
|
||||
} else {
|
||||
const position = wiseParent.getPosition();
|
||||
y = Math.round(position.y - ((childrenCount / 2) * FreemindConstant.SECOND_LEVEL_TOPIC_HEIGHT - (order * FreemindConstant.SECOND_LEVEL_TOPIC_HEIGHT)));
|
||||
y = Math.round(
|
||||
position.y -
|
||||
((childrenCount / 2) * FreemindConstant.SECOND_LEVEL_TOPIC_HEIGHT -
|
||||
order * FreemindConstant.SECOND_LEVEL_TOPIC_HEIGHT),
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -17,7 +17,15 @@
|
||||
*/
|
||||
import Events from '../Events';
|
||||
|
||||
export type EventType = 'topicResize' | 'topicMoved' | 'childShrinked' | 'topicConnected' | 'topicAdded' | 'topicRemoved' | 'forceLayout' | 'topicDisconect';
|
||||
export type EventType =
|
||||
| 'topicResize'
|
||||
| 'topicMoved'
|
||||
| 'childShrinked'
|
||||
| 'topicConnected'
|
||||
| 'topicAdded'
|
||||
| 'topicRemoved'
|
||||
| 'forceLayout'
|
||||
| 'topicDisconect';
|
||||
class EventBus extends Events {
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
static _instance: EventBus = new EventBus();
|
||||
|
@ -43,11 +43,11 @@ class EventBusDispatcher {
|
||||
EventBus.instance.addEvent('forceLayout', this._forceLayout.bind(this));
|
||||
}
|
||||
|
||||
private _topicResizeEvent(args: { node: Topic, size: SizeType }) {
|
||||
private _topicResizeEvent(args: { node: Topic; size: SizeType }) {
|
||||
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
||||
}
|
||||
|
||||
private _topicMoved(args: { node: Topic, position: PositionType }) {
|
||||
private _topicMoved(args: { node: Topic; position: PositionType }) {
|
||||
this._layoutManager.moveNode(args.node.getId(), args.position);
|
||||
}
|
||||
|
||||
@ -55,9 +55,11 @@ class EventBusDispatcher {
|
||||
this._layoutManager.disconnectNode(node.getId());
|
||||
}
|
||||
|
||||
private _topicConnected(args: { parentNode: Topic, childNode: Topic }) {
|
||||
private _topicConnected(args: { parentNode: Topic; childNode: Topic }) {
|
||||
this._layoutManager.connectNode(
|
||||
args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder(),
|
||||
args.parentNode.getId(),
|
||||
args.childNode.getId(),
|
||||
args.childNode.getOrder(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,11 @@ class LayoutManager extends Events {
|
||||
return this;
|
||||
}
|
||||
|
||||
predict(parentId: number, nodeId: number, position: PositionType): { order: number, position: PositionType } {
|
||||
predict(
|
||||
parentId: number,
|
||||
nodeId: number,
|
||||
position: PositionType,
|
||||
): { order: number; position: PositionType } {
|
||||
$assert($defined(parentId), 'parentId can not be null');
|
||||
|
||||
const parent = this._treeSet.find(parentId);
|
||||
@ -179,14 +183,14 @@ class LayoutManager extends Events {
|
||||
}
|
||||
|
||||
private _flushEvents() {
|
||||
this._events.forEach(((event) => {
|
||||
this._events.forEach((event) => {
|
||||
this.fireEvent('change', event);
|
||||
}));
|
||||
});
|
||||
this._events = [];
|
||||
}
|
||||
|
||||
private _collectChanges(nodes: Node[]) {
|
||||
nodes.forEach(((node) => {
|
||||
nodes.forEach((node) => {
|
||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||
// Find or create a event ...
|
||||
const id = node.getId();
|
||||
@ -205,7 +209,7 @@ class LayoutManager extends Events {
|
||||
this._events.push(event);
|
||||
}
|
||||
this._collectChanges(this._treeSet.getChildren(node));
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,10 +186,12 @@ class Node {
|
||||
// This is a performance improvement to avoid movements that really could be avoided.
|
||||
const currentPos = this.getPosition();
|
||||
if (
|
||||
currentPos == null
|
||||
|| Math.abs(currentPos.x - position.x) > 2
|
||||
|| Math.abs(currentPos.y - position.y) > 2
|
||||
) this._setProperty('position', position);
|
||||
currentPos == null ||
|
||||
Math.abs(currentPos.x - position.x) > 2 ||
|
||||
Math.abs(currentPos.y - position.y) > 2
|
||||
) {
|
||||
this._setProperty('position', position);
|
||||
}
|
||||
}
|
||||
|
||||
_setProperty(key: string, value) {
|
||||
@ -228,16 +230,11 @@ class Node {
|
||||
|
||||
/** @return {String} returns id, order, position, size and shrink information */
|
||||
toString() {
|
||||
return (
|
||||
`[id:${this.getId()
|
||||
}, order:${this.getOrder()
|
||||
}, position: {${this.getPosition().x
|
||||
},${this.getPosition().y
|
||||
}}, size: {${this.getSize().width
|
||||
},${this.getSize().height
|
||||
}}, shrink:${this.areChildrenShrunken()
|
||||
}]`
|
||||
);
|
||||
return `[id:${this.getId()}, order:${this.getOrder()}, position: {${this.getPosition().x},${
|
||||
this.getPosition().y
|
||||
}}, size: {${this.getSize().width},${
|
||||
this.getSize().height
|
||||
}}, shrink:${this.areChildrenShrunken()}]`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,9 +297,7 @@ class RootedTreeSet {
|
||||
if (this._rootNodes.includes(node)) {
|
||||
fillColor = '#000';
|
||||
} else {
|
||||
fillColor = node.isFree()
|
||||
? '#abc'
|
||||
: '#c00';
|
||||
fillColor = node.isFree() ? '#abc' : '#c00';
|
||||
}
|
||||
rect.attr('fill', fillColor);
|
||||
|
||||
@ -310,28 +308,20 @@ class RootedTreeSet {
|
||||
const rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
||||
rect.click(() => {
|
||||
console.log(
|
||||
`[id:${node.getId()
|
||||
}, order:${node.getOrder()
|
||||
}, position:(${rectPosition.x
|
||||
}, ${rectPosition.y
|
||||
}), size:${rectSize.width
|
||||
},${rectSize.height
|
||||
}, freeDisplacement:(${node.getFreeDisplacement().x
|
||||
},${node.getFreeDisplacement().y
|
||||
})]`,
|
||||
`[id:${node.getId()}, order:${node.getOrder()}, position:(${rectPosition.x}, ${
|
||||
rectPosition.y
|
||||
}), size:${rectSize.width},${rectSize.height}, freeDisplacement:(${
|
||||
node.getFreeDisplacement().x
|
||||
},${node.getFreeDisplacement().y})]`,
|
||||
);
|
||||
});
|
||||
text.click(() => {
|
||||
console.log(
|
||||
`[id:${node.getId()
|
||||
}, order:${node.getOrder()
|
||||
}, position:(${rectPosition.x
|
||||
},${rectPosition.y
|
||||
}), size:${rectSize.width
|
||||
}x${rectSize.height
|
||||
}, freeDisplacement:(${node.getFreeDisplacement().x
|
||||
},${node.getFreeDisplacement().y
|
||||
})]`,
|
||||
`[id:${node.getId()}, order:${node.getOrder()}, position:(${rectPosition.x},${
|
||||
rectPosition.y
|
||||
}), size:${rectSize.width}x${rectSize.height}, freeDisplacement:(${
|
||||
node.getFreeDisplacement().x
|
||||
},${node.getFreeDisplacement().y})]`,
|
||||
);
|
||||
});
|
||||
|
||||
@ -385,12 +375,12 @@ class RootedTreeSet {
|
||||
// (depending on the direction of the offset and on the same side as their parent)
|
||||
const parent = this.getParent(node);
|
||||
const siblings = this.getSiblings(node).filter((sibling) => {
|
||||
const sameSide = node.getPosition().x > parent.getPosition().x
|
||||
const sameSide =
|
||||
node.getPosition().x > parent.getPosition().x
|
||||
? sibling.getPosition().x > parent.getPosition().x
|
||||
: sibling.getPosition().x < parent.getPosition().x;
|
||||
const orderOK = yOffset < 0
|
||||
? sibling.getOrder() < node.getOrder()
|
||||
: sibling.getOrder() > node.getOrder();
|
||||
const orderOK =
|
||||
yOffset < 0 ? sibling.getOrder() < node.getOrder() : sibling.getOrder() > node.getOrder();
|
||||
return orderOK && sameSide;
|
||||
});
|
||||
|
||||
@ -411,15 +401,16 @@ class RootedTreeSet {
|
||||
// direct descendants of the root that do not contain the node and are on the same side
|
||||
// and on the direction of the offset
|
||||
const rootNode = this.getRootNode(node);
|
||||
const branches = this.getChildren(rootNode)
|
||||
.filter(((child) => this._find(node.getId(), child)));
|
||||
const branches = this.getChildren(rootNode).filter((child) => this._find(node.getId(), child));
|
||||
|
||||
const branch = branches[0];
|
||||
const result = this.getSiblings(branch).filter((sibling) => {
|
||||
const sameSide = node.getPosition().x > rootNode.getPosition().x
|
||||
const sameSide =
|
||||
node.getPosition().x > rootNode.getPosition().x
|
||||
? sibling.getPosition().x > rootNode.getPosition().x
|
||||
: sibling.getPosition().x < rootNode.getPosition().x;
|
||||
const sameDirection = yOffset < 0
|
||||
const sameDirection =
|
||||
yOffset < 0
|
||||
? sibling.getOrder() < branch.getOrder()
|
||||
: sibling.getOrder() > branch.getOrder();
|
||||
return sameSide && sameDirection;
|
||||
|
@ -6,28 +6,31 @@ import FeatureModel from './FeatureModel';
|
||||
import FeatureType from './FeatureType';
|
||||
|
||||
interface NodeById {
|
||||
id: FeatureType,
|
||||
id: FeatureType;
|
||||
model: typeof FeatureModel;
|
||||
}
|
||||
|
||||
class FeatureModelFactory {
|
||||
static modelById: Array<NodeById> = [{
|
||||
static modelById: Array<NodeById> = [
|
||||
{
|
||||
id: 'icon',
|
||||
model: IconModel,
|
||||
}, {
|
||||
},
|
||||
{
|
||||
id: 'link',
|
||||
model: LinkModel,
|
||||
}, {
|
||||
},
|
||||
{
|
||||
id: 'note',
|
||||
model: NoteModel,
|
||||
}];
|
||||
},
|
||||
];
|
||||
|
||||
static createModel(type: FeatureType, attributes): FeatureModel {
|
||||
$assert(type, 'type can not be null');
|
||||
$assert(attributes, 'attributes can not be null');
|
||||
|
||||
const { model: Model } = FeatureModelFactory.modelById
|
||||
.filter((elem) => elem.id === type)[0];
|
||||
const { model: Model } = FeatureModelFactory.modelById.filter((elem) => elem.id === type)[0];
|
||||
return new Model(attributes);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ abstract class IMindmap {
|
||||
|
||||
abstract setDescription(value: string): void;
|
||||
|
||||
abstract getId(): string
|
||||
abstract getId(): string;
|
||||
|
||||
abstract setId(id: string): void;
|
||||
|
||||
@ -73,7 +73,7 @@ abstract class IMindmap {
|
||||
|
||||
abstract hasAlreadyAdded(node): boolean;
|
||||
|
||||
abstract createNode(type: NodeType, id: number)
|
||||
abstract createNode(type: NodeType, id: number);
|
||||
|
||||
abstract createRelationship(fromNodeId: number, toNodeId: number): void;
|
||||
|
||||
@ -81,7 +81,7 @@ abstract class IMindmap {
|
||||
|
||||
abstract deleteRelationship(relationship: RelationshipModel): void;
|
||||
|
||||
inspect():string {
|
||||
inspect(): string {
|
||||
let result = '';
|
||||
result = '{ ';
|
||||
|
||||
@ -102,7 +102,7 @@ abstract class IMindmap {
|
||||
return result;
|
||||
}
|
||||
|
||||
copyTo(target:IMindmap) {
|
||||
copyTo(target: IMindmap) {
|
||||
const version = this.getVersion();
|
||||
target.setVersion(version);
|
||||
|
||||
|
@ -24,7 +24,8 @@ import Mindmap from './Mindmap';
|
||||
export type NodeModelType = 'CentralTopic' | 'MainTopic';
|
||||
|
||||
// regex taken from https://stackoverflow.com/a/34763398/58128
|
||||
const parseJsObject = (str: string) => JSON.parse(str.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '));
|
||||
const parseJsObject = (str: string) =>
|
||||
JSON.parse(str.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '));
|
||||
|
||||
abstract class INodeModel {
|
||||
static MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
|
||||
@ -90,7 +91,7 @@ abstract class INodeModel {
|
||||
this.putProperty('imageSize', `{width:${width},height:${height}}`);
|
||||
}
|
||||
|
||||
getImageSize(): { width: number, height: number } {
|
||||
getImageSize(): { width: number; height: number } {
|
||||
const value = this.getProperty('imageSize') as string;
|
||||
let result;
|
||||
if (value != null) {
|
||||
|
@ -28,7 +28,7 @@ class IconModel extends FeatureModel {
|
||||
return this.getAttribute('id') as string;
|
||||
}
|
||||
|
||||
setIconType(iconType: string):void {
|
||||
setIconType(iconType: string): void {
|
||||
$assert(iconType, 'iconType id can not be null');
|
||||
this.setAttribute('id', iconType);
|
||||
}
|
||||
|
@ -41,7 +41,11 @@ class LinkModel extends FeatureModel {
|
||||
// url format is already checked in LinkEditor.checkUrl
|
||||
static _fixUrl(url: string): string {
|
||||
let result = url;
|
||||
if (!result.includes('http://') && !result.includes('https://') && !result.includes('mailto://')) {
|
||||
if (
|
||||
!result.includes('http://') &&
|
||||
!result.includes('https://') &&
|
||||
!result.includes('mailto://')
|
||||
) {
|
||||
result = `http://${result}`;
|
||||
}
|
||||
return result;
|
||||
|
@ -100,7 +100,7 @@ class Mindmap extends IMindmap {
|
||||
this._branches = this._branches.filter((b) => b !== nodeModel);
|
||||
}
|
||||
|
||||
getBranches():NodeModel[] {
|
||||
getBranches(): NodeModel[] {
|
||||
return this._branches;
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ class Mindmap extends IMindmap {
|
||||
return result;
|
||||
}
|
||||
|
||||
createNode(type: NodeModelType = 'MainTopic', id?: number):NodeModel {
|
||||
createNode(type: NodeModelType = 'MainTopic', id?: number): NodeModel {
|
||||
return new NodeModel(type, this, id);
|
||||
}
|
||||
|
||||
|
@ -125,11 +125,7 @@ class RelationshipModel {
|
||||
* @return {String} textual information about the relationship's source and target node
|
||||
*/
|
||||
inspect(): string {
|
||||
return (
|
||||
`(fromNode:${this.getFromNode()
|
||||
} , toNode: ${this.getToNode()
|
||||
})`
|
||||
);
|
||||
return `(fromNode:${this.getFromNode()} , toNode: ${this.getToNode()})`;
|
||||
}
|
||||
|
||||
static _nextUUID() {
|
||||
|
@ -83,7 +83,7 @@ class Pela2TangoMigrator implements XMLMindmapSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
private _fixNodePosition(node: NodeModel, parentPosition: { x: number, y: number }): void {
|
||||
private _fixNodePosition(node: NodeModel, parentPosition: { x: number; y: number }): void {
|
||||
// Position was not required in previous versions. Try to synthesize one .
|
||||
let position = node.getPosition();
|
||||
if (!position) {
|
||||
|
@ -14,9 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
$defined, $assert, createDocument,
|
||||
} from '@wisemapping/core-js';
|
||||
import { $defined, $assert, createDocument } from '@wisemapping/core-js';
|
||||
import ModelCodeName from './ModelCodeName';
|
||||
import Mindmap from '../model/Mindmap';
|
||||
import FeatureModelFactory from '../model/FeatureModelFactory';
|
||||
@ -99,11 +97,11 @@ class XMLSerializerBeta implements XMLMindmapSerializer {
|
||||
font += `${fontStyle || ''};`;
|
||||
|
||||
if (
|
||||
$defined(fontFamily)
|
||||
|| $defined(fontSize)
|
||||
|| $defined(fontColor)
|
||||
|| $defined(fontWeight)
|
||||
|| $defined(fontStyle)
|
||||
$defined(fontFamily) ||
|
||||
$defined(fontSize) ||
|
||||
$defined(fontColor) ||
|
||||
$defined(fontWeight) ||
|
||||
$defined(fontStyle)
|
||||
) {
|
||||
parentTopic.setAttribute('fontStyle', font);
|
||||
}
|
||||
@ -180,7 +178,8 @@ class XMLSerializerBeta implements XMLMindmapSerializer {
|
||||
// Is a wisemap?.
|
||||
$assert(
|
||||
documentElement.tagName === XMLSerializerBeta.MAP_ROOT_NODE,
|
||||
`This seem not to be a map document. Root Tag: '${documentElement.tagName}',HTML:${dom.innerHTML
|
||||
`This seem not to be a map document. Root Tag: '${documentElement.tagName}',HTML:${
|
||||
dom.innerHTML
|
||||
}, XML:,${new XMLSerializer().serializeToString(dom)}`,
|
||||
);
|
||||
|
||||
@ -202,9 +201,7 @@ class XMLSerializerBeta implements XMLMindmapSerializer {
|
||||
}
|
||||
|
||||
_deserializeNode(domElem, mindmap) {
|
||||
const type = domElem.getAttribute('central') != null
|
||||
? 'CentralTopic'
|
||||
: 'MainTopic';
|
||||
const type = domElem.getAttribute('central') != null ? 'CentralTopic' : 'MainTopic';
|
||||
const topic = mindmap.createNode(type);
|
||||
|
||||
// Load attributes...
|
||||
@ -275,10 +272,10 @@ class XMLSerializerBeta implements XMLMindmapSerializer {
|
||||
const child = children[i];
|
||||
if (child.nodeType === 1) {
|
||||
$assert(
|
||||
child.tagName === 'topic'
|
||||
|| child.tagName === 'icon'
|
||||
|| child.tagName === 'link'
|
||||
|| child.tagName === 'note',
|
||||
child.tagName === 'topic' ||
|
||||
child.tagName === 'icon' ||
|
||||
child.tagName === 'link' ||
|
||||
child.tagName === 'note',
|
||||
`Illegal node type:${child.tagName}`,
|
||||
);
|
||||
if (child.tagName === 'topic') {
|
||||
|
@ -24,7 +24,7 @@ import XMLSerializerTango from './XMLSerializerTango';
|
||||
import Mindmap from '../model/Mindmap';
|
||||
import XMLMindmapSerializer from './XMLMindmapSerializer';
|
||||
|
||||
const codeToSerializer: { codeName: string, serializer, migrator }[] = [
|
||||
const codeToSerializer: { codeName: string; serializer; migrator }[] = [
|
||||
{
|
||||
codeName: ModelCodeName.BETA,
|
||||
serializer: XMLSerializerBeta,
|
||||
@ -51,8 +51,7 @@ class XMLSerializerFactory {
|
||||
* mindplot.persistence.XMLSerializer_Tango} serializer corresponding to the mindmap's version
|
||||
*/
|
||||
static createInstanceFromMindmap(mindmap: Mindmap) {
|
||||
return XMLSerializerFactory
|
||||
.getSerializer(mindmap.getVersion());
|
||||
return XMLSerializerFactory.getSerializer(mindmap.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +82,7 @@ class XMLSerializerFactory {
|
||||
if (!found) {
|
||||
found = codeToSerializer[i].codeName === version;
|
||||
// eslint-disable-next-line new-cap
|
||||
if (found) result = new (codeToSerializer[i].serializer)();
|
||||
if (found) result = new codeToSerializer[i].serializer();
|
||||
} else {
|
||||
const { migrator } = codeToSerializer[i];
|
||||
// eslint-disable-next-line new-cap
|
||||
|
@ -60,8 +60,8 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
const relationships = mindmap.getRelationships();
|
||||
relationships.forEach((relationship) => {
|
||||
if (
|
||||
mindmap.findNodeById(relationship.getFromNode()) !== null
|
||||
&& mindmap.findNodeById(relationship.getToNode()) !== null
|
||||
mindmap.findNodeById(relationship.getFromNode()) !== null &&
|
||||
mindmap.findNodeById(relationship.getToNode()) !== null
|
||||
) {
|
||||
// Isolated relationships are not persisted ....
|
||||
const relationDom = XMLSerializerTango._relationshipToXML(document, relationship);
|
||||
@ -99,14 +99,15 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
|
||||
if (shape === TopicShape.IMAGE) {
|
||||
const size = topic.getImageSize();
|
||||
parentTopic.setAttribute(
|
||||
'image',
|
||||
`${size.width},${size.height}:${topic.getImageUrl()}`,
|
||||
);
|
||||
parentTopic.setAttribute('image', `${size.width},${size.height}:${topic.getImageUrl()}`);
|
||||
}
|
||||
}
|
||||
|
||||
if ((topic.areChildrenShrunken() && topic.getChildren().length > 0) && topic.getType() !== 'CentralTopic') {
|
||||
if (
|
||||
topic.areChildrenShrunken() &&
|
||||
topic.getChildren().length > 0 &&
|
||||
topic.getType() !== 'CentralTopic'
|
||||
) {
|
||||
parentTopic.setAttribute('shrink', 'true');
|
||||
}
|
||||
|
||||
@ -132,11 +133,11 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
font += `${fontStyle || ''};`;
|
||||
|
||||
if (
|
||||
$defined(fontFamily)
|
||||
|| $defined(fontSize)
|
||||
|| $defined(fontColor)
|
||||
|| $defined(fontWeight)
|
||||
|| $defined(fontStyle)
|
||||
$defined(fontFamily) ||
|
||||
$defined(fontSize) ||
|
||||
$defined(fontColor) ||
|
||||
$defined(fontWeight) ||
|
||||
$defined(fontStyle)
|
||||
) {
|
||||
parentTopic.setAttribute('fontStyle', font);
|
||||
}
|
||||
@ -208,10 +209,7 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
if (lineType === ConnectionLine.CURVED || lineType === ConnectionLine.SIMPLE_CURVED) {
|
||||
if ($defined(relationship.getSrcCtrlPoint())) {
|
||||
const srcPoint = relationship.getSrcCtrlPoint();
|
||||
result.setAttribute(
|
||||
'srcCtrlPoint',
|
||||
`${Math.round(srcPoint.x)},${Math.round(srcPoint.y)}`,
|
||||
);
|
||||
result.setAttribute('srcCtrlPoint', `${Math.round(srcPoint.x)},${Math.round(srcPoint.y)}`);
|
||||
}
|
||||
if ($defined(relationship.getDestCtrlPoint())) {
|
||||
const destPoint = relationship.getDestCtrlPoint();
|
||||
@ -246,9 +244,7 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
// Add all the topics nodes ...
|
||||
const childNodes = Array.from(rootElem.childNodes);
|
||||
const topicsNodes = childNodes
|
||||
.filter(
|
||||
(child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'topic',
|
||||
)
|
||||
.filter((child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'topic')
|
||||
.map((c) => c as Element);
|
||||
topicsNodes.forEach((child) => {
|
||||
const topic = this._deserializeNode(child, mindmap);
|
||||
@ -505,12 +501,12 @@ class XMLSerializerTango implements XMLMindmapSerializer {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const c = str.charCodeAt(i);
|
||||
if (
|
||||
c === 0x9
|
||||
|| c === 0xa
|
||||
|| c === 0xd
|
||||
|| (c >= 0x20 && c <= 0xd7ff)
|
||||
|| (c >= 0xe000 && c <= 0xfffd)
|
||||
|| (c >= 0x10000 && c <= 0x10ffff)
|
||||
c === 0x9 ||
|
||||
c === 0xa ||
|
||||
c === 0xd ||
|
||||
(c >= 0x20 && c <= 0xd7ff) ||
|
||||
(c >= 0xe000 && c <= 0xfffd) ||
|
||||
(c >= 0x10000 && c <= 0x10ffff)
|
||||
) {
|
||||
result += str.charAt(i);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ class FloatingTip extends Events {
|
||||
|
||||
if (this.addEvent) {
|
||||
Object.keys(options).forEach((option) => {
|
||||
if (options[option] instanceof Function && (/^on[A-Z]/).test(option)) {
|
||||
if (options[option] instanceof Function && /^on[A-Z]/.test(option)) {
|
||||
this.addEvent(option, options[option]);
|
||||
delete options[option];
|
||||
}
|
||||
|
@ -49,7 +49,10 @@ export const parseXMLString = (xmlStr: string, mimeType: DOMParserSupportedType)
|
||||
return xmlDoc;
|
||||
};
|
||||
|
||||
export const parseXMLFile = (filePath: fs.PathOrFileDescriptor, mimeType: DOMParserSupportedType) => {
|
||||
export const parseXMLFile = (
|
||||
filePath: fs.PathOrFileDescriptor,
|
||||
mimeType: DOMParserSupportedType,
|
||||
) => {
|
||||
const stream = fs.readFileSync(filePath, { encoding: 'utf-8' });
|
||||
|
||||
let content = stream.toString();
|
||||
|
@ -7,9 +7,12 @@ import { parseXMLFile, setupBlob, exporterAssert } from './Helper';
|
||||
setupBlob();
|
||||
|
||||
describe('SVG export test execution', () => {
|
||||
test.each(fs.readdirSync(path.resolve(__dirname, './input/'))
|
||||
test.each(
|
||||
fs
|
||||
.readdirSync(path.resolve(__dirname, './input/'))
|
||||
.filter((f) => f.endsWith('.wxml'))
|
||||
.map((filename: string) => filename.split('.')[0]))('Exporting %p suite', async (testName: string) => {
|
||||
.map((filename: string) => filename.split('.')[0]),
|
||||
)('Exporting %p suite', async (testName: string) => {
|
||||
// Load SVG ...
|
||||
const svgPath = path.resolve(__dirname, `./input/${testName}.svg`);
|
||||
expect(fs.existsSync(svgPath)).toEqual(true);
|
||||
|
@ -15,7 +15,10 @@ export const parseXMLString = (xmlStr: string, mimeType: DOMParserSupportedType)
|
||||
return xmlDoc;
|
||||
};
|
||||
|
||||
export const parseXMLFile = (filePath: fs.PathOrFileDescriptor, mimeType: DOMParserSupportedType) => {
|
||||
export const parseXMLFile = (
|
||||
filePath: fs.PathOrFileDescriptor,
|
||||
mimeType: DOMParserSupportedType,
|
||||
) => {
|
||||
const stream = fs.readFileSync(filePath, { encoding: 'utf-8' });
|
||||
|
||||
const content = stream.toString();
|
||||
|
@ -14,6 +14,6 @@ if (Cypress.env('imageSnaphots')) {
|
||||
{
|
||||
prevSubject: ['optional', 'element', 'window', 'document'],
|
||||
},
|
||||
() => Promise.resolve()
|
||||
() => Promise.resolve(),
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import Client from "../client";
|
||||
import CacheDecoratorClient from "../client/cache-decorator-client";
|
||||
import MockClient from "../client/mock-client";
|
||||
import RestClient from "../client/rest-client";
|
||||
|
||||
import Client from '../client';
|
||||
import CacheDecoratorClient from '../client/cache-decorator-client';
|
||||
import MockClient from '../client/mock-client';
|
||||
import RestClient from '../client/rest-client';
|
||||
|
||||
interface Config {
|
||||
apiBaseUrl: string;
|
||||
@ -13,13 +12,12 @@ interface Config {
|
||||
}
|
||||
|
||||
class _AppConfig {
|
||||
|
||||
private defaultInstance: Config = {
|
||||
apiBaseUrl: `${window.location.protocol}//${window.location.hostname}:${window.location.port}`,
|
||||
clientType: 'mock',
|
||||
recaptcha2Enabled: true,
|
||||
recaptcha2SiteKey: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'
|
||||
}
|
||||
recaptcha2SiteKey: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
|
||||
};
|
||||
|
||||
isDevelopEnv(): boolean {
|
||||
const config = this.getInstance();
|
||||
@ -53,7 +51,6 @@ class _AppConfig {
|
||||
}
|
||||
|
||||
buildClient(): Client {
|
||||
|
||||
const config = this.getInstance();
|
||||
let result: Client;
|
||||
if (config.clientType == 'rest') {
|
||||
|
@ -33,7 +33,6 @@ export default abstract class AppI18n {
|
||||
if (account?.locale && result.code !== localStorage.getItem(AppI18n.LOCAL_STORAGE_KEY)) {
|
||||
localStorage.setItem(AppI18n.LOCAL_STORAGE_KEY, result.code);
|
||||
}
|
||||
|
||||
} else {
|
||||
result = this.getDefaultLocale();
|
||||
}
|
||||
@ -81,7 +80,6 @@ export const Locales = {
|
||||
FR: new Locale('de', 'Deutsch', require('./../../compiled-lang/de.json')), // eslint-disable-line
|
||||
RU: new Locale('ru', 'Pусский', require('./../../compiled-lang/ru.json')), // eslint-disable-line
|
||||
ZH: new Locale('zh', '中文 (简体)', require('./../../compiled-lang/zh.json')), // eslint-disable-line
|
||||
|
||||
};
|
||||
|
||||
export const localeFromStr = (code: string): Locale => {
|
||||
|
@ -137,7 +137,6 @@ class CacheDecoratorClient implements Client {
|
||||
removePersistenceManager(): void {
|
||||
return this.client.removePersistenceManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CacheDecoratorClient;
|
@ -17,19 +17,19 @@ const label1: Label = {
|
||||
id: 1,
|
||||
title: 'label 1',
|
||||
color: 'black',
|
||||
}
|
||||
};
|
||||
|
||||
const label2: Label = {
|
||||
id: 2,
|
||||
title: 'label 2',
|
||||
color: 'green',
|
||||
}
|
||||
};
|
||||
|
||||
const label3: Label = {
|
||||
id: 3,
|
||||
title: 'label 3',
|
||||
color: 'red',
|
||||
}
|
||||
};
|
||||
|
||||
class MockClient implements Client {
|
||||
private maps: MapInfo[] = [];
|
||||
@ -50,7 +50,7 @@ class MockClient implements Client {
|
||||
modifiedTime: string,
|
||||
description: string,
|
||||
isPublic: boolean,
|
||||
role: 'owner' | 'viewer' | 'editor'
|
||||
role: 'owner' | 'viewer' | 'editor',
|
||||
): MapInfo {
|
||||
return {
|
||||
id,
|
||||
@ -79,7 +79,7 @@ class MockClient implements Client {
|
||||
'2008-06-02T00:00:00Z',
|
||||
'',
|
||||
true,
|
||||
'owner'
|
||||
'owner',
|
||||
),
|
||||
createMapInfo(
|
||||
11,
|
||||
@ -92,7 +92,7 @@ class MockClient implements Client {
|
||||
'2008-06-02T00:00:00Z',
|
||||
'',
|
||||
false,
|
||||
'editor'
|
||||
'editor',
|
||||
),
|
||||
createMapInfo(
|
||||
12,
|
||||
@ -105,7 +105,7 @@ class MockClient implements Client {
|
||||
'2008-06-02T00:00:00Z',
|
||||
'',
|
||||
false,
|
||||
'editor'
|
||||
'editor',
|
||||
),
|
||||
];
|
||||
|
||||
@ -118,11 +118,14 @@ class MockClient implements Client {
|
||||
|
||||
fetchMindmap(id: number): Mindmap {
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(`
|
||||
const xmlDoc = parser.parseFromString(
|
||||
`
|
||||
<map name="${id}" version="tango">
|
||||
<topic central="true" text="This is the map ${id}" id="1" fontStyle=";;#ffffff;;;"></topic>
|
||||
</map>
|
||||
`, 'text/xml');
|
||||
`,
|
||||
'text/xml',
|
||||
);
|
||||
|
||||
const serializer = new XMLSerializerTango();
|
||||
return serializer.loadFromDom(xmlDoc, String(id));
|
||||
@ -334,7 +337,11 @@ class MockClient implements Client {
|
||||
}
|
||||
|
||||
createLabel(title: string, color: string): Promise<number> {
|
||||
const newId = Math.max.apply(Number, this.labels.map(l => l.id)) + 1;
|
||||
const newId =
|
||||
Math.max.apply(
|
||||
Number,
|
||||
this.labels.map((l) => l.id),
|
||||
) + 1;
|
||||
this.labels.push({
|
||||
id: newId,
|
||||
title,
|
||||
@ -345,10 +352,10 @@ class MockClient implements Client {
|
||||
|
||||
deleteLabel(id: number): Promise<void> {
|
||||
this.labels = this.labels.filter((l) => l.id != id);
|
||||
this.maps = this.maps.map(m => {
|
||||
this.maps = this.maps.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
labels: m.labels.filter((l) => l.id != id)
|
||||
labels: m.labels.filter((l) => l.id != id),
|
||||
};
|
||||
});
|
||||
return Promise.resolve();
|
||||
@ -383,8 +390,8 @@ class MockClient implements Client {
|
||||
|
||||
registerNewUser(user: NewUser): Promise<void> {
|
||||
console.log('user:' + user);
|
||||
if (user.email == "error@example.com") {
|
||||
return Promise.reject({ msg: "Unexpected error" });
|
||||
if (user.email == 'error@example.com') {
|
||||
return Promise.reject({ msg: 'Unexpected error' });
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { EditorRenderMode, LocalStorageManager, Mindmap, PersistenceManager, RESTPersistenceManager } from '@wisemapping/mindplot';
|
||||
import {
|
||||
EditorRenderMode,
|
||||
LocalStorageManager,
|
||||
Mindmap,
|
||||
PersistenceManager,
|
||||
RESTPersistenceManager,
|
||||
} from '@wisemapping/mindplot';
|
||||
import { PersistenceError } from '@wisemapping/mindplot/src/components/PersistenceManager';
|
||||
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
||||
import Client, {
|
||||
@ -20,7 +26,9 @@ export default class RestClient implements Client {
|
||||
private persistenceManager: PersistenceManager;
|
||||
private axios: AxiosInstance;
|
||||
|
||||
private checkResponseForSessionExpired = <T>(error: { response?: AxiosResponse<T> }): Promise<{ response?: AxiosResponse<T> }> => {
|
||||
private checkResponseForSessionExpired = <T>(error: {
|
||||
response?: AxiosResponse<T>;
|
||||
}): Promise<{ response?: AxiosResponse<T> }> => {
|
||||
// TODO: Improve session timeout response and response handling
|
||||
if (error.response && error.response.status === 405) {
|
||||
this.sessionExpired();
|
||||
@ -37,7 +45,10 @@ export default class RestClient implements Client {
|
||||
} else {
|
||||
console.warn('csrf token not found in html head');
|
||||
}
|
||||
this.axios.interceptors.response.use((r) => r, (r) => this.checkResponseForSessionExpired(r));
|
||||
this.axios.interceptors.response.use(
|
||||
(r) => r,
|
||||
(r) => this.checkResponseForSessionExpired(r),
|
||||
);
|
||||
}
|
||||
|
||||
private _onSessionExpired: () => void;
|
||||
@ -56,10 +67,7 @@ export default class RestClient implements Client {
|
||||
|
||||
fetchMindmap(id: number): Mindmap {
|
||||
// Load mindmap ...
|
||||
const persistence = new LocalStorageManager(
|
||||
`/c/restful/maps/{id}/document/xml`,
|
||||
true
|
||||
);
|
||||
const persistence = new LocalStorageManager(`/c/restful/maps/{id}/document/xml`, true);
|
||||
const mindmap = persistence.load(String(id));
|
||||
return mindmap;
|
||||
}
|
||||
@ -90,7 +98,7 @@ export default class RestClient implements Client {
|
||||
message: message,
|
||||
collaborations: permissions,
|
||||
},
|
||||
{ headers: { 'Content-Type': 'application/json' } }
|
||||
{ headers: { 'Content-Type': 'application/json' } },
|
||||
)
|
||||
.then(() => {
|
||||
// All was ok, let's sent to success page ...;
|
||||
@ -107,7 +115,7 @@ export default class RestClient implements Client {
|
||||
fetchMapPermissions(id: number): Promise<Permission[]> {
|
||||
const handler = (
|
||||
success: (labels: Permission[]) => void,
|
||||
reject: (error: ErrorInfo) => void
|
||||
reject: (error: ErrorInfo) => void,
|
||||
) => {
|
||||
this.axios
|
||||
.get(`${this.baseUrl}/c/restful/maps/${id}/collabs`, {
|
||||
@ -213,10 +221,11 @@ export default class RestClient implements Client {
|
||||
const handler = (success: (mapId: number) => void, reject: (error: ErrorInfo) => void) => {
|
||||
this.axios
|
||||
.post(
|
||||
`${this.baseUrl}/c/restful/maps?title=${encodeURIComponent(model.title)}&description=${model.description ? model.description : ''
|
||||
`${this.baseUrl}/c/restful/maps?title=${encodeURIComponent(model.title)}&description=${
|
||||
model.description ? model.description : ''
|
||||
}`,
|
||||
model.content,
|
||||
{ headers: { 'Content-Type': 'application/xml' } }
|
||||
{ headers: { 'Content-Type': 'application/xml' } },
|
||||
)
|
||||
.then((response) => {
|
||||
const mapId = response.headers.resourceid;
|
||||
@ -233,7 +242,7 @@ export default class RestClient implements Client {
|
||||
fetchAccountInfo(): Promise<AccountInfo> {
|
||||
const handler = (
|
||||
success: (account: AccountInfo) => void,
|
||||
reject: (error: ErrorInfo) => void
|
||||
reject: (error: ErrorInfo) => void,
|
||||
) => {
|
||||
this.axios
|
||||
.get(`${this.baseUrl}/c/restful/account`, {
|
||||
@ -312,7 +321,7 @@ export default class RestClient implements Client {
|
||||
fetchHistory(id: number): Promise<ChangeHistory[]> {
|
||||
const handler = (
|
||||
success: (historyList: ChangeHistory[]) => void,
|
||||
reject: (error: ErrorInfo) => void
|
||||
reject: (error: ErrorInfo) => void,
|
||||
) => {
|
||||
this.axios
|
||||
.get(`${this.baseUrl}/c/restful/maps/${id}/history/`, {
|
||||
@ -345,8 +354,9 @@ export default class RestClient implements Client {
|
||||
})
|
||||
.then(() => {
|
||||
return this.axios.put(
|
||||
`${this.baseUrl}/c/restful/maps/${id}/description`, basicInfo.description || ' ',
|
||||
{ headers: { 'Content-Type': 'text/plain' } }
|
||||
`${this.baseUrl}/c/restful/maps/${id}/description`,
|
||||
basicInfo.description || ' ',
|
||||
{ headers: { 'Content-Type': 'text/plain' } },
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
@ -366,10 +376,11 @@ export default class RestClient implements Client {
|
||||
const handler = (success: (mapId: number) => void, reject: (error: ErrorInfo) => void) => {
|
||||
this.axios
|
||||
.post(
|
||||
`${this.baseUrl}/c/restful/maps?title=${model.title}&description=${model.description ? model.description : ''
|
||||
`${this.baseUrl}/c/restful/maps?title=${model.title}&description=${
|
||||
model.description ? model.description : ''
|
||||
}`,
|
||||
null,
|
||||
{ headers: { 'Content-Type': 'application/json' } }
|
||||
{ headers: { 'Content-Type': 'application/json' } },
|
||||
)
|
||||
.then((response) => {
|
||||
const mapId = response.headers.resourceid;
|
||||
@ -386,7 +397,7 @@ export default class RestClient implements Client {
|
||||
fetchAllMaps(): Promise<MapInfo[]> {
|
||||
const handler = (
|
||||
success: (mapsInfo: MapInfo[]) => void,
|
||||
reject: (error: ErrorInfo) => void
|
||||
reject: (error: ErrorInfo) => void,
|
||||
) => {
|
||||
this.axios
|
||||
.get(`${this.baseUrl}/c/restful/maps/`, {
|
||||
@ -458,9 +469,13 @@ export default class RestClient implements Client {
|
||||
resetPassword(email: string): Promise<void> {
|
||||
const handler = (success: () => void, reject: (error: ErrorInfo) => void) => {
|
||||
this.axios
|
||||
.put(`${this.baseUrl}/service/users/resetPassword?email=${encodeURIComponent(email)}`, null, {
|
||||
.put(
|
||||
`${this.baseUrl}/service/users/resetPassword?email=${encodeURIComponent(email)}`,
|
||||
null,
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
},
|
||||
)
|
||||
.then(() => {
|
||||
// All was ok, let's sent to success page ...;
|
||||
success();
|
||||
@ -512,10 +527,7 @@ export default class RestClient implements Client {
|
||||
}
|
||||
|
||||
fetchLabels(): Promise<Label[]> {
|
||||
const handler = (
|
||||
success: (labels: Label[]) => void,
|
||||
reject: (error: ErrorInfo) => void
|
||||
) => {
|
||||
const handler = (success: (labels: Label[]) => void, reject: (error: ErrorInfo) => void) => {
|
||||
this.axios
|
||||
.get(`${this.baseUrl}/c/restful/labels/`, {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@ -544,9 +556,13 @@ export default class RestClient implements Client {
|
||||
createLabel(title: string, color: string): Promise<number> {
|
||||
const handler = (success: (labelId: number) => void, reject: (error: ErrorInfo) => void) => {
|
||||
this.axios
|
||||
.post(`${this.baseUrl}/c/restful/labels`, JSON.stringify({ title, color, iconName: 'smile' }), {
|
||||
.post(
|
||||
`${this.baseUrl}/c/restful/labels`,
|
||||
JSON.stringify({ title, color, iconName: 'smile' }),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
},
|
||||
)
|
||||
.then((response) => {
|
||||
success(response.headers.resourceid);
|
||||
})
|
||||
@ -625,9 +641,10 @@ export default class RestClient implements Client {
|
||||
});
|
||||
} else {
|
||||
persistence = new LocalStorageManager(
|
||||
`/c/restful/maps/{id}/${global.historyId ? `${global.historyId}/` : ''}document/xml${editorMode === 'showcase' ? '-pub' : ''
|
||||
`/c/restful/maps/{id}/${global.historyId ? `${global.historyId}/` : ''}document/xml${
|
||||
editorMode === 'showcase' ? '-pub' : ''
|
||||
}`,
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
persistence.addErrorHandler((err) => this.onPersistenceManagerError(err));
|
||||
|
@ -4,7 +4,6 @@ import AppConfig from '../../classes/app-config';
|
||||
|
||||
class EditorOptionsBuilder {
|
||||
static build(locale: string, mode: EditorRenderMode, hotkeys: boolean): EditorOptions {
|
||||
|
||||
let options: EditorOptions = {
|
||||
enableKeyboardEvents: hotkeys,
|
||||
locale: locale,
|
||||
@ -13,23 +12,24 @@ class EditorOptionsBuilder {
|
||||
|
||||
if (!AppConfig.isDevelopEnv()) {
|
||||
options = {
|
||||
zoom: (global.userOptions?.zoom != undefined
|
||||
zoom:
|
||||
global.userOptions?.zoom != undefined
|
||||
? Number.parseFloat(global?.userOptions?.zoom as string)
|
||||
: 0.8),
|
||||
: 0.8,
|
||||
locked: global.mindmapLocked,
|
||||
lockedMsg: global.mindmapLockedMsg,
|
||||
mapTitle: global.mapTitle,
|
||||
...options
|
||||
}
|
||||
...options,
|
||||
};
|
||||
} else {
|
||||
// Running in a development mode.
|
||||
console.log('Running editor in development mode');
|
||||
options = {
|
||||
zoom: 0.8,
|
||||
locked: false,
|
||||
mapTitle: "Develop Mindnap",
|
||||
...options
|
||||
}
|
||||
mapTitle: 'Develop Mindnap',
|
||||
...options,
|
||||
};
|
||||
}
|
||||
return options;
|
||||
}
|
||||
@ -37,7 +37,9 @@ class EditorOptionsBuilder {
|
||||
static loadMapId(): number {
|
||||
const result = !AppConfig.isDevelopEnv() ? global.mapId : 11;
|
||||
if (result === undefined) {
|
||||
throw Error(`Could not resolve mapId. Map Id: global.mapId: ${result} , global.mapTitle: ${global.mapTitle}, global.lockSession: ${global.lockSession}`);
|
||||
throw Error(
|
||||
`Could not resolve mapId. Map Id: global.mapId: ${result} , global.mapTitle: ${global.mapTitle}, global.lockSession: ${global.lockSession}`,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ export const StyledNav = styled.nav`
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
|
||||
.header-area-content-span {
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 3;
|
||||
@ -55,7 +54,6 @@ export const StyledNav = styled.nav`
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
export const StyledDiv = styled.nav`
|
||||
|
@ -16,5 +16,5 @@ export const useStyles = makeStyles(() =>
|
||||
label: {
|
||||
margin: '5px 0px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -11,5 +11,5 @@ export const useStyles = makeStyles(() =>
|
||||
textDesc: {
|
||||
width: '150px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -6,5 +6,5 @@ export const useStyles = makeStyles(() =>
|
||||
paper: {
|
||||
maxWidth: '420px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -8,5 +8,5 @@ export const useStyles = makeStyles(() =>
|
||||
padding: '15px 15px',
|
||||
marging: '0px 10px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -22,5 +22,5 @@ export const useStyles = makeStyles(() =>
|
||||
width: '850px',
|
||||
minWidth: '850px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -38,7 +38,7 @@ export const useStyles = makeStyles((theme: Theme) =>
|
||||
overflow: 'hidden',
|
||||
textAlign: 'right',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis'
|
||||
textOverflow: 'ellipsis',
|
||||
},
|
||||
visuallyHidden: {
|
||||
border: 0,
|
||||
@ -59,7 +59,7 @@ export const useStyles = makeStyles((theme: Theme) =>
|
||||
},
|
||||
toolbarActions: {
|
||||
flexGrow: 1,
|
||||
paddingLeft: '23px;'
|
||||
paddingLeft: '23px;',
|
||||
},
|
||||
toolbarListActions: {
|
||||
flexGrow: 1,
|
||||
@ -107,5 +107,5 @@ export const useStyles = makeStyles((theme: Theme) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -62,5 +62,5 @@ export const useStyles = makeStyles((theme: Theme) =>
|
||||
flexGrow: 1,
|
||||
padding: '24px 0px',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
@ -6,7 +6,6 @@ import { useSelector } from 'react-redux';
|
||||
import AppConfig from '../classes/app-config';
|
||||
import { RootState } from './rootReducer';
|
||||
|
||||
|
||||
export interface ClientStatus {
|
||||
state: 'healthy' | 'session-expired';
|
||||
msg?: string;
|
||||
@ -58,7 +57,11 @@ export const fetchMapById = (id: number): MapLoadResult => {
|
||||
// Seach for object...
|
||||
map = data?.find((m) => m.id == id);
|
||||
if (!map && !errorMsg) {
|
||||
errorMsg = { msg: `Map with id ${id} could not be found. Please, reflesh the page. Map: ${JSON.stringify(data)}` }
|
||||
errorMsg = {
|
||||
msg: `Map with id ${id} could not be found. Please, reflesh the page. Map: ${JSON.stringify(
|
||||
data,
|
||||
)}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
return { isLoading: isLoading, error: errorMsg, map: map };
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { RootState } from "./rootReducer";
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { RootState } from './rootReducer';
|
||||
|
||||
export interface EditorState {
|
||||
hotkeysEnabled: boolean;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { adaptV4Theme, createTheme } from '@mui/material/styles';
|
||||
|
||||
const theme = createTheme(adaptV4Theme({
|
||||
const theme = createTheme(
|
||||
adaptV4Theme({
|
||||
overrides: {
|
||||
MuiCssBaseline: {
|
||||
'@global': {
|
||||
@ -39,7 +40,7 @@ const theme = createTheme(adaptV4Theme({
|
||||
whiteSpace: 'nowrap',
|
||||
textTransform: 'none',
|
||||
borderRadius: '9px',
|
||||
padding: '6px 20px 6px 20px'
|
||||
padding: '6px 20px 6px 20px',
|
||||
},
|
||||
containedPrimary: {
|
||||
color: 'white',
|
||||
@ -74,6 +75,7 @@ const theme = createTheme(adaptV4Theme({
|
||||
contrastText: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
export { theme };
|
||||
|
Loading…
Reference in New Issue
Block a user