diff --git a/README.md b/README.md index 164f2c93..069ec594 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,16 @@ Mindmapping made simple: Host and create your own mindmaps. Share your mindmap s TeamMapper is based on mindmapp (https://github.com/cedoor/mindmapp , discontinued). In contrast to mindmapp, TeamMapper features shared mindmapping sessions for your team based on websockets. +![TeamMapper Screenshot](docs/teammapper-screenshot.png?raw=true "TeamMapper Screenshot with two users") + ## Features: - Host and create your own mindmaps - Set node images, colors and font properties. - Shortcuts -- Import and export functionality (JSON, PDF, PNG...) +- Import and export functionality (JSON, SVG, PDF, PNG...) - Mutli user support: Share your mindmap with friends and collegues. Work at the same time on the same mindmap! +- Use a QR Code or URL to share your maps - By default, mindmaps are deleted after 30 days to ensure GDPR compliancy. ## Getting started @@ -26,15 +29,13 @@ TeamMapper is based on mindmapp (https://github.com/cedoor/mindmapp , discontinu - Start frontend and backend at once ```bash - docker-compose exec app sh - # Inside docker container, you execute the following - npm --prefix teammapper-backend run dev + docker-compose exec app npm --prefix teammapper-backend run dev ``` or start frontend and backend separately ```bash - # Open to terminal session on your host machine + # Open two terminal sessions on your host machine # In first terminal session docker-compose exec app npm --prefix teammapper-backend start @@ -125,7 +126,7 @@ docker-compose --file docker-compose-prod.yml --env-file .env.prod exec app_prod Example of running sql via typeorm: ``` -npx typeorm query "select * from mmp_node" --config dist/ormconfig.js +docker-compose --file docker-compose-prod.yml --env-file .env.prod exec app_prod npx --prefix teammapper-backend typeorm query "select * from mmp_node" --config dist/ormconfig.js ``` ### Further details diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 9942bbac..a283e1fe 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -28,6 +28,7 @@ services: image: postgres:12-alpine # Pass config parameters to the postgres server. # Find more information below when you need to generate the ssl-relevant file your self + # In case you dont plan to use a certificate, uncomment this line command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key environment: PGDATA: /var/lib/postgresql/data/pgdata diff --git a/docs/teammapper-screenshot.png b/docs/teammapper-screenshot.png new file mode 100644 index 00000000..1953cea0 Binary files /dev/null and b/docs/teammapper-screenshot.png differ diff --git a/teammapper-backend/src/map/services/maps.service.ts b/teammapper-backend/src/map/services/maps.service.ts index d6d82efa..fa12f5bd 100644 --- a/teammapper-backend/src/map/services/maps.service.ts +++ b/teammapper-backend/src/map/services/maps.service.ts @@ -114,20 +114,4 @@ export class MapsService { deleteMap(uuid: string) { this.mapsRepository.delete({ id: uuid }); } - - // In case cascade is too slow, this is a WIP - // async recursiveFindAllNodeChildren(node: MmpNode): Promise { - // const children = await this.nodesRepository.find({ - // where: { - // nodeParentId: node.id, - // nodeMapId: node.nodeMapId, - // } - // }); - - // if (children === undefined || children.length === 0) return []; - - // return (await Promise.all(children.map(async (node: MmpNode): Promise => { - // return [node, ...await this.recursiveFindAllNodeChildren(node)]; - // }, []))).flat() - // } } diff --git a/teammapper-frontend/mmp/src/map/options.ts b/teammapper-frontend/mmp/src/map/options.ts index 6ea4ba46..b28d0d4f 100644 --- a/teammapper-frontend/mmp/src/map/options.ts +++ b/teammapper-frontend/mmp/src/map/options.ts @@ -34,7 +34,7 @@ export default class Options implements OptionParameters { // Default node properties this.defaultNode = Utils.mergeObjects({ - name: 'Node', + name: '', image: { src: '', size: 60 diff --git a/teammapper-frontend/mmp/src/utils/utils.ts b/teammapper-frontend/mmp/src/utils/utils.ts index 021a1464..c24bee75 100644 --- a/teammapper-frontend/mmp/src/utils/utils.ts +++ b/teammapper-frontend/mmp/src/utils/utils.ts @@ -152,8 +152,8 @@ export default class Utils { sel = window.getSelection() element.focus() - range.setStart(element.firstChild, 0) - range.setEnd(element.firstChild, element.firstChild.textContent.length) + range.selectNodeContents(element) + range.collapse(false) sel.removeAllRanges() sel.addRange(range) } diff --git a/teammapper-frontend/src/app/core/services/mmp/mmp.service.ts b/teammapper-frontend/src/app/core/services/mmp/mmp.service.ts index c85ed23f..b4bb4862 100644 --- a/teammapper-frontend/src/app/core/services/mmp/mmp.service.ts +++ b/teammapper-frontend/src/app/core/services/mmp/mmp.service.ts @@ -120,7 +120,7 @@ export class MmpService { * Add a node in the mind mmp. */ public addNode (properties?: ExportNodeProperties, notifyWithEvent = true) { - const newProps: UserNodeProperties = properties || {} + const newProps: UserNodeProperties = properties || { name: '' } // when the method is called with no params (from shortcut service), use the current selected node as parent const parent = properties?.parent ? this.getNode(properties.parent) : this.selectNode() const settings = this.settingsService.getCachedSettings() @@ -142,6 +142,7 @@ export class MmpService { } this.currentMap.instance.addNode(newProps, notifyWithEvent, properties?.parent, properties?.id) + this.editNode() } /** diff --git a/teammapper-frontend/src/app/core/services/shortcuts/shortcuts.service.ts b/teammapper-frontend/src/app/core/services/shortcuts/shortcuts.service.ts index 48d415a4..47a82fa1 100644 --- a/teammapper-frontend/src/app/core/services/shortcuts/shortcuts.service.ts +++ b/teammapper-frontend/src/app/core/services/shortcuts/shortcuts.service.ts @@ -50,7 +50,7 @@ export class ShortcutsService { this.mmpService.addNode() } }, { - keys: '-', + keys: ['-', 'backspace'], description: 'TOOLTIPS.REMOVE_NODE', callback: () => { this.mmpService.removeNode()