Merge branch 'develop' of https://bitbucket.org/wisemapping/wisemapping-frontend into feature/exports-mindmap

This commit is contained in:
Ezequiel-Vega 2022-02-24 10:51:36 -03:00
commit a7df3b2db6
10 changed files with 130 additions and 106 deletions

View File

@ -16,6 +16,8 @@ body {
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
overflow: hidden; overflow: hidden;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
} }
div#mindplot { div#mindplot {

View File

@ -1,8 +1,4 @@
/* Overwrite some styles */ /* Overwrite some styles */
body {
position: inherit;
}
div#footer { div#footer {
width: 100%; width: 100%;
padding: 20px 30px; padding: 20px 30px;

View File

@ -69,7 +69,7 @@ class Designer extends Events {
private _workspace: Workspace; private _workspace: Workspace;
private _eventBussDispatcher: EventBusDispatcher; _eventBussDispatcher: EventBusDispatcher;
private _dragManager: DragManager; private _dragManager: DragManager;
@ -208,15 +208,12 @@ class Designer extends Events {
}); });
dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => { dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => {
dragTopic.updateFreeLayout(event);
if (!dragTopic.isFreeLayoutOn()) {
// The node is being drag. Is the connection still valid ? // The node is being drag. Is the connection still valid ?
dragConnector.checkConnection(dragTopic); dragConnector.checkConnection(dragTopic);
if (!dragTopic.isVisible() && dragTopic.isConnected()) { if (!dragTopic.isVisible() && dragTopic.isConnected()) {
dragTopic.setVisibility(true); dragTopic.setVisibility(true);
} }
}
}); });
dragManager.addEvent('enddragging', (event: MouseEvent, dragTopic: DragTopic) => { dragManager.addEvent('enddragging', (event: MouseEvent, dragTopic: DragTopic) => {

View File

@ -31,7 +31,6 @@ export function buildDesigner(options: DesignerOptions): Designer {
// Register load events ... // Register load events ...
designer = new Designer(options, divContainer); designer = new Designer(options, divContainer);
designer.addEvent('loadSuccess', () => { designer.addEvent('loadSuccess', () => {
globalThis.mindmapLoadReady = true;
console.log('Map loadded successfully'); console.log('Map loadded successfully');
}); });

View File

@ -16,18 +16,27 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d';
import DesignerModel from './DesignerModel';
import DragTopic from './DragTopic';
import SizeType from './SizeType';
import Topic from './Topic';
import Workspace from './Workspace';
class DragConnector { class DragConnector {
constructor(designerModel, workspace) { private _designerModel: DesignerModel;
private _workspace: Workspace;
constructor(designerModel: DesignerModel, workspace: Workspace) {
$assert(designerModel, 'designerModel can not be null'); $assert(designerModel, 'designerModel can not be null');
$assert(workspace, 'workspace can not be null'); $assert(workspace, 'workspace can not be null');
// this._layoutManager = layoutManager;
this._designerModel = designerModel; this._designerModel = designerModel;
this._workspace = workspace; this._workspace = workspace;
} }
checkConnection(dragTopic) { checkConnection(dragTopic: DragTopic): void {
// Must be disconnected from their current connection ?. // Must be disconnected from their current connection ?.
const candidates = this._searchConnectionCandidates(dragTopic); const candidates = this._searchConnectionCandidates(dragTopic);
const currentConnection = dragTopic.getConnectedToTopic(); const currentConnection = dragTopic.getConnectedToTopic();
@ -42,12 +51,13 @@ class DragConnector {
} }
} }
_searchConnectionCandidates(dragTopic) { private _searchConnectionCandidates(dragTopic: DragTopic): Topic[] {
let topics = this._designerModel.getTopics(); let topics = this._designerModel.getTopics();
const draggedNode = dragTopic.getDraggedTopic(); const draggedNode = dragTopic.getDraggedTopic();
// Drag node connects to the border ... // Drag node connects to the border ...
const dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack... // const dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
const dragTopicWidth = 0;
const xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth; const xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
const sPos = { x: dragTopic.getPosition().x - xMouseGap, y: dragTopic.getPosition().y }; const sPos = { x: dragTopic.getPosition().x - xMouseGap, y: dragTopic.getPosition().y };
@ -56,7 +66,7 @@ class DragConnector {
// - Exclude dragTopic pivot // - Exclude dragTopic pivot
// - Nodes that are collapsed // - Nodes that are collapsed
// - It's not part of the branch dragged itself // - It's not part of the branch dragged itself
topics = topics.filter((topic) => { topics = topics.filter((topic: Topic) => {
let result = draggedNode !== topic; let result = draggedNode !== topic;
result = result && topic !== draggedNode; result = result && topic !== draggedNode;
result = result && !topic.areChildrenShrunken() && !topic.isCollapsed(); result = result && !topic.areChildrenShrunken() && !topic.isCollapsed();
@ -67,7 +77,7 @@ class DragConnector {
// Filter all the nodes that are outside the vertical boundary: // Filter all the nodes that are outside the vertical boundary:
// * The node is to out of the x scope // * The node is to out of the x scope
// * The x distance greater the vertical tolerated distance // * The x distance greater the vertical tolerated distance
topics = topics.filter((topic) => { topics = topics.filter((topic: Topic) => {
const tpos = topic.getPosition(); const tpos = topic.getPosition();
// Center topic has different alignment than the rest of the nodes. // Center topic has different alignment than the rest of the nodes.
// That's why i need to divide it by two... // That's why i need to divide it by two...
@ -95,17 +105,17 @@ class DragConnector {
return topics; return topics;
} }
_proximityWeight(isAligned, target, sPos, currentConnection) { private _proximityWeight(isAligned: boolean, target: Topic, sPos: Point, currentConnection: Topic): number {
const tPos = target.getPosition(); const tPos = target.getPosition();
return (isAligned ? 0 : 200) + Math.abs(tPos.x - sPos.x) return (isAligned ? 0 : 200) + Math.abs(tPos.x - sPos.x)
+ Math.abs(tPos.y - sPos.y) + (currentConnection === target ? 0 : 100); + Math.abs(tPos.y - sPos.y) + (currentConnection === target ? 0 : 100);
} }
_isVerticallyAligned(targetSize, targetPosition, sourcePosition) { private _isVerticallyAligned(targetSize: SizeType, targetPosition: Point, sourcePosition: Point): boolean {
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2; return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
} }
static MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
} }
DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
export default DragConnector; export default DragConnector;

View File

@ -19,9 +19,28 @@ import { $assert, $defined } from '@wisemapping/core-js';
import { Point, CurvedLine, Rect } from '@wisemapping/web2d'; import { Point, CurvedLine, Rect } from '@wisemapping/web2d';
import DragTopicConfig from './DragTopicConfig'; import DragTopicConfig from './DragTopicConfig';
import SizeType from './SizeType';
import Topic from './Topic';
import Shape from './util/Shape'; import Shape from './util/Shape';
import Workspace from './Workspace';
class DragPivot { class DragPivot {
private _position: Point;
private _isVisible: boolean;
private _targetTopic: Topic;
private _connectRect: Rect;
private _dragPivot: Rect;
private _curvedLine: CurvedLine;
private _straightLine: CurvedLine;
private _size: SizeType;
constructor() { constructor() {
this._position = new Point(); this._position = new Point();
this._size = DragTopicConfig.PIVOT_SIZE; this._size = DragTopicConfig.PIVOT_SIZE;
@ -34,15 +53,15 @@ class DragPivot {
this._isVisible = false; this._isVisible = false;
} }
isVisible() { isVisible(): boolean {
return this._isVisible; return this._isVisible;
} }
getTargetTopic() { getTargetTopic(): Topic {
return this._targetTopic; return this._targetTopic;
} }
_buildStraightLine() { private _buildStraightLine(): CurvedLine {
const line = new CurvedLine(); const line = new CurvedLine();
line.setStyle(CurvedLine.SIMPLE_LINE); line.setStyle(CurvedLine.SIMPLE_LINE);
line.setStroke(1, 'solid', '#CC0033'); line.setStroke(1, 'solid', '#CC0033');
@ -51,7 +70,7 @@ class DragPivot {
return line; return line;
} }
_buildCurvedLine() { private _buildCurvedLine(): CurvedLine {
const line = new CurvedLine(); const line = new CurvedLine();
line.setStyle(CurvedLine.SIMPLE_LINE); line.setStyle(CurvedLine.SIMPLE_LINE);
line.setStroke(1, 'solid', '#CC0033'); line.setStroke(1, 'solid', '#CC0033');
@ -60,7 +79,7 @@ class DragPivot {
return line; return line;
} }
_redrawLine() { private _redrawLine(): void {
// Update line position. // Update line position.
$assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null'); $assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null');
@ -81,8 +100,8 @@ class DragPivot {
line.setFrom(pivotPoint.x, pivotPoint.y); line.setFrom(pivotPoint.x, pivotPoint.y);
// Update rect position // Update rect position
const cx = position.x - parseInt(size.width, 10) / 2; const cx = position.x - size.width / 2;
const cy = position.y - parseInt(size.height, 10) / 2; const cy = position.y - size.height / 2;
pivotRect.setPosition(cx, cy); pivotRect.setPosition(cx, cy);
// Make line visible only when the position has been already changed. // Make line visible only when the position has been already changed.
@ -91,16 +110,16 @@ class DragPivot {
line.setTo(targetPoint.x, targetPoint.y); line.setTo(targetPoint.x, targetPoint.y);
} }
setPosition(point) { setPosition(point: Point): void {
this._position = point; this._position = point;
this._redrawLine(); this._redrawLine();
} }
getPosition() { getPosition(): Point {
return this._position; return this._position;
} }
_buildRect() { private _buildRect(): Rect {
const size = this._size; const size = this._size;
const rectAttributes = { const rectAttributes = {
fillColor: '#CC0033', fillColor: '#CC0033',
@ -114,16 +133,16 @@ class DragPivot {
return rect; return rect;
} }
_getPivotRect() { private _getPivotRect(): Rect {
return this._dragPivot; return this._dragPivot;
} }
getSize() { getSize(): SizeType {
const elem2d = this._getPivotRect(); const elem2d = this._getPivotRect();
return elem2d.getSize(); return elem2d.getSize();
} }
setVisibility(value) { setVisibility(value: boolean) {
if (this.isVisible() !== value) { if (this.isVisible() !== value) {
const pivotRect = this._getPivotRect(); const pivotRect = this._getPivotRect();
pivotRect.setVisibility(value); pivotRect.setVisibility(value);
@ -140,7 +159,7 @@ class DragPivot {
} }
// If the node is connected, validate that there is a line connecting both... // If the node is connected, validate that there is a line connecting both...
_getConnectionLine() { _getConnectionLine(): CurvedLine {
let result = null; let result = null;
const parentTopic = this._targetTopic; const parentTopic = this._targetTopic;
if (parentTopic) { if (parentTopic) {
@ -153,7 +172,7 @@ class DragPivot {
return result; return result;
} }
addToWorkspace(workspace) { addToWorkspace(workspace: Workspace) {
const pivotRect = this._getPivotRect(); const pivotRect = this._getPivotRect();
workspace.append(pivotRect); workspace.append(pivotRect);
@ -179,7 +198,7 @@ class DragPivot {
connectRect.moveToBack(); connectRect.moveToBack();
} }
removeFromWorkspace(workspace) { removeFromWorkspace(workspace: Workspace) {
const shape = this._getPivotRect(); const shape = this._getPivotRect();
workspace.removeChild(shape); workspace.removeChild(shape);
@ -195,9 +214,7 @@ class DragPivot {
} }
} }
connectTo(targetTopic, position) { connectTo(targetTopic: Topic, position: Point) {
$assert(!this._outgoingLine, 'Could not connect an already connected node');
$assert(targetTopic !== this, 'Circular connection are not allowed');
$assert(position, 'position can not be null'); $assert(position, 'position can not be null');
$assert(targetTopic, 'parent can not be null'); $assert(targetTopic, 'parent can not be null');
@ -227,7 +244,7 @@ class DragPivot {
this._redrawLine(); this._redrawLine();
} }
disconnect(workspace) { disconnect(workspace: Workspace): void {
$assert(workspace, 'workspace can not be null.'); $assert(workspace, 'workspace can not be null.');
$assert(this._targetTopic, 'There are not connected topic.'); $assert(this._targetTopic, 'There are not connected topic.');

View File

@ -16,13 +16,24 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d'; import { Point, ElementClass } from '@wisemapping/web2d';
import ActionDispatcher from './ActionDispatcher'; import ActionDispatcher from './ActionDispatcher';
import DragPivot from './DragPivot'; import DragPivot from './DragPivot';
import LayoutManager from './layout/LayoutManager';
import NodeGraph from './NodeGraph';
import Topic from './Topic';
import Workspace from './Workspace';
class DragTopic { class DragTopic {
constructor(dragShape, draggedNode, layoutManger) { private _elem2d: ElementClass;
private _order: number | null;
private _draggedNode: NodeGraph;
private _layoutManager: LayoutManager;
private _position: any;
private _isInWorkspace: boolean;
static _dragPivot: any;
constructor(dragShape: ElementClass, draggedNode: NodeGraph, layoutManger: LayoutManager) {
$assert(dragShape, 'Rect can not be null.'); $assert(dragShape, 'Rect can not be null.');
$assert(draggedNode, 'draggedNode can not be null.'); $assert(draggedNode, 'draggedNode can not be null.');
$assert(layoutManger, 'layoutManger can not be null.'); $assert(layoutManger, 'layoutManger can not be null.');
@ -33,26 +44,15 @@ class DragTopic {
this._layoutManager = layoutManger; this._layoutManager = layoutManger;
this._position = new Point(); this._position = new Point();
this._isInWorkspace = false; this._isInWorkspace = false;
this._isFreeLayoutEnabled = false;
} }
setOrder(order) { setOrder(order: number) {
this._order = order; this._order = order;
} }
setPosition(x, y) { setPosition(x: number, y: number) {
// Update drag shadow position .... // Update drag shadow position ....
let position = { x, y }; let position = { x, y };
if (this.isFreeLayoutOn() && this.isConnected()) {
const { _layoutManager } = this;
const par = this.getConnectedToTopic();
position = _layoutManager.predict(
par.getId(),
this._draggedNode.getId(),
position,
true,
).position;
}
this._position.setValue(position.x, position.y); this._position.setValue(position.x, position.y);
// Elements are positioned in the center. // Elements are positioned in the center.
@ -80,45 +80,35 @@ class DragTopic {
} }
} }
updateFreeLayout(event) { setVisibility(value: boolean) {
const isMac = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
const isFreeEnabled = (event.metaKey && isMac) || (event.ctrlKey && !isMac);
if (this.isFreeLayoutOn() !== isFreeEnabled) {
const dragPivot = this._getDragPivot();
dragPivot.setVisibility(!isFreeEnabled);
this._isFreeLayoutEnabled = isFreeEnabled;
}
}
setVisibility(value) {
const dragPivot = this._getDragPivot(); const dragPivot = this._getDragPivot();
dragPivot.setVisibility(value); dragPivot.setVisibility(value);
} }
isVisible() { isVisible(): boolean {
const dragPivot = this._getDragPivot(); const dragPivot = this._getDragPivot();
return dragPivot.isVisible(); return dragPivot.isVisible();
} }
getInnerShape() { getInnerShape(): ElementClass {
return this._elem2d; return this._elem2d;
} }
disconnect(workspace) { disconnect(workspace: Workspace) {
// Clear connection line ... // Clear connection line ...
const dragPivot = this._getDragPivot(); const dragPivot = this._getDragPivot();
dragPivot.disconnect(workspace); dragPivot.disconnect(workspace);
} }
connectTo(parent) { connectTo(parent: Topic) {
$assert(parent, 'Parent connection node can not be null.'); $assert(parent, 'Parent connection node can not be null.');
// Where it should be connected ? // Where it should be connected ?
// @todo: This is a hack for the access of the editor. // @todo: This is a hack for the access of the editor.
// It's required to review why this is needed forcing the declaration of a global variable. // It's required to review why this is needed forcing the declaration of a global variable.
const predict = designer._eventBussDispatcher._layoutManager.predict(
const predict = global.designer._eventBussDispatcher._layoutManager.predict(
parent.getId(), parent.getId(),
this._draggedNode.getId(), this._draggedNode.getId(),
this.getPosition(), this.getPosition(),
@ -133,11 +123,11 @@ class DragTopic {
this.setOrder(predict.order); this.setOrder(predict.order);
} }
getDraggedTopic() { getDraggedTopic(): Topic {
return this._draggedNode; return this._draggedNode as Topic;
} }
removeFromWorkspace(workspace) { removeFromWorkspace(workspace: Workspace) {
if (this._isInWorkspace) { if (this._isInWorkspace) {
// Remove drag shadow. // Remove drag shadow.
workspace.removeChild(this._elem2d); workspace.removeChild(this._elem2d);
@ -151,11 +141,11 @@ class DragTopic {
} }
} }
isInWorkspace() { isInWorkspace(): boolean {
return this._isInWorkspace; return this._isInWorkspace;
} }
addToWorkspace(workspace) { addToWorkspace(workspace: Workspace) {
if (!this._isInWorkspace) { if (!this._isInWorkspace) {
workspace.append(this._elem2d); workspace.append(this._elem2d);
const dragPivot = this._getDragPivot(); const dragPivot = this._getDragPivot();
@ -164,19 +154,19 @@ class DragTopic {
} }
} }
_getDragPivot() { _getDragPivot(): DragPivot {
return DragTopic.__getDragPivot(); return DragTopic.__getDragPivot();
} }
getPosition() { getPosition(): Point {
return this._position; return this._position;
} }
isDragTopic() { isDragTopic(): boolean {
return true; return true;
} }
applyChanges(workspace) { applyChanges(workspace: Workspace) {
$assert(workspace, 'workspace can not be null'); $assert(workspace, 'workspace can not be null');
const actionDispatcher = ActionDispatcher.getInstance(); const actionDispatcher = ActionDispatcher.getInstance();
@ -201,33 +191,33 @@ class DragTopic {
} }
} }
getConnectedToTopic() { getConnectedToTopic(): Topic {
const dragPivot = this._getDragPivot(); const dragPivot = this._getDragPivot();
return dragPivot.getTargetTopic(); return dragPivot.getTargetTopic();
} }
isConnected() { isConnected(): boolean {
return this.getConnectedToTopic() != null; return this.getConnectedToTopic() != null;
} }
isFreeLayoutOn() { isFreeLayoutOn(): false {
return false; return false;
} }
}
DragTopic.init = function init(workspace) { static init(workspace: Workspace) {
$assert(workspace, 'workspace can not be null'); $assert(workspace, 'workspace can not be null');
const pivot = DragTopic.__getDragPivot(); const pivot = DragTopic.__getDragPivot();
workspace.append(pivot); workspace.append(pivot);
}; };
DragTopic.__getDragPivot = function __getDragPivot() { static __getDragPivot() {
let result = DragTopic._dragPivot; let result = DragTopic._dragPivot;
if (!$defined(result)) { if (!$defined(result)) {
result = new DragPivot(); result = new DragPivot();
DragTopic._dragPivot = result; DragTopic._dragPivot = result;
} }
return result; return result;
}; };
}
export default DragTopic; export default DragTopic;

View File

@ -64,6 +64,11 @@ class MainTopic extends Topic {
const text = this.getText(); const text = this.getText();
textShape.setText(text); textShape.setText(text);
textShape.setOpacity(0.5); textShape.setOpacity(0.5);
// Copy text position of the topic element ...
const textPosition = this.getTextShape().getPosition();
textShape.setPosition(textPosition.x, textPosition.y);
group.append(textShape); group.append(textShape);
} }
return group; return group;

View File

@ -159,9 +159,9 @@ abstract class NodeGraph {
workspace.removeChild(this); workspace.removeChild(this);
} }
/** */
createDragNode(layoutManager: LayoutManager) { createDragNode(layoutManager: LayoutManager) {
const dragShape = this._buildDragShape(); const dragShape = this._buildDragShape();
return new DragTopic(dragShape, this, layoutManager); return new DragTopic(dragShape, this, layoutManager);
} }

View File

@ -17,8 +17,16 @@ export class Locale {
export default abstract class AppI18n { export default abstract class AppI18n {
public static getUserLocale(): Locale { public static getUserLocale(): Locale {
// @Todo Hack: Try page must not account info. Add this to avoid 403 errors.
const isTryPage = window.location.href.endsWith('/try');
let result: Locale;
if (!isTryPage) {
const account = fetchAccount(); const account = fetchAccount();
return account?.locale ? account.locale : this.getBrowserLocale(); result = account?.locale ? account.locale : this.getBrowserLocale();
} else {
result = this.getBrowserLocale();
}
return result;
} }
public static getBrowserLocale(): Locale { public static getBrowserLocale(): Locale {