mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-30 18:05:55 +01:00 
			
		
		
		
	fixes for relation handling + visual design restyled into gray colors
This commit is contained in:
		| @@ -42,8 +42,7 @@ const biDirectionalOverlays = [ | ||||
| function loadMapData() { | ||||
|     const currentNote = noteDetailService.getCurrentNote(); | ||||
|     mapData = { | ||||
|         notes: [], | ||||
|         relations: [] | ||||
|         notes: [] | ||||
|     }; | ||||
|  | ||||
|     if (currentNote.content) { | ||||
| @@ -115,7 +114,7 @@ async function loadNotesAndRelations() { | ||||
|             } | ||||
|  | ||||
|             const connection = instance.connect({ | ||||
|                 id: `${relation.sourceNoteId}${relation.targetNoteId}`, | ||||
|                 id: relation.attributeIds, | ||||
|                 source: relation.sourceNoteId, | ||||
|                 target: relation.targetNoteId, | ||||
|                 type: relation.type | ||||
| @@ -155,8 +154,8 @@ function initPanZoom() { | ||||
| async function initJsPlumb () { | ||||
|     instance = jsPlumb.getInstance({ | ||||
|         Endpoint: ["Dot", {radius: 2}], | ||||
|         Connector: "StateMachine", | ||||
|         HoverPaintStyle: {stroke: "#1e8151", strokeWidth: 2 }, | ||||
|         Connector: "Straight", | ||||
|         HoverPaintStyle: {stroke: "#777", strokeWidth: 1 }, | ||||
|         Container: "relation-map-canvas" | ||||
|     }); | ||||
|  | ||||
| @@ -181,8 +180,7 @@ async function initJsPlumb () { | ||||
|         delegate: ".connection-label,.jtk-connector", | ||||
|         autoTrigger: false, // it doesn't open automatically, needs to be triggered explicitly by .open() call | ||||
|         menu: [ | ||||
|             {title: "Remove relation", cmd: "remove", uiIcon: "ui-icon-trash"}, | ||||
|             {title: "Edit relation name", cmd: "edit-name", uiIcon: "ui-icon-pencil"}, | ||||
|             {title: "Remove relation", cmd: "remove", uiIcon: "ui-icon-trash"} | ||||
|         ], | ||||
|         select: relationContextMenuHandler | ||||
|     }); | ||||
| @@ -222,12 +220,12 @@ async function connectionCreatedHandler(info, originalEvent) { | ||||
|     const targetNoteId = connection.target.id; | ||||
|     const sourceNoteId = connection.source.id; | ||||
|  | ||||
|     const existing = relations.some(rel => | ||||
|     const relationExists = relations.some(rel => | ||||
|         rel.targetNoteId === targetNoteId | ||||
|         && rel.sourceNoteId === sourceNoteId | ||||
|         && rel.name === name); | ||||
|  | ||||
|     if (existing) { | ||||
|     if (relationExists) { | ||||
|         alert("Connection '" + name + "' between these notes already exists."); | ||||
|  | ||||
|         instance.deleteConnection(connection); | ||||
| @@ -235,15 +233,15 @@ async function connectionCreatedHandler(info, originalEvent) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     await server.put(`notes/${sourceNoteId}/relations/${name}/to/${targetNoteId}`); | ||||
|     const attribute = await server.put(`notes/${sourceNoteId}/relations/${name}/to/${targetNoteId}`); | ||||
|  | ||||
|     relations.push({ targetNoteId, sourceNoteId, name }); | ||||
|     relations.push({ attributeId: attribute.attributeId , targetNoteId, sourceNoteId, name }); | ||||
|  | ||||
|     connection.setType("uniDirectional"); | ||||
|     connection.getOverlay("label").setLabel(name); | ||||
| } | ||||
|  | ||||
| function relationContextMenuHandler(event, ui) { | ||||
| async function relationContextMenuHandler(event, ui) { | ||||
|     const {connection} = ui.extraData; | ||||
|  | ||||
|     if (ui.cmd === 'remove') { | ||||
| @@ -251,36 +249,30 @@ function relationContextMenuHandler(event, ui) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const relation = relations.find(rel => rel.attributeId === connection.id); | ||||
|  | ||||
|         await server.remove(`notes/${relation.sourceNoteId}/relations/${relation.name}/to/${relation.targetNoteId}`); | ||||
|  | ||||
|         instance.deleteConnection(connection); | ||||
|  | ||||
|         mapData.relations = mapData.relations.filter(relation => relation.connectionId !== connection.id); | ||||
|         saveData(); | ||||
|     } | ||||
|     else if (ui.cmd === 'edit-name') { | ||||
|         const relationName = prompt("Specify new relation name:"); | ||||
|  | ||||
|         connection.getOverlay("label").setLabel(relationName); | ||||
|  | ||||
|         const relation = mapData.relations.find(relation => relation.connectionId === connection.id); | ||||
|         relation.name = relationName; | ||||
|  | ||||
|         saveData(); | ||||
|         relations = relations.filter(relation => relation.attributeId !== connection.id); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function noteContextMenuHandler(event, ui) { | ||||
| async function noteContextMenuHandler(event, ui) { | ||||
|     const $noteBox = ui.target.closest(".note-box"); | ||||
|     const noteId = $noteBox.prop("id"); | ||||
|  | ||||
|     if (ui.cmd === "remove") { | ||||
|         if (!confirm("Are you sure you want to remove the note?")) { | ||||
|         if (!confirm("Are you sure you want to remove the note from this diagram?")) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         instance.remove(noteId); | ||||
|  | ||||
|         mapData.notes = mapData.notes.filter(note => note.id !== noteId); | ||||
|         mapData.relations = mapData.relations.filter(relation => relation.source !== noteId && relation.target !== noteId); | ||||
|  | ||||
|         relations = relations.filter(relation => relation.sourceNoteId !== noteId && relation.targetNoteId !== noteId); | ||||
|  | ||||
|         saveData(); | ||||
|     } | ||||
| @@ -329,12 +321,7 @@ function initNode(el) { | ||||
|     instance.makeSource(el, { | ||||
|         filter: ".endpoint", | ||||
|         anchor: "Continuous", | ||||
|         connectorStyle: { | ||||
|             stroke: "#5c96bc", | ||||
|             strokeWidth: 2, | ||||
|             outlineStroke: "transparent", | ||||
|             outlineWidth: 4 | ||||
|         }, | ||||
|         connectorStyle: { stroke: "#000", strokeWidth: 1 }, | ||||
|         connectionType: "basic", | ||||
|         extract:{ | ||||
|             "action": "the-action" | ||||
| @@ -409,12 +396,6 @@ $addChildNotesButton.click(async () => { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             mapData.relations.push({ | ||||
|                 source: child.noteId, | ||||
|                 target: relation.targetNoteId, | ||||
|                 name: relation.name | ||||
|             }); | ||||
|  | ||||
|             relation.connectionId = connection.id; | ||||
|  | ||||
|             connection.getOverlay("label").setLabel(relation.name); | ||||
|   | ||||
| @@ -16,13 +16,12 @@ | ||||
|     padding: 16px; | ||||
|     position: absolute !important; | ||||
|     z-index: 4; | ||||
|     border: 1px solid #2e6f9a; | ||||
|     box-shadow: 2px 2px 19px #e0e0e0; | ||||
|     border: 1px solid #666; | ||||
|     box-shadow: 2px 2px 19px #999; | ||||
|     border-radius: 8px; | ||||
|     opacity: 0.8; | ||||
|     background-color: white; | ||||
|     font-size: 11px; | ||||
|     transition: background-color 0.25s ease-in; | ||||
|     width: auto; | ||||
|     height: auto; | ||||
|     max-width: 200px; | ||||
| @@ -32,8 +31,7 @@ | ||||
| } | ||||
|  | ||||
| .note-box:hover { | ||||
|     background-color: #5c96bc; | ||||
|     color: white; | ||||
|     background-color: #ddd; | ||||
| } | ||||
|  | ||||
| .note-box .title { | ||||
| @@ -41,13 +39,8 @@ | ||||
|     font-weight: 600; | ||||
| } | ||||
|  | ||||
| .connection-label { | ||||
|     transition: background-color 0.25s ease-in; | ||||
| } | ||||
|  | ||||
| .connection-label.jtk-hover, .jtk-source-hover, .jtk-target-hover { | ||||
|     background-color: #1e8151; | ||||
|     color: white; | ||||
|     background-color: #ddd; | ||||
| } | ||||
|  | ||||
| .connection-label { | ||||
| @@ -55,7 +48,7 @@ | ||||
|     opacity: 0.8; | ||||
|     padding: 0.3em; | ||||
|     border-radius: 0.5em; | ||||
|     border: 1px solid #346789; | ||||
|     border: 1px solid #666; | ||||
|     cursor: pointer; | ||||
| } | ||||
|  | ||||
| @@ -65,10 +58,9 @@ | ||||
|     right: 5px; | ||||
|     width: 1em; | ||||
|     height: 1em; | ||||
|     background-color: orange; | ||||
|     background-color: #333; | ||||
|     cursor: pointer; | ||||
|     box-shadow: 0 0 2px black; | ||||
|     transition: box-shadow 0.25s ease-in; | ||||
| } | ||||
|  | ||||
| .endpoint:hover { | ||||
|   | ||||
| @@ -123,8 +123,31 @@ async function createRelation(req) { | ||||
|  | ||||
|         await attribute.save(); | ||||
|     } | ||||
|  | ||||
|     return attribute; | ||||
| } | ||||
|  | ||||
| async function deleteRelation(req) { | ||||
|     const sourceNoteId = req.params.noteId; | ||||
|     const targetNoteId = req.params.targetNoteId; | ||||
|     const name = req.params.name; | ||||
|  | ||||
|     let attribute = await repository.getEntity(`SELECT * FROM attributes WHERE isDeleted = 0 AND noteId = ? AND type = 'relation' AND name = ? AND value = ?`, [sourceNoteId, name, targetNoteId]); | ||||
|  | ||||
|     if (!attribute) { | ||||
|         attribute = new Attribute(); | ||||
|         attribute.noteId = sourceNoteId; | ||||
|         attribute.name = name; | ||||
|         attribute.type = 'relation'; | ||||
|         attribute.value = targetNoteId; | ||||
|  | ||||
|         await attribute.save(); | ||||
|     } | ||||
|  | ||||
|     return attribute; | ||||
| } | ||||
|  | ||||
|  | ||||
| module.exports = { | ||||
|     updateNoteAttributes, | ||||
|     updateNoteAttribute, | ||||
| @@ -132,5 +155,6 @@ module.exports = { | ||||
|     getAttributeNames, | ||||
|     getValuesForAttribute, | ||||
|     getEffectiveNoteAttributes, | ||||
|     createRelation | ||||
|     createRelation, | ||||
|     deleteRelation | ||||
| }; | ||||
| @@ -111,6 +111,7 @@ async function getRelationMap(req) { | ||||
|     // FIXME: this actually doesn't take into account inherited relations! But maybe it is better this way? | ||||
|     resp.relations = (await repository.getEntities(`SELECT * FROM attributes WHERE isDeleted = 0 AND type = 'relation' AND noteId IN (${questionMarks})`, noteIds)) | ||||
|         .map(relation => { return { | ||||
|             attributeId: relation.attributeId, | ||||
|             sourceNoteId: relation.noteId, | ||||
|             targetNoteId: relation.value, | ||||
|             name: relation.name | ||||
|   | ||||
| @@ -138,6 +138,7 @@ function register(app) { | ||||
|     apiRoute(PUT, '/api/notes/:noteId/attributes', attributesRoute.updateNoteAttributes); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/attribute', attributesRoute.updateNoteAttribute); | ||||
|     apiRoute(PUT, '/api/notes/:noteId/relations/:name/to/:targetNoteId', attributesRoute.createRelation); | ||||
|     apiRoute(DELETE, '/api/notes/:noteId/relations/:name/to/:targetNoteId', attributesRoute.deleteRelation); | ||||
|     apiRoute(DELETE, '/api/notes/:noteId/attributes/:attributeId', attributesRoute.deleteNoteAttribute); | ||||
|     apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames); | ||||
|     apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user