|
@@ -14,11 +14,15 @@
|
|
:cx="node.x"
|
|
:cx="node.x"
|
|
:cy="node.y"
|
|
:cy="node.y"
|
|
class="svg-dot"
|
|
class="svg-dot"
|
|
|
|
+ :id="'preview-node-' + node.data.id"
|
|
:class="['svg-dot-' + node.data.variant, { 'origin': node.parent === null }]"
|
|
:class="['svg-dot-' + node.data.variant, { 'origin': node.parent === null }]"
|
|
tabindex="0"
|
|
tabindex="0"
|
|
- @click="onNodeClick(node.data)"
|
|
|
|
- @keyup.enter="onNodeClick(node.data)"
|
|
|
|
|
|
+ @focus="activeNode = node"
|
|
@mouseenter="activeNode = node"
|
|
@mouseenter="activeNode = node"
|
|
|
|
+ @mouseleave="activeNode = null"
|
|
|
|
+ @blur="activeNode = null"
|
|
|
|
+ @click.stop="onNodeClick(node.data)"
|
|
|
|
+ @keyup.enter="onNodeClick(node.data)"
|
|
/>
|
|
/>
|
|
|
|
|
|
<g>
|
|
<g>
|
|
@@ -30,20 +34,20 @@
|
|
>
|
|
>
|
|
<dot-button
|
|
<dot-button
|
|
:variant="activeNode.data.variant"
|
|
:variant="activeNode.data.variant"
|
|
- class="active"
|
|
|
|
|
|
+ active hovered
|
|
@click="onNodeClick(activeNode.data)"
|
|
@click="onNodeClick(activeNode.data)"
|
|
- @mouseleave="activeNode = null"
|
|
|
|
>
|
|
>
|
|
- <template v-if="activeNode.data.variant !== 'depart'">
|
|
|
|
|
|
+ <template v-if="activeNode.data.type === 'prod'">
|
|
{{ $t('variants.' + activeNode.data.variant) }}<br>
|
|
{{ $t('variants.' + activeNode.data.variant) }}<br>
|
|
</template>
|
|
</template>
|
|
- {{ toCommaList(activeNode.data.authors) }},<br>
|
|
|
|
- <span v-if="activeNode.data.preTitle" v-html="trim(activeNode.data.preTitle) + ','" />
|
|
|
|
- <span v-html="trim(activeNode.data.title) || '<em>pas de titre ital</em>'" />
|
|
|
|
|
|
+
|
|
|
|
+ <node-view-title v-else :node="activeNode.data" block />
|
|
</dot-button>
|
|
</dot-button>
|
|
</foreignObject>
|
|
</foreignObject>
|
|
</g>
|
|
</g>
|
|
</map-zoom>
|
|
</map-zoom>
|
|
|
|
+
|
|
|
|
+ <node-preview-zone v-model="previewNode" :nodes="dataNodes" @open-node="onPreviewNodeClick" />
|
|
</b-overlay>
|
|
</b-overlay>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -52,26 +56,33 @@ import { mapGetters } from 'vuex'
|
|
import { line } from 'd3-shape'
|
|
import { line } from 'd3-shape'
|
|
import { forceSimulation, forceLink, forceManyBody, forceX, forceY } from 'd3-force'
|
|
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 {
|
|
export default {
|
|
name: 'LibraryTree',
|
|
name: 'LibraryTree',
|
|
|
|
|
|
components: {
|
|
components: {
|
|
- MapZoom
|
|
|
|
|
|
+ MapZoom,
|
|
|
|
+ NodePreviewZone,
|
|
|
|
+ NodeViewTitle
|
|
},
|
|
},
|
|
|
|
|
|
data () {
|
|
data () {
|
|
return {
|
|
return {
|
|
- activeNode: null
|
|
|
|
|
|
+ activeNode: null,
|
|
|
|
+ previewNode: null
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
|
|
computed: {
|
|
computed: {
|
|
...mapGetters(['nodeTree']),
|
|
...mapGetters(['nodeTree']),
|
|
|
|
|
|
|
|
+ dataNodes () {
|
|
|
|
+ return this.nodeTree.nodes.map(node => node.data)
|
|
|
|
+ },
|
|
|
|
+
|
|
// ONE TIME GETTER
|
|
// ONE TIME GETTER
|
|
simulation () {
|
|
simulation () {
|
|
return forceSimulation()
|
|
return forceSimulation()
|
|
@@ -98,6 +109,7 @@ export default {
|
|
watch: {
|
|
watch: {
|
|
nodeTree (tree) {
|
|
nodeTree (tree) {
|
|
this.activeNode = null
|
|
this.activeNode = null
|
|
|
|
+ this.previewNode = null
|
|
this.simulation.nodes(tree.nodes)
|
|
this.simulation.nodes(tree.nodes)
|
|
this.simulation.force('link').links(tree.links)
|
|
this.simulation.force('link').links(tree.links)
|
|
this.simulation.alpha(0.5).restart()
|
|
this.simulation.alpha(0.5).restart()
|
|
@@ -105,15 +117,16 @@ export default {
|
|
},
|
|
},
|
|
|
|
|
|
methods: {
|
|
methods: {
|
|
- toCommaList,
|
|
|
|
- trim,
|
|
|
|
-
|
|
|
|
onNodeClick (node) {
|
|
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 {
|
|
&-dot {
|
|
|
|
+ cursor: pointer;
|
|
r: 9.5px;
|
|
r: 9.5px;
|
|
|
|
|
|
@each $color, $value in $theme-colors {
|
|
@each $color, $value in $theme-colors {
|
|
@@ -177,5 +191,10 @@ foreignObject {
|
|
|
|
|
|
.dot-btn {
|
|
.dot-btn {
|
|
transform: translate(-50%, -50%);
|
|
transform: translate(-50%, -50%);
|
|
|
|
+ pointer-events: none;
|
|
|
|
+
|
|
|
|
+ h6 {
|
|
|
|
+ margin: 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|