diff --git a/src/pages/library/LibraryList.vue b/src/pages/library/LibraryList.vue index db9c762..ae7b017 100644 --- a/src/pages/library/LibraryList.vue +++ b/src/pages/library/LibraryList.vue @@ -1,6 +1,6 @@ @@ -21,8 +29,8 @@ import { randomUniform } from 'd3' import { forceSimulation, forceCollide, forceManyBody } from 'd3-force' import { mapGetters } from 'vuex' -import { searchInNode, tagsInNode } from '@/store/utils' -import { MapZoom } from '@/components/layouts' +import { searchInNode, tagsInNode, getRelation } from '@/store/utils' +import { MapZoom, NodePreviewZone } from '@/components/layouts' import { NodeView } from '@/components/nodes' @@ -31,13 +39,15 @@ export default { components: { MapZoom, + NodePreviewZone, NodeView }, data () { return { simulation: forceSimulation(), - nodes: undefined + nodes: undefined, + previewNode: null } }, @@ -53,16 +63,27 @@ export default { }) }) return this.nodes + }, + + dataNodes () { + if (!this.nodes) return + return this.nodes.map(node => node.data) } }, methods: { onOpen (node) { - if (node.parents && node.parents.length) { - this.$emit('open-node', { parentId: node.parents[0].id, childId: node.id }) - } else { - this.$emit('open-node', { parentId: node.id }) - } + this.$parent.$emit('open-node', getRelation(node)) + }, + + onNodeClick (node) { + this.previewNode = node + this.$root.$emit('bv::show::popover', 'preview-node-' + node.id) + }, + + onPreviewNodeClick (ids) { + this.$root.$emit('bv::hide::popover', 'preview-node-' + this.previewNode.id) + this.$emit('open-node', ids) } }, @@ -93,4 +114,14 @@ foreignObject { cursor: pointer; } } + +.node-view.hidden { + border: $line; + border-style: dashed; + background-color: transparent; + + ::v-deep .node-view-wrapper { + opacity: 0; + } +} diff --git a/src/pages/library/LibraryTree.vue b/src/pages/library/LibraryTree.vue index 7f321b2..65bbebd 100644 --- a/src/pages/library/LibraryTree.vue +++ b/src/pages/library/LibraryTree.vue @@ -14,11 +14,15 @@ :cx="node.x" :cy="node.y" class="svg-dot" + :id="'preview-node-' + node.data.id" :class="['svg-dot-' + node.data.variant, { 'origin': node.parent === null }]" tabindex="0" - @click="onNodeClick(node.data)" - @keyup.enter="onNodeClick(node.data)" + @focus="activeNode = node" @mouseenter="activeNode = node" + @mouseleave="activeNode = null" + @blur="activeNode = null" + @click.stop="onNodeClick(node.data)" + @keyup.enter="onNodeClick(node.data)" /> @@ -30,20 +34,20 @@ > - @@ -52,26 +56,33 @@ import { mapGetters } from 'vuex' import { line } from 'd3-shape' import { forceSimulation, forceLink, forceManyBody, forceX, forceY } from 'd3-force' -import { trim, toCommaList } from '@/helpers/common' -import { MapZoom } from '@/components/layouts' +import { MapZoom, NodePreviewZone } from '@/components/layouts' +import { NodeViewTitle } from '@/components/nodes' export default { name: 'LibraryTree', components: { - MapZoom + MapZoom, + NodePreviewZone, + NodeViewTitle }, data () { return { - activeNode: null + activeNode: null, + previewNode: null } }, computed: { ...mapGetters(['nodeTree']), + dataNodes () { + return this.nodeTree.nodes.map(node => node.data) + }, + // ONE TIME GETTER simulation () { return forceSimulation() @@ -98,6 +109,7 @@ export default { watch: { nodeTree (tree) { this.activeNode = null + this.previewNode = null this.simulation.nodes(tree.nodes) this.simulation.force('link').links(tree.links) this.simulation.alpha(0.5).restart() @@ -105,15 +117,16 @@ export default { }, methods: { - toCommaList, - trim, - onNodeClick (node) { - if (node.parents && node.parents.length) { - this.$emit('open-node', { parentId: node.parents[0].id, childId: node.id }) - } else { - this.$emit('open-node', { parentId: node.id }) - } + this.$store.dispatch('GET_NODE', { id: node.id, dataLevel: 'partial' }) + this.previewNode = node + this.$root.$emit('bv::show::popover', 'preview-node-' + node.id) + }, + + onPreviewNodeClick (ids) { + this.$root.$emit('bv::hide::popover', 'preview-node-' + this.previewNode.id) + this.$emit('open-node', ids) + this.previewNode = null } }, @@ -140,6 +153,7 @@ export default { } &-dot { + cursor: pointer; r: 9.5px; @each $color, $value in $theme-colors { @@ -177,5 +191,10 @@ foreignObject { .dot-btn { transform: translate(-50%, -50%); + pointer-events: none; + + h6 { + margin: 0; + } }