diff --git a/packages/editor/src/classes/menu/Menu.ts b/packages/editor/src/classes/menu/Menu.ts index 0cd63062..21f1a556 100644 --- a/packages/editor/src/classes/menu/Menu.ts +++ b/packages/editor/src/classes/menu/Menu.ts @@ -38,150 +38,17 @@ class Menu extends IMenu { const widgetsBaseUrl = `${baseUrl}css/widget`; // Create panels ... + const designerModel = designer.getModel(); - const fontFamilyModel = { - getValue() { - const nodes = designerModel.filterSelectedTopics(); - let result = null; - for (let i = 0; i < nodes.length; i++) { - const fontFamily = nodes[i].getFontFamily(); - if (result != null && result !== fontFamily) { - result = null; - break; - } - result = fontFamily; - } - return result; - }, - setValue(value: string) { - designer.changeFontFamily(value); - }, - }; - this._toolbarElems.push(new FontFamilyPanel('fontFamily', fontFamilyModel)); - Menu._registerTooltip('fontFamily', $msg('FONT_FAMILY')); - - const fontSizeModel = { - getValue(): number { - const nodes = designerModel.filterSelectedTopics(); - - let result = null; - for (let i = 0; i < nodes.length; i++) { - const fontSize = nodes[i].getFontSize(); - if (result != null && result !== fontSize) { - result = null; - break; - } - result = fontSize; - } - return result; - }, - setValue(value: number) { - designer.changeFontSize(value); - }, - }; - this._toolbarElems.push(new FontSizePanel('fontSize', fontSizeModel)); - Menu._registerTooltip('fontSize', $msg('FONT_SIZE')); - - const topicShapeModel = { - getValue() { - const nodes = designerModel.filterSelectedTopics(); - let result = null; - for (let i = 0; i < nodes.length; i++) { - const shapeType = nodes[i].getShapeType(); - if (result != null && result !== shapeType) { - result = null; - break; - } - result = shapeType; - } - return result; - }, - setValue(value: string) { - designer.changeTopicShape(value); - }, - }; - this._toolbarElems.push(new TopicShapePanel('topicShape', topicShapeModel)); - Menu._registerTooltip('topicShape', $msg('TOPIC_SHAPE')); - - // Create icon panel dialog ... - const topicIconModel = { - getValue() { - return null; - }, - setValue(value: string) { - designer.addIconType(value); - }, - }; - this._toolbarElems.push(new IconPanel('topicIcon', topicIconModel)); - Menu._registerTooltip('topicIcon', $msg('TOPIC_ICON')); - - const topicColorModel = { - getValue() { - const nodes = designerModel.filterSelectedTopics(); - let result = null; - for (let i = 0; i < nodes.length; i++) { - const color = nodes[i].getBackgroundColor(); - if (result != null && result !== color) { - result = null; - break; - } - result = color; - } - return result; - }, - setValue(hex: string) { - designer.changeBackgroundColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('topicColor', topicColorModel, widgetsBaseUrl)); - Menu._registerTooltip('topicColor', $msg('TOPIC_COLOR')); - - const borderColorModel = { - getValue() { - const nodes = designerModel.filterSelectedTopics(); - let result = null; - for (let i = 0; i < nodes.length; i++) { - const color = nodes[i].getBorderColor(); - if (result != null && result !== color) { - result = null; - break; - } - result = color; - } - return result; - }, - setValue(hex: string) { - designer.changeBorderColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('topicBorder', borderColorModel, widgetsBaseUrl)); - Menu._registerTooltip('topicBorder', $msg('TOPIC_BORDER_COLOR')); - - const fontColorModel = { - getValue() { - let result = null; - const nodes = designerModel.filterSelectedTopics(); - for (let i = 0; i < nodes.length; i++) { - const color = nodes[i].getFontColor(); - if (result != null && result !== color) { - result = null; - break; - } - result = color; - } - return result; - }, - setValue(hex) { - designer.changeFontColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('fontColor', fontColorModel, baseUrl)); - Menu._registerTooltip('fontColor', $msg('FONT_COLOR')); - - Menu._registerTooltip('export', $msg('EXPORT')); - - Menu._registerTooltip('print', $msg('PRINT')); + // Common actions .... + const backTolist = $('#backToList'); + backTolist.bind('click', (event) => { + event.stopPropagation(); + window.location.href = '/c/maps/'; + return false; + }); + Menu._registerTooltip('backToList', $msg('BACK_TO_MAP_LIST')); this._addButton('zoom-plus', false, false, () => { designer.zoomIn(); @@ -198,98 +65,246 @@ class Menu extends IMenu { }); Menu._registerTooltip('position', $msg('CENTER_POSITION')); - const undoButton = this._addButton('undoEdition', false, false, () => { - designer.undo(); - }); - if (undoButton) { - undoButton.disable(); - } - Menu._registerTooltip('undoEdition', $msg('UNDO'), 'meta+Z'); - - const redoButton = this._addButton('redoEdition', false, false, () => { - designer.redo(); - }); - if (redoButton) { - redoButton.disable(); - } - Menu._registerTooltip('redoEdition', $msg('REDO'), 'meta+shift+Z'); - - if (redoButton && undoButton) { - designer.addEvent('modelUpdate', (event) => { - if (event.undoSteps > 0) { - undoButton.enable(); - } else { - undoButton.disable(); - } - if (event.redoSteps > 0) { - redoButton.enable(); - } else { - redoButton.disable(); - } - }); - } - - this._addButton('addTopic', true, false, () => { - designer.createSiblingForSelectedNode(); - }); - Menu._registerTooltip('addTopic', $msg('ADD_TOPIC'), 'Enter'); - - this._addButton('deleteTopic', true, true, () => { - designer.deleteSelectedEntities(); - }); - Menu._registerTooltip('deleteTopic', $msg('TOPIC_DELETE'), 'Delete'); - - this._addButton('topicLink', true, false, () => { - designer.addLink(); - }); - Menu._registerTooltip('topicLink', $msg('TOPIC_LINK')); - - this._addButton('topicRelation', true, false, (event) => { - designer.showRelPivot(event); - }); - Menu._registerTooltip('topicRelation', $msg('TOPIC_RELATIONSHIP')); - - this._addButton('topicNote', true, false, () => { - designer.addNote(); - }); - Menu._registerTooltip('topicNote', $msg('TOPIC_NOTE')); - - this._addButton('fontBold', true, false, () => { - designer.changeFontWeight(); - }); - Menu._registerTooltip('fontBold', $msg('FONT_BOLD'), 'meta+B'); - - this._addButton('fontItalic', true, false, () => { - designer.changeFontStyle(); - }); - Menu._registerTooltip('fontItalic', $msg('FONT_ITALIC'), 'meta+I'); - - if (saveElem) { - this._addButton('save', false, false, - () => { - this.save(saveElem, designer, true); - }); - Menu._registerTooltip('save', $msg('SAVE'), 'meta+S'); - - if (!readOnly) { - window.addEventListener('beforeunload', () => { - if (this.isSaveRequired()) { - this.save(saveElem, designer, false); + // Edition actions ... + if (!readOnly) { + const fontFamilyModel = { + getValue() { + const nodes = designerModel.filterSelectedTopics(); + let result = null; + for (let i = 0; i < nodes.length; i++) { + const fontFamily = nodes[i].getFontFamily(); + if (result != null && result !== fontFamily) { + result = null; + break; + } + result = fontFamily; } - this.unlockMap(designer); - }); + return result; + }, - // Autosave on a fixed period of time ... - setInterval( + setValue(value: string) { + designer.changeFontFamily(value); + }, + }; + this._toolbarElems.push(new FontFamilyPanel('fontFamily', fontFamilyModel)); + Menu._registerTooltip('fontFamily', $msg('FONT_FAMILY')); + + const fontSizeModel = { + getValue(): number { + const nodes = designerModel.filterSelectedTopics(); + + let result = null; + for (let i = 0; i < nodes.length; i++) { + const fontSize = nodes[i].getFontSize(); + if (result != null && result !== fontSize) { + result = null; + break; + } + result = fontSize; + } + return result; + }, + setValue(value: number) { + designer.changeFontSize(value); + }, + }; + this._toolbarElems.push(new FontSizePanel('fontSize', fontSizeModel)); + Menu._registerTooltip('fontSize', $msg('FONT_SIZE')); + + const topicShapeModel = { + getValue() { + const nodes = designerModel.filterSelectedTopics(); + let result = null; + for (let i = 0; i < nodes.length; i++) { + const shapeType = nodes[i].getShapeType(); + if (result != null && result !== shapeType) { + result = null; + break; + } + result = shapeType; + } + return result; + }, + setValue(value: string) { + designer.changeTopicShape(value); + }, + }; + this._toolbarElems.push(new TopicShapePanel('topicShape', topicShapeModel)); + Menu._registerTooltip('topicShape', $msg('TOPIC_SHAPE')); + + // Create icon panel dialog ... + const topicIconModel = { + getValue() { + return null; + }, + setValue(value: string) { + designer.addIconType(value); + }, + }; + this._toolbarElems.push(new IconPanel('topicIcon', topicIconModel)); + Menu._registerTooltip('topicIcon', $msg('TOPIC_ICON')); + + const topicColorModel = { + getValue() { + const nodes = designerModel.filterSelectedTopics(); + let result = null; + for (let i = 0; i < nodes.length; i++) { + const color = nodes[i].getBackgroundColor(); + if (result != null && result !== color) { + result = null; + break; + } + result = color; + } + return result; + }, + setValue(hex: string) { + designer.changeBackgroundColor(hex); + }, + }; + this._toolbarElems.push(new ColorPalettePanel('topicColor', topicColorModel, widgetsBaseUrl)); + Menu._registerTooltip('topicColor', $msg('TOPIC_COLOR')); + + const borderColorModel = { + getValue() { + const nodes = designerModel.filterSelectedTopics(); + let result = null; + for (let i = 0; i < nodes.length; i++) { + const color = nodes[i].getBorderColor(); + if (result != null && result !== color) { + result = null; + break; + } + result = color; + } + return result; + }, + setValue(hex: string) { + designer.changeBorderColor(hex); + }, + }; + this._toolbarElems.push(new ColorPalettePanel('topicBorder', borderColorModel, widgetsBaseUrl)); + Menu._registerTooltip('topicBorder', $msg('TOPIC_BORDER_COLOR')); + + const fontColorModel = { + getValue() { + let result = null; + const nodes = designerModel.filterSelectedTopics(); + for (let i = 0; i < nodes.length; i++) { + const color = nodes[i].getFontColor(); + if (result != null && result !== color) { + result = null; + break; + } + result = color; + } + return result; + }, + setValue(hex) { + designer.changeFontColor(hex); + }, + }; + this._toolbarElems.push(new ColorPalettePanel('fontColor', fontColorModel, baseUrl)); + Menu._registerTooltip('fontColor', $msg('FONT_COLOR')); + + const undoButton = this._addButton('undoEdition', false, false, () => { + designer.undo(); + }); + if (undoButton) { + undoButton.disable(); + } + Menu._registerTooltip('undoEdition', $msg('UNDO'), 'meta+Z'); + + const redoButton = this._addButton('redoEdition', false, false, () => { + designer.redo(); + }); + if (redoButton) { + redoButton.disable(); + } + Menu._registerTooltip('redoEdition', $msg('REDO'), 'meta+shift+Z'); + + if (redoButton && undoButton) { + designer.addEvent('modelUpdate', (event) => { + if (event.undoSteps > 0) { + undoButton.enable(); + } else { + undoButton.disable(); + } + if (event.redoSteps > 0) { + redoButton.enable(); + } else { + redoButton.disable(); + } + }); + } + + this._addButton('addTopic', true, false, () => { + designer.createSiblingForSelectedNode(); + }); + Menu._registerTooltip('addTopic', $msg('ADD_TOPIC'), 'Enter'); + + this._addButton('deleteTopic', true, true, () => { + designer.deleteSelectedEntities(); + }); + Menu._registerTooltip('deleteTopic', $msg('TOPIC_DELETE'), 'Delete'); + + this._addButton('topicLink', true, false, () => { + designer.addLink(); + }); + Menu._registerTooltip('topicLink', $msg('TOPIC_LINK')); + + this._addButton('topicRelation', true, false, (event) => { + designer.showRelPivot(event); + }); + Menu._registerTooltip('topicRelation', $msg('TOPIC_RELATIONSHIP')); + + this._addButton('topicNote', true, false, () => { + designer.addNote(); + }); + Menu._registerTooltip('topicNote', $msg('TOPIC_NOTE')); + + this._addButton('fontBold', true, false, () => { + designer.changeFontWeight(); + }); + Menu._registerTooltip('fontBold', $msg('FONT_BOLD'), 'meta+B'); + + this._addButton('fontItalic', true, false, () => { + designer.changeFontStyle(); + }); + Menu._registerTooltip('fontItalic', $msg('FONT_ITALIC'), 'meta+I'); + + + if (saveElem) { + this._addButton('save', false, false, () => { + this.save(saveElem, designer, true); + }); + Menu._registerTooltip('save', $msg('SAVE'), 'meta+S'); + + if (!readOnly) { + window.addEventListener('beforeunload', () => { if (this.isSaveRequired()) { this.save(saveElem, designer, false); } - }, 10000, - ); + this.unlockMap(designer); + }); + + // Autosave on a fixed period of time ... + setInterval( + () => { + if (this.isSaveRequired()) { + this.save(saveElem, designer, false); + } + }, 10000, + ); + } } } + Menu._registerTooltip('export', $msg('EXPORT')); + + Menu._registerTooltip('print', $msg('PRINT')); + const shareElem = $('#shareIt'); if (shareElem.length !== 0) { Menu._registerTooltip('shareIt', $msg('COLLABORATE')); @@ -316,14 +331,6 @@ class Menu extends IMenu { Menu._registerTooltip('keyboardShortcuts', $msg('KEYBOARD_SHOTCUTS')); } - const backTolist = $('#backToList'); - backTolist.bind('click', (event) => { - event.stopPropagation(); - window.location.href = '/c/maps/'; - return false; - }); - Menu._registerTooltip('backToList', $msg('BACK_TO_MAP_LIST')); - // Account dialog ... const accountSettings = $('#account'); if (accountSettings.length !== 0) { diff --git a/packages/editor/src/components/toolbar/index.tsx b/packages/editor/src/components/toolbar/index.tsx index 9a08ea4f..22803507 100644 --- a/packages/editor/src/components/toolbar/index.tsx +++ b/packages/editor/src/components/toolbar/index.tsx @@ -55,63 +55,67 @@ export default function Toolbar({ )} -
- - - - - - -
-
- - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - -
-
+ {(editorMode === 'edition-editor' || editorMode === 'edition-owner' || editorMode === 'showcase') && ( + <> +
+ + + + + + +
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + +
+
+ + )} ${this.saveMapXml}`); } discardChanges(mapId: string) { - localStorage.removeItem(`${mapId}-xml`); + if (!this.readOnly) { + localStorage.removeItem(`${mapId}-xml`); + } } loadMapDom(mapId: string) { - let xml = localStorage.getItem(`${mapId}-xml`); + let xml; + if (!this.readOnly) { + xml = localStorage.getItem(`${mapId}-xml`); + } if (xml == null || this.forceLoad) { $.ajax({ url: this.documentUrl.replace('{id}', mapId), diff --git a/packages/mindplot/src/components/Relationship.ts b/packages/mindplot/src/components/Relationship.ts index 8b6cd4d7..624b67d6 100644 --- a/packages/mindplot/src/components/Relationship.ts +++ b/packages/mindplot/src/components/Relationship.ts @@ -20,8 +20,10 @@ import { Arrow, Point, ElementClass } from '@wisemapping/web2d'; import ConnectionLine from './ConnectionLine'; import ControlPoint from './ControlPoint'; import RelationshipModel from './model/RelationshipModel'; +import PositionType from './PositionType'; import Topic from './Topic'; import Shape from './util/Shape'; +import Workspace from './Workspace'; class Relationship extends ConnectionLine { private _focusShape: ElementClass; @@ -187,7 +189,7 @@ class Relationship extends ConnectionLine { this._startArrow.setVisibility(this.isVisible() && this._showStartArrow); } - addToWorkspace(workspace) { + addToWorkspace(workspace: Workspace): void { workspace.append(this._focusShape); workspace.append(this._controlPointsController); @@ -207,11 +209,11 @@ class Relationship extends ConnectionLine { this.redraw(); } - _initializeControlPointController(): void { + private _initializeControlPointController(): void { this.setOnFocus(true); } - removeFromWorkspace(workspace) { + removeFromWorkspace(workspace: Workspace): void { workspace.removeChild(this._focusShape); workspace.removeChild(this._controlPointsController); if (!workspace.isReadOnly) { @@ -243,7 +245,7 @@ class Relationship extends ConnectionLine { } } - private _refreshShape() { + private _refreshShape(): void { const sPos = this._line2d.getFrom(); const tPos = this._line2d.getTo(); const ctrlPoints = this._line2d.getControlPoints(); @@ -279,19 +281,31 @@ class Relationship extends ConnectionLine { setVisibility(value: boolean, fade = 0) { super.setVisibility(value, fade); - if (this._showEndArrow) this._endArrow.setVisibility(this._showEndArrow); + + // If visibility change, remove the on focus. + this.setOnFocus(false); + + if (this._showEndArrow) { + this._endArrow.setVisibility(this._showEndArrow); + } this._startArrow.setVisibility(this._showStartArrow && value, fade); } - setOpacity(opacity: number) { + setOpacity(opacity: number): void { super.setOpacity(opacity); - if (this._showEndArrow) this._endArrow.setOpacity(opacity); - if (this._showStartArrow) this._startArrow.setOpacity(opacity); + if (this._showEndArrow) { + this._endArrow.setOpacity(opacity); + } + if (this._showStartArrow) { + this._startArrow.setOpacity(opacity); + } } setShowEndArrow(visible: boolean) { this._showEndArrow = visible; - if (this._isInWorkspace) this.redraw(); + if (this._isInWorkspace) { + this.redraw(); + } } setShowStartArrow(visible: boolean) { @@ -315,25 +329,25 @@ class Relationship extends ConnectionLine { if (this._endArrow) this._endArrow.setFrom(x, y); } - setSrcControlPoint(control) { + setSrcControlPoint(control: PositionType): void { this._line2d.setSrcControlPoint(control); this._startArrow.setControlPoint(control); } - setDestControlPoint(control) { + setDestControlPoint(control: PositionType) { this._line2d.setDestControlPoint(control); if (this._showEndArrow) this._endArrow.setControlPoint(control); } - getControlPoints() { + getControlPoints(): PositionType { return this._line2d.getControlPoints(); } - isSrcControlPointCustom() { + isSrcControlPointCustom(): boolean { return this._line2d.isSrcControlPointCustom(); } - isDestControlPointCustom() { + isDestControlPointCustom(): boolean { return this._line2d.isDestControlPointCustom(); } @@ -345,7 +359,7 @@ class Relationship extends ConnectionLine { this._line2d.setIsDestControlPointCustom(isCustom); } - getId() { + getId(): number { return this._model.getId(); } diff --git a/packages/mindplot/src/components/Topic.ts b/packages/mindplot/src/components/Topic.ts index f646ce1d..7e56bd3e 100644 --- a/packages/mindplot/src/components/Topic.ts +++ b/packages/mindplot/src/components/Topic.ts @@ -375,17 +375,14 @@ abstract class Topic extends NodeGraph { this.adjustShapes(); } - /** */ addRelationship(relationship: Relationship) { this._relationships.push(relationship); } - /** */ deleteRelationship(relationship: Rect) { this._relationships = this._relationships.filter((r) => r !== relationship); } - /** */ getRelationships(): Relationship[] { return this._relationships; } @@ -1093,6 +1090,7 @@ abstract class Topic extends NodeGraph { const connector = targetTopic.getShrinkConnector(); if ($defined(connector)) { connector.setVisibility(false); + targetTopic.isCollapsed(false); } } } diff --git a/packages/mindplot/src/components/commands/AddRelationshipCommand.ts b/packages/mindplot/src/components/commands/AddRelationshipCommand.ts index f16df219..b32273d7 100644 --- a/packages/mindplot/src/components/commands/AddRelationshipCommand.ts +++ b/packages/mindplot/src/components/commands/AddRelationshipCommand.ts @@ -17,6 +17,7 @@ */ import { $assert } from '@wisemapping/core-js'; import Command from '../Command'; +import CommandContext from '../CommandContext'; import RelationshipModel from '../model/RelationshipModel'; class AddRelationshipCommand extends Command { @@ -25,27 +26,20 @@ class AddRelationshipCommand extends Command { /** * @classdesc This command class handles do/undo of adding a relationship to a topic. */ - constructor(model:RelationshipModel) { + constructor(model: RelationshipModel) { $assert(model, 'Relationship model can not be null'); super(); this._model = model; } - /** - * Overrides abstract parent method - */ - execute(commandContext) { + execute(commandContext: CommandContext) { const relationship = commandContext.addRelationship(this._model); relationship.setOnFocus(true); } - /** - * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} - */ - undoExecute(commandContext) { - const rel = commandContext.findRelationships(this._model.getId()); + undoExecute(commandContext: CommandContext) { + const rel = commandContext.findRelationships([this._model.getId()]); commandContext.deleteRelationship(rel[0]); } } diff --git a/packages/mindplot/src/components/commands/AddTopicCommand.ts b/packages/mindplot/src/components/commands/AddTopicCommand.ts index ce273552..2208a495 100644 --- a/packages/mindplot/src/components/commands/AddTopicCommand.ts +++ b/packages/mindplot/src/components/commands/AddTopicCommand.ts @@ -38,9 +38,6 @@ class AddTopicCommand extends Command { this._parentsIds = parentTopicsId; } - /** - * Overrides abstract parent method - */ execute(commandContext: CommandContext) { const me = this; this._models.forEach((model, index) => { @@ -68,10 +65,6 @@ class AddTopicCommand extends Command { }); } - /** - * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} - */ undoExecute(commandContext: CommandContext) { // Delete disconnected the nodes. Create a copy of the topics ... const clonedModel = []; diff --git a/packages/mindplot/src/components/commands/ChangeFeatureToTopicCommand.ts b/packages/mindplot/src/components/commands/ChangeFeatureToTopicCommand.ts index 07253e15..573a2923 100644 --- a/packages/mindplot/src/components/commands/ChangeFeatureToTopicCommand.ts +++ b/packages/mindplot/src/components/commands/ChangeFeatureToTopicCommand.ts @@ -37,9 +37,6 @@ class ChangeFeatureToTopicCommand extends Command { this._attributes = attributes; } - /** - * Overrides abstract parent method - */ execute(commandContext: CommandContext) { const topic = commandContext.findTopics([this._topicId])[0]; const feature = topic.findFeatureById(this._featureId); @@ -49,10 +46,6 @@ class ChangeFeatureToTopicCommand extends Command { this._attributes = oldAttributes; } - /** - * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} - */ undoExecute(commandContext: CommandContext) { this.execute(commandContext); } diff --git a/packages/mindplot/src/components/commands/DragTopicCommand.ts b/packages/mindplot/src/components/commands/DragTopicCommand.ts index d550a378..d8cf4d38 100644 --- a/packages/mindplot/src/components/commands/DragTopicCommand.ts +++ b/packages/mindplot/src/components/commands/DragTopicCommand.ts @@ -47,9 +47,6 @@ class DragTopicCommand extends Command { this._order = order; } - /** - * Overrides abstract parent method - */ execute(commandContext: CommandContext): void { const topic = commandContext.findTopics([this._topicsId])[0]; topic.setVisibility(false); diff --git a/packages/mindplot/src/components/commands/MoveControlPointCommand.ts b/packages/mindplot/src/components/commands/MoveControlPointCommand.ts index 85f9868a..2856c6e5 100644 --- a/packages/mindplot/src/components/commands/MoveControlPointCommand.ts +++ b/packages/mindplot/src/components/commands/MoveControlPointCommand.ts @@ -19,19 +19,20 @@ import { $assert, $defined } from '@wisemapping/core-js'; import { Line } from '@wisemapping/web2d'; import Command from '../Command'; import ControlPoint from '../ControlPoint'; +import PositionType from '../PositionType'; class MoveControlPointCommand extends Command { private _ctrlPointControler: ControlPoint; private _line: Line; - private _controlPoint: any; + private _controlPoint: Line; - private _oldControlPoint: any; + private _oldControlPoint: Line; - private _originalEndPoint: any; + private _originalEndPoint: PositionType; - private _wasCustom: any; + private _wasCustom: boolean; private _endPoint: any; @@ -68,9 +69,6 @@ class MoveControlPointCommand extends Command { this._point = point; } - /** - * Overrides abstract parent method - */ execute() { const model = this._line.getModel(); switch (this._point) { @@ -97,10 +95,6 @@ class MoveControlPointCommand extends Command { this._line.getLine().updateLine(this._point); } - /** - * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} - */ undoExecute() { const line = this._line; const model = line.getModel(); diff --git a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts index b7551016..fbd98485 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts @@ -106,7 +106,7 @@ class XMLSerializerTango implements XMLMindmapSerializer { } } - if (topic.areChildrenShrunken() && topic.getType() !== 'CentralTopic') { + if ((topic.areChildrenShrunken() && topic.getChildren().length > 0) && topic.getType() !== 'CentralTopic') { parentTopic.setAttribute('shrink', 'true'); } diff --git a/packages/webapp/src/classes/client/rest-client/index.ts b/packages/webapp/src/classes/client/rest-client/index.ts index eb7f7fa3..a0ace132 100644 --- a/packages/webapp/src/classes/client/rest-client/index.ts +++ b/packages/webapp/src/classes/client/rest-client/index.ts @@ -615,8 +615,14 @@ export default class RestClient implements Client { if (this.persistenceManager) { return this.persistenceManager; } + let persistence: PersistenceManager; if (editorMode === 'edition-owner' || editorMode === 'edition-editor') { + + if (!global.lockSession) { + throw new Error(`Session could not be found: global.lockSession: '${global.lockSession}' - global.lockTimestamp: '${global.lockTimestamp}' - ${global.mindmapLocked} - ${global.mindmapLockedMsg}`) + } + persistence = new RESTPersistenceManager({ documentUrl: '/c/restful/maps/{id}/document', revertUrl: '/c/restful/maps/{id}/history/latest', diff --git a/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts b/packages/webapp/src/components/editor-page/EditorOptionsBuilder.ts similarity index 96% rename from packages/webapp/src/components/editor-page/EditorOptionsBuider.ts rename to packages/webapp/src/components/editor-page/EditorOptionsBuilder.ts index 7342bb0e..cf6a2ff7 100644 --- a/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts +++ b/packages/webapp/src/components/editor-page/EditorOptionsBuilder.ts @@ -2,7 +2,7 @@ import { EditorOptions } from '@wisemapping/editor'; import { EditorRenderMode } from '@wisemapping/mindplot'; import AppConfig from '../../classes/app-config'; -export default class EditorOptionsBulder { +export default class EditorOptionsBuilder { static build(locale: string, mode: EditorRenderMode, hotkeys: boolean): EditorOptions { let options: EditorOptions = { diff --git a/packages/webapp/src/components/editor-page/index.tsx b/packages/webapp/src/components/editor-page/index.tsx index 5e521c86..2651230f 100644 --- a/packages/webapp/src/components/editor-page/index.tsx +++ b/packages/webapp/src/components/editor-page/index.tsx @@ -10,7 +10,7 @@ import { hotkeysEnabled } from '../../redux/editorSlice'; import ReactGA from 'react-ga'; import Client from '../../classes/client'; import { activeInstance, fetchAccount, fetchMapById } from '../../redux/clientSlice'; -import EditorOptionsBulder from './EditorOptionsBuider'; +import EditorOptionsBuilder from './EditorOptionsBuilder'; export type EditorPropsType = { isTryMode: boolean; @@ -23,6 +23,7 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => { const client: Client = useSelector(activeInstance); useEffect(() => { + document.title = `${global.mapTitle ? global.mapTitle : 'unknown'} | WiseMapping `; ReactGA.pageview(window.location.pathname + window.location.search); }, []); @@ -36,16 +37,16 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => { const fetchResult = fetchMapById(mapId); if (!fetchResult.isLoading) { if (fetchResult.error) { - throw new Error(`User coild not be loaded: ${JSON.stringify(fetchResult.error)}`); + throw new Error(`Map information could not be loaded: ${JSON.stringify(fetchResult)}`); } - result = fetchResult.map.role === 'owner' ? 'edition-owner' : 'edition-editor'; + result = `edition-${fetchResult?.map?.role}`; } } return result; } // What is the role ? - const mapId = EditorOptionsBulder.loadMapId(); + const mapId = EditorOptionsBuilder.loadMapId(); const mode = findEditorMode(isTryMode, mapId); // Account settings can be null and editor cannot be initilized multiple times. This creates problems @@ -55,7 +56,7 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => { let options, persistence: PersistenceManager; if (loadCompleted) { - options = EditorOptionsBulder.build(userLocale.code, mode, hotkey); + options = EditorOptionsBuilder.build(userLocale.code, mode, hotkey); persistence = client.buildPersistenceManager(mode); } diff --git a/packages/webapp/src/redux/clientSlice.ts b/packages/webapp/src/redux/clientSlice.ts index ef7329df..b15a765b 100644 --- a/packages/webapp/src/redux/clientSlice.ts +++ b/packages/webapp/src/redux/clientSlice.ts @@ -47,9 +47,21 @@ export const fetchMapById = (id: number): MapLoadResult => { return client.fetchAllMaps(); }); - const result = data?.find((m) => m.id == id); - const map = result || null; - return { isLoading: isLoading, error: error, map: map }; + // If the map can not be loaded, create an error object. + let map: MapInfo; + let errorMsg: ErrorInfo = error; + if (!isLoading) { + // Sanitize error structure ... + if (errorMsg) { + errorMsg = Object.keys(error).length !== 0 ? error : null; + } + // Seach for object... + map = data?.find((m) => m.id == id); + if (map === null && !errorMsg) { + errorMsg = { msg: `Map with id ${id} could not be found. Please, reflesh the page` } + } + } + return { isLoading: isLoading, error: errorMsg, map: map }; }; export const fetchAccount = (): AccountInfo | undefined => {