148 lines
3.2 KiB
Vue
148 lines
3.2 KiB
Vue
<template>
|
|
<b-overlay :show="filteredNodes === undefined" class="h-100" z-index="0">
|
|
<div class="library-list">
|
|
<div class="library-list-container" @click="onContainerClick">
|
|
<div v-for="([char, nodes]) in filteredNodes" :key="char">
|
|
<h3 :id="char">
|
|
{{ char }}
|
|
</h3>
|
|
|
|
<div class="library-list-nodes-group">
|
|
<node-view
|
|
v-for="node in nodes" :key="char + '-' + node.id"
|
|
:node="node"
|
|
mode="card"
|
|
@click.native.capture="previewNode = node"
|
|
:preview="previewNode === node"
|
|
@open-node="$emit('open-node', $event)"
|
|
@open-child="$emit('open-node', { parentId: node.id, ...$event })"
|
|
:style="`--opacity: ${getStrangenessOpacity(strangeness, node)};`"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</b-overlay>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters } from 'vuex'
|
|
|
|
import { searchInNode, tagsInNode, getStrangenessOpacity } from '@/store/utils'
|
|
import { NodeView } from '@/components/nodes'
|
|
|
|
|
|
export default {
|
|
name: 'LibraryList',
|
|
|
|
components: {
|
|
NodeView
|
|
},
|
|
|
|
data () {
|
|
return {
|
|
previewNode: null
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
...mapGetters(['orderedTextsDepart', 'search', 'tags', 'strangeness']),
|
|
|
|
filteredNodes () {
|
|
if (!this.orderedTextsDepart) return
|
|
const nodesGroups = []
|
|
const search = this.search.toLowerCase()
|
|
this.orderedTextsDepart.forEach(([char, nodes]) => {
|
|
const filteredNodes = nodes
|
|
.filter(node => tagsInNode(this.tags, node.tags))
|
|
.filter(node => searchInNode(search, node))
|
|
if (filteredNodes.length) {
|
|
nodesGroups.push([char, filteredNodes])
|
|
}
|
|
})
|
|
return nodesGroups
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
getStrangenessOpacity,
|
|
|
|
onContainerClick (e) {
|
|
if (!e.target.classList.contains('node-view')) {
|
|
this.previewNode = null
|
|
}
|
|
}
|
|
},
|
|
|
|
created () {
|
|
this.$store.dispatch('INIT_LIBRARY_LIST')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.library-list {
|
|
overflow-y: auto;
|
|
height: 100%;
|
|
padding: 0 1.15rem;
|
|
|
|
@include media-breakpoint-up($size-bp) {
|
|
padding: 0 2.15rem;
|
|
}
|
|
|
|
h3 {
|
|
font-family: $font-family-text;
|
|
line-height: 1;
|
|
font-size: 6.25rem;
|
|
margin-top: 2rem;
|
|
|
|
@include media-breakpoint-up($size-bp) {
|
|
margin-top: 2rem;
|
|
font-size: 16.5rem;
|
|
}
|
|
}
|
|
|
|
&-nodes-group {
|
|
display: grid;
|
|
grid-gap: 2.2rem;
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: auto;
|
|
|
|
@include media-breakpoint-up(lg) {
|
|
grid-gap: 3.4rem;
|
|
}
|
|
|
|
@media (min-width: 650px) {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
@include media-breakpoint-up(lg) {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
}
|
|
|
|
@include media-breakpoint-up(xxl) {
|
|
grid-template-columns: repeat(4, 1fr);
|
|
}
|
|
|
|
.node-view {
|
|
max-width: 100%;
|
|
height: $node-card-height-sm;
|
|
|
|
@include media-breakpoint-up($size-bp) {
|
|
max-width: $node-card-width;
|
|
height: $node-card-height;
|
|
}
|
|
|
|
&.preview {
|
|
top: -2rem;
|
|
}
|
|
|
|
&:not(.preview) {
|
|
opacity: var(--opacity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|