Merge branch 'feature/exports-mindmap' of https://bitbucket.org/wisemapping/wisemapping-frontend into feature/exports-mindmap
@ -17,6 +17,7 @@ pipelines:
|
|||||||
- cypress
|
- cypress
|
||||||
script:
|
script:
|
||||||
- export CYPRESS_imageSnaphots="true"
|
- export CYPRESS_imageSnaphots="true"
|
||||||
|
- yarn install
|
||||||
- yarn bootstrap
|
- yarn bootstrap
|
||||||
- yarn build
|
- yarn build
|
||||||
- yarn lint
|
- yarn lint
|
||||||
|
@ -3,7 +3,7 @@ services:
|
|||||||
e2e:
|
e2e:
|
||||||
image: cypress/included:8.4.1
|
image: cypress/included:8.4.1
|
||||||
container_name: wisemapping-integration-tests
|
container_name: wisemapping-integration-tests
|
||||||
entrypoint: '/bin/sh -c "yarn bootstrap && yarn build && yarn test:integration"'
|
entrypoint: '/bin/sh -c "yarn install && yarn bootstrap && yarn build && yarn test:integration"'
|
||||||
working_dir: /e2e
|
working_dir: /e2e
|
||||||
environment:
|
environment:
|
||||||
- CYPRESS_imageSnaphots=true
|
- CYPRESS_imageSnaphots=true
|
||||||
|
87
lang/en.json
@ -1,87 +0,0 @@
|
|||||||
{
|
|
||||||
"footer.aboutus": {
|
|
||||||
"defaultMessage": "About Us"
|
|
||||||
},
|
|
||||||
"footer.contactus": {
|
|
||||||
"defaultMessage": "Contact Us"
|
|
||||||
},
|
|
||||||
"footer.donations": {
|
|
||||||
"defaultMessage": "PayPal Donations"
|
|
||||||
},
|
|
||||||
"footer.faq": {
|
|
||||||
"defaultMessage": "F.A.Q."
|
|
||||||
},
|
|
||||||
"footer.feedback": {
|
|
||||||
"defaultMessage": "Feedback"
|
|
||||||
},
|
|
||||||
"footer.opensource": {
|
|
||||||
"defaultMessage": "Open Source"
|
|
||||||
},
|
|
||||||
"footer.termsandconditions": {
|
|
||||||
"defaultMessage": "Term And Conditions"
|
|
||||||
},
|
|
||||||
"header.donthaveaccount": {
|
|
||||||
"defaultMessage": "Don't have an account ?"
|
|
||||||
},
|
|
||||||
"header.haveaccount": {
|
|
||||||
"defaultMessage": "Already have an account?"
|
|
||||||
},
|
|
||||||
"login.email": {
|
|
||||||
"defaultMessage": "Email"
|
|
||||||
},
|
|
||||||
"login.error": {
|
|
||||||
"defaultMessage": "The login.email address or login.password you entered is not valid."
|
|
||||||
},
|
|
||||||
"login.forgotpwd": {
|
|
||||||
"defaultMessage": "Forgot Password ?"
|
|
||||||
},
|
|
||||||
"login.hsqldbcofig": {
|
|
||||||
"defaultMessage": "Although HSQLDB is bundled with WiseMapping by default during the installation, we do not recommend this database for production use. Please consider using MySQL 5.7 instead. You can find more information how to configure MySQL",
|
|
||||||
"description": "Missing production database configured"
|
|
||||||
},
|
|
||||||
"login.loginto": {
|
|
||||||
"defaultMessage": "Log Into Your Account"
|
|
||||||
},
|
|
||||||
"login.password": {
|
|
||||||
"defaultMessage": "Password"
|
|
||||||
},
|
|
||||||
"login.remberme": {
|
|
||||||
"defaultMessage": "Remember me"
|
|
||||||
},
|
|
||||||
"login.signin": {
|
|
||||||
"defaultMessage": "Sign In"
|
|
||||||
},
|
|
||||||
"login.signup": {
|
|
||||||
"defaultMessage": "Sign Up"
|
|
||||||
},
|
|
||||||
"login.userinactive": {
|
|
||||||
"defaultMessage": "Sorry, your account has not been activated yet. You'll receive a notification login.email when it becomes active. Stay tuned!."
|
|
||||||
},
|
|
||||||
"login.welcome": {
|
|
||||||
"defaultMessage": "Welcome"
|
|
||||||
},
|
|
||||||
"registration.become": {
|
|
||||||
"defaultMessage": "Become a member of our comunity"
|
|
||||||
},
|
|
||||||
"registration.email": {
|
|
||||||
"defaultMessage": "Email"
|
|
||||||
},
|
|
||||||
"registration.firstname": {
|
|
||||||
"defaultMessage": "First Name"
|
|
||||||
},
|
|
||||||
"registration.lastname": {
|
|
||||||
"defaultMessage": "Last Name"
|
|
||||||
},
|
|
||||||
"registration.password": {
|
|
||||||
"defaultMessage": "Password"
|
|
||||||
},
|
|
||||||
"registration.register": {
|
|
||||||
"defaultMessage": "Register"
|
|
||||||
},
|
|
||||||
"registration.signup": {
|
|
||||||
"defaultMessage": "Signing up is free and just take a moment"
|
|
||||||
},
|
|
||||||
"registration.termandconditions": {
|
|
||||||
"defaultMessage": "Terms of Service: Please check the WiseMapping Account information you've entered above, and review the Terms of Service here. By clicking on 'Register' below you are agreeing to the Terms of Service above and the Privacy Policy"
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,5 +28,8 @@ module.exports = {
|
|||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js'],
|
extensions: ['.js'],
|
||||||
},
|
},
|
||||||
plugins: [new CleanWebpackPlugin()],
|
plugins: [new CleanWebpackPlugin({
|
||||||
|
dangerouslyAllowCleanPatternsOutsideProject: true,
|
||||||
|
dry: false,
|
||||||
|
})],
|
||||||
};
|
};
|
||||||
|
28
packages/editor/README.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Editor
|
||||||
|
|
||||||
|
React Component for the wisemapping editor.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This is a work in progress and for now mindplot needs to be instantiated using the initCallback prop. Check `test/playground/map-render` for some usage examples.
|
||||||
|
|
||||||
|
import Editor from `@wisemapping/editor`;
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Editor
|
||||||
|
mapId={1}
|
||||||
|
memoryPersistence={false}
|
||||||
|
readOnlyMode={false}
|
||||||
|
locale="en"
|
||||||
|
onAction={(action) => console.log('action called:', action)}
|
||||||
|
initCallback={initialization}
|
||||||
|
/>,
|
||||||
|
document.getElementById('root'),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
## i18n
|
||||||
|
|
||||||
|
Messages are translated in the `lang` folder, and then compiled to `src/compiled-lang` using the following command:
|
||||||
|
|
||||||
|
yarn compile lang/de.json --ast --out-file src/compiled-lang/de.json
|
@ -15,7 +15,7 @@ context('Edit Topic', () => {
|
|||||||
|
|
||||||
it('Change Font Size', () => {
|
it('Change Font Size', () => {
|
||||||
cy.get('#fontSizeTip').click();
|
cy.get('#fontSizeTip').click();
|
||||||
cy.get('.popover #small').click();
|
cy.get('.popover #small').click({ force: true });
|
||||||
|
|
||||||
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '8.0625');
|
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '8.0625');
|
||||||
cy.matchImageSnapshot('changeFontSizeSmall');
|
cy.matchImageSnapshot('changeFontSizeSmall');
|
||||||
|
@ -7,7 +7,7 @@ context('Change Topic shape', () => {
|
|||||||
|
|
||||||
it('change to square shape', () => {
|
it('change to square shape', () => {
|
||||||
cy.get('#topicShapeTip').click();
|
cy.get('#topicShapeTip').click();
|
||||||
cy.get('#rectagle').click();
|
cy.get('#rectagle').click({ force: true });
|
||||||
|
|
||||||
cy.get('[test-id=11] > rect').eq(1).invoke('attr', 'rx').should('eq', '0');
|
cy.get('[test-id=11] > rect').eq(1).invoke('attr', 'rx').should('eq', '0');
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 121 KiB |
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 139 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 105 KiB |
14
packages/editor/lang/de.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"editor.try-welcome": {
|
||||||
|
"defaultMessage": "Dieser Ausgabebereich zeigt einige der Mindmap-Editor-Funktionen!"
|
||||||
|
},
|
||||||
|
"editor.try-welcome-description": {
|
||||||
|
"defaultMessage": "Melden Sie sich an, um kostenlos eine unbegrenzte Anzahl von Mindmaps zu erstellen, zu teilen und zu veröffentlichen."
|
||||||
|
},
|
||||||
|
"login.signup": {
|
||||||
|
"defaultMessage": "Anmeldung"
|
||||||
|
},
|
||||||
|
"action.share": {
|
||||||
|
"defaultMessage": "Teilen"
|
||||||
|
}
|
||||||
|
}
|
14
packages/editor/lang/en.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"editor.try-welcome": {
|
||||||
|
"defaultMessage": "This edition space showcases some of the mindmap editor capabilities !"
|
||||||
|
},
|
||||||
|
"editor.try-welcome-description": {
|
||||||
|
"defaultMessage": "Sign Up to start creating, sharing and publishing unlimited number of mindmaps for free."
|
||||||
|
},
|
||||||
|
"login.signup": {
|
||||||
|
"defaultMessage": "Sign Up"
|
||||||
|
},
|
||||||
|
"action.share": {
|
||||||
|
"defaultMessage": "Share"
|
||||||
|
}
|
||||||
|
}
|
14
packages/editor/lang/es.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"editor.try-welcome": {
|
||||||
|
"defaultMessage": "¡Este espacio de edición muestra algunas de las capacidades del editor de mapas mentales!"
|
||||||
|
},
|
||||||
|
"editor.try-welcome-description": {
|
||||||
|
"defaultMessage": "Registrate para comenzar a crear, compartir y publicar una cantidad ilimitada de mapas mentales de forma gratuita."
|
||||||
|
},
|
||||||
|
"login.signup": {
|
||||||
|
"defaultMessage": "Crear cuenta"
|
||||||
|
},
|
||||||
|
"action.share": {
|
||||||
|
"defaultMessage": "Compartir"
|
||||||
|
}
|
||||||
|
}
|
14
packages/editor/lang/fr.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"editor.try-welcome": {
|
||||||
|
"defaultMessage": "Cet espace d'édition présente certaines des fonctionnalités de l'éditeur de cartes mentales !"
|
||||||
|
},
|
||||||
|
"editor.try-welcome-description": {
|
||||||
|
"defaultMessage": "Inscrivez-vous pour commencer à créer, partager et publier gratuitement un nombre illimité de cartes mentales."
|
||||||
|
},
|
||||||
|
"login.signup": {
|
||||||
|
"defaultMessage": "S'inscrire"
|
||||||
|
},
|
||||||
|
"action.share": {
|
||||||
|
"defaultMessage": "Partager"
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,9 @@
|
|||||||
"playground": "webpack serve --config webpack.playground.js",
|
"playground": "webpack serve --config webpack.playground.js",
|
||||||
"cy:run": "cypress run",
|
"cy:run": "cypress run",
|
||||||
"test:integration": "start-server-and-test 'yarn playground' http-get://localhost:8081 'yarn cy:run'",
|
"test:integration": "start-server-and-test 'yarn playground' http-get://localhost:8081 'yarn cy:run'",
|
||||||
"test": "yarn test:integration"
|
"test": "yarn test:integration",
|
||||||
|
"extract": "for lang in {'es','en','fr','de'};do formatjs extract 'src/**/*.ts*' --ignore 'src/@types/**/*' --out-file lang/${lang}.json;done",
|
||||||
|
"compile": "formatjs compile"
|
||||||
},
|
},
|
||||||
"repository": "http://www.wisemapping.com",
|
"repository": "http://www.wisemapping.com",
|
||||||
"author": "Paulo Veiga <pveiga@gmail.com>, Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>",
|
"author": "Paulo Veiga <pveiga@gmail.com>, Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>",
|
||||||
@ -16,6 +18,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/preset-env": "^7.16.11",
|
"@babel/preset-env": "^7.16.11",
|
||||||
"@babel/preset-react": "^7.16.7",
|
"@babel/preset-react": "^7.16.7",
|
||||||
|
"@formatjs/cli": "^4.8.1",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@types/react-dom": "^17.0.0",
|
"@types/react-dom": "^17.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
||||||
|
4
packages/editor/src/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
declare module "*.svg" {
|
||||||
|
const content: any;
|
||||||
|
export default content;
|
||||||
|
}
|
26
packages/editor/src/compiled-lang/de.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"action.share": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Teilen"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Dieser Ausgabebereich zeigt einige der Mindmap-Editor-Funktionen!"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome-description": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Melden Sie sich an, um kostenlos eine unbegrenzte Anzahl von Mindmaps zu erstellen, zu teilen und zu veröffentlichen."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"login.signup": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Anmeldung"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
packages/editor/src/compiled-lang/en.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"action.share": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Share"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "This edition space showcases some of the mindmap editor capabilities !"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome-description": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Sign Up to start creating, sharing and publishing unlimited number of mindmaps for free."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"login.signup": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Sign Up"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
packages/editor/src/compiled-lang/es.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"action.share": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Compartir"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "¡Este espacio de edición muestra algunas de las capacidades del editor de mapas mentales!"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome-description": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Registrate para comenzar a crear, compartir y publicar una cantidad ilimitada de mapas mentales de forma gratuita."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"login.signup": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Crear cuenta"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
packages/editor/src/compiled-lang/fr.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"action.share": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Partager"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Cet espace d'édition présente certaines des fonctionnalités de l'éditeur de cartes mentales !"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.try-welcome-description": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Inscrivez-vous pour commencer à créer, partager et publier gratuitement un nombre illimité de cartes mentales."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"login.signup": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "S'inscrire"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
25
packages/editor/src/components/action-button/index.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const ActionButton = styled.div`
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0px 10px;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
user-select: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 25px;
|
||||||
|
font-size: 15px;
|
||||||
|
min-width: 64px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 9px;
|
||||||
|
color: white;
|
||||||
|
background-color: #ffa800;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default ActionButton;
|
@ -1,11 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyledLogo } from './styled';
|
import { StyledLogo, Notifier } from './styled';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
import KeyboardSvg from '../../../images/keyboard.svg';
|
import KeyboardSvg from '../../../images/keyboard.svg';
|
||||||
import AddSvg from '../../../images/add.svg';
|
import AddSvg from '../../../images/add.svg';
|
||||||
import MinusSvg from '../../../images/minus.svg';
|
import MinusSvg from '../../../images/minus.svg';
|
||||||
import CenterFocusSvg from '../../../images/center_focus.svg';
|
import CenterFocusSvg from '../../../images/center_focus.svg';
|
||||||
|
import ActionButton from '../action-button';
|
||||||
|
|
||||||
export type FooterPropsType = {
|
export type FooterPropsType = {
|
||||||
showTryPanel?: boolean;
|
showTryPanel?: boolean;
|
||||||
@ -35,15 +36,15 @@ const Footer = ({ showTryPanel }: FooterPropsType): React.ReactElement => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<StyledLogo id="bottom-logo"></StyledLogo>
|
<StyledLogo id="bottom-logo"></StyledLogo>
|
||||||
<div id="headerNotifier"></div>
|
<Notifier id="headerNotifier"></Notifier>
|
||||||
{showTryPanel && (
|
{showTryPanel && (
|
||||||
<div id="tryInfoPanel">
|
<div id="tryInfoPanel">
|
||||||
<p>{intl.formatMessage({ id: 'editor.try-welcome' })}</p>
|
<p>{intl.formatMessage({ id: 'editor.try-welcome' })}</p>
|
||||||
<p>{intl.formatMessage({ id: 'editor.try-welcome-description' })}</p>
|
<p>{intl.formatMessage({ id: 'editor.try-welcome-description' })}</p>
|
||||||
<a href="/c/registration">
|
<a href="/c/registration">
|
||||||
<div className="actionButton">
|
<ActionButton>
|
||||||
{intl.formatMessage({ id: 'login.signup', defaultMessage: 'Sign Up' })}
|
{intl.formatMessage({ id: 'login.signup', defaultMessage: 'Sign Up' })}
|
||||||
</div>
|
</ActionButton>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -15,4 +15,17 @@ export const StyledLogo = styled.div`
|
|||||||
background: url(${LogoTextBlackSvg}) no-repeat;
|
background: url(${LogoTextBlackSvg}) no-repeat;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
`
|
`;
|
||||||
|
|
||||||
|
export const Notifier = styled.div`
|
||||||
|
border: 1px solid rgb(241, 163, 39);
|
||||||
|
background-color: rgb(252, 235, 192);
|
||||||
|
border-radius: 3px;
|
||||||
|
position: fixed;
|
||||||
|
padding: 5px 9px;
|
||||||
|
color: back;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-top: 5px;
|
||||||
|
display: none;
|
||||||
|
bottom: 10px;
|
||||||
|
`;
|
||||||
|
@ -3,7 +3,6 @@ import { useIntl } from 'react-intl';
|
|||||||
|
|
||||||
import BackIconSvg from '../../../images/back-icon.svg';
|
import BackIconSvg from '../../../images/back-icon.svg';
|
||||||
import SaveSvg from '../../../images/save.svg';
|
import SaveSvg from '../../../images/save.svg';
|
||||||
import DiscardSvg from '../../../images/discard.svg';
|
|
||||||
import UndoSvg from '../../../images/undo.svg';
|
import UndoSvg from '../../../images/undo.svg';
|
||||||
import RedoSvg from '../../../images/redo.svg';
|
import RedoSvg from '../../../images/redo.svg';
|
||||||
import TopicAddSvg from '../../../images/topic-add.svg';
|
import TopicAddSvg from '../../../images/topic-add.svg';
|
||||||
@ -26,118 +25,130 @@ import HistorySvg from '../../../images/history.svg';
|
|||||||
import PrintSvg from '../../../images/print.svg';
|
import PrintSvg from '../../../images/print.svg';
|
||||||
import AccountSvg from '../../../images/account.svg';
|
import AccountSvg from '../../../images/account.svg';
|
||||||
|
|
||||||
|
import { HeaderContainer, ToolbarButton, ToolbarButtonExt, ToolbarRightContainer } from './styled';
|
||||||
|
import ActionButton from '../action-button';
|
||||||
|
|
||||||
export type ToolbarActionType = 'export' | 'publish' | 'history' | 'print' | 'share';
|
export type ToolbarActionType = 'export' | 'publish' | 'history' | 'print' | 'share';
|
||||||
|
|
||||||
export type ToolbarPropsType = {
|
export type ToolbarPropsType = {
|
||||||
memoryPersistence: boolean;
|
isTryMode: boolean;
|
||||||
readOnlyMode: boolean;
|
|
||||||
onAction: (action: ToolbarActionType) => void;
|
onAction: (action: ToolbarActionType) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Toolbar({
|
export default function Toolbar({
|
||||||
memoryPersistence,
|
isTryMode: isTryMode,
|
||||||
readOnlyMode,
|
|
||||||
onAction,
|
onAction,
|
||||||
}: ToolbarPropsType): React.ReactElement {
|
}: ToolbarPropsType): React.ReactElement {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
return (
|
return (
|
||||||
<div id="toolbar">
|
<HeaderContainer>
|
||||||
<div id="backToList">
|
<div id="toolbar">
|
||||||
<img src={BackIconSvg} />
|
<div id="backToList">
|
||||||
|
<img src={BackIconSvg} />
|
||||||
|
</div>
|
||||||
|
{!isTryMode && (
|
||||||
|
<div id="persist" className="buttonContainer">
|
||||||
|
<ToolbarButton id="save" className="buttonOn">
|
||||||
|
<img src={SaveSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div id="edit" className="buttonContainer">
|
||||||
|
<ToolbarButton id="undoEdition" className="buttonOn">
|
||||||
|
<img src={UndoSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="redoEdition" className="buttonOn">
|
||||||
|
<img src={RedoSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
</div>
|
||||||
|
<div id="nodeStyle" className="buttonContainer">
|
||||||
|
<ToolbarButton id="addTopic" className="buttonOn">
|
||||||
|
<img src={TopicAddSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="deleteTopic" className="buttonOn">
|
||||||
|
<img src={TopicDeleteSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButtonExt id="topicBorder" className="buttonExtOn">
|
||||||
|
<img src={TopicBorderSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
<ToolbarButtonExt id="topicColor" className="buttonExtOn">
|
||||||
|
<img src={TopicColorSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
<ToolbarButtonExt id="topicShape" className="buttonExtOn">
|
||||||
|
<img src={TopicShapeSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
</div>
|
||||||
|
<div id="font" className="buttonContainer">
|
||||||
|
<ToolbarButton id="fontFamily" className="buttonOn">
|
||||||
|
<img src={FontTypeSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButtonExt id="fontSize" className="buttonExtOn">
|
||||||
|
<img src={FontSizeSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
<ToolbarButton id="fontBold" className="buttonOn">
|
||||||
|
<img src={FontBoldSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="fontItalic" className="buttonOn">
|
||||||
|
<img src={FontItalicSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButtonExt id="fontColor" className="buttonExtOn">
|
||||||
|
<img src={FontColorSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
</div>
|
||||||
|
<div id="nodeContent" className="buttonContainer">
|
||||||
|
<ToolbarButtonExt id="topicIcon" className="buttonExtOn">
|
||||||
|
<img src={TopicIconSvg} />
|
||||||
|
</ToolbarButtonExt>
|
||||||
|
<ToolbarButton id="topicNote" className="buttonOn">
|
||||||
|
<img src={TopicNoteSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="topicLink" className="buttonOn">
|
||||||
|
<img src={TopicLinkSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="topicRelation" className="buttonOn">
|
||||||
|
<img src={TopicRelationSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
</div>
|
||||||
|
<div id="separator" className="buttonContainer"></div>
|
||||||
|
{!isTryMode && (
|
||||||
|
<ToolbarRightContainer>
|
||||||
|
<ToolbarButton
|
||||||
|
id="export"
|
||||||
|
className="buttonOn"
|
||||||
|
onClick={() => onAction('export')}
|
||||||
|
>
|
||||||
|
<img src={ExportSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton
|
||||||
|
id="publishIt"
|
||||||
|
className="buttonOn"
|
||||||
|
onClick={() => onAction('publish')}
|
||||||
|
>
|
||||||
|
<img src={PublicSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton
|
||||||
|
id="history"
|
||||||
|
className="buttonOn"
|
||||||
|
onClick={() => onAction('history')}
|
||||||
|
>
|
||||||
|
<img src={HistorySvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton
|
||||||
|
id="print"
|
||||||
|
className="buttonOn"
|
||||||
|
onClick={() => onAction('print')}
|
||||||
|
>
|
||||||
|
<img src={PrintSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton id="account">
|
||||||
|
<img src={AccountSvg} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ActionButton onClick={() => onAction('share')}>
|
||||||
|
{intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' })}
|
||||||
|
</ActionButton>
|
||||||
|
</ToolbarRightContainer>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!memoryPersistence && (
|
</HeaderContainer>
|
||||||
<div id="persist" className="buttonContainer">
|
|
||||||
<div id="save" className="buttonOn">
|
|
||||||
<img src={SaveSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="discard" className="buttonOn">
|
|
||||||
<img src={DiscardSvg}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!readOnlyMode && (
|
|
||||||
<>
|
|
||||||
<div id="edit" className="buttonContainer">
|
|
||||||
<div id="undoEdition" className="buttonOn">
|
|
||||||
<img src={UndoSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="redoEdition" className="buttonOn">
|
|
||||||
<img src={RedoSvg} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="nodeStyle" className="buttonContainer">
|
|
||||||
<div id="addTopic" className="buttonOn">
|
|
||||||
<img src={TopicAddSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="deleteTopic" className="buttonOn">
|
|
||||||
<img src={TopicDeleteSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicBorder" className="buttonExtOn">
|
|
||||||
<img src={TopicBorderSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicColor" className="buttonExtOn">
|
|
||||||
<img src={TopicColorSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicShape" className="buttonExtOn">
|
|
||||||
<img src={TopicShapeSvg} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="font" className="buttonContainer">
|
|
||||||
<div id="fontFamily" className="buttonOn">
|
|
||||||
<img src={FontTypeSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="fontSize" className="buttonExtOn">
|
|
||||||
<img src={FontSizeSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="fontBold" className="buttonOn">
|
|
||||||
<img src={FontBoldSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="fontItalic" className="buttonOn">
|
|
||||||
<img src={FontItalicSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="fontColor" className="buttonExtOn">
|
|
||||||
<img src={FontColorSvg} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="nodeContent" className="buttonContainer">
|
|
||||||
<div id="topicIcon" className="buttonExtOn">
|
|
||||||
<img src={TopicIconSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicNote" className="buttonOn">
|
|
||||||
<img src={TopicNoteSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicLink" className="buttonOn">
|
|
||||||
<img src={TopicLinkSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="topicRelation" className="buttonOn">
|
|
||||||
<img src={TopicRelationSvg} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="separator" className="buttonContainer"></div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{!memoryPersistence && (
|
|
||||||
<div id="toolbarRight">
|
|
||||||
<div id="export" className="buttonOn" onClick={() => onAction('export')}>
|
|
||||||
<img src={ExportSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="publishIt" className="buttonOn" onClick={() => onAction('publish')}>
|
|
||||||
<img src={PublicSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="history" className="buttonOn" onClick={() => onAction('history')}>
|
|
||||||
<img src={HistorySvg} />
|
|
||||||
</div>
|
|
||||||
<div id="print" className="buttonOn" onClick={() => onAction('print')}>
|
|
||||||
<img src={PrintSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="account">
|
|
||||||
<img src={AccountSvg} />
|
|
||||||
</div>
|
|
||||||
<div id="share" className="actionButton" onClick={() => onAction('share')}>
|
|
||||||
{ intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' }) }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
50
packages/editor/src/components/toolbar/styled.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export const HeaderContainer = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
height: 0px;
|
||||||
|
background: #202020;
|
||||||
|
z-index: 1000;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ToolbarContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ToolbarButton = styled.div`
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 4;
|
||||||
|
margin-top: 3px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-left: 2px;
|
||||||
|
margin-left: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ToolbarButtonExt = styled(ToolbarButton)`
|
||||||
|
width: 40px;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const AccountButton = styled.div`
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 3px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ToolbarRightContainer = styled.div`
|
||||||
|
flex-shrink: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
`;
|
30
packages/editor/src/custom.d.ts
vendored
@ -1,30 +0,0 @@
|
|||||||
declare module "*.svg" {
|
|
||||||
const content: any;
|
|
||||||
export default content;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "@wisemapping/mindplot" {
|
|
||||||
const mindplot: {
|
|
||||||
Mindmap: any,
|
|
||||||
PersistenceManager: any,
|
|
||||||
Designer: any,
|
|
||||||
LocalStorageManager: any,
|
|
||||||
Menu: any,
|
|
||||||
DesignerBuilder: any,
|
|
||||||
RESTPersistenceManager: any,
|
|
||||||
DesignerOptionsBuilder: any,
|
|
||||||
buildDesigner: any,
|
|
||||||
$notify: any
|
|
||||||
};
|
|
||||||
export var Mindmap: any;
|
|
||||||
export var PersistenceManager: any;
|
|
||||||
export var Designer: any;
|
|
||||||
export var LocalStorageManager: any;
|
|
||||||
export var Menu: any;
|
|
||||||
export var DesignerBuilder: any;
|
|
||||||
export var RESTPersistenceManager: any;
|
|
||||||
export var DesignerOptionsBuilder: any;
|
|
||||||
export var buildDesigner: any;
|
|
||||||
export var $notify: any;
|
|
||||||
export default mindplot;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
export const Locales = {
|
|
||||||
EN: {},
|
|
||||||
ES: {},
|
|
||||||
DE: {},
|
|
||||||
FR: {}
|
|
||||||
};
|
|
||||||
|
|
@ -2,7 +2,21 @@ import React from 'react';
|
|||||||
import Toolbar, { ToolbarActionType } from './components/toolbar';
|
import Toolbar, { ToolbarActionType } from './components/toolbar';
|
||||||
import Footer from './components/footer';
|
import Footer from './components/footer';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
import * as mindplot from '@wisemapping/mindplot';
|
import {
|
||||||
|
$notify,
|
||||||
|
buildDesigner,
|
||||||
|
LocalStorageManager,
|
||||||
|
PersistenceManager,
|
||||||
|
RESTPersistenceManager,
|
||||||
|
DesignerOptionsBuilder,
|
||||||
|
Designer
|
||||||
|
} from '@wisemapping/mindplot';
|
||||||
|
import FR from './compiled-lang/fr.json';
|
||||||
|
import ES from './compiled-lang/es.json';
|
||||||
|
import EN from './compiled-lang/en.json';
|
||||||
|
import DE from './compiled-lang/de.json';
|
||||||
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var memoryPersistence: boolean;
|
var memoryPersistence: boolean;
|
||||||
var readOnly: boolean;
|
var readOnly: boolean;
|
||||||
@ -15,26 +29,43 @@ declare global {
|
|||||||
var locale: string;
|
var locale: string;
|
||||||
var mindmapLocked: boolean;
|
var mindmapLocked: boolean;
|
||||||
var mindmapLockedMsg: string;
|
var mindmapLockedMsg: string;
|
||||||
|
var mapTitle: string;
|
||||||
|
|
||||||
|
// used in mindplot
|
||||||
|
var designer: Designer;
|
||||||
|
var accountEmail: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EditorPropsType = {
|
export type EditorPropsType = {
|
||||||
initCallback?: (m: typeof mindplot) => () => void;
|
initCallback?: (locale: string) => void;
|
||||||
mapId: number;
|
mapId?: number;
|
||||||
memoryPersistence: boolean;
|
isTryMode: boolean;
|
||||||
readOnlyMode: boolean;
|
readOnlyMode: boolean;
|
||||||
locale?: string;
|
locale?: string;
|
||||||
onAction: (action: ToolbarActionType) => void;
|
onAction: (action: ToolbarActionType) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initMindplot = ({
|
const loadLocaleData = (locale: string) => {
|
||||||
PersistenceManager,
|
switch (locale) {
|
||||||
RESTPersistenceManager,
|
case 'fr':
|
||||||
LocalStorageManager,
|
return FR;
|
||||||
DesignerOptionsBuilder,
|
case 'en':
|
||||||
buildDesigner,
|
return EN;
|
||||||
$notify,
|
case 'es':
|
||||||
}: typeof mindplot) => () => {
|
return ES;
|
||||||
let persistence: typeof PersistenceManager;
|
case 'de':
|
||||||
|
return DE;
|
||||||
|
default:
|
||||||
|
return EN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initMindplot = (locale: string) => {
|
||||||
|
// Change page title ...
|
||||||
|
document.title = `${global.mapTitle} | WiseMapping `;
|
||||||
|
|
||||||
|
// Configure persistence manager ...
|
||||||
|
let persistence: PersistenceManager;
|
||||||
if (!global.memoryPersistence && !global.readOnly) {
|
if (!global.memoryPersistence && !global.readOnly) {
|
||||||
persistence = new RESTPersistenceManager({
|
persistence = new RESTPersistenceManager({
|
||||||
documentUrl: '/c/restful/maps/{id}/document',
|
documentUrl: '/c/restful/maps/{id}/document',
|
||||||
@ -45,8 +76,7 @@ const initMindplot = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
persistence = new LocalStorageManager(
|
persistence = new LocalStorageManager(
|
||||||
`/c/restful/maps/{id}/${global.historyId ? `${global.historyId}/` : ''}document/xml${
|
`/c/restful/maps/{id}/${global.historyId ? `${global.historyId}/` : ''}document/xml${!global.isAuth ? '-pub' : ''
|
||||||
!global.isAuth ? '-pub' : ''
|
|
||||||
}`,
|
}`,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -58,10 +88,14 @@ const initMindplot = ({
|
|||||||
const options = DesignerOptionsBuilder.buildOptions({
|
const options = DesignerOptionsBuilder.buildOptions({
|
||||||
persistenceManager: persistence,
|
persistenceManager: persistence,
|
||||||
readOnly: Boolean(global.readOnly || false),
|
readOnly: Boolean(global.readOnly || false),
|
||||||
mapId: global.mapId,
|
mapId: String(global.mapId),
|
||||||
container: 'mindplot',
|
container: 'mindplot',
|
||||||
zoom: zoomParam || global.userOptions ? global.userOptions.zoom : 1,
|
zoom:
|
||||||
locale: global.locale,
|
zoomParam ||
|
||||||
|
(global.userOptions?.zoom != undefined
|
||||||
|
? Number.parseFloat(global.userOptions.zoom as string)
|
||||||
|
: 0.8),
|
||||||
|
locale: locale,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build designer ...
|
// Build designer ...
|
||||||
@ -69,7 +103,7 @@ const initMindplot = ({
|
|||||||
|
|
||||||
// Load map from XML file persisted on disk...
|
// Load map from XML file persisted on disk...
|
||||||
const instance = PersistenceManager.getInstance();
|
const instance = PersistenceManager.getInstance();
|
||||||
const mindmap = instance.load(global.mapId);
|
const mindmap = instance.load(String(global.mapId));
|
||||||
designer.loadMap(mindmap);
|
designer.loadMap(mindmap);
|
||||||
|
|
||||||
if (global.mindmapLocked) {
|
if (global.mindmapLocked) {
|
||||||
@ -77,28 +111,26 @@ const initMindplot = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Editor({
|
const Editor = ({
|
||||||
initCallback = initMindplot,
|
initCallback = initMindplot,
|
||||||
mapId,
|
mapId,
|
||||||
memoryPersistence,
|
isTryMode: isTryMode,
|
||||||
readOnlyMode,
|
|
||||||
locale = 'en',
|
locale = 'en',
|
||||||
onAction,
|
onAction,
|
||||||
}: EditorPropsType): React.ReactElement {
|
}: EditorPropsType): React.ReactElement => {
|
||||||
|
React.useEffect(() => {
|
||||||
React.useEffect(initCallback(mindplot), []);
|
initCallback(locale);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IntlProvider locale={locale} defaultLocale="en" messages={{}}>
|
<IntlProvider locale={locale} messages={loadLocaleData(locale)}>
|
||||||
<div id="header">
|
<Toolbar
|
||||||
<Toolbar
|
isTryMode={isTryMode}
|
||||||
memoryPersistence={memoryPersistence}
|
onAction={onAction}
|
||||||
readOnlyMode={readOnlyMode}
|
/>
|
||||||
onAction={onAction}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div id="mindplot"></div>
|
<div id="mindplot"></div>
|
||||||
<Footer showTryPanel={memoryPersistence} />
|
<Footer showTryPanel={isTryMode} />
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export default Editor;
|
||||||
|
@ -136,6 +136,7 @@ div.shareModalDialog {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#position {
|
div#position {
|
||||||
|
@ -1,80 +1,6 @@
|
|||||||
@import "toolbar.css";
|
@import "toolbar.css";
|
||||||
|
|
||||||
div#header {
|
|
||||||
width: 100%;
|
|
||||||
height: 0px;
|
|
||||||
background: #202020;
|
|
||||||
z-index: 1000;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#headerActions span {
|
|
||||||
border-bottom: 3px solid rgb(247, 201, 49);
|
|
||||||
}
|
|
||||||
|
|
||||||
div#headerActions a {
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#headerNotifier {
|
|
||||||
border: 1px solid rgb(241, 163, 39);
|
|
||||||
background-color: rgb(252, 235, 192);
|
|
||||||
border-radius: 3px;
|
|
||||||
position: fixed;
|
|
||||||
padding: 5px 9px;
|
|
||||||
color: back;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-top: 5px;
|
|
||||||
display: none;
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#toolbarRight {
|
|
||||||
float: right;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: middle;
|
|
||||||
justify-content: center;
|
|
||||||
margin: 6px 10px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
#account {
|
|
||||||
float: right;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
#account >img {
|
|
||||||
width: 36x;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#accountSettingsPanel{
|
#accountSettingsPanel{
|
||||||
padding:10px 10px;
|
padding:10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#share {
|
|
||||||
margin: 0 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actionButton {
|
|
||||||
float: right;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 0px 10px;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
user-select: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 10px 25px;
|
|
||||||
font-size: 15px;
|
|
||||||
min-width: 64px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-weight: 600;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: white;
|
|
||||||
background-color: #ffa800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actionButton:hover {
|
|
||||||
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
|
||||||
}
|
|
@ -27,6 +27,7 @@ div#footer-logo {
|
|||||||
|
|
||||||
#floating-panel {
|
#floating-panel {
|
||||||
bottom: 80px;
|
bottom: 80px;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#mindplot {
|
div#mindplot {
|
||||||
|
@ -2,6 +2,7 @@ import '../css/editor.css';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Editor from '../../../../src/index';
|
import Editor from '../../../../src/index';
|
||||||
|
import { buildDesigner, LocalStorageManager, PersistenceManager, DesignerOptionsBuilder } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
global.accountName = 'Test User';
|
global.accountName = 'Test User';
|
||||||
global.accountEmail = 'test@example.com';
|
global.accountEmail = 'test@example.com';
|
||||||
@ -11,12 +12,7 @@ global.mapId = 'welcome';
|
|||||||
global.locale = 'en';
|
global.locale = 'en';
|
||||||
|
|
||||||
|
|
||||||
const initialization = ({
|
const initialization = () => {
|
||||||
LocalStorageManager,
|
|
||||||
DesignerOptionsBuilder,
|
|
||||||
buildDesigner,
|
|
||||||
PersistenceManager
|
|
||||||
}) => () => {
|
|
||||||
const p = new LocalStorageManager('samples/{id}.wxml');
|
const p = new LocalStorageManager('samples/{id}.wxml');
|
||||||
const options = DesignerOptionsBuilder.buildOptions({
|
const options = DesignerOptionsBuilder.buildOptions({
|
||||||
persistenceManager: p
|
persistenceManager: p
|
||||||
|
@ -2,25 +2,25 @@ import '../css/embedded.css';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Editor from '../../../../src/index';
|
import Editor from '../../../../src/index';
|
||||||
|
import { buildDesigner, LocalStorageManager, PersistenceManager, DesignerOptionsBuilder } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
const initialization =
|
|
||||||
({ LocalStorageManager, DesignerOptionsBuilder, buildDesigner, PersistenceManager }) =>
|
|
||||||
() => {
|
|
||||||
// Options has been defined in by a external file ?
|
|
||||||
const p = new LocalStorageManager('samples/{id}.wxml');
|
|
||||||
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p });
|
|
||||||
const designer = buildDesigner(options);
|
|
||||||
|
|
||||||
designer.addEvent('loadSuccess', () => {
|
const initialization = () => {
|
||||||
document.getElementById('mindplot').classList.add('ready');
|
// Options has been defined in by a external file ?
|
||||||
});
|
const p = new LocalStorageManager('samples/{id}.wxml');
|
||||||
|
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p });
|
||||||
|
const designer = buildDesigner(options);
|
||||||
|
|
||||||
// Load map from XML file persisted on disk...
|
designer.addEvent('loadSuccess', () => {
|
||||||
const mapId = 'welcome';
|
document.getElementById('mindplot').classList.add('ready');
|
||||||
const persistence = PersistenceManager.getInstance();
|
});
|
||||||
const mindmap = persistence.load(mapId);
|
|
||||||
designer.loadMap(mindmap);
|
// Load map from XML file persisted on disk...
|
||||||
};
|
const mapId = 'welcome';
|
||||||
|
const persistence = PersistenceManager.getInstance();
|
||||||
|
const mindmap = persistence.load(mapId);
|
||||||
|
designer.loadMap(mindmap);
|
||||||
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Editor
|
<Editor
|
||||||
|
@ -2,13 +2,10 @@ import '../css/viewmode.css';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Editor from '../../../../src/index';
|
import Editor from '../../../../src/index';
|
||||||
|
import { buildDesigner, LocalStorageManager, PersistenceManager, DesignerOptionsBuilder } from '@wisemapping/mindplot';
|
||||||
|
|
||||||
const initialization = ({
|
|
||||||
LocalStorageManager,
|
const initialization = () => {
|
||||||
DesignerOptionsBuilder,
|
|
||||||
buildDesigner,
|
|
||||||
PersistenceManager
|
|
||||||
}) => () => {
|
|
||||||
const p = new LocalStorageManager('samples/{id}.wxml');
|
const p = new LocalStorageManager('samples/{id}.wxml');
|
||||||
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p, readOnly: true, saveOnLoad: false });
|
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p, readOnly: true, saveOnLoad: false });
|
||||||
|
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
{
|
{
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"jsx": "react",
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": false,
|
||||||
"module": "commonjs",
|
"module": "amd",
|
||||||
"target": "es5",
|
"moduleResolution": "node",
|
||||||
"jsx": "react",
|
"strict": false,
|
||||||
|
"target": "es6",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"declaration": true,
|
||||||
|
"rootDirs": [
|
||||||
|
"src",
|
||||||
|
],
|
||||||
|
"resolveJsonModule": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"]
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
@ -1,6 +1,4 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
output: {
|
output: {
|
||||||
@ -9,7 +7,9 @@ module.exports = {
|
|||||||
publicPath: '',
|
publicPath: '',
|
||||||
library: {
|
library: {
|
||||||
type: 'umd',
|
type: 'umd',
|
||||||
},
|
}, },
|
||||||
|
stats:{
|
||||||
|
errorDetails: true
|
||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
"editor.bundle": path.join(__dirname, 'src', 'index.tsx')
|
"editor.bundle": path.join(__dirname, 'src', 'index.tsx')
|
||||||
@ -38,7 +38,4 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
|
||||||
new CleanWebpackPlugin(),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,10 @@ const playgroundConfig = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin(),
|
new CleanWebpackPlugin({
|
||||||
|
dangerouslyAllowCleanPatternsOutsideProject: true,
|
||||||
|
dry: false,
|
||||||
|
}),
|
||||||
new CopyPlugin({
|
new CopyPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
{ from: 'test/playground/map-render/images/favicon.ico', to: 'favicon.ico' },
|
{ from: 'test/playground/map-render/images/favicon.ico', to: 'favicon.ico' },
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const { merge } = require('webpack-merge');
|
const { merge } = require('webpack-merge');
|
||||||
const common = require('./webpack.common');
|
const common = require('./webpack.common');
|
||||||
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
|
|
||||||
const prodConfig = {
|
const prodConfig = {
|
||||||
optimization: {
|
optimization: {
|
||||||
@ -8,9 +9,12 @@ const prodConfig = {
|
|||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
react: 'react',
|
react: 'react',
|
||||||
reactDOM: 'react-dom',
|
"react-dom": 'react-dom',
|
||||||
reactIntl: 'react-intl',
|
"react-intl": 'react-intl',
|
||||||
},
|
},
|
||||||
|
plugins: [
|
||||||
|
new CleanWebpackPlugin(),
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = merge(common, prodConfig);
|
module.exports = merge(common, prodConfig);
|
||||||
|
@ -20,33 +20,43 @@
|
|||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@typescript-eslint"
|
"@typescript-eslint"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-underscore-dangle": "off",
|
"no-underscore-dangle": "off",
|
||||||
"no-plusplus": "off",
|
"no-plusplus": "off",
|
||||||
"no-param-reassign": "off",
|
"no-param-reassign": "off",
|
||||||
"max-len": [1,300],
|
"max-len": [
|
||||||
|
1,
|
||||||
|
300
|
||||||
|
],
|
||||||
"class-methods-use-this": "off",
|
"class-methods-use-this": "off",
|
||||||
"no-console" : "off",
|
"no-console": "off",
|
||||||
"no-unused-vars": ["error", { "args": "none" }],
|
|
||||||
"import/extensions": ["error", {
|
|
||||||
"ts": "never"
|
|
||||||
}],
|
|
||||||
// codebase contains many this aliases, fix in the future?
|
// codebase contains many this aliases, fix in the future?
|
||||||
"@typescript-eslint/no-this-alias": "off",
|
"@typescript-eslint/no-this-alias": "off",
|
||||||
// no-unused-vars already used
|
// Remove once migration is completed ...
|
||||||
"@typescript-eslint/no-unused-vars": "off",
|
"@typescript-eslint/no-explicit-any": "warn",
|
||||||
"@typescript-eslint/ban-ts-comment": "warn",
|
"import/extensions": [
|
||||||
"import/no-extraneous-dependencies": ["warn", {"packageDir": "./", "devDependencies": false, "optionalDependencies": false, "peerDependencies": false}]
|
"error",
|
||||||
|
"ignorePackages",
|
||||||
|
{
|
||||||
|
"js": "never",
|
||||||
|
"jsx": "never",
|
||||||
|
"ts": "never",
|
||||||
|
"tsx": "never"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"import/resolver": {
|
"import/resolver": {
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"config": "./webpack.common.js"
|
"config": "./webpack.common.js"
|
||||||
},
|
},
|
||||||
"node": {
|
"node": {
|
||||||
"extensions": [".js",".ts"]
|
"extensions": [
|
||||||
}
|
".js",
|
||||||
}
|
".ts"
|
||||||
}
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,8 +2,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"module": "ES6",
|
"module": "ES6",
|
||||||
"paths": {
|
|
||||||
"@libraries/*": ["../../libraries/*"] }
|
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
12
packages/mindplot/mindplot.d.ts
vendored
@ -1,12 +0,0 @@
|
|||||||
declare module "@wisemapping/mindplot" {
|
|
||||||
const mindplot: {
|
|
||||||
Mindmap,
|
|
||||||
PersistenceManager,
|
|
||||||
Designer,
|
|
||||||
LocalStorageManager,
|
|
||||||
Menu,
|
|
||||||
DesignerBuilder,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default mindplot;
|
|
||||||
}
|
|
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@wisemapping/mindplot",
|
"name": "@wisemapping/mindplot",
|
||||||
"version": "5.0.2",
|
"version": "5.0.3",
|
||||||
"description": "WiseMapping - Mindplot Canvas Library",
|
"description": "WiseMapping - Mindplot Canvas Library",
|
||||||
"homepage": "http://www.wisemapping.org/",
|
"homepage": "http://www.wisemapping.org/",
|
||||||
"main": "dist/mindplot.js",
|
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "src",
|
"lib": "src",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
},
|
},
|
||||||
|
"main": "src/index.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"assets",
|
"assets",
|
||||||
|
@ -21,62 +21,63 @@ import { $assert } from '@wisemapping/core-js';
|
|||||||
import Point from '@wisemapping/web2d';
|
import Point from '@wisemapping/web2d';
|
||||||
import { Mindmap } from '..';
|
import { Mindmap } from '..';
|
||||||
import CommandContext from './CommandContext';
|
import CommandContext from './CommandContext';
|
||||||
|
import ControlPoint from './ControlPoint';
|
||||||
import Events from './Events';
|
import Events from './Events';
|
||||||
import NodeModel from './model/NodeModel';
|
import NodeModel from './model/NodeModel';
|
||||||
import RelationshipModel from './model/RelationshipModel';
|
import RelationshipModel from './model/RelationshipModel';
|
||||||
import Topic from './Topic';
|
import Topic from './Topic';
|
||||||
|
|
||||||
abstract class ActionDispatcher extends Events {
|
abstract class ActionDispatcher extends Events {
|
||||||
static _instance: ActionDispatcher;
|
private static _instance: ActionDispatcher;
|
||||||
|
|
||||||
constructor(commandContext: CommandContext) {
|
constructor(commandContext: CommandContext) {
|
||||||
$assert(commandContext, 'commandContext can not be null');
|
$assert(commandContext, 'commandContext can not be null');
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract addRelationship(model: RelationshipModel, mindmap: Mindmap);
|
abstract addRelationship(model: RelationshipModel, mindmap: Mindmap): void;
|
||||||
|
|
||||||
abstract addTopics(models: NodeModel[], parentTopicId: any[]);
|
abstract addTopics(models: NodeModel[], parentTopicId: number[]): void;
|
||||||
|
|
||||||
abstract deleteEntities(topicsIds: number[], relIds: number[]);
|
abstract deleteEntities(topicsIds: number[], relIds: number[]): void;
|
||||||
|
|
||||||
abstract dragTopic(topicId: number, position: Point, order: number, parentTopic: Topic);
|
abstract dragTopic(topicId: number, position: Point, order: number, parentTopic: Topic): void;
|
||||||
|
|
||||||
abstract moveTopic(topicId: number, position: any);
|
abstract moveTopic(topicId: number, position: Point): void;
|
||||||
|
|
||||||
abstract moveControlPoint(ctrlPoint: this, point: any);
|
abstract moveControlPoint(ctrlPoint: ControlPoint, point: Point): void;
|
||||||
|
|
||||||
abstract changeFontFamilyToTopic(topicIds: number[], fontFamily: string);
|
abstract changeFontFamilyToTopic(topicIds: number[], fontFamily: string): void;
|
||||||
|
|
||||||
abstract changeFontStyleToTopic(topicsIds: number[]);
|
abstract changeFontStyleToTopic(topicsIds: number[]): void;
|
||||||
|
|
||||||
abstract changeFontColorToTopic(topicsIds: number[], color: string);
|
abstract changeFontColorToTopic(topicsIds: number[], color: string): void;
|
||||||
|
|
||||||
abstract changeFontSizeToTopic(topicsIds: number[], size: number);
|
abstract changeFontSizeToTopic(topicsIds: number[], size: number): void;
|
||||||
|
|
||||||
abstract changeBackgroundColorToTopic(topicsIds: number[], color: string);
|
abstract changeBackgroundColorToTopic(topicsIds: number[], color: string): void;
|
||||||
|
|
||||||
abstract changeBorderColorToTopic(topicsIds: number[], color: string);
|
abstract changeBorderColorToTopic(topicsIds: number[], color: string): void;
|
||||||
|
|
||||||
abstract changeShapeTypeToTopic(topicsIds: number[], shapeType: string);
|
abstract changeShapeTypeToTopic(topicsIds: number[], shapeType: string): void;
|
||||||
|
|
||||||
abstract changeFontWeightToTopic(topicsIds: number[]);
|
abstract changeFontWeightToTopic(topicsIds: number[]): void;
|
||||||
|
|
||||||
abstract changeTextToTopic(topicsIds: number[], text: string);
|
abstract changeTextToTopic(topicsIds: number[], text: string): void;
|
||||||
|
|
||||||
abstract shrinkBranch(topicsIds: number[], collapse: boolean);
|
abstract shrinkBranch(topicsIds: number[], collapse: boolean): void;
|
||||||
|
|
||||||
abstract addFeatureToTopic(topicId: number, type: string, attributes: object);
|
abstract addFeatureToTopic(topicId: number, type: string, attributes: object): void;
|
||||||
|
|
||||||
abstract changeFeatureToTopic(topicId: number, featureId: any, attributes: object);
|
abstract changeFeatureToTopic(topicId: number, featureId: number, attributes: object): void;
|
||||||
|
|
||||||
abstract removeFeatureFromTopic(topicId: number, featureId: number);
|
abstract removeFeatureFromTopic(topicId: number, featureId: number): void;
|
||||||
|
|
||||||
static setInstance = (dispatcher: ActionDispatcher) => {
|
static setInstance = (dispatcher: ActionDispatcher) => {
|
||||||
this._instance = dispatcher;
|
this._instance = dispatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
static getInstance = (): ActionDispatcher => ActionDispatcher._instance;
|
static getInstance = (): ActionDispatcher => ActionDispatcher._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ActionDispatcher;
|
export default ActionDispatcher;
|
||||||
|
@ -21,7 +21,11 @@ import Topic from './Topic';
|
|||||||
import Shape from './util/Shape';
|
import Shape from './util/Shape';
|
||||||
|
|
||||||
class CentralTopic extends Topic {
|
class CentralTopic extends Topic {
|
||||||
_registerEvents() {
|
_buildDragShape() {
|
||||||
|
// Ignore ..
|
||||||
|
}
|
||||||
|
|
||||||
|
_registerEvents(): void {
|
||||||
super._registerEvents();
|
super._registerEvents();
|
||||||
|
|
||||||
// This disable the drag of the central topic.
|
// This disable the drag of the central topic.
|
||||||
@ -31,17 +35,14 @@ class CentralTopic extends Topic {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
workoutIncomingConnectionPoint(): Point {
|
||||||
workoutIncomingConnectionPoint() {
|
|
||||||
return this.getPosition();
|
return this.getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
setCursor(type: string) {
|
||||||
setCursor(type) {
|
|
||||||
super.setCursor(type === 'move' ? 'default' : type);
|
super.setCursor(type === 'move' ? 'default' : type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
|
||||||
updateTopicShape() {
|
updateTopicShape() {
|
||||||
// Overwite behaviour ...
|
// Overwite behaviour ...
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ class CentralTopic extends Topic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
workoutOutgoingConnectionPoint(targetPosition) {
|
workoutOutgoingConnectionPoint(targetPosition: Point) {
|
||||||
$assert(targetPosition, 'targetPoint can not be null');
|
$assert(targetPosition, 'targetPoint can not be null');
|
||||||
const pos = this.getPosition();
|
const pos = this.getPosition();
|
||||||
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
@ -23,15 +23,18 @@ abstract class Command {
|
|||||||
|
|
||||||
static _uuid: number;
|
static _uuid: number;
|
||||||
|
|
||||||
|
private _discardDuplicated: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._id = Command._nextUUID();
|
this._id = Command._nextUUID();
|
||||||
|
this._discardDuplicated = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract execute(commandContext:CommandContext):void;
|
abstract execute(commandContext: CommandContext): void;
|
||||||
|
|
||||||
abstract undoExecute(commandContext:CommandContext):void;
|
abstract undoExecute(commandContext: CommandContext): void;
|
||||||
|
|
||||||
getId():number {
|
getId(): number {
|
||||||
return this._id;
|
return this._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +45,14 @@ abstract class Command {
|
|||||||
this._uuid += 1;
|
this._uuid += 1;
|
||||||
return this._uuid;
|
return this._uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get discardDuplicated(): string {
|
||||||
|
return this._discardDuplicated;
|
||||||
|
}
|
||||||
|
|
||||||
|
set discardDuplicated(value: string) {
|
||||||
|
this._discardDuplicated = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Command;
|
export default Command;
|
||||||
|
@ -20,8 +20,33 @@ import { $defined } from '@wisemapping/core-js';
|
|||||||
|
|
||||||
import Shape from './util/Shape';
|
import Shape from './util/Shape';
|
||||||
import ActionDispatcher from './ActionDispatcher';
|
import ActionDispatcher from './ActionDispatcher';
|
||||||
|
import Workspace from './Workspace';
|
||||||
|
|
||||||
class ControlPoint {
|
class ControlPoint {
|
||||||
|
private control1: Elipse;
|
||||||
|
|
||||||
|
private control2: Elipse;
|
||||||
|
|
||||||
|
private _controlPointsController: Elipse[];
|
||||||
|
|
||||||
|
private _controlLines: Line[];
|
||||||
|
|
||||||
|
private _isBinded: boolean;
|
||||||
|
|
||||||
|
_line: Line;
|
||||||
|
|
||||||
|
private _workspace: Workspace;
|
||||||
|
|
||||||
|
private _endPoint: any[];
|
||||||
|
|
||||||
|
private _orignalCtrlPoint: any;
|
||||||
|
|
||||||
|
private _controls: any;
|
||||||
|
|
||||||
|
private _mouseMoveFunction: (e: Event) => void;
|
||||||
|
|
||||||
|
private _mouseUpFunction: (e: Event) => void;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.control1 = new Elipse({
|
this.control1 = new Elipse({
|
||||||
width: 6,
|
width: 6,
|
||||||
@ -70,7 +95,7 @@ class ControlPoint {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setLine(line) {
|
setLine(line: Line) {
|
||||||
if ($defined(this._line)) {
|
if ($defined(this._line)) {
|
||||||
this._removeLine();
|
this._removeLine();
|
||||||
}
|
}
|
||||||
@ -93,7 +118,7 @@ class ControlPoint {
|
|||||||
if ($defined(this._line)) this._createControlPoint();
|
if ($defined(this._line)) this._createControlPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
_createControlPoint() {
|
private _createControlPoint() {
|
||||||
this._controls = this._line.getLine().getControlPoints();
|
this._controls = this._line.getLine().getControlPoints();
|
||||||
let pos = this._line.getLine().getFrom();
|
let pos = this._line.getLine().getFrom();
|
||||||
this._controlPointsController[0].setPosition(
|
this._controlPointsController[0].setPosition(
|
||||||
@ -117,11 +142,11 @@ class ControlPoint {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeLine() {
|
private _removeLine() {
|
||||||
// Overwrite default behaviour ...
|
// Overwrite default behaviour ...
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouseDown(event, point, me) {
|
private _mouseDown(event: Event, point, me) {
|
||||||
if (!this._isBinded) {
|
if (!this._isBinded) {
|
||||||
this._isBinded = true;
|
this._isBinded = true;
|
||||||
this._mouseMoveFunction = (e) => {
|
this._mouseMoveFunction = (e) => {
|
||||||
@ -129,7 +154,7 @@ class ControlPoint {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
|
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
|
||||||
this._mouseUpFunction = (e) => {
|
this._mouseUpFunction = (e: Event) => {
|
||||||
me._mouseUp(e, point, me);
|
me._mouseUp(e, point, me);
|
||||||
};
|
};
|
||||||
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
|
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
|
||||||
@ -139,7 +164,7 @@ class ControlPoint {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouseMoveEvent(event, point) {
|
private _mouseMoveEvent(event: MouseEvent, point: Point) {
|
||||||
const screen = this._workspace.getScreenManager();
|
const screen = this._workspace.getScreenManager();
|
||||||
const pos = screen.getWorkspaceMousePosition(event);
|
const pos = screen.getWorkspaceMousePosition(event);
|
||||||
|
|
||||||
@ -162,7 +187,7 @@ class ControlPoint {
|
|||||||
this._line.getLine().updateLine(point);
|
this._line.getLine().updateLine(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouseUp(event, point) {
|
private _mouseUp(event: MouseEvent, point: Point) {
|
||||||
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
|
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
|
||||||
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
|
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
|
||||||
|
|
||||||
@ -171,13 +196,13 @@ class ControlPoint {
|
|||||||
this._isBinded = false;
|
this._isBinded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouseClick(event) {
|
_mouseClick(event: MouseEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setVisibility(visible) {
|
setVisibility(visible: boolean) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
this._controlLines[0].moveToFront();
|
this._controlLines[0].moveToFront();
|
||||||
this._controlLines[1].moveToFront();
|
this._controlLines[1].moveToFront();
|
||||||
@ -190,7 +215,7 @@ class ControlPoint {
|
|||||||
this._controlLines[1].setVisibility(visible);
|
this._controlLines[1].setVisibility(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
addToWorkspace(workspace) {
|
addToWorkspace(workspace: Workspace): void {
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
workspace.append(this._controlPointsController[0]);
|
workspace.append(this._controlPointsController[0]);
|
||||||
workspace.append(this._controlPointsController[1]);
|
workspace.append(this._controlPointsController[1]);
|
||||||
@ -198,7 +223,7 @@ class ControlPoint {
|
|||||||
workspace.append(this._controlLines[1]);
|
workspace.append(this._controlLines[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromWorkspace(workspace) {
|
removeFromWorkspace(workspace: Workspace) {
|
||||||
this._workspace = null;
|
this._workspace = null;
|
||||||
workspace.removeChild(this._controlPointsController[0]);
|
workspace.removeChild(this._controlPointsController[0]);
|
||||||
workspace.removeChild(this._controlPointsController[1]);
|
workspace.removeChild(this._controlPointsController[1]);
|
||||||
@ -206,20 +231,21 @@ class ControlPoint {
|
|||||||
workspace.removeChild(this._controlLines[1]);
|
workspace.removeChild(this._controlLines[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getControlPoint(index) {
|
getControlPoint(index: number): ControlPoint {
|
||||||
return this._controls[index];
|
return this._controls[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
getOriginalEndPoint(index) {
|
getOriginalEndPoint(index: number) {
|
||||||
return this._endPoint[index];
|
return this._endPoint[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
getOriginalCtrlPoint(index) {
|
getOriginalCtrlPoint(index: number): ControlPoint {
|
||||||
return this._orignalCtrlPoint[index];
|
return this._orignalCtrlPoint[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FROM = 0;
|
||||||
|
|
||||||
|
static TO = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlPoint.FROM = 0;
|
|
||||||
ControlPoint.TO = 1;
|
|
||||||
|
|
||||||
export default ControlPoint;
|
export default ControlPoint;
|
21
packages/mindplot/src/components/CursorType.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2021] [wisemapping]
|
||||||
|
*
|
||||||
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
|
* "powered by wisemapping" text requirement on every single page;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the license at
|
||||||
|
*
|
||||||
|
* http://www.wisemapping.org/license
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
type CursorType = 'default' | 'move';
|
||||||
|
|
||||||
|
export default CursorType;
|
@ -56,6 +56,7 @@ import { DesignerOptions } from './DesignerOptionsBuilder';
|
|||||||
import MainTopic from './MainTopic';
|
import MainTopic from './MainTopic';
|
||||||
import DragTopic from './DragTopic';
|
import DragTopic from './DragTopic';
|
||||||
import CentralTopic from './CentralTopic';
|
import CentralTopic from './CentralTopic';
|
||||||
|
import FeatureType from './model/FeatureType';
|
||||||
|
|
||||||
class Designer extends Events {
|
class Designer extends Events {
|
||||||
private _mindmap: Mindmap;
|
private _mindmap: Mindmap;
|
||||||
@ -136,8 +137,8 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _registerWheelEvents(): void {
|
private _registerWheelEvents(): void {
|
||||||
const zoomFactor = 1.006;
|
const zoomFactor = 1.02;
|
||||||
document.addEventListener('wheel', (event) => {
|
document.addEventListener('wheel', (event: WheelEvent) => {
|
||||||
if (event.deltaX > 0 || event.deltaY > 0) {
|
if (event.deltaX > 0 || event.deltaY > 0) {
|
||||||
this.zoomOut(zoomFactor);
|
this.zoomOut(zoomFactor);
|
||||||
} else {
|
} else {
|
||||||
@ -151,14 +152,14 @@ class Designer extends Events {
|
|||||||
return this._actionDispatcher;
|
return this._actionDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
addEvent(type: string, listener): Events {
|
||||||
addEvent(type: string, listener: any): void {
|
|
||||||
if (type === TopicEvent.EDIT || type === TopicEvent.CLICK) {
|
if (type === TopicEvent.EDIT || type === TopicEvent.CLICK) {
|
||||||
const editor = TopicEventDispatcher.getInstance();
|
const editor = TopicEventDispatcher.getInstance();
|
||||||
editor.addEvent(type, listener);
|
editor.addEvent(type, listener);
|
||||||
} else {
|
} else {
|
||||||
super.addEvent(type, listener);
|
super.addEvent(type, listener);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _registerMouseEvents() {
|
private _registerMouseEvents() {
|
||||||
@ -186,7 +187,7 @@ class Designer extends Events {
|
|||||||
screenManager.addEvent('dblclick', (event: MouseEvent) => {
|
screenManager.addEvent('dblclick', (event: MouseEvent) => {
|
||||||
if (workspace.isWorkspaceEventsEnabled()) {
|
if (workspace.isWorkspaceEventsEnabled()) {
|
||||||
const mousePos = screenManager.getWorkspaceMousePosition(event);
|
const mousePos = screenManager.getWorkspaceMousePosition(event);
|
||||||
const centralTopic:CentralTopic = me.getModel()
|
const centralTopic: CentralTopic = me.getModel()
|
||||||
.getCentralTopic();
|
.getCentralTopic();
|
||||||
|
|
||||||
const model = me._createChildModel(centralTopic, mousePos);
|
const model = me._createChildModel(centralTopic, mousePos);
|
||||||
@ -208,7 +209,7 @@ class Designer extends Events {
|
|||||||
|
|
||||||
dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => {
|
dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => {
|
||||||
dragTopic.updateFreeLayout(event);
|
dragTopic.updateFreeLayout(event);
|
||||||
if (!dragTopic.isFreeLayoutOn(event)) {
|
if (!dragTopic.isFreeLayoutOn()) {
|
||||||
// The node is being drag. Is the connection still valid ?
|
// The node is being drag. Is the connection still valid ?
|
||||||
dragConnector.checkConnection(dragTopic);
|
dragConnector.checkConnection(dragTopic);
|
||||||
|
|
||||||
@ -354,6 +355,20 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shrinkSelectedBranch() {
|
||||||
|
const nodes = this.getModel().filterSelectedTopics();
|
||||||
|
if (nodes.length <= 0 || nodes.length !== 1) {
|
||||||
|
// If there are more than one node selected,
|
||||||
|
$notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED_COLLAPSE'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Execute event ...
|
||||||
|
const topic = nodes[0];
|
||||||
|
if (topic.getType() !== 'CentralTopic') {
|
||||||
|
this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
copyToClipboard(): void {
|
copyToClipboard(): void {
|
||||||
let topics = this.getModel().filterSelectedTopics();
|
let topics = this.getModel().filterSelectedTopics();
|
||||||
if (topics.length <= 0) {
|
if (topics.length <= 0) {
|
||||||
@ -876,7 +891,7 @@ class Designer extends Events {
|
|||||||
addIconType(iconType: string): void {
|
addIconType(iconType: string): void {
|
||||||
const topicsIds = this.getModel().filterTopicsIds();
|
const topicsIds = this.getModel().filterTopicsIds();
|
||||||
if (topicsIds.length > 0) {
|
if (topicsIds.length > 0) {
|
||||||
this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeatureFactory.Icon.id, {
|
this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeatureFactory.Icon.id as FeatureType, {
|
||||||
id: iconType,
|
id: iconType,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -33,25 +33,35 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
|||||||
// Register load events ...
|
// Register load events ...
|
||||||
designer = new Designer(options, divContainer);
|
designer = new Designer(options, divContainer);
|
||||||
designer.addEvent('loadSuccess', () => {
|
designer.addEvent('loadSuccess', () => {
|
||||||
// @ts-ignore
|
globalThis.mindmapLoadReady = true;
|
||||||
window.mindmapLoadReady = true;
|
|
||||||
console.log('Map loadded successfully');
|
console.log('Map loadded successfully');
|
||||||
});
|
});
|
||||||
|
|
||||||
const onerrorFn = (message: string, url, lineNo) => {
|
const onerrorFn = (msg: string, url: string, lineNo: number, columnNo: number, error: Error) => {
|
||||||
// Close loading dialog ...
|
const message = [
|
||||||
// @ts-ignore
|
`Message: ${msg}`,
|
||||||
if (window.waitDialog) {
|
`URL: ${url}`,
|
||||||
// @ts-ignore
|
`Line: ${lineNo}`,
|
||||||
window.waitDialog.close();
|
`Column: ${columnNo}`,
|
||||||
// @ts-ignore
|
].join(' - ');
|
||||||
window.waitDialog = null;
|
console.log(message);
|
||||||
}
|
|
||||||
|
// Send error to server ...
|
||||||
|
$.ajax({
|
||||||
|
method: 'post',
|
||||||
|
url: '/c/restful/logger/editor',
|
||||||
|
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
||||||
|
data: JSON.stringify({
|
||||||
|
jsErrorMsg: message,
|
||||||
|
jsStack: JSON.stringify(error),
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
mapId: options.mapId,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
// Open error dialog only in case of mindmap loading errors. The rest of the error are reported but not display the dialog.
|
// Open error dialog only in case of mindmap loading errors. The rest of the error are reported but not display the dialog.
|
||||||
// Remove this in the near future.
|
// Remove this in the near future.
|
||||||
// @ts-ignore
|
if (!globalThis.mindmapLoadReady) {
|
||||||
if (!window.mindmapLoadReady) {
|
|
||||||
$notifyModal($msg('UNEXPECTED_ERROR_LOADING'));
|
$notifyModal($msg('UNEXPECTED_ERROR_LOADING'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -64,7 +74,7 @@ export function buildDesigner(options: DesignerOptions): Designer {
|
|||||||
|
|
||||||
// Register toolbar event ...
|
// Register toolbar event ...
|
||||||
if ($('#toolbar').length) {
|
if ($('#toolbar').length) {
|
||||||
const menu = new Menu(designer, 'toolbar', options.mapId ? options.mapId : 'unknown');
|
const menu = new Menu(designer, 'toolbar');
|
||||||
|
|
||||||
// If a node has focus, focus can be move to another node using the keys.
|
// If a node has focus, focus can be move to another node using the keys.
|
||||||
designer.cleanScreen = () => {
|
designer.cleanScreen = () => {
|
||||||
|
@ -18,41 +18,48 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import Keyboard from './Keyboard';
|
import Keyboard from './Keyboard';
|
||||||
|
import { Designer } from '..';
|
||||||
|
import Topic from './Topic';
|
||||||
|
|
||||||
class DesignerKeyboard extends Keyboard {
|
class DesignerKeyboard extends Keyboard {
|
||||||
constructor(designer) {
|
// eslint-disable-next-line no-use-before-define
|
||||||
super(designer);
|
static _instance: DesignerKeyboard;
|
||||||
|
|
||||||
|
constructor(designer: Designer) {
|
||||||
|
super();
|
||||||
$assert(designer, 'designer can not be null');
|
$assert(designer, 'designer can not be null');
|
||||||
this._registerEvents(designer);
|
this._registerEvents(designer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_registerEvents(designer) {
|
private _registerEvents(designer: Designer) {
|
||||||
// Try with the keyboard ..
|
// Try with the keyboard ..
|
||||||
const model = designer.getModel();
|
const model = designer.getModel();
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['backspace'], (event) => {
|
['backspace'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.deleteSelectedEntities();
|
designer.deleteSelectedEntities();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['space'], () => {
|
['space'], (event: Event) => {
|
||||||
designer.shrinkSelectedBranch();
|
designer.shrinkSelectedBranch();
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['f2'], (event) => {
|
['f2'], (event: Event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const node = model.selectedTopic();
|
const node = model.selectedTopic();
|
||||||
if (node) {
|
if (node) {
|
||||||
node.showTextEditor();
|
node.showTextEditor(node.getText());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['del'], (event) => {
|
['del'], (event: Event) => {
|
||||||
designer.deleteSelectedEntities();
|
designer.deleteSelectedEntities();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@ -64,63 +71,63 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['insert'], (event) => {
|
['insert'], (event: Event) => {
|
||||||
designer.createChildForSelectedNode();
|
designer.createChildForSelectedNode();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['tab'], (event) => {
|
['tab'], (eventevent: Event) => {
|
||||||
designer.createChildForSelectedNode();
|
designer.createChildForSelectedNode();
|
||||||
event.preventDefault();
|
eventevent.preventDefault();
|
||||||
event.stopPropagation();
|
eventevent.stopPropagation();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['meta+enter'], (event) => {
|
['meta+enter'], (eventevent: Event) => {
|
||||||
event.preventDefault();
|
eventevent.preventDefault();
|
||||||
event.stopPropagation();
|
eventevent.stopPropagation();
|
||||||
designer.createChildForSelectedNode();
|
designer.createChildForSelectedNode();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+z', 'meta+z'], (event) => {
|
['ctrl+z', 'meta+z'], (event: Event) => {
|
||||||
event.preventDefault(event);
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.undo();
|
designer.undo();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+c', 'meta+c'], (event) => {
|
['ctrl+c', 'meta+c'], (event: Event) => {
|
||||||
event.preventDefault(event);
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.copyToClipboard();
|
designer.copyToClipboard();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+v', 'meta+v'], (event) => {
|
['ctrl+v', 'meta+v'], (event: Event) => {
|
||||||
event.preventDefault(event);
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.pasteClipboard();
|
designer.pasteClipboard();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], (event) => {
|
['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.redo();
|
designer.redo();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+a', 'meta+a'], (event) => {
|
['ctrl+a', 'meta+a'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
designer.selectAll();
|
designer.selectAll();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+b', 'meta+b'], (event) => {
|
['ctrl+b', 'meta+b'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -128,14 +135,14 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+s', 'meta+s'], (event) => {
|
['ctrl+s', 'meta+s'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
$(document).find('#save').trigger('click');
|
$(document).find('#save').trigger('click');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+i', 'meta+i'], (event) => {
|
['ctrl+i', 'meta+i'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -143,7 +150,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['ctrl+shift+a', 'meta+shift+a'], (event) => {
|
['ctrl+shift+a', 'meta+shift+a'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -151,7 +158,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['meta+=', 'ctrl+='], (event) => {
|
['meta+=', 'ctrl+='], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -159,7 +166,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
['meta+-', 'ctrl+-'], (event) => {
|
['meta+-', 'ctrl+-'], (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -168,7 +175,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
);
|
);
|
||||||
const me = this;
|
const me = this;
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
'right', (event) => {
|
'right', (event: Event) => {
|
||||||
const node = model.selectedTopic();
|
const node = model.selectedTopic();
|
||||||
if (node) {
|
if (node) {
|
||||||
if (node.isCentralTopic()) {
|
if (node.isCentralTopic()) {
|
||||||
@ -187,7 +194,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
'left', (event) => {
|
'left', (event: Event) => {
|
||||||
const node = model.selectedTopic();
|
const node = model.selectedTopic();
|
||||||
if (node) {
|
if (node) {
|
||||||
if (node.isCentralTopic()) {
|
if (node.isCentralTopic()) {
|
||||||
@ -206,7 +213,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
'up', (event) => {
|
'up', (event: Event) => {
|
||||||
const node = model.selectedTopic();
|
const node = model.selectedTopic();
|
||||||
if (node) {
|
if (node) {
|
||||||
if (!node.isCentralTopic()) {
|
if (!node.isCentralTopic()) {
|
||||||
@ -221,7 +228,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.addShortcut(
|
this.addShortcut(
|
||||||
'down', (event) => {
|
'down', (event: Event) => {
|
||||||
const node = model.selectedTopic();
|
const node = model.selectedTopic();
|
||||||
if (node) {
|
if (node) {
|
||||||
if (!node.isCentralTopic()) {
|
if (!node.isCentralTopic()) {
|
||||||
@ -238,7 +245,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
const excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'];
|
const excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'];
|
||||||
|
|
||||||
$(document).on('keypress', (event) => {
|
$(document).on('keypress', (event) => {
|
||||||
let keyCode;
|
let keyCode: number;
|
||||||
// Firefox doesn't skip special keys for keypress event...
|
// Firefox doesn't skip special keys for keypress event...
|
||||||
if (event.key && excludes.includes(event.key.toLowerCase())) {
|
if (event.key && excludes.includes(event.key.toLowerCase())) {
|
||||||
return;
|
return;
|
||||||
@ -250,8 +257,10 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
keyCode = event.keyCode;
|
keyCode = event.keyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const specialKey = $.hotkeys.specialKeys[keyCode];
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
if (['enter', 'capslock'].indexOf(specialKey) === -1 && !$.hotkeys.shiftNums[keyCode]) {
|
const jq: any = $;
|
||||||
|
const specialKey = jq.hotkeys.specialKeys[keyCode];
|
||||||
|
if (['enter', 'capslock'].indexOf(specialKey) === -1 && !jq.hotkeys.shiftNums[keyCode]) {
|
||||||
const nodes = designer.getModel().filterSelectedTopics();
|
const nodes = designer.getModel().filterSelectedTopics();
|
||||||
if (nodes.length > 0) {
|
if (nodes.length > 0) {
|
||||||
// If a modifier is press, the key selected must be ignored.
|
// If a modifier is press, the key selected must be ignored.
|
||||||
@ -266,7 +275,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_goToBrother(designer, node, direction) {
|
private _goToBrother(designer: Designer, node: Topic, direction) {
|
||||||
const parent = node.getParent();
|
const parent = node.getParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const brothers = parent.getChildren();
|
const brothers = parent.getChildren();
|
||||||
@ -305,7 +314,7 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_goToSideChild(designer, node, side) {
|
private _goToSideChild(designer: Designer, node: Topic, side: 'LEFT' | 'RIGHT') {
|
||||||
const children = node.getChildren();
|
const children = node.getChildren();
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
let target = children[0];
|
let target = children[0];
|
||||||
@ -331,14 +340,14 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_goToParent(designer, node) {
|
private _goToParent(designer: Designer, node: Topic) {
|
||||||
const parent = node.getParent();
|
const parent = node.getParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this._goToNode(designer, parent);
|
this._goToNode(designer, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_goToChild(designer, node) {
|
private _goToChild(designer, node) {
|
||||||
const children = node.getChildren();
|
const children = node.getChildren();
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
let target = children[0];
|
let target = children[0];
|
||||||
@ -354,79 +363,79 @@ class DesignerKeyboard extends Keyboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_goToNode(designer, node) {
|
private _goToNode(designer: Designer, node: Topic) {
|
||||||
// First deselect all the nodes ...
|
// First deselect all the nodes ...
|
||||||
designer.deselectAll();
|
designer.deselectAll();
|
||||||
|
|
||||||
// Give focus to the selected node....
|
// Give focus to the selected node....
|
||||||
node.setOnFocus(true);
|
node.setOnFocus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static register = function register(designer: Designer) {
|
||||||
|
this._instance = new DesignerKeyboard(designer);
|
||||||
|
};
|
||||||
|
|
||||||
|
static specialKeys = {
|
||||||
|
8: 'backspace',
|
||||||
|
9: 'tab',
|
||||||
|
10: 'return',
|
||||||
|
13: 'enter',
|
||||||
|
16: 'shift',
|
||||||
|
17: 'ctrl',
|
||||||
|
18: 'alt',
|
||||||
|
19: 'pause',
|
||||||
|
20: 'capslock',
|
||||||
|
27: 'esc',
|
||||||
|
32: 'space',
|
||||||
|
33: 'pageup',
|
||||||
|
34: 'pagedown',
|
||||||
|
35: 'end',
|
||||||
|
36: 'home',
|
||||||
|
37: 'left',
|
||||||
|
38: 'up',
|
||||||
|
39: 'right',
|
||||||
|
40: 'down',
|
||||||
|
45: 'insert',
|
||||||
|
46: 'del',
|
||||||
|
96: '0',
|
||||||
|
97: '1',
|
||||||
|
98: '2',
|
||||||
|
99: '3',
|
||||||
|
100: '4',
|
||||||
|
101: '5',
|
||||||
|
102: '6',
|
||||||
|
103: '7',
|
||||||
|
104: '8',
|
||||||
|
105: '9',
|
||||||
|
106: '*',
|
||||||
|
107: '+',
|
||||||
|
109: '-',
|
||||||
|
110: '.',
|
||||||
|
111: '/',
|
||||||
|
112: 'f1',
|
||||||
|
113: 'f2',
|
||||||
|
114: 'f3',
|
||||||
|
115: 'f4',
|
||||||
|
116: 'f5',
|
||||||
|
117: 'f6',
|
||||||
|
118: 'f7',
|
||||||
|
119: 'f8',
|
||||||
|
120: 'f9',
|
||||||
|
121: 'f10',
|
||||||
|
122: 'f11',
|
||||||
|
123: 'f12',
|
||||||
|
144: 'numlock',
|
||||||
|
145: 'scroll',
|
||||||
|
186: ';',
|
||||||
|
191: '/',
|
||||||
|
220: '\\',
|
||||||
|
222: "'",
|
||||||
|
224: 'meta',
|
||||||
|
};
|
||||||
|
|
||||||
|
static getInstance() {
|
||||||
|
return this._instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DesignerKeyboard.specialKeys = {
|
|
||||||
8: 'backspace',
|
|
||||||
9: 'tab',
|
|
||||||
10: 'return',
|
|
||||||
13: 'enter',
|
|
||||||
16: 'shift',
|
|
||||||
17: 'ctrl',
|
|
||||||
18: 'alt',
|
|
||||||
19: 'pause',
|
|
||||||
20: 'capslock',
|
|
||||||
27: 'esc',
|
|
||||||
32: 'space',
|
|
||||||
33: 'pageup',
|
|
||||||
34: 'pagedown',
|
|
||||||
35: 'end',
|
|
||||||
36: 'home',
|
|
||||||
37: 'left',
|
|
||||||
38: 'up',
|
|
||||||
39: 'right',
|
|
||||||
40: 'down',
|
|
||||||
45: 'insert',
|
|
||||||
46: 'del',
|
|
||||||
96: '0',
|
|
||||||
97: '1',
|
|
||||||
98: '2',
|
|
||||||
99: '3',
|
|
||||||
100: '4',
|
|
||||||
101: '5',
|
|
||||||
102: '6',
|
|
||||||
103: '7',
|
|
||||||
104: '8',
|
|
||||||
105: '9',
|
|
||||||
106: '*',
|
|
||||||
107: '+',
|
|
||||||
109: '-',
|
|
||||||
110: '.',
|
|
||||||
111: '/',
|
|
||||||
112: 'f1',
|
|
||||||
113: 'f2',
|
|
||||||
114: 'f3',
|
|
||||||
115: 'f4',
|
|
||||||
116: 'f5',
|
|
||||||
117: 'f6',
|
|
||||||
118: 'f7',
|
|
||||||
119: 'f8',
|
|
||||||
120: 'f9',
|
|
||||||
121: 'f10',
|
|
||||||
122: 'f11',
|
|
||||||
123: 'f12',
|
|
||||||
144: 'numlock',
|
|
||||||
145: 'scroll',
|
|
||||||
186: ';',
|
|
||||||
191: '/',
|
|
||||||
220: '\\',
|
|
||||||
222: "'",
|
|
||||||
224: 'meta',
|
|
||||||
};
|
|
||||||
|
|
||||||
DesignerKeyboard.register = function register(designer) {
|
|
||||||
this._instance = new DesignerKeyboard(designer);
|
|
||||||
};
|
|
||||||
|
|
||||||
DesignerKeyboard.getInstance = function getInstance() {
|
|
||||||
return this._instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DesignerKeyboard;
|
export default DesignerKeyboard;
|
@ -17,11 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import PersistenceManager from './PersistenceManager';
|
import PersistenceManager from './PersistenceManager';
|
||||||
import { Size } from './Size';
|
import SizeType from './SizeType';
|
||||||
|
|
||||||
export type DesignerOptions = {
|
export type DesignerOptions = {
|
||||||
zoom: number,
|
zoom: number,
|
||||||
containerSize?: Size,
|
containerSize?: SizeType,
|
||||||
readOnly?: boolean,
|
readOnly?: boolean,
|
||||||
mapId?: string,
|
mapId?: string,
|
||||||
container: string,
|
container: string,
|
||||||
|
@ -16,15 +16,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
|
import Command from './Command';
|
||||||
|
import CommandContext from './CommandContext';
|
||||||
|
|
||||||
class DesignerUndoManager {
|
class DesignerUndoManager {
|
||||||
|
private _undoQueue: Command[];
|
||||||
|
|
||||||
|
private _redoQueue: Command[];
|
||||||
|
|
||||||
|
private _baseId: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._undoQueue = [];
|
this._undoQueue = [];
|
||||||
this._redoQueue = [];
|
this._redoQueue = [];
|
||||||
this._baseId = 0;
|
this._baseId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enqueue(command) {
|
enqueue(command: Command) {
|
||||||
$assert(command, 'Command can not be null');
|
$assert(command, 'Command can not be null');
|
||||||
const { length } = this._undoQueue;
|
const { length } = this._undoQueue;
|
||||||
if (command.discardDuplicated && length > 0) {
|
if (command.discardDuplicated && length > 0) {
|
||||||
@ -39,7 +47,7 @@ class DesignerUndoManager {
|
|||||||
this._redoQueue = [];
|
this._redoQueue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
execUndo(commandContext) {
|
execUndo(commandContext: CommandContext) {
|
||||||
if (this._undoQueue.length > 0) {
|
if (this._undoQueue.length > 0) {
|
||||||
const command = this._undoQueue.pop();
|
const command = this._undoQueue.pop();
|
||||||
this._redoQueue.push(command);
|
this._redoQueue.push(command);
|
@ -17,9 +17,25 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
import DragTopic from './DragTopic';
|
import DragTopic from './DragTopic';
|
||||||
|
import EventBusDispatcher from './layout/EventBusDispatcher';
|
||||||
|
import Workspace from './Workspace';
|
||||||
|
|
||||||
class DragManager {
|
class DragManager {
|
||||||
constructor(workspace, eventDispatcher) {
|
private _workspace: Workspace;
|
||||||
|
|
||||||
|
private _designerModel: Workspace;
|
||||||
|
|
||||||
|
private _isDragInProcess: boolean;
|
||||||
|
|
||||||
|
private _eventDispatcher: EventBusDispatcher;
|
||||||
|
|
||||||
|
private _listeners;
|
||||||
|
|
||||||
|
private _mouseMoveListener;
|
||||||
|
|
||||||
|
private _mouseUpListener;
|
||||||
|
|
||||||
|
constructor(workspace: Workspace, eventDispatcher: EventBusDispatcher) {
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
this._designerModel = workspace;
|
this._designerModel = workspace;
|
||||||
this._listeners = {};
|
this._listeners = {};
|
||||||
@ -34,7 +50,7 @@ class DragManager {
|
|||||||
const screen = workspace.getScreenManager();
|
const screen = workspace.getScreenManager();
|
||||||
const dragManager = this;
|
const dragManager = this;
|
||||||
const me = this;
|
const me = this;
|
||||||
const mouseDownListener = function mouseDownListener(event) {
|
const mouseDownListener = function mouseDownListener() {
|
||||||
if (workspace.isWorkspaceEventsEnabled()) {
|
if (workspace.isWorkspaceEventsEnabled()) {
|
||||||
// Disable double drag...
|
// Disable double drag...
|
||||||
workspace.enableWorkspaceEvents(false);
|
workspace.enableWorkspaceEvents(false);
|
||||||
@ -62,11 +78,11 @@ class DragManager {
|
|||||||
node.addEvent('mousedown', mouseDownListener);
|
node.addEvent('mousedown', mouseDownListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(node) {
|
remove() {
|
||||||
throw new Error('Not implemented: DragManager.prototype.remove');
|
throw new Error('Not implemented: DragManager.prototype.remove');
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildMouseMoveListener(workspace, dragNode, dragManager) {
|
protected _buildMouseMoveListener(workspace: Workspace, dragNode, dragManager: DragManager) {
|
||||||
const screen = workspace.getScreenManager();
|
const screen = workspace.getScreenManager();
|
||||||
const me = this;
|
const me = this;
|
||||||
const result = (event) => {
|
const result = (event) => {
|
||||||
@ -98,7 +114,7 @@ class DragManager {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildMouseUpListener(workspace, node, dragNode, dragManager) {
|
protected _buildMouseUpListener(workspace: Workspace, node, dragNode, dragManager: DragManager) {
|
||||||
const screen = workspace.getScreenManager();
|
const screen = workspace.getScreenManager();
|
||||||
const me = this;
|
const me = this;
|
||||||
const result = (event) => {
|
const result = (event) => {
|
@ -210,9 +210,7 @@ class DragTopic {
|
|||||||
return this.getConnectedToTopic() != null;
|
return this.getConnectedToTopic() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isFreeLayoutOn(dragTopic) {
|
isFreeLayoutOn() {
|
||||||
// return this._isFreeLayoutEnabled;
|
|
||||||
// Disable free layout ...
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,15 +17,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class Events {
|
class Events {
|
||||||
|
private $events;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.$events = {};
|
this.$events = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static _removeOn(string) {
|
static _removeOn(string: string) {
|
||||||
return string.replace(/^on([A-Z])/, (full, first) => first.toLowerCase());
|
return string.replace(/^on([A-Z])/, (full, first) => first.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
addEvent(typeName, fn, internal) {
|
addEvent(typeName: string, fn?, internal?: boolean): Events {
|
||||||
const type = Events._removeOn(typeName);
|
const type = Events._removeOn(typeName);
|
||||||
|
|
||||||
// Add function had not been added yet
|
// Add function had not been added yet
|
||||||
@ -36,12 +38,11 @@ class Events {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark reference ...
|
// Mark reference ...
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
fn.internal = Boolean(internal);
|
fn.internal = Boolean(internal);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
fireEvent(typeName, eventArgs, delay) {
|
fireEvent(typeName: string, eventArgs?, delay?: boolean): Events {
|
||||||
const type = Events._removeOn(typeName);
|
const type = Events._removeOn(typeName);
|
||||||
const events = this.$events[type];
|
const events = this.$events[type];
|
||||||
if (!events) return this;
|
if (!events) return this;
|
||||||
@ -57,7 +58,7 @@ class Events {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEvent(typeName, fn) {
|
removeEvent(typeName: string, fn?): Events {
|
||||||
const type = Events._removeOn(typeName);
|
const type = Events._removeOn(typeName);
|
||||||
const events = this.$events[type];
|
const events = this.$events[type];
|
||||||
if (events && !fn.internal) {
|
if (events && !fn.internal) {
|
@ -16,24 +16,29 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { Mindmap } from '..';
|
||||||
import PersistenceManager from './PersistenceManager';
|
import PersistenceManager from './PersistenceManager';
|
||||||
|
|
||||||
class LocalStorageManager extends PersistenceManager {
|
class LocalStorageManager extends PersistenceManager {
|
||||||
constructor(documentUrl, forceLoad) {
|
private documentUrl: string;
|
||||||
|
|
||||||
|
private forceLoad: boolean;
|
||||||
|
|
||||||
|
constructor(documentUrl: string, forceLoad: boolean) {
|
||||||
super();
|
super();
|
||||||
this.documentUrl = documentUrl;
|
this.documentUrl = documentUrl;
|
||||||
this.forceLoad = forceLoad;
|
this.forceLoad = forceLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveMapXml(mapId, mapXml, pref, saveHistory, events) {
|
saveMapXml(mapId: string, mapXml: string) {
|
||||||
localStorage.setItem(`${mapId}-xml`, mapXml);
|
localStorage.setItem(`${mapId}-xml`, mapXml);
|
||||||
}
|
}
|
||||||
|
|
||||||
discardChanges(mapId) {
|
discardChanges(mapId: string) {
|
||||||
localStorage.removeItem(`${mapId}-xml`);
|
localStorage.removeItem(`${mapId}-xml`);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMapDom(mapId) {
|
loadMapDom(mapId: string) {
|
||||||
let xml = localStorage.getItem(`${mapId}-xml`);
|
let xml = localStorage.getItem(`${mapId}-xml`);
|
||||||
if (xml == null || this.forceLoad) {
|
if (xml == null || this.forceLoad) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -58,7 +63,7 @@ class LocalStorageManager extends PersistenceManager {
|
|||||||
return $.parseXML(xml);
|
return $.parseXML(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockMap(mindmap) {
|
unlockMap(mindmap: Mindmap) {
|
||||||
// Ignore, no implementation required ...
|
// Ignore, no implementation required ...
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,25 +16,30 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
import { Point, Group } from '@wisemapping/web2d';
|
import { Point, Group, ElementClass } from '@wisemapping/web2d';
|
||||||
|
|
||||||
import Topic from './Topic';
|
import Topic from './Topic';
|
||||||
import { TopicShape } from './model/INodeModel';
|
import { TopicShape } from './model/INodeModel';
|
||||||
import Shape from './util/Shape';
|
import Shape from './util/Shape';
|
||||||
|
import NodeModel from './model/NodeModel';
|
||||||
|
import Workspace from './Workspace';
|
||||||
|
import SizeType from './SizeType';
|
||||||
|
|
||||||
class MainTopic extends Topic {
|
class MainTopic extends Topic {
|
||||||
|
private INNER_RECT_ATTRIBUTES: { stroke: string; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.Topic
|
* @extends mindplot.Topic
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param model
|
* @param model
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
constructor(model, options) {
|
constructor(model: NodeModel, options) {
|
||||||
super(model, options);
|
super(model, options);
|
||||||
this.INNER_RECT_ATTRIBUTES = { stroke: '0.5 solid #009900' };
|
this.INNER_RECT_ATTRIBUTES = { stroke: '0.5 solid #009900' };
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildDragShape() {
|
_buildDragShape(): ElementClass {
|
||||||
const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
innerShape.setSize(size.width, size.height);
|
innerShape.setSize(size.width, size.height);
|
||||||
@ -70,9 +75,7 @@ class MainTopic extends Topic {
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
updateTopicShape(targetTopic: Topic) {
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
updateTopicShape(targetTopic, workspace) {
|
|
||||||
// Change figure based on the connected topic ...
|
// Change figure based on the connected topic ...
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
let shapeType = model.getShapeType();
|
let shapeType = model.getShapeType();
|
||||||
@ -86,7 +89,7 @@ class MainTopic extends Topic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
disconnect(workspace) {
|
disconnect(workspace: Workspace) {
|
||||||
super.disconnect(workspace);
|
super.disconnect(workspace);
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
let shapeType = model.getShapeType();
|
let shapeType = model.getShapeType();
|
||||||
@ -99,7 +102,7 @@ class MainTopic extends Topic {
|
|||||||
innerShape.setVisibility(true);
|
innerShape.setVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePositionOnChangeSize(oldSize, newSize) {
|
_updatePositionOnChangeSize(oldSize: SizeType, newSize: SizeType) {
|
||||||
const xOffset = Math.round((newSize.width - oldSize.width) / 2);
|
const xOffset = Math.round((newSize.width - oldSize.width) / 2);
|
||||||
const pos = this.getPosition();
|
const pos = this.getPosition();
|
||||||
if ($defined(pos)) {
|
if ($defined(pos)) {
|
||||||
@ -112,22 +115,20 @@ class MainTopic extends Topic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
workoutIncomingConnectionPoint(sourcePosition: Point) {
|
||||||
workoutIncomingConnectionPoint(sourcePosition) {
|
|
||||||
return Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
return Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
workoutOutgoingConnectionPoint(targetPosition: Point) {
|
||||||
workoutOutgoingConnectionPoint(targetPosition) {
|
|
||||||
$assert(targetPosition, 'targetPoint can not be null');
|
$assert(targetPosition, 'targetPoint can not be null');
|
||||||
const pos = this.getPosition();
|
const pos = this.getPosition();
|
||||||
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
|
|
||||||
let result;
|
let result: Point;
|
||||||
if (this.getShapeType() === TopicShape.LINE) {
|
if (this.getShapeType() === TopicShape.LINE) {
|
||||||
result = new Point();
|
result = new Point();
|
||||||
const groupPosition = this._elem2d.getPosition();
|
const groupPosition = this.get2DElement().getPosition();
|
||||||
const innerShareSize = this.getInnerShape().getSize();
|
const innerShareSize = this.getInnerShape().getSize();
|
||||||
|
|
||||||
if (innerShareSize) {
|
if (innerShareSize) {
|
||||||
@ -149,7 +150,7 @@ class MainTopic extends Topic {
|
|||||||
result.y = pos.y + size.height / 2;
|
result.y = pos.y + size.height / 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = Shape.calculateRectConnectionPoint(pos, size, isAtRight, true);
|
result = Shape.calculateRectConnectionPoint(pos, size, isAtRight);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
@ -17,9 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
import { $defined } from '@wisemapping/core-js';
|
import { $defined } from '@wisemapping/core-js';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
// TODO: use jquery.hotkeys from npm or setup eslint-import-resolver-alias plugin
|
|
||||||
// eslint-disable-next-line import/no-unresolved, import/no-extraneous-dependencies
|
import initHotKeyPluggin from '../../../../libraries/jquery.hotkeys';
|
||||||
import initHotKeyPluggin from '@libraries/jquery.hotkeys';
|
|
||||||
import Events from './Events';
|
import Events from './Events';
|
||||||
import ActionDispatcher from './ActionDispatcher';
|
import ActionDispatcher from './ActionDispatcher';
|
||||||
|
|
||||||
|
@ -16,17 +16,29 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
|
import { ElementClass } from '@wisemapping/web2d';
|
||||||
import TopicConfig from './TopicConfig';
|
import TopicConfig from './TopicConfig';
|
||||||
|
import NodeModel from './model/NodeModel';
|
||||||
|
import Workspace from './Workspace';
|
||||||
import DragTopic from './DragTopic';
|
import DragTopic from './DragTopic';
|
||||||
|
import LayoutManager from './layout/LayoutManager';
|
||||||
|
import SizeType from './SizeType';
|
||||||
|
import PositionType from './PositionType';
|
||||||
|
|
||||||
class NodeGraph {
|
abstract class NodeGraph {
|
||||||
/**
|
private _mouseEvents: boolean;
|
||||||
* @constructs
|
|
||||||
* @param {mindplot.model.NodeModel} nodeModel
|
private _options;
|
||||||
* @param {Object<Number, String, Boolean>} options
|
|
||||||
* @throws will throw an error if nodeModel is null or undefined
|
private _onFocus: boolean;
|
||||||
*/
|
|
||||||
constructor(nodeModel, options) {
|
private _size: SizeType;
|
||||||
|
|
||||||
|
private _model: NodeModel;
|
||||||
|
|
||||||
|
private _elem2d: ElementClass;
|
||||||
|
|
||||||
|
constructor(nodeModel: NodeModel, options) {
|
||||||
$assert(nodeModel, 'model can not be null');
|
$assert(nodeModel, 'model can not be null');
|
||||||
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
@ -36,46 +48,33 @@ class NodeGraph {
|
|||||||
this._size = { width: 50, height: 20 };
|
this._size = { width: 50, height: 20 };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if option is set to read-only */
|
isReadOnly(): boolean {
|
||||||
isReadOnly() {
|
|
||||||
return this._options.readOnly;
|
return this._options.readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return model type */
|
getType(): string {
|
||||||
getType() {
|
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
return model.getType();
|
return model.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
setId(id: number) {
|
||||||
* @param {String} id
|
|
||||||
* @throws will throw an error if the topic id is not a number
|
|
||||||
*/
|
|
||||||
setId(id) {
|
|
||||||
$assert(typeof id === 'number', `id is not a number:${id}`);
|
$assert(typeof id === 'number', `id is not a number:${id}`);
|
||||||
this.getModel().setId(id);
|
this.getModel().setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_set2DElement(elem2d) {
|
protected _set2DElement(elem2d: ElementClass) {
|
||||||
this._elem2d = elem2d;
|
this._elem2d = elem2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
get2DElement(): ElementClass {
|
||||||
* @return 2D element
|
|
||||||
* @throws will throw an error if the element is null or undefined within node graph
|
|
||||||
*/
|
|
||||||
get2DElement() {
|
|
||||||
$assert(this._elem2d, 'NodeGraph has not been initialized properly');
|
$assert(this._elem2d, 'NodeGraph has not been initialized properly');
|
||||||
return this._elem2d;
|
return this._elem2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @abstract */
|
abstract setPosition(point, fireEvent): void;
|
||||||
setPosition(point, fireEvent) {
|
|
||||||
throw new Error('Unsupported operation');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addEvent(type, listener) {
|
addEvent(type: string, listener) {
|
||||||
const elem = this.get2DElement();
|
const elem = this.get2DElement();
|
||||||
elem.addEvent(type, listener);
|
elem.addEvent(type, listener);
|
||||||
}
|
}
|
||||||
@ -102,41 +101,30 @@ class NodeGraph {
|
|||||||
return this._mouseEvents;
|
return this._mouseEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {Object<Number>} size */
|
getSize(): SizeType {
|
||||||
getSize() {
|
|
||||||
return this._size;
|
return this._size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {Object<Number>} size */
|
setSize(size: SizeType, force?: boolean) {
|
||||||
setSize(size) {
|
this._size.width = size.width;
|
||||||
this._size.width = parseInt(size.width, 10);
|
this._size.height = size.height;
|
||||||
this._size.height = parseInt(size.height, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getModel(): NodeModel {
|
||||||
* @return {mindplot.model.NodeModel} the node model
|
|
||||||
*/
|
|
||||||
getModel() {
|
|
||||||
$assert(this._model, 'Model has not been initialized yet');
|
$assert(this._model, 'Model has not been initialized yet');
|
||||||
return this._model;
|
return this._model;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
setModel(model: NodeModel) {
|
||||||
* @param {mindplot.NodeModel} model the node model
|
|
||||||
* @throws will throw an error if model is null or undefined
|
|
||||||
*/
|
|
||||||
setModel(model) {
|
|
||||||
$assert(model, 'Model can not be null');
|
$assert(model, 'Model can not be null');
|
||||||
this._model = model;
|
this._model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
getId(): number {
|
||||||
getId() {
|
|
||||||
return this._model.getId();
|
return this._model.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
setOnFocus(focus: boolean) {
|
||||||
setOnFocus(focus) {
|
|
||||||
if (this._onFocus !== focus) {
|
if (this._onFocus !== focus) {
|
||||||
this._onFocus = focus;
|
this._onFocus = focus;
|
||||||
const outerShape = this.getOuterShape();
|
const outerShape = this.getOuterShape();
|
||||||
@ -157,29 +145,30 @@ class NodeGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {Boolean} true if the node graph is on focus */
|
abstract closeEditors(): void;
|
||||||
isOnFocus() {
|
|
||||||
|
abstract setCursor(type: string): void;
|
||||||
|
|
||||||
|
abstract getOuterShape(): ElementClass;
|
||||||
|
|
||||||
|
isOnFocus(): boolean {
|
||||||
return this._onFocus;
|
return this._onFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
dispose(workspace: Workspace) {
|
||||||
dispose(workspace) {
|
|
||||||
this.setOnFocus(false);
|
this.setOnFocus(false);
|
||||||
workspace.removeChild(this);
|
workspace.removeChild(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
createDragNode(layoutManager) {
|
createDragNode(layoutManager: LayoutManager) {
|
||||||
const dragShape = this._buildDragShape();
|
const dragShape = this._buildDragShape();
|
||||||
return new DragTopic(dragShape, this, layoutManager);
|
return new DragTopic(dragShape, this, layoutManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildDragShape() {
|
abstract _buildDragShape();
|
||||||
$assert(false, '_buildDragShape must be implemented by all nodes.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** */
|
getPosition(): PositionType {
|
||||||
getPosition() {
|
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
return model.getPosition();
|
return model.getPosition();
|
||||||
}
|
}
|
@ -17,10 +17,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
|
import { Mindmap } from '..';
|
||||||
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
|
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
|
||||||
|
|
||||||
class PersistenceManager {
|
abstract class PersistenceManager {
|
||||||
save(mindmap, editorProperties, saveHistory, events, sync) {
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
static _instance: PersistenceManager;
|
||||||
|
|
||||||
|
save(mindmap: Mindmap, editorProperties, saveHistory: boolean, events, sync: boolean) {
|
||||||
$assert(mindmap, 'mindmap can not be null');
|
$assert(mindmap, 'mindmap can not be null');
|
||||||
$assert(editorProperties, 'editorProperties can not be null');
|
$assert(editorProperties, 'editorProperties can not be null');
|
||||||
|
|
||||||
@ -36,45 +40,39 @@ class PersistenceManager {
|
|||||||
this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync);
|
this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
events.onError(this._buildError());
|
events.onError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load(mapId) {
|
load(mapId: string) {
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
const domDocument = this.loadMapDom(mapId);
|
const domDocument = this.loadMapDom(mapId);
|
||||||
return PersistenceManager.loadFromDom(mapId, domDocument);
|
return PersistenceManager.loadFromDom(mapId, domDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
discardChanges(mapId) {
|
abstract discardChanges(mapId: string): void;
|
||||||
throw new Error('Method must be implemented');
|
|
||||||
|
abstract loadMapDom(mapId: string): Document;
|
||||||
|
|
||||||
|
abstract saveMapXml(mapId: string, mapXml, pref, saveHistory, events, sync);
|
||||||
|
|
||||||
|
abstract unlockMap(mindmap: Mindmap): void;
|
||||||
|
|
||||||
|
static init = (instance: PersistenceManager) => {
|
||||||
|
this._instance = instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
static getInstance(): PersistenceManager {
|
||||||
|
return this._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMapDom(mapId) {
|
static loadFromDom(mapId: string, mapDom: Document) {
|
||||||
throw new Error('Method must be implemented');
|
$assert(mapId, 'mapId can not be null');
|
||||||
}
|
$assert(mapDom, 'mapDom can not be null');
|
||||||
|
|
||||||
saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) {
|
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDom);
|
||||||
throw new Error('Method must be implemented');
|
return serializer.loadFromDom(mapDom, mapId);
|
||||||
}
|
|
||||||
|
|
||||||
unlockMap(mindmap) {
|
|
||||||
throw new Error('Method must be implemented');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistenceManager.init = (instance) => {
|
|
||||||
PersistenceManager._instance = instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
PersistenceManager.getInstance = () => PersistenceManager._instance;
|
|
||||||
|
|
||||||
PersistenceManager.loadFromDom = function loadFromDom(mapId, mapDom) {
|
|
||||||
$assert(mapId, 'mapId can not be null');
|
|
||||||
$assert(mapDom, 'mapDom can not be null');
|
|
||||||
|
|
||||||
const serializer = XMLSerializerFactory.createInstanceFromDocument(mapDom);
|
|
||||||
return serializer.loadFromDom(mapDom, mapId);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PersistenceManager;
|
export default PersistenceManager;
|
20
packages/mindplot/src/components/PositionType.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2021] [wisemapping]
|
||||||
|
*
|
||||||
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
|
* "powered by wisemapping" text requirement on every single page;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the license at
|
||||||
|
*
|
||||||
|
* http://www.wisemapping.org/license
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
type PositionType = { x: number, y: number };
|
||||||
|
|
||||||
|
export default PositionType;
|
@ -258,7 +258,7 @@ class Relationship extends ConnectionLine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @typescript-eslint/ban-types
|
// @typescript-eslint/ban-types
|
||||||
addEvent(eventType: string, listener: any) {
|
addEvent(eventType: string, listener) {
|
||||||
let type = eventType;
|
let type = eventType;
|
||||||
// Translate to web 2d events ...
|
// Translate to web 2d events ...
|
||||||
if (type === 'onfocus') {
|
if (type === 'onfocus') {
|
||||||
|
@ -28,7 +28,7 @@ class RelationshipPivot {
|
|||||||
|
|
||||||
private _designer: Designer;
|
private _designer: Designer;
|
||||||
|
|
||||||
private _mouseMoveEvent: MouseEvent;
|
private _mouseMoveEvent;
|
||||||
|
|
||||||
private _onClickEvent: (event: MouseEvent) => void;
|
private _onClickEvent: (event: MouseEvent) => void;
|
||||||
|
|
||||||
@ -154,8 +154,8 @@ class RelationshipPivot {
|
|||||||
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
||||||
|
|
||||||
const spoint = new Point();
|
const spoint = new Point();
|
||||||
spoint.x = parseInt(controlPoint[0].x, 10) + parseInt(sourcePosition.x, 10);
|
spoint.x = parseInt(controlPoint[0].x, 10) + sourcePosition.x;
|
||||||
spoint.y = parseInt(controlPoint[0].y, 10) + parseInt(sourcePosition.y, 10);
|
spoint.y = parseInt(controlPoint[0].y, 10) + sourcePosition.y;
|
||||||
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,10 +17,25 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { Mindmap } from '..';
|
||||||
import { $msg } from './Messages';
|
import { $msg } from './Messages';
|
||||||
import PersistenceManager from './PersistenceManager';
|
import PersistenceManager from './PersistenceManager';
|
||||||
|
|
||||||
class RESTPersistenceManager extends PersistenceManager {
|
class RESTPersistenceManager extends PersistenceManager {
|
||||||
|
private documentUrl: string;
|
||||||
|
|
||||||
|
private revertUrl: string;
|
||||||
|
|
||||||
|
private lockUrl: string;
|
||||||
|
|
||||||
|
private timestamp: string;
|
||||||
|
|
||||||
|
private session: string;
|
||||||
|
|
||||||
|
private onSave: boolean;
|
||||||
|
|
||||||
|
private clearTimeout;
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
$assert(options.documentUrl, 'documentUrl can not be null');
|
$assert(options.documentUrl, 'documentUrl can not be null');
|
||||||
$assert(options.revertUrl, 'revertUrl can not be null');
|
$assert(options.revertUrl, 'revertUrl can not be null');
|
||||||
@ -36,41 +51,38 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
this.session = options.session;
|
this.session = options.session;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) {
|
saveMapXml(mapId: string, mapXml: Document, pref: string, saveHistory: boolean, events, sync: boolean): void {
|
||||||
const data = {
|
const data = {
|
||||||
id: mapId,
|
id: mapId,
|
||||||
xml: mapXml,
|
xml: mapXml,
|
||||||
properties: pref,
|
properties: pref,
|
||||||
};
|
};
|
||||||
|
|
||||||
const persistence = this;
|
|
||||||
let query = `minor=${!saveHistory}`;
|
let query = `minor=${!saveHistory}`;
|
||||||
query = `${query}×tamp=${this.timestamp}`;
|
query = `${query}×tamp=${this.timestamp}`;
|
||||||
query = `${query}&session=${this.session}`;
|
query = `${query}&session=${this.session}`;
|
||||||
|
|
||||||
if (!persistence.onSave) {
|
if (!this.onSave) {
|
||||||
// Mark save in process and fire a event unlocking the save ...
|
// Mark save in process and fire a event unlocking the save ...
|
||||||
persistence.onSave = true;
|
this.onSave = true;
|
||||||
persistence.clearTimeout = setTimeout(() => {
|
this.clearTimeout = setTimeout(() => {
|
||||||
persistence.clearTimeout = null;
|
this.clearTimeout = null;
|
||||||
persistence.onSave = false;
|
this.onSave = false;
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
|
const persistence = this;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: `${this.documentUrl.replace('{id}', mapId)}?${query}`,
|
|
||||||
type: 'put',
|
type: 'put',
|
||||||
|
url: `${this.documentUrl.replace('{id}', mapId)}?${query}`,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
contentType: 'application/json; charset=utf-8',
|
contentType: 'application/json; charset=utf-8',
|
||||||
async: !sync,
|
async: !sync,
|
||||||
|
|
||||||
success(successData, textStatus, jqXHRresponseText) {
|
success(successData) {
|
||||||
persistence.timestamp = successData;
|
persistence.timestamp = successData;
|
||||||
events.onSuccess();
|
events.onSuccess();
|
||||||
},
|
},
|
||||||
error(jqXHR, textStatus, errorThrown) {
|
|
||||||
events.onError(persistence._buildError());
|
|
||||||
},
|
|
||||||
complete() {
|
complete() {
|
||||||
// Clear event timeout ...
|
// Clear event timeout ...
|
||||||
if (persistence.clearTimeout) {
|
if (persistence.clearTimeout) {
|
||||||
@ -78,7 +90,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
}
|
}
|
||||||
persistence.onSave = false;
|
persistence.onSave = false;
|
||||||
},
|
},
|
||||||
fail(xhr, textStatus) {
|
error(xhr) {
|
||||||
const { responseText } = xhr;
|
const { responseText } = xhr;
|
||||||
let userMsg = { severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED') };
|
let userMsg = { severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED') };
|
||||||
|
|
||||||
@ -102,7 +114,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
discardChanges(mapId) {
|
discardChanges(mapId: string) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: this.revertUrl.replace('{id}', mapId),
|
url: this.revertUrl.replace('{id}', mapId),
|
||||||
async: false,
|
async: false,
|
||||||
@ -114,7 +126,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockMap(mindmap) {
|
unlockMap(mindmap: Mindmap) {
|
||||||
const mapId = mindmap.getId();
|
const mapId = mindmap.getId();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: this.lockUrl.replace('{id}', mapId),
|
url: this.lockUrl.replace('{id}', mapId),
|
||||||
@ -128,7 +140,7 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildError(jsonSeverResponse) {
|
private _buildError(jsonSeverResponse) {
|
||||||
let message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
|
let message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
|
||||||
let severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
|
let severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
|
||||||
|
|
||||||
@ -142,9 +154,9 @@ class RESTPersistenceManager extends PersistenceManager {
|
|||||||
return { severity, message };
|
return { severity, message };
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMapDom(mapId) {
|
loadMapDom(mapId: string): Document {
|
||||||
// Let's try to open one from the local directory ...
|
// Let's try to open one from the local directory ...
|
||||||
let xml;
|
let xml: Document;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: `${this.documentUrl.replace('{id}', mapId)}/xml`,
|
url: `${this.documentUrl.replace('{id}', mapId)}/xml`,
|
||||||
method: 'get',
|
method: 'get',
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert } from '@wisemapping/core-js';
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import { Point } from '@wisemapping/web2d';
|
import { Point } from '@wisemapping/web2d';
|
||||||
|
import Icon from './Icon';
|
||||||
import Topic from './Topic';
|
import Topic from './Topic';
|
||||||
|
|
||||||
class ScreenManager {
|
class ScreenManager {
|
||||||
@ -24,7 +25,7 @@ class ScreenManager {
|
|||||||
|
|
||||||
private _padding: { x: number; y: number; };
|
private _padding: { x: number; y: number; };
|
||||||
|
|
||||||
private _clickEvents: ((event: UIEvent) => void)[];
|
private _clickEvents;
|
||||||
|
|
||||||
private _scale: number;
|
private _scale: number;
|
||||||
|
|
||||||
@ -60,14 +61,13 @@ class ScreenManager {
|
|||||||
this._scale = scale;
|
this._scale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEvent(eventType: string, listener: any) {
|
addEvent(eventType: string, listener) {
|
||||||
if (eventType === 'click') this._clickEvents.push(listener);
|
if (eventType === 'click') this._clickEvents.push(listener);
|
||||||
else this._divContainer.bind(eventType, listener);
|
else this._divContainer.bind(eventType, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEvent(event: string, listener: any) {
|
removeEvent(event: string, listener) {
|
||||||
if (event === 'click') {
|
if (event === 'click') {
|
||||||
// @ts-ignore @Todo: needs review ...
|
|
||||||
this._clickEvents.remove(listener);
|
this._clickEvents.remove(listener);
|
||||||
} else {
|
} else {
|
||||||
this._divContainer.unbind(event, listener);
|
this._divContainer.unbind(event, listener);
|
||||||
@ -76,7 +76,7 @@ class ScreenManager {
|
|||||||
|
|
||||||
fireEvent(type: string, event: UIEvent = null) {
|
fireEvent(type: string, event: UIEvent = null) {
|
||||||
if (type === 'click') {
|
if (type === 'click') {
|
||||||
this._clickEvents.forEach((listener: (arg0: any, arg1: any) => void) => {
|
this._clickEvents.forEach((listener) => {
|
||||||
listener(type, event);
|
listener(type, event);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -102,7 +102,7 @@ class ScreenManager {
|
|||||||
return { x, y };
|
return { x, y };
|
||||||
}
|
}
|
||||||
|
|
||||||
getWorkspaceIconPosition(e: { getImage: () => any; getSize: () => any; getGroup: () => any; }) {
|
getWorkspaceIconPosition(e: Icon) {
|
||||||
// Retrieve current icon position.
|
// Retrieve current icon position.
|
||||||
const image = e.getImage();
|
const image = e.getImage();
|
||||||
const elementPosition = image.getPosition();
|
const elementPosition = image.getPosition();
|
||||||
|
@ -19,16 +19,22 @@ import { Elipse } from '@wisemapping/web2d';
|
|||||||
|
|
||||||
import TopicConfig from './TopicConfig';
|
import TopicConfig from './TopicConfig';
|
||||||
import ActionDispatcher from './ActionDispatcher';
|
import ActionDispatcher from './ActionDispatcher';
|
||||||
|
import Topic from './Topic';
|
||||||
|
|
||||||
class ShirinkConnector {
|
class ShirinkConnector {
|
||||||
constructor(topic) {
|
private _isShrink: boolean;
|
||||||
|
|
||||||
|
private _ellipse: Elipse;
|
||||||
|
|
||||||
|
constructor(topic: Topic) {
|
||||||
this._isShrink = false;
|
this._isShrink = false;
|
||||||
const ellipse = new Elipse(TopicConfig.INNER_RECT_ATTRIBUTES);
|
const ellipse = new Elipse(TopicConfig.INNER_RECT_ATTRIBUTES);
|
||||||
this._ellipse = ellipse;
|
this._ellipse = ellipse;
|
||||||
|
|
||||||
ellipse.setFill('rgb(62,118,179)');
|
ellipse.setFill('rgb(62,118,179)');
|
||||||
|
|
||||||
ellipse.setSize(TopicConfig.CONNECTOR_WIDTH, TopicConfig.CONNECTOR_WIDTH);
|
ellipse.setSize(TopicConfig.CONNECTOR_WIDTH, TopicConfig.CONNECTOR_WIDTH);
|
||||||
ellipse.addEvent('click', (event) => {
|
ellipse.addEvent('click', (event: Event) => {
|
||||||
const model = topic.getModel();
|
const model = topic.getModel();
|
||||||
const collapse = !model.areChildrenShrunken();
|
const collapse = !model.areChildrenShrunken();
|
||||||
|
|
||||||
@ -39,12 +45,12 @@ class ShirinkConnector {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
ellipse.addEvent('mousedown', (event) => {
|
ellipse.addEvent('mousedown', (event: Event) => {
|
||||||
// Avoid node creation ...
|
// Avoid node creation ...
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
ellipse.addEvent('dblclick', (event) => {
|
ellipse.addEvent('dblclick', (event: Event) => {
|
||||||
// Avoid node creation ...
|
// Avoid node creation ...
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
@ -58,12 +64,11 @@ class ShirinkConnector {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ellipse.setCursor('default');
|
ellipse.setCursor('default');
|
||||||
this._fillColor = '#f7f7f7';
|
|
||||||
const model = topic.getModel();
|
const model = topic.getModel();
|
||||||
this.changeRender(model.areChildrenShrunken());
|
this.changeRender(model.areChildrenShrunken());
|
||||||
}
|
}
|
||||||
|
|
||||||
changeRender(isShrink) {
|
changeRender(isShrink: boolean) {
|
||||||
const elipse = this._ellipse;
|
const elipse = this._ellipse;
|
||||||
if (isShrink) {
|
if (isShrink) {
|
||||||
elipse.setStroke('2', 'solid');
|
elipse.setStroke('2', 'solid');
|
||||||
@ -73,36 +78,35 @@ class ShirinkConnector {
|
|||||||
this._isShrink = isShrink;
|
this._isShrink = isShrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
setVisibility(value) {
|
setVisibility(value: boolean): void {
|
||||||
this._ellipse.setVisibility(value);
|
this._ellipse.setVisibility(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
setOpacity(opacity) {
|
setOpacity(opacity: number): void {
|
||||||
this._ellipse.setOpacity(opacity);
|
this._ellipse.setOpacity(opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFill(color) {
|
setFill(color: string): void {
|
||||||
this._fillColor = color;
|
|
||||||
this._ellipse.setFill(color);
|
this._ellipse.setFill(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAttribute(name, value) {
|
setAttribute(name: string, value) {
|
||||||
this._ellipse.setAttribute(name, value);
|
this._ellipse.setAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
addToWorkspace(group) {
|
addToWorkspace(group): void {
|
||||||
group.append(this._ellipse);
|
group.append(this._ellipse);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPosition(x, y) {
|
setPosition(x: number, y: number): void {
|
||||||
this._ellipse.setPosition(x, y);
|
this._ellipse.setPosition(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveToBack() {
|
moveToBack(): void {
|
||||||
this._ellipse.moveToBack();
|
this._ellipse.moveToBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
moveToFront() {
|
moveToFront(): void {
|
||||||
this._ellipse.moveToFront();
|
this._ellipse.moveToFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +0,0 @@
|
|||||||
export type Size = {
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
};
|
|
23
packages/mindplot/src/components/SizeType.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2021] [wisemapping]
|
||||||
|
*
|
||||||
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
|
* "powered by wisemapping" text requirement on every single page;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the license at
|
||||||
|
*
|
||||||
|
* http://www.wisemapping.org/license
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
type SizeType = {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SizeType;
|