From c6db14b99af8c25fb77915e07b537ce58ba1ed16 Mon Sep 17 00:00:00 2001 From: Paulo Veiga Date: Sat, 5 Mar 2022 16:10:03 +0000 Subject: [PATCH] Merged in feature/remove_actions (pull request #45) Remove actions in toobar when user is not owner. * Fix eslit errors --- .../editor/src/components/toolbar/index.tsx | 79 ++--- packages/editor/src/index.tsx | 1 - .../test/playground/map-render/js/editor.tsx | 2 +- packages/mindplot/src/@types/custom.d.ts | 4 +- .../mindplot/src/components/CommandContext.ts | 11 +- .../src/components/DesignerBuilder.ts | 2 +- .../src/components/DesignerOptionsBuilder.ts | 2 +- .../src/components/EditorRenderMode.ts | 2 +- packages/mindplot/src/components/IconGroup.ts | 12 +- packages/mindplot/src/components/LinkIcon.ts | 5 +- packages/mindplot/src/components/NodeGraph.ts | 2 +- packages/mindplot/src/components/NoteIcon.ts | 4 +- .../components/StandaloneActionDispatcher.ts | 3 +- packages/mindplot/src/components/Topic.ts | 10 +- .../commands/GenericFunctionCommand.ts | 8 +- .../layout/ChildrenSorterStrategy.ts | 4 +- .../src/components/layout/LayoutManager.ts | 1 - .../src/components/model/FeatureModel.ts | 6 +- .../src/components/model/INodeModel.ts | 10 +- .../src/components/model/RelationshipModel.ts | 6 +- .../mindplot/src/components/widget/Menu.ts | 301 ++++++++---------- packages/webapp/src/app.tsx | 2 +- .../src/classes/client/rest-client/index.ts | 10 +- .../editor-page/EditorOptionsBuider.ts | 23 +- .../src/components/editor-page/index.tsx | 38 ++- 25 files changed, 270 insertions(+), 278 deletions(-) diff --git a/packages/editor/src/components/toolbar/index.tsx b/packages/editor/src/components/toolbar/index.tsx index 2363e3ea..df27da4f 100644 --- a/packages/editor/src/components/toolbar/index.tsx +++ b/packages/editor/src/components/toolbar/index.tsx @@ -48,7 +48,7 @@ export default function Toolbar({
- {editorMode === 'edition' && ( + {(editorMode === 'edition-editor' || editorMode === 'edition-owner') && (
@@ -112,44 +112,51 @@ export default function Toolbar({
- {editorMode === 'edition' && ( - - onAction('export')} - > - - - onAction('publish')} - > - - - onAction('history')} - > - - - onAction('print')} - > - - - - - + + onAction('export')} + > + + + onAction('print')} + > + + + {editorMode === 'edition-owner' && ( + <> + onAction('history')} + > + + + onAction('publish')} + > + + + + )} + {(editorMode === 'edition-owner' || editorMode === 'edition-editor') && ( + + + + )} + {editorMode === 'edition-owner' && ( onAction('share')}> {intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' })} - - )} + + )} + ); diff --git a/packages/editor/src/index.tsx b/packages/editor/src/index.tsx index ab54a3a7..79b0fd87 100644 --- a/packages/editor/src/index.tsx +++ b/packages/editor/src/index.tsx @@ -13,7 +13,6 @@ import { } from '@wisemapping/mindplot'; import './global-styled.css'; import I18nMsg from './classes/i18n-msg'; -import Messages from '@wisemapping/mindplot/src/components/Messages'; declare global { // used in mindplot diff --git a/packages/editor/test/playground/map-render/js/editor.tsx b/packages/editor/test/playground/map-render/js/editor.tsx index ab06149b..bc09334b 100644 --- a/packages/editor/test/playground/map-render/js/editor.tsx +++ b/packages/editor/test/playground/map-render/js/editor.tsx @@ -36,7 +36,7 @@ const options: EditorOptions = { zoom: 0.8, locked: false, mapTitle: "Develop Mindnap", - mode: 'edition', + mode: 'edition-owner', locale: 'en', enableKeyboardEvents: true }; diff --git a/packages/mindplot/src/@types/custom.d.ts b/packages/mindplot/src/@types/custom.d.ts index e2013b53..60bd434c 100644 --- a/packages/mindplot/src/@types/custom.d.ts +++ b/packages/mindplot/src/@types/custom.d.ts @@ -1,4 +1,4 @@ -declare module "*.svg" { +declare module '*.svg' { const content: any; export default content; -} \ No newline at end of file +} diff --git a/packages/mindplot/src/components/CommandContext.ts b/packages/mindplot/src/components/CommandContext.ts index 3d489b78..054f491e 100644 --- a/packages/mindplot/src/components/CommandContext.ts +++ b/packages/mindplot/src/components/CommandContext.ts @@ -41,20 +41,15 @@ class CommandContext { } findTopics(topicIds: number[]): Topic[] { - $assert($defined(topicIds), 'topicsIds can not be null'); const topicsIds = Array.isArray(topicIds) ? topicIds : [topicIds]; const designerTopics = this._designer.getModel().getTopics(); const result = designerTopics.filter((topic) => topicsIds.includes(topic.getId())); if (result.length !== topicsIds.length) { const ids = designerTopics.map((topic) => topic.getId()); - $assert( - result.length === topicsIds.length, - `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; } diff --git a/packages/mindplot/src/components/DesignerBuilder.ts b/packages/mindplot/src/components/DesignerBuilder.ts index ae720d51..a657b24a 100644 --- a/packages/mindplot/src/components/DesignerBuilder.ts +++ b/packages/mindplot/src/components/DesignerBuilder.ts @@ -37,7 +37,7 @@ export function buildDesigner(options: DesignerOptions): Designer { PersistenceManager.init(persistence); // Register toolbar event ... - if (options.mode === 'edition' || options.mode === 'showcase') { + if (options.mode === 'edition-owner' || options.mode === 'edition-editor' || options.mode === 'showcase') { const menu = new Menu(designer, 'toolbar'); // If a node has focus, focus can be move to another node using the keys. diff --git a/packages/mindplot/src/components/DesignerOptionsBuilder.ts b/packages/mindplot/src/components/DesignerOptionsBuilder.ts index 877e7dec..02a1a2e1 100644 --- a/packages/mindplot/src/components/DesignerOptionsBuilder.ts +++ b/packages/mindplot/src/components/DesignerOptionsBuilder.ts @@ -46,7 +46,7 @@ class OptionsBuilder { } const defaultOptions: DesignerOptions = { - mode: 'edition', + mode: 'edition-owner', zoom: 0.85, saveOnLoad: true, containerSize, diff --git a/packages/mindplot/src/components/EditorRenderMode.ts b/packages/mindplot/src/components/EditorRenderMode.ts index 80cbd2c4..4986dae6 100644 --- a/packages/mindplot/src/components/EditorRenderMode.ts +++ b/packages/mindplot/src/components/EditorRenderMode.ts @@ -1,2 +1,2 @@ -type EditorRenderMode = 'viewonly' | 'edition' | 'showcase'; +type EditorRenderMode = 'viewonly' | 'edition-owner' | 'edition-editor' | 'showcase'; export default EditorRenderMode; diff --git a/packages/mindplot/src/components/IconGroup.ts b/packages/mindplot/src/components/IconGroup.ts index b4ac5691..3f0c506d 100644 --- a/packages/mindplot/src/components/IconGroup.ts +++ b/packages/mindplot/src/components/IconGroup.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// eslint-disable-next-line max-classes-per-file + import { $assert, $defined, @@ -23,12 +23,11 @@ import { import { Group, ElementClass, + Point, } from '@wisemapping/web2d'; import IconGroupRemoveTip from './IconGroupRemoveTip'; -import { Point } from '@wisemapping/web2d'; import Icon from './Icon'; import SizeType from './SizeType'; -import IconModel from './model/IconModel'; import FeatureModel from './model/FeatureModel'; const ORDER_BY_TYPE = new Map(); @@ -38,10 +37,15 @@ ORDER_BY_TYPE.set('link', 2); class IconGroup { private _icons: Icon[]; + private _group: any; + private _removeTip: IconGroupRemoveTip; + private _iconSize: SizeType; + private _topicId: number; + constructor(topicId: number, iconSize: number) { $assert($defined(topicId), 'topicId can not be null'); $assert($defined(iconSize), 'iconSize can not be null'); @@ -59,7 +63,6 @@ class IconGroup { this._removeTip = new IconGroupRemoveTip(this._group); this.seIconSize(iconSize, iconSize); this._registerListeners(); - } setPosition(x: number, y: number): void { @@ -189,7 +192,6 @@ class IconGroup { } static ICON_PADDING = 5; - } export default IconGroup; diff --git a/packages/mindplot/src/components/LinkIcon.ts b/packages/mindplot/src/components/LinkIcon.ts index f49df66b..c47bba87 100644 --- a/packages/mindplot/src/components/LinkIcon.ts +++ b/packages/mindplot/src/components/LinkIcon.ts @@ -26,8 +26,11 @@ import FeatureModel from './model/FeatureModel'; class LinkIcon extends Icon { private _linksModel: FeatureModel; + private _topic: Topic; + private _readOnly: boolean; + private _tip: LinkIconTooltip; constructor(topic: Topic, linkModel: LinkModel, readOnly: boolean) { @@ -73,8 +76,8 @@ class LinkIcon extends Icon { getModel(): FeatureModel { return this._linksModel; } - static IMAGE_URL = LinksImage; + static IMAGE_URL = LinksImage; } export default LinkIcon; diff --git a/packages/mindplot/src/components/NodeGraph.ts b/packages/mindplot/src/components/NodeGraph.ts index ed4bf609..d0a00db6 100644 --- a/packages/mindplot/src/components/NodeGraph.ts +++ b/packages/mindplot/src/components/NodeGraph.ts @@ -161,7 +161,7 @@ abstract class NodeGraph { createDragNode(layoutManager: LayoutManager) { const dragShape = this._buildDragShape(); - + return new DragTopic(dragShape, this, layoutManager); } diff --git a/packages/mindplot/src/components/NoteIcon.ts b/packages/mindplot/src/components/NoteIcon.ts index 363fd9ec..6d891fcc 100644 --- a/packages/mindplot/src/components/NoteIcon.ts +++ b/packages/mindplot/src/components/NoteIcon.ts @@ -27,8 +27,11 @@ import FeatureModel from './model/FeatureModel'; class NoteIcon extends Icon { private _linksModel: NoteModel; + private _topic: Topic; + private _readOnly: boolean; + private _tip: FloatingTip; constructor(topic: Topic, noteModel: NoteModel, readOnly: boolean) { @@ -87,7 +90,6 @@ class NoteIcon extends Icon { } static IMAGE_URL = NotesImage; - } export default NoteIcon; diff --git a/packages/mindplot/src/components/StandaloneActionDispatcher.ts b/packages/mindplot/src/components/StandaloneActionDispatcher.ts index 011f8d44..f38c9b77 100644 --- a/packages/mindplot/src/components/StandaloneActionDispatcher.ts +++ b/packages/mindplot/src/components/StandaloneActionDispatcher.ts @@ -110,8 +110,7 @@ class StandaloneActionDispatcher extends ActionDispatcher { this.execute(command); } - /** */ - changeTextToTopic(topicsIds: number[], text: string) { + changeTextToTopic(topicsIds: number[], text: string): void { $assert($defined(topicsIds), 'topicsIds can not be null'); const commandFunc = (topic: Topic, value: string) => { diff --git a/packages/mindplot/src/components/Topic.ts b/packages/mindplot/src/components/Topic.ts index 92b0080e..f646ce1d 100644 --- a/packages/mindplot/src/components/Topic.ts +++ b/packages/mindplot/src/components/Topic.ts @@ -707,11 +707,10 @@ abstract class Topic extends NodeGraph { // Do some fancy animation .... const elements = this._flatten2DElements(this); elements.forEach((elem) => { - elem.setVisibility(!value, 250) + elem.setVisibility(!value, 250); }); EventBus.instance.fireEvent('childShrinked', model); - } getShrinkConnector(): ShirinkConnector | undefined { @@ -893,7 +892,6 @@ abstract class Topic extends NodeGraph { this._relationships.forEach((r) => r.redraw()); } - /** */ setBranchVisibility(value: boolean): void { let current: Topic = this; let parent: Topic = this; @@ -904,7 +902,6 @@ abstract class Topic extends NodeGraph { current.setVisibility(value); } - /** */ setVisibility(value: boolean, fade = 0): void { this._setTopicVisibility(value, fade); @@ -961,8 +958,9 @@ abstract class Topic extends NodeGraph { relationship.setVisibility( value && (targetParent == null || !targetParent.areChildrenShrunken()) - && (sourceParent == null || !sourceParent.areChildrenShrunken()) - , fade); + && (sourceParent == null || !sourceParent.areChildrenShrunken()), + fade, + ); }); } diff --git a/packages/mindplot/src/components/commands/GenericFunctionCommand.ts b/packages/mindplot/src/components/commands/GenericFunctionCommand.ts index b7887967..ab198609 100644 --- a/packages/mindplot/src/components/commands/GenericFunctionCommand.ts +++ b/packages/mindplot/src/components/commands/GenericFunctionCommand.ts @@ -25,7 +25,7 @@ type CommandTypes = string | object | boolean | number; class GenericFunctionCommand extends Command { private _value: CommandTypes; - private _topicsId: number[]; + private _topicsIds: number[]; private _commandFunc: (topic: Topic, value: CommandTypes) => CommandTypes; @@ -39,7 +39,7 @@ class GenericFunctionCommand extends Command { super(); this._value = value; - this._topicsId = topicsIds; + this._topicsIds = topicsIds; this._commandFunc = commandFunc; this._oldValues = []; } @@ -49,7 +49,7 @@ class GenericFunctionCommand extends Command { */ execute(commandContext: CommandContext) { if (!this._applied) { - const topics = commandContext.findTopics(this._topicsId); + const topics = commandContext.findTopics(this._topicsIds); if (topics != null) { const me = this; @@ -66,7 +66,7 @@ class GenericFunctionCommand extends Command { undoExecute(commandContext: CommandContext): void { if (this._applied) { - const topics = commandContext.findTopics(this._topicsId); + const topics = commandContext.findTopics(this._topicsIds); topics.forEach(((topic: Topic, index: number) => { this._commandFunc(topic, this._oldValues[index]); diff --git a/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts b/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts index 34419adb..fbf2cb25 100644 --- a/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts +++ b/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts @@ -15,9 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import RootedTreeSet from "./RootedTreeSet"; +import RootedTreeSet from './RootedTreeSet'; import Node from './Node'; -import PositionType from "../PositionType"; +import PositionType from '../PositionType'; abstract class ChildrenSorterStrategy { abstract computeChildrenIdByHeights(treeSet: RootedTreeSet, node: Node); diff --git a/packages/mindplot/src/components/layout/LayoutManager.ts b/packages/mindplot/src/components/layout/LayoutManager.ts index 64c9a1b9..94c6964c 100644 --- a/packages/mindplot/src/components/layout/LayoutManager.ts +++ b/packages/mindplot/src/components/layout/LayoutManager.ts @@ -15,7 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import $ from 'jquery'; import { $assert, $defined } from '@wisemapping/core-js'; import Events from '../Events'; import RootedTreeSet from './RootedTreeSet'; diff --git a/packages/mindplot/src/components/model/FeatureModel.ts b/packages/mindplot/src/components/model/FeatureModel.ts index 0652d319..8fb14a55 100644 --- a/packages/mindplot/src/components/model/FeatureModel.ts +++ b/packages/mindplot/src/components/model/FeatureModel.ts @@ -19,7 +19,7 @@ import { $assert } from '@wisemapping/core-js'; import FeatureType from './FeatureType'; class FeatureModel { - static _next_id = 0; + static _nextId = 0; private _id: number; @@ -85,8 +85,8 @@ class FeatureModel { } static _nextUUID(): number { - const result = FeatureModel._next_id + 1; - FeatureModel._next_id = result; + const result = FeatureModel._nextId + 1; + FeatureModel._nextId = result; return result; } } diff --git a/packages/mindplot/src/components/model/INodeModel.ts b/packages/mindplot/src/components/model/INodeModel.ts index 9cc60bab..46bb9e3a 100644 --- a/packages/mindplot/src/components/model/INodeModel.ts +++ b/packages/mindplot/src/components/model/INodeModel.ts @@ -29,7 +29,7 @@ const parseJsObject = (str: string) => JSON.parse(str.replace(/(['"])?([a-z0-9A- abstract class INodeModel { static MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220; - private static _next_uuid = 0; + private static _nextUuid = 0; protected _mindmap: Mindmap; @@ -49,9 +49,9 @@ abstract class INodeModel { const newId = INodeModel._nextUUID(); this.putProperty('id', newId); } else { - if (id > INodeModel._next_uuid) { + if (id > INodeModel._nextUuid) { $assert(Number.isFinite(id)); - INodeModel._next_uuid = id; + INodeModel._nextUuid = id; } this.putProperty('id', id); } @@ -358,8 +358,8 @@ abstract class INodeModel { abstract removeChild(child: INodeModel); static _nextUUID(): number { - INodeModel._next_uuid += 1; - return INodeModel._next_uuid; + INodeModel._nextUuid += 1; + return INodeModel._nextUuid; } } diff --git a/packages/mindplot/src/components/model/RelationshipModel.ts b/packages/mindplot/src/components/model/RelationshipModel.ts index fa6d150c..ddf34d7d 100644 --- a/packages/mindplot/src/components/model/RelationshipModel.ts +++ b/packages/mindplot/src/components/model/RelationshipModel.ts @@ -20,7 +20,7 @@ import Point from '@wisemapping/web2d'; import ConnectionLine from '../ConnectionLine'; class RelationshipModel { - static _next_uuid = 0; + static _nextUuid = 0; private _id: number; @@ -133,8 +133,8 @@ class RelationshipModel { } static _nextUUID() { - RelationshipModel._next_uuid += 1; - return RelationshipModel._next_uuid; + RelationshipModel._nextUuid += 1; + return RelationshipModel._nextUuid; } } diff --git a/packages/mindplot/src/components/widget/Menu.ts b/packages/mindplot/src/components/widget/Menu.ts index 25ef72cb..f14efca9 100644 --- a/packages/mindplot/src/components/widget/Menu.ts +++ b/packages/mindplot/src/components/widget/Menu.ts @@ -39,170 +39,145 @@ class Menu extends IMenu { // Create panels ... const designerModel = designer.getModel(); - - const fontFamilyBtn = $('#fontFamily'); - if (fontFamilyBtn) { - 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; + 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; } - return result; - }, + result = fontFamily; + } + return result; + }, - setValue(value: string) { - designer.changeFontFamily(value); - }, - }; - this._toolbarElems.push(new FontFamilyPanel('fontFamily', fontFamilyModel)); - Menu._registerTooltip('fontFamily', $msg('FONT_FAMILY')); - } + setValue(value: string) { + designer.changeFontFamily(value); + }, + }; + this._toolbarElems.push(new FontFamilyPanel('fontFamily', fontFamilyModel)); + Menu._registerTooltip('fontFamily', $msg('FONT_FAMILY')); - const fontSizeBtn = $('#fontSize'); - if (fontSizeBtn) { - const fontSizeModel = { - getValue(): number { - const nodes = designerModel.filterSelectedTopics(); + 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; + let result = null; + for (let i = 0; i < nodes.length; i++) { + const fontSize = nodes[i].getFontSize(); + if (result != null && result !== fontSize) { + result = null; + break; } - return result; - }, - setValue(value: number) { - designer.changeFontSize(value); - }, - }; - this._toolbarElems.push(new FontSizePanel('fontSize', fontSizeModel)); - Menu._registerTooltip('fontSize', $msg('FONT_SIZE')); - } + result = fontSize; + } + return result; + }, + setValue(value: number) { + designer.changeFontSize(value); + }, + }; + this._toolbarElems.push(new FontSizePanel('fontSize', fontSizeModel)); + Menu._registerTooltip('fontSize', $msg('FONT_SIZE')); - const topicShapeBtn = $('#topicShape'); - if (topicShapeBtn) { - 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; + 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; } - return result; - }, - setValue(value: string) { - designer.changeTopicShape(value); - }, - }; - this._toolbarElems.push(new TopicShapePanel('topicShape', topicShapeModel)); - Menu._registerTooltip('topicShape', $msg('TOPIC_SHAPE')); - } + result = shapeType; + } + return result; + }, + setValue(value: string) { + designer.changeTopicShape(value); + }, + }; + this._toolbarElems.push(new TopicShapePanel('topicShape', topicShapeModel)); + Menu._registerTooltip('topicShape', $msg('TOPIC_SHAPE')); - const topicIconBtn = $('#topicIcon'); - if (topicIconBtn) { - // 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')); - } + // 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')); - // Topic color item ... - const topicColorBtn = $('#topicColor'); - if (topicColorBtn) { - 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; + 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; } - return result; - }, - setValue(hex: string) { - designer.changeBackgroundColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('topicColor', topicColorModel, widgetsBaseUrl)); - Menu._registerTooltip('topicColor', $msg('TOPIC_COLOR')); - } + result = color; + } + return result; + }, + setValue(hex: string) { + designer.changeBackgroundColor(hex); + }, + }; + this._toolbarElems.push(new ColorPalettePanel('topicColor', topicColorModel, widgetsBaseUrl)); + Menu._registerTooltip('topicColor', $msg('TOPIC_COLOR')); - // Border color item ... - const topicBorderBtn = $('#topicBorder'); - if (topicBorderBtn) { - 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; + 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; } - return result; - }, - setValue(hex: string) { - designer.changeBorderColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('topicBorder', borderColorModel, widgetsBaseUrl)); - Menu._registerTooltip('topicBorder', $msg('TOPIC_BORDER_COLOR')); - } + 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')); - // Font color item ... - const fontColorBtn = $('#fontColor'); - if (fontColorBtn) { - 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; + 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; } - return result; - }, - setValue(hex) { - designer.changeFontColor(hex); - }, - }; - this._toolbarElems.push(new ColorPalettePanel('fontColor', fontColorModel, baseUrl)); - Menu._registerTooltip('fontColor', $msg('FONT_COLOR')); - } + 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')); @@ -315,14 +290,6 @@ class Menu extends IMenu { } } - const discardElem = $('#discard'); - if (discardElem.length !== 0) { - this._addButton('discard', false, false, () => { - this.discardChanges(designer); - }); - Menu._registerTooltip('discard', $msg('DISCARD_CHANGES')); - } - const shareElem = $('#shareIt'); if (shareElem.length !== 0) { Menu._registerTooltip('shareIt', $msg('COLLABORATE')); @@ -350,14 +317,12 @@ class Menu extends IMenu { } const backTolist = $('#backToList'); - if (backTolist.length !== 0) { - backTolist.bind('click', (event) => { - event.stopPropagation(); - window.location.href = '/c/maps/'; - return false; - }); - Menu._registerTooltip('backToList', $msg('BACK_TO_MAP_LIST')); - } + 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'); @@ -367,9 +332,9 @@ class Menu extends IMenu { }); this._toolbarElems.push(new AccountSettingsPanel('account')); Menu._registerTooltip('account', `${global.accountEmail}`); - } - this._registerEvents(designer); + this._registerEvents(designer); + } } private _registerEvents(designer: Designer) { diff --git a/packages/webapp/src/app.tsx b/packages/webapp/src/app.tsx index 7733404e..f5b1ac02 100644 --- a/packages/webapp/src/app.tsx +++ b/packages/webapp/src/app.tsx @@ -81,7 +81,7 @@ const App = (): ReactElement => { component={withSessionExpirationHandling(MapsPage)} /> - + diff --git a/packages/webapp/src/classes/client/rest-client/index.ts b/packages/webapp/src/classes/client/rest-client/index.ts index 38273db6..eb7f7fa3 100644 --- a/packages/webapp/src/classes/client/rest-client/index.ts +++ b/packages/webapp/src/classes/client/rest-client/index.ts @@ -611,12 +611,12 @@ export default class RestClient implements Client { } } - buildPersistenceManager(editorMode: EditorRenderMode ): PersistenceManager { + buildPersistenceManager(editorMode: EditorRenderMode): PersistenceManager { if (this.persistenceManager) { return this.persistenceManager; } let persistence: PersistenceManager; - if (editorMode === 'edition') { + if (editorMode === 'edition-owner' || editorMode === 'edition-editor') { persistence = new RESTPersistenceManager({ documentUrl: '/c/restful/maps/{id}/document', revertUrl: '/c/restful/maps/{id}/history/latest', @@ -645,13 +645,15 @@ export default class RestClient implements Client { // eslint-disable-next-line @typescript-eslint/no-explicit-any private parseResponseOnError = (response: any): ErrorInfo => { - console.error("Backend error=>"); - console.error(response.data); + console.error(`Performing backend action error: ${JSON.stringify(response)}`); let result: ErrorInfo | undefined; if (response) { const status: number = response.status; const data = response.data; + console.error(`Status Code: ${status}`); + console.error(`Status Data: ${response.data}`); + console.error(`Status Message: ${response.message}`); switch (status) { case 401: diff --git a/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts b/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts index be3e0cea..894b7a6f 100644 --- a/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts +++ b/packages/webapp/src/components/editor-page/EditorOptionsBuider.ts @@ -1,25 +1,16 @@ import { EditorOptions } from '@wisemapping/editor'; +import { EditorRenderMode } from '@wisemapping/mindplot'; import AppConfig from '../../classes/app-config'; export default class EditorOptionsBulder { - static build(locale: string, hotkeys: boolean, isTryMode: boolean): { options: EditorOptions, mapId: number } { + static build(locale: string, mode: EditorRenderMode, hotkeys: boolean): EditorOptions { let options: EditorOptions = { enableKeyboardEvents: hotkeys, locale: locale, + mode: mode, }; - if (isTryMode) { - // Sent to try mode ... - options.mode = 'showcase'; - } else if (global.mindmapLocked) { - // Map locked, open for view mode ... - options.mode = 'viewonly'; - } else { - options.mode = 'edition'; - } - - let mapId: number; if (!AppConfig.isDevelopEnv()) { options = { zoom: (global.userOptions?.zoom != undefined @@ -30,7 +21,6 @@ export default class EditorOptionsBulder { mapTitle: global.mapTitle, ...options } - mapId = global.mapId; } else { // Running in a development mode. console.log('Running editor in development mode'); @@ -40,8 +30,11 @@ export default class EditorOptionsBulder { mapTitle: "Develop Mindnap", ...options } - mapId = 666; } - return { options, mapId }; + return options; + } + + static loadMapId(): number { + return !AppConfig.isDevelopEnv() ? global.mapId : 555; } } \ No newline at end of file diff --git a/packages/webapp/src/components/editor-page/index.tsx b/packages/webapp/src/components/editor-page/index.tsx index 326bcb09..5e521c86 100644 --- a/packages/webapp/src/components/editor-page/index.tsx +++ b/packages/webapp/src/components/editor-page/index.tsx @@ -2,13 +2,14 @@ import React, { useEffect } from 'react'; import ActionDispatcher from '../maps-page/action-dispatcher'; import { ActionType } from '../maps-page/action-chooser'; import Editor from '@wisemapping/editor'; +import { EditorRenderMode, PersistenceManager } from '@wisemapping/mindplot'; + import AppI18n from '../../classes/app-i18n'; import { useSelector } from 'react-redux'; import { hotkeysEnabled } from '../../redux/editorSlice'; import ReactGA from 'react-ga'; import Client from '../../classes/client'; -import { activeInstance, fetchAccount } from '../../redux/clientSlice'; -import { PersistenceManager } from '@wisemapping/mindplot'; +import { activeInstance, fetchAccount, fetchMapById } from '../../redux/clientSlice'; import EditorOptionsBulder from './EditorOptionsBuider'; export type EditorPropsType = { @@ -20,16 +21,43 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => { const hotkey = useSelector(hotkeysEnabled); const userLocale = AppI18n.getUserLocale(); const client: Client = useSelector(activeInstance); - const { mapId, options } = EditorOptionsBulder.build(userLocale.code, hotkey, isTryMode); useEffect(() => { ReactGA.pageview(window.location.pathname + window.location.search); }, []); + const findEditorMode = (isTryMode: boolean, mapId: number): EditorRenderMode | null => { + let result: EditorRenderMode = null; + if (isTryMode) { + result = 'showcase'; + } else if (global.mindmapLocked) { + result = 'viewonly'; + } else { + const fetchResult = fetchMapById(mapId); + if (!fetchResult.isLoading) { + if (fetchResult.error) { + throw new Error(`User coild not be loaded: ${JSON.stringify(fetchResult.error)}`); + } + result = fetchResult.map.role === 'owner' ? 'edition-owner' : 'edition-editor'; + } + } + return result; + } + + // What is the role ? + const mapId = EditorOptionsBulder.loadMapId(); + const mode = findEditorMode(isTryMode, mapId); + // Account settings can be null and editor cannot be initilized multiple times. This creates problems // at the i18n resource loading. - const persistence = client.buildPersistenceManager(options.mode); - const loadCompleted = persistence && (options.mode === 'showcase' || fetchAccount()); + const isAccountLoaded = mode === 'showcase' || fetchAccount; + const loadCompleted = mode && isAccountLoaded; + + let options, persistence: PersistenceManager; + if (loadCompleted) { + options = EditorOptionsBulder.build(userLocale.code, mode, hotkey); + persistence = client.buildPersistenceManager(mode); + } return loadCompleted ? ( <>