From 8061bd375a712ffc9a2b6492be74a8f1ec72eaa9 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 6 Jan 2023 23:57:39 -0800 Subject: [PATCH] Add disconnect node capabilities. --- packages/editor/lang/de.json | 15 +++-- packages/editor/lang/en.json | 31 +++++----- packages/editor/lang/es.json | 15 +++-- packages/editor/lang/fr.json | 16 +++-- .../react-component.tsx | 8 +-- packages/editor/src/compiled-lang/de.json | 60 +++++++++++------- packages/editor/src/compiled-lang/en.json | 58 +++++++++-------- packages/editor/src/compiled-lang/es.json | 60 +++++++++++------- packages/editor/src/compiled-lang/fr.json | 62 +++++++++++-------- .../pane/keyboard-shortcut-help/index.tsx | 12 +++- .../pane/save-and-delete/index.tsx | 24 ++++--- .../index.tsx | 5 +- .../index.tsx | 4 +- .../editor-toolbar/configBuilder.tsx | 10 +-- packages/mindplot/src/components/Designer.ts | 2 +- .../src/components/DesignerKeyboard.ts | 12 ++-- .../mindplot/src/components/DragConnector.ts | 12 ++-- .../mindplot/src/components/DragManager.ts | 38 +++++++----- packages/mindplot/src/components/DragTopic.ts | 3 +- packages/mindplot/src/components/NodeGraph.ts | 4 +- packages/mindplot/src/components/Topic.ts | 3 +- .../layout/ChildrenSorterStrategy.ts | 4 +- .../src/components/layout/LayoutManager.ts | 2 - 23 files changed, 277 insertions(+), 183 deletions(-) rename packages/editor/src/components/action-widget/pane/{topic-link => topic-link-editor}/index.tsx (97%) rename packages/editor/src/components/action-widget/pane/{topic-note => topic-note-editor}/index.tsx (96%) diff --git a/packages/editor/lang/de.json b/packages/editor/lang/de.json index 1e03b05e..398f41d6 100644 --- a/packages/editor/lang/de.json +++ b/packages/editor/lang/de.json @@ -11,9 +11,7 @@ "editor.try-welcome-description-mobile": { "defaultMessage": "Melden Sie sich an, um kostenlos eine unbegrenzte Anzahl von Mindmaps zu erstellen, zu teilen und zu veröffentlichen. Eingeschränkte Funktionen der Mindmap-Edition werden auf Mobilgeräten unterstützt. Verwenden Sie den Desktop-Browser für vollständige Editorfunktionen." }, - "editor.edit-mobile": { - "defaultMessage": "Hinweis für Mobilgeräte." - }, + "editor.edit-description-mobile": { "defaultMessage": "Eingeschränkte Funktionen der Mindmap-Edition werden auf Mobilgeräten unterstützt. Verwenden Sie den Desktop-Browser für vollständige Editorfunktionen." }, @@ -80,7 +78,7 @@ "editor-panel.note-panel-title": { "defaultMessage": "Notiz" }, - "icon.label": { + "editor-panel.icon-title": { "defaultMessage": "Symbol" }, "editor-panel.link-panel-title": { @@ -259,5 +257,14 @@ }, "editor-panel.tooltip-topic-fill-color-default": { "defaultMessage": "Standardfüllfarbe" + }, + "action.delete": { + "defaultMessage": "Löschen" + }, + "editor-panel.tooltip-topic-font-color-default": { + "defaultMessage": "Farbe defekt" + }, + "shortcut-help-pane.drag-disconnect": { + "defaultMessage": "Color de relleno por defekto" } } \ No newline at end of file diff --git a/packages/editor/lang/en.json b/packages/editor/lang/en.json index 048a2abc..983fb8ca 100644 --- a/packages/editor/lang/en.json +++ b/packages/editor/lang/en.json @@ -2,8 +2,8 @@ "action.accept": { "defaultMessage": "Accept" }, - "action.cancel": { - "defaultMessage": "Cancel" + "action.delete": { + "defaultMessage": "Delete" }, "appbar.back-to-map-list": { "defaultMessage": "Back to maps list" @@ -47,6 +47,12 @@ "appbar.tooltip-undo": { "defaultMessage": "Undo" }, + "editor-panel.link-panel-title": { + "defaultMessage": "Link" + }, + "editor-panel.note-panel-title": { + "defaultMessage": "Note" + }, "editor-panel.tooltip-add-icon": { "defaultMessage": "Add Icon" }, @@ -107,6 +113,9 @@ "editor-panel.tooltip-topic-font-color": { "defaultMessage": "Color" }, + "editor-panel.tooltip-topic-font-color-default": { + "defaultMessage": "Default color" + }, "editor-panel.tooltip-topic-font-italic": { "defaultMessage": "Italic" }, @@ -134,9 +143,6 @@ "editor.edit-description-mobile": { "defaultMessage": "Limited mindmap edition capabilities are supported in Mobile devices. Use Desktop browser for full editor capabilities." }, - "editor.edit-mobile": { - "defaultMessage": "Note for mobile devices." - }, "editor.try-welcome": { "defaultMessage": "This edition space showcases some of the mindmap editor capabilities!" }, @@ -152,21 +158,15 @@ "icon-picker.show-images": { "defaultMessage": "Show images" }, + "editor-panel.icon-title": { + "defaultMessage": "Icon" + }, "link.help_text": { "defaultMessage": "Address is not valid" }, "link.placeholder": { "defaultMessage": "https://www.example.com" }, - "editor-panel.note-panel-title": { - "defaultMessage": "Note" - }, - "icon.label": { - "defaultMessage": "Icon" - }, - "editor-panel.link-panel-title": { - "defaultMessage": "Link" - }, "shortcut-help-pane.action": { "defaultMessage": "Action" }, @@ -203,6 +203,9 @@ "shortcut-help-pane.deselect-all-topics": { "defaultMessage": "Deselect all topics" }, + "shortcut-help-pane.drag-disconnect": { + "defaultMessage": "Disconnect topic" + }, "shortcut-help-pane.edit-multiline": { "defaultMessage": "Add multi-line topic text" }, diff --git a/packages/editor/lang/es.json b/packages/editor/lang/es.json index 1c819e1d..0b67a009 100644 --- a/packages/editor/lang/es.json +++ b/packages/editor/lang/es.json @@ -11,9 +11,7 @@ "editor.try-welcome-description-mobile": { "defaultMessage": "Registrate para comenzar a crear, compartir y publicar una cantidad ilimitada de mapas mentales de forma gratuita. En dispositivos móbiles las funciones son limitadas. Use la versión de escritorio para tener las funciones completas." }, - "editor.edit-mobile": { - "defaultMessage": "Nota para dispositivos móbiles." - }, + "editor.edit-description-mobile": { "defaultMessage": "En dispositivos móbiles las funciones son limitadas. Use la versión de escritorio para tener las funciones completas." }, @@ -74,7 +72,7 @@ "editor-panel.note-panel-title": { "defaultMessage": "Nota" }, - "icon.label": { + "editor-panel.icon-title": { "defaultMessage": "Icono" }, "editor-panel.link-panel-title": { @@ -253,5 +251,14 @@ }, "editor-panel.tooltip-topic-fill-color-default": { "defaultMessage": "Color de relleno por defecto" + }, + "action.delete": { + "defaultMessage": "Borrar" + }, + "editor-panel.tooltip-topic-font-color-default": { + "defaultMessage": "Color por defecto" + }, + "shortcut-help-pane.drag-disconnect": { + "defaultMessage": "Desconectar tópico" } } \ No newline at end of file diff --git a/packages/editor/lang/fr.json b/packages/editor/lang/fr.json index c9c51e46..ad827983 100644 --- a/packages/editor/lang/fr.json +++ b/packages/editor/lang/fr.json @@ -11,9 +11,6 @@ "editor.try-welcome-description-mobile": { "defaultMessage": "Inscrivez-vous pour commencer à créer, partager et publier gratuitement un nombre illimité de cartes mentales. Les capacités d'édition limitées de mindmap sont prises en charge dans les appareils mobiles. Utilisez le navigateur de bureau pour bénéficier de toutes les fonctionnalités de l'éditeur." }, - "editor.edit-mobile": { - "defaultMessage": "Remarque pour les appareils mobiles." - }, "editor.edit-description-mobile": { "defaultMessage": "Les capacités d'édition limitées de mindmap sont prises en charge dans les appareils mobiles. Utilisez le navigateur de bureau pour bénéficier de toutes les fonctionnalités de l'éditeur." }, @@ -74,7 +71,7 @@ "editor-panel.note-panel-title": { "defaultMessage": "Note" }, - "icon.label": { + "editor-panel.icon-title": { "defaultMessage": "Icône" }, "editor-panel.link-panel-title": { @@ -252,6 +249,15 @@ "defaultMessage": "La couleur de remplissage" }, "editor-panel.tooltip-topic-fill-color-default": { - "defaultMessage": "Color de relleno por defecto" + "defaultMessage": "Couleur de relleno por defecto" + }, + "action.delete": { + "defaultMessage": "Supprimer" + }, + "editor-panel.tooltip-topic-font-color-default": { + "defaultMessage": "Couleur par défaut" + }, + "shortcut-help-pane.drag-disconnect": { + "defaultMessage": "Déconnecter le sujet" } } \ No newline at end of file diff --git a/packages/editor/src/classes/default-widget-manager/react-component.tsx b/packages/editor/src/classes/default-widget-manager/react-component.tsx index e008f0fd..de143d8b 100644 --- a/packages/editor/src/classes/default-widget-manager/react-component.tsx +++ b/packages/editor/src/classes/default-widget-manager/react-component.tsx @@ -16,22 +16,22 @@ * limitations under the License. */ import React from 'react'; -import TopicLink from '../../components/action-widget/pane/topic-link'; -import TopicNote from '../../components/action-widget/pane/topic-note'; +import TopicLinkEditor from '../../components/action-widget/pane/topic-link-editor'; +import TopicNoteEditor from '../../components/action-widget/pane/topic-note-editor'; import NodeProperty from '../model/node-property'; const linkContent = ( linkModel: NodeProperty, closeModal: () => void, ): React.ReactElement => { - return ; + return ; }; const noteContent = ( noteModel: NodeProperty, closeModal: () => void, ): React.ReactElement => { - return ; + return ; }; export { linkContent, noteContent }; diff --git a/packages/editor/src/compiled-lang/de.json b/packages/editor/src/compiled-lang/de.json index 7c3a83f5..3076ea76 100644 --- a/packages/editor/src/compiled-lang/de.json +++ b/packages/editor/src/compiled-lang/de.json @@ -11,6 +11,12 @@ "value": "Abbrechen" } ], + "action.delete": [ + { + "type": 0, + "value": "Löschen" + } + ], "action.share": [ { "type": 0, @@ -101,6 +107,24 @@ "value": "Rückgängig" } ], + "editor-panel.icon-title": [ + { + "type": 0, + "value": "Symbol" + } + ], + "editor-panel.link-panel-title": [ + { + "type": 0, + "value": "Link" + } + ], + "editor-panel.note-panel-title": [ + { + "type": 0, + "value": "Notiz" + } + ], "editor-panel.tooltip-add-icon": [ { "type": 0, @@ -221,6 +245,12 @@ "value": "Farbe" } ], + "editor-panel.tooltip-topic-font-color-default": [ + { + "type": 0, + "value": "Farbe defekt" + } + ], "editor-panel.tooltip-topic-font-italic": [ { "type": 0, @@ -275,12 +305,6 @@ "value": "Eingeschränkte Funktionen der Mindmap-Edition werden auf Mobilgeräten unterstützt. Verwenden Sie den Desktop-Browser für vollständige Editorfunktionen." } ], - "editor.edit-mobile": [ - { - "type": 0, - "value": "Hinweis für Mobilgeräte." - } - ], "editor.try-welcome": [ { "type": 0, @@ -311,24 +335,12 @@ "value": "Bilder anzeigen" } ], - "icon.label": [ - { - "type": 0, - "value": "Symbol" - } - ], "link.help_text": [ { "type": 0, "value": "Ingültige Adresse" } ], - "editor-panel.link-panel-title": [ - { - "type": 0, - "value": "Link" - } - ], "link.placeholder": [ { "type": 0, @@ -341,12 +353,6 @@ "value": "Anmeldung" } ], - "editor-panel.note-panel-title": [ - { - "type": 0, - "value": "Notiz" - } - ], "shortcut-help-pane.action": [ { "type": 0, @@ -419,6 +425,12 @@ "value": "Alle Themen auswählen" } ], + "shortcut-help-pane.drag-disconnect": [ + { + "type": 0, + "value": "Color de relleno por defekto" + } + ], "shortcut-help-pane.edit-multiline": [ { "type": 0, diff --git a/packages/editor/src/compiled-lang/en.json b/packages/editor/src/compiled-lang/en.json index 43b50dfb..1c61624c 100644 --- a/packages/editor/src/compiled-lang/en.json +++ b/packages/editor/src/compiled-lang/en.json @@ -5,10 +5,10 @@ "value": "Accept" } ], - "action.cancel": [ + "action.delete": [ { "type": 0, - "value": "Cancel" + "value": "Delete" } ], "appbar.back-to-map-list": [ @@ -95,6 +95,24 @@ "value": "Undo" } ], + "editor-panel.icon-title": [ + { + "type": 0, + "value": "Icon" + } + ], + "editor-panel.link-panel-title": [ + { + "type": 0, + "value": "Link" + } + ], + "editor-panel.note-panel-title": [ + { + "type": 0, + "value": "Note" + } + ], "editor-panel.tooltip-add-icon": [ { "type": 0, @@ -215,6 +233,12 @@ "value": "Color" } ], + "editor-panel.tooltip-topic-font-color-default": [ + { + "type": 0, + "value": "Default color" + } + ], "editor-panel.tooltip-topic-font-italic": [ { "type": 0, @@ -269,12 +293,6 @@ "value": "Limited mindmap edition capabilities are supported in Mobile devices. Use Desktop browser for full editor capabilities." } ], - "editor.edit-mobile": [ - { - "type": 0, - "value": "Note for mobile devices." - } - ], "editor.try-welcome": [ { "type": 0, @@ -305,36 +323,18 @@ "value": "Show images" } ], - "icon.label": [ - { - "type": 0, - "value": "Icon" - } - ], "link.help_text": [ { "type": 0, "value": "Address is not valid" } ], - "editor-panel.link-panel-title": [ - { - "type": 0, - "value": "Link" - } - ], "link.placeholder": [ { "type": 0, "value": "https://www.example.com" } ], - "editor-panel.note-panel-title": [ - { - "type": 0, - "value": "Note" - } - ], "shortcut-help-pane.action": [ { "type": 0, @@ -407,6 +407,12 @@ "value": "Deselect all topics" } ], + "shortcut-help-pane.drag-disconnect": [ + { + "type": 0, + "value": "Disconnect topic" + } + ], "shortcut-help-pane.edit-multiline": [ { "type": 0, diff --git a/packages/editor/src/compiled-lang/es.json b/packages/editor/src/compiled-lang/es.json index 00bf91b7..c833f8ef 100644 --- a/packages/editor/src/compiled-lang/es.json +++ b/packages/editor/src/compiled-lang/es.json @@ -11,6 +11,12 @@ "value": "Cancelar" } ], + "action.delete": [ + { + "type": 0, + "value": "Borrar" + } + ], "appbar.back-to-map-list": [ { "type": 0, @@ -95,6 +101,24 @@ "value": "Deshacer" } ], + "editor-panel.icon-title": [ + { + "type": 0, + "value": "Icono" + } + ], + "editor-panel.link-panel-title": [ + { + "type": 0, + "value": "Enlace" + } + ], + "editor-panel.note-panel-title": [ + { + "type": 0, + "value": "Nota" + } + ], "editor-panel.tooltip-add-icon": [ { "type": 0, @@ -215,6 +239,12 @@ "value": "Color" } ], + "editor-panel.tooltip-topic-font-color-default": [ + { + "type": 0, + "value": "Color por defecto" + } + ], "editor-panel.tooltip-topic-font-italic": [ { "type": 0, @@ -269,12 +299,6 @@ "value": "En dispositivos móbiles las funciones son limitadas. Use la versión de escritorio para tener las funciones completas." } ], - "editor.edit-mobile": [ - { - "type": 0, - "value": "Nota para dispositivos móbiles." - } - ], "editor.try-welcome": [ { "type": 0, @@ -305,36 +329,18 @@ "value": "Mostrar imagenes" } ], - "icon.label": [ - { - "type": 0, - "value": "Icono" - } - ], "link.help_text": [ { "type": 0, "value": "Dirección invalida" } ], - "editor-panel.link-panel-title": [ - { - "type": 0, - "value": "Enlace" - } - ], "link.placeholder": [ { "type": 0, "value": "https://www.example.com" } ], - "editor-panel.note-panel-title": [ - { - "type": 0, - "value": "Nota" - } - ], "shortcut-help-pane.action": [ { "type": 0, @@ -407,6 +413,12 @@ "value": "Deseleccionar tópicos" } ], + "shortcut-help-pane.drag-disconnect": [ + { + "type": 0, + "value": "Desconectar tópico" + } + ], "shortcut-help-pane.edit-multiline": [ { "type": 0, diff --git a/packages/editor/src/compiled-lang/fr.json b/packages/editor/src/compiled-lang/fr.json index 1f24df9f..ca1e2298 100644 --- a/packages/editor/src/compiled-lang/fr.json +++ b/packages/editor/src/compiled-lang/fr.json @@ -11,6 +11,12 @@ "value": "Annuler" } ], + "action.delete": [ + { + "type": 0, + "value": "Supprimer" + } + ], "appbar.back-to-map-list": [ { "type": 0, @@ -95,6 +101,24 @@ "value": "Annuler édition" } ], + "editor-panel.icon-title": [ + { + "type": 0, + "value": "Icône" + } + ], + "editor-panel.link-panel-title": [ + { + "type": 0, + "value": "Lien" + } + ], + "editor-panel.note-panel-title": [ + { + "type": 0, + "value": "Note" + } + ], "editor-panel.tooltip-add-icon": [ { "type": 0, @@ -194,7 +218,7 @@ "editor-panel.tooltip-topic-fill-color-default": [ { "type": 0, - "value": "Color de relleno por defecto" + "value": "Couleur de relleno por defecto" } ], "editor-panel.tooltip-topic-font-bigger": [ @@ -215,6 +239,12 @@ "value": "Couleur" } ], + "editor-panel.tooltip-topic-font-color-default": [ + { + "type": 0, + "value": "Couleur par défaut" + } + ], "editor-panel.tooltip-topic-font-italic": [ { "type": 0, @@ -269,12 +299,6 @@ "value": "Les capacités d'édition limitées de mindmap sont prises en charge dans les appareils mobiles. Utilisez le navigateur de bureau pour bénéficier de toutes les fonctionnalités de l'éditeur." } ], - "editor.edit-mobile": [ - { - "type": 0, - "value": "Remarque pour les appareils mobiles." - } - ], "editor.try-welcome": [ { "type": 0, @@ -305,36 +329,18 @@ "value": "Afficher les images" } ], - "icon.label": [ - { - "type": 0, - "value": "Icône" - } - ], "link.help_text": [ { "type": 0, "value": "Adresse invalide" } ], - "editor-panel.link-panel-title": [ - { - "type": 0, - "value": "Lien" - } - ], "link.placeholder": [ { "type": 0, "value": "https://www.example.com" } ], - "editor-panel.note-panel-title": [ - { - "type": 0, - "value": "Note" - } - ], "shortcut-help-pane.action": [ { "type": 0, @@ -407,6 +413,12 @@ "value": "Désélectionner tous les sujets" } ], + "shortcut-help-pane.drag-disconnect": [ + { + "type": 0, + "value": "Déconnecter le sujet" + } + ], "shortcut-help-pane.edit-multiline": [ { "type": 0, diff --git a/packages/editor/src/components/action-widget/pane/keyboard-shortcut-help/index.tsx b/packages/editor/src/components/action-widget/pane/keyboard-shortcut-help/index.tsx index 8184669c..0422e6bc 100644 --- a/packages/editor/src/components/action-widget/pane/keyboard-shortcut-help/index.tsx +++ b/packages/editor/src/components/action-widget/pane/keyboard-shortcut-help/index.tsx @@ -128,6 +128,7 @@ const KeyboardShorcutsHelp = (): ReactElement => { Ctrl + Enter ⌘ + Enter + { Ctrl + C / Ctrl + V ⌘ + C / ⌘ + V - + + + + + Ctrl + drag topic + ⌘ + drag topic + void; submitHandler: () => void; }): ReactElement => { + const value = props.model.getValue(); return ( - - - {props.model.getValue() && props.model.getValue().trim() !== '' && ( - { props.closeModal(); props.model.setValue(undefined); }} + size="small" > - - + + )} ); diff --git a/packages/editor/src/components/action-widget/pane/topic-link/index.tsx b/packages/editor/src/components/action-widget/pane/topic-link-editor/index.tsx similarity index 97% rename from packages/editor/src/components/action-widget/pane/topic-link/index.tsx rename to packages/editor/src/components/action-widget/pane/topic-link-editor/index.tsx index c32cda47..6fdc1082 100644 --- a/packages/editor/src/components/action-widget/pane/topic-link/index.tsx +++ b/packages/editor/src/components/action-widget/pane/topic-link-editor/index.tsx @@ -29,7 +29,7 @@ import { useIntl } from 'react-intl'; /** * Url form for toolbar and node contextual editor */ -const TopicLink = (props: { +const TopicLinkEditor = (props: { closeModal: () => void; urlModel: NodeProperty; }): ReactElement => { @@ -91,7 +91,6 @@ const TopicLink = (props: { ), }} /> -
void; noteModel: NodeProperty | null; }): ReactElement => { @@ -55,4 +55,4 @@ const TopicNote = (props: { ); }; -export default TopicNote; +export default TopicNoteEditor; diff --git a/packages/editor/src/components/editor-toolbar/configBuilder.tsx b/packages/editor/src/components/editor-toolbar/configBuilder.tsx index 714eb9bc..fb5d3f27 100644 --- a/packages/editor/src/components/editor-toolbar/configBuilder.tsx +++ b/packages/editor/src/components/editor-toolbar/configBuilder.tsx @@ -45,8 +45,8 @@ import ActionConfig from '../../classes/action/action-config'; import { SwitchValueDirection } from '../toolbar/ToolbarValueModelBuilder'; import NodePropertyValueModelBuilder from '../../classes/model/node-property-builder'; import ColorPicker from '../action-widget/pane/color-picker'; -import TopicLink from '../action-widget/pane/topic-link'; -import TopicNote from '../action-widget/pane/topic-note'; +import TopicLinkEditor from '../action-widget/pane/topic-link-editor'; +import TopicNoteEditor from '../action-widget/pane/topic-note-editor'; import IconPicker from '../action-widget/pane/icon-picker'; import FontFamilySelector from '../action-widget/button/font-family-selector'; import Editor from '../../classes/model/editor'; @@ -364,7 +364,7 @@ export function buildEditorPanelConfig(model: Editor, intl: IntlShape): ActionCo options: [ { render: (closeModal) => ( - + ), }, ], @@ -389,7 +389,7 @@ export function buildEditorPanelConfig(model: Editor, intl: IntlShape): ActionCo defaultMessage: 'Note', }), render: (closeModal) => ( - + ), }, ], @@ -406,7 +406,7 @@ export function buildEditorPanelConfig(model: Editor, intl: IntlShape): ActionCo defaultMessage: 'Add Icon', }), useClickToClose: true, - title: intl.formatMessage({ id: 'icon.label', defaultMessage: 'Icon' }), + title: intl.formatMessage({ id: 'editor-panel.icon-title', defaultMessage: 'Icon' }), options: [ { tooltip: intl.formatMessage({ diff --git a/packages/mindplot/src/components/Designer.ts b/packages/mindplot/src/components/Designer.ts index 8dbd1f98..a3c557e4 100644 --- a/packages/mindplot/src/components/Designer.ts +++ b/packages/mindplot/src/components/Designer.ts @@ -214,7 +214,7 @@ class Designer extends Events { dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => { // The node is being drag. Is the connection still valid ? - dragConnector.checkConnection(dragTopic); + dragConnector.checkConnection(dragTopic, event.metaKey || event.ctrlKey); if (!dragTopic.isVisible() && dragTopic.isConnected()) { dragTopic.setVisibility(true); diff --git a/packages/mindplot/src/components/DesignerKeyboard.ts b/packages/mindplot/src/components/DesignerKeyboard.ts index ec77efdb..31f3b7f8 100644 --- a/packages/mindplot/src/components/DesignerKeyboard.ts +++ b/packages/mindplot/src/components/DesignerKeyboard.ts @@ -258,7 +258,7 @@ class DesignerKeyboard extends Keyboard { } } - private _goToSideChild(designer: Designer, node: Topic, side: 'LEFT' | 'RIGHT') { + private _goToSideChild(designer: Designer, node: Topic, side: 'LEFT' | 'RIGHT'): void { const children = node.getChildren(); if (children.length > 0) { let target = children[0]; @@ -284,14 +284,14 @@ class DesignerKeyboard extends Keyboard { } } - private _goToParent(designer: Designer, node: Topic) { + private _goToParent(designer: Designer, node: Topic): void { const parent = node.getParent(); if (parent) { this._goToNode(designer, parent); } } - private _goToChild(designer: Designer, node: Topic) { + private _goToChild(designer: Designer, node: Topic): void { const children = node.getChildren(); if (children.length > 0) { let target = children[0]; @@ -307,7 +307,7 @@ class DesignerKeyboard extends Keyboard { } } - private _goToNode(designer: Designer, node: Topic) { + private _goToNode(designer: Designer, node: Topic): void { // First deselect all the nodes ... designer.deselectAll(); @@ -315,10 +315,10 @@ class DesignerKeyboard extends Keyboard { node.setOnFocus(true); } - static register = function register(designer: Designer) { + static register(designer: Designer) { this._instance = new DesignerKeyboard(designer); this._disabled = false; - }; + } static pause() { this._disabled = true; diff --git a/packages/mindplot/src/components/DragConnector.ts b/packages/mindplot/src/components/DragConnector.ts index 62b27c6f..a28946d7 100644 --- a/packages/mindplot/src/components/DragConnector.ts +++ b/packages/mindplot/src/components/DragConnector.ts @@ -36,11 +36,15 @@ class DragConnector { this._workspace = workspace; } - checkConnection(dragTopic: DragTopic): void { - // Must be disconnected from their current connection ?. - const candidates = this._searchConnectionCandidates(dragTopic); - const currentConnection = dragTopic.getConnectedToTopic(); + checkConnection(dragTopic: DragTopic, forceDisconnected: boolean): void { + // Is forced disconexion enabled ? + let candidates: Topic[] = []; + if (!forceDisconnected) { + candidates = this._searchConnectionCandidates(dragTopic); + } + // Must be disconnected from their current connection ?. + const currentConnection = dragTopic.getConnectedToTopic(); if (currentConnection && (candidates.length === 0 || candidates[0] !== currentConnection)) { dragTopic.disconnect(this._workspace); } diff --git a/packages/mindplot/src/components/DragManager.ts b/packages/mindplot/src/components/DragManager.ts index c0ce6e2b..2c14c46e 100644 --- a/packages/mindplot/src/components/DragManager.ts +++ b/packages/mindplot/src/components/DragManager.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $assert, $defined } from '@wisemapping/core-js'; +import { $assert } from '@wisemapping/core-js'; import DragTopic from './DragTopic'; import EventBusDispatcher from './layout/EventBusDispatcher'; import Topic from './Topic'; @@ -55,10 +55,10 @@ class DragManager { // Set initial position. const layoutManager = me._eventDispatcher.getLayoutManager(); - const dragNode = topic.createDragNode(layoutManager); + const dragNode: DragTopic = topic.createDragNode(layoutManager); // Register mouse move listener ... - const mouseMoveListener = dragManager._buildMouseMoveListener( + const mouseMoveListener = dragManager.buildMouseMoveListener( workspace, dragNode, dragManager, @@ -80,19 +80,21 @@ class DragManager { throw new Error('Not implemented: DragManager.prototype.remove'); } - protected _buildMouseMoveListener(workspace: Workspace, dragNode, dragManager: DragManager) { + protected buildMouseMoveListener( + workspace: Workspace, + dragNode: DragTopic, + dragManager: DragManager, + ): (event: MouseEvent) => void { const screen = workspace.getScreenManager(); - const me = this; - const result = (event) => { - if (!me._isDragInProcess) { + const result = (event: MouseEvent) => { + if (!this._isDragInProcess) { // Execute Listeners .. const startDragListener = dragManager._listeners.startdragging; startDragListener(event, dragNode); // Add shadow node to the workspace. workspace.append(dragNode); - - me._isDragInProcess = true; + this._isDragInProcess = true; } const pos = screen.getWorkspaceMousePosition(event); @@ -100,7 +102,7 @@ class DragManager { // Call mouse move listeners ... const dragListener = dragManager._listeners.dragging; - if ($defined(dragListener)) { + if (dragListener) { dragListener(event, dragNode); } @@ -112,9 +114,12 @@ class DragManager { return result; } - protected _buildMouseUpListener(workspace: Workspace, dragNode, dragManager: DragManager) { + protected _buildMouseUpListener( + workspace: Workspace, + dragNode: DragTopic, + dragManager: DragManager, + ) { const screen = workspace.getScreenManager(); - const me = this; const result = (event: Event) => { $assert(dragNode.isDragTopic, 'dragNode must be an DragTopic'); @@ -131,7 +136,7 @@ class DragManager { // Change the cursor to the default. window.document.body.style.cursor = 'default'; - if (me._isDragInProcess) { + if (this._isDragInProcess) { // Execute Listeners only if the node has been moved. const endDragListener = dragManager._listeners.enddragging; endDragListener(event, dragNode); @@ -139,14 +144,17 @@ class DragManager { // Remove drag node from the workspace. dragNode.removeFromWorkspace(workspace); - me._isDragInProcess = false; + this._isDragInProcess = false; } }; dragManager._mouseUpListener = result; return result; } - addEvent(type: 'startdragging' | 'dragging' | 'enddragging', listener) { + addEvent( + type: 'startdragging' | 'dragging' | 'enddragging', + listener: (event: MouseEvent, dragTopic: DragTopic) => void, + ) { this._listeners[type] = listener; } } diff --git a/packages/mindplot/src/components/DragTopic.ts b/packages/mindplot/src/components/DragTopic.ts index 3bd775f0..6faa8bbe 100644 --- a/packages/mindplot/src/components/DragTopic.ts +++ b/packages/mindplot/src/components/DragTopic.ts @@ -70,13 +70,14 @@ class DragTopic { this._elem2d.setPosition(cx, cy); // In case is not free, pivot must be draw ... - if (this.isConnected() && !this.isFreeLayoutOn()) { + if (this.isConnected()) { const parent = this.getConnectedToTopic(); const predict = this._layoutManager.predict( parent!.getId(), this._draggedNode.getId(), this.getPosition(), ); + if (this._order !== predict.order) { const dragPivot = this._getDragPivot(); const pivotPosition = predict.position; diff --git a/packages/mindplot/src/components/NodeGraph.ts b/packages/mindplot/src/components/NodeGraph.ts index 7435cbeb..4e006cf8 100644 --- a/packages/mindplot/src/components/NodeGraph.ts +++ b/packages/mindplot/src/components/NodeGraph.ts @@ -95,7 +95,7 @@ abstract class NodeGraph { } /** */ - setMouseEventsEnabled(isEnabled) { + setMouseEventsEnabled(isEnabled: boolean) { this._mouseEvents = isEnabled; } @@ -163,7 +163,7 @@ abstract class NodeGraph { workspace.removeChild(this); } - createDragNode(layoutManager: LayoutManager) { + createDragNode(layoutManager: LayoutManager): DragTopic { const dragShape = this._buildDragShape(); return new DragTopic(dragShape, this, layoutManager); diff --git a/packages/mindplot/src/components/Topic.ts b/packages/mindplot/src/components/Topic.ts index 00cb5256..77dddac7 100644 --- a/packages/mindplot/src/components/Topic.ts +++ b/packages/mindplot/src/components/Topic.ts @@ -46,6 +46,7 @@ import ColorUtil from './render/ColorUtil'; import Icon from './Icon'; import { FontStyleType } from './FontStyleType'; import { FontWeightType } from './FontWeightType'; +import DragTopic from './DragTopic'; const ICON_SCALING_FACTOR = 1.3; @@ -1135,7 +1136,7 @@ abstract class Topic extends NodeGraph { return this._isInWorkspace; } - createDragNode(layoutManager: LayoutManager) { + createDragNode(layoutManager: LayoutManager): DragTopic { const result = super.createDragNode(layoutManager); // Is the node already connected ? diff --git a/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts b/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts index 6b958fea..3b0b852f 100644 --- a/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts +++ b/packages/mindplot/src/components/layout/ChildrenSorterStrategy.ts @@ -30,10 +30,10 @@ abstract class ChildrenSorterStrategy { abstract predict( treeSet: RootedTreeSet, - parent, + parent: Node, node: Node | null, position: PositionType | null, - ): void; + ); abstract verify(treeSet: RootedTreeSet, node: Node): void; diff --git a/packages/mindplot/src/components/layout/LayoutManager.ts b/packages/mindplot/src/components/layout/LayoutManager.ts index dcbe9e67..4a429745 100644 --- a/packages/mindplot/src/components/layout/LayoutManager.ts +++ b/packages/mindplot/src/components/layout/LayoutManager.ts @@ -131,8 +131,6 @@ class LayoutManager extends Events { nodeId: number | null, position: PositionType | null, ): { order: number; position: PositionType } { - $assert($defined(parentId), 'parentId can not be null'); - const parent = this._treeSet.find(parentId); const node = nodeId ? this._treeSet.find(nodeId) : null; const sorter = parent.getSorter();