update library opening strategy

This commit is contained in:
axolotle
2021-06-10 18:26:14 +02:00
parent ddff9313cb
commit ecc5253f38
9 changed files with 169 additions and 160 deletions
+46 -120
View File
@@ -1,101 +1,55 @@
<template>
<div class="library">
<!-- BACKGROUND (mode) -->
<component :is="mode" @open="openText" />
<component :is="'library-' + mode" @open-node="openNode" />
<!-- FOREGROUND (texts) -->
<div v-if="parents.length" class="main-texts-container">
<section
v-for="(parent, i) in parents" :key="parent.id"
class="main-text-container text-break"
:style="`--n: ${i};`"
:class="{ 'text-blur': i !== parents.length - 1 }"
>
<text-card
:id="parent.id"
:children="parent.children"
class="text-card-main"
@open="openText" @close="closeText"
@click.native="onMainTextClick(i)"
/>
<section class="sub-texts-container">
<text-card
v-for="(id, j) in parent.children" :key="id"
:id="id"
class="text-card-sub text-break"
:style="`--n: ${j};`"
@close="closeText(parent.id, $event)"
@click.native="onSubTextClick(i, j)"
/>
</section>
</section>
</div>
<!-- FOREGROUND (nodes) -->
<node-book
v-if="nodebook.length"
:nodes="nodebook"
class="library-node-book no-events-container"
@open-node="openNode"
@close-node="closeNode"
/>
</div>
</template>
<script>
import { CardList, CardMap, TreeMap } from './library'
import TextCard from '@/components/text/TextCard'
import { mapGetters } from 'vuex'
import {
LibraryList,
LibraryMap,
LibraryTree
} from './library'
import { NodeBook } from '@/components/layouts'
export default {
name: 'Library',
components: {
CardList,
CardMap,
TreeMap,
TextCard
LibraryList,
LibraryMap,
LibraryTree,
NodeBook
},
props: {
mode: { type: String, required: true },
texts: { type: Array, required: true }
query: { type: Object, required: true }
},
computed: {
parents () {
return this.texts.map(text => {
const [id, ...children] = text
return { id, children }
})
...mapGetters(['mode', 'nodebook'])
},
watch: {
query (query) {
this.$store.dispatch('UPDATE_NODEBOOK', query)
}
},
methods: {
openText (id, childId) {
const parent = this.parents.find(p => p.id === id)
if (parent && (childId === undefined || parent.children.includes(childId))) return
if (!parent) {
this.parents.push({ id, children: childId ? [childId] : [] })
} else if (childId) {
parent.children.push(childId)
}
this.updateQuery(this.parents)
},
closeText (id, childId) {
const parent = this.parents.find(p => p.id === id)
if (!childId) {
this.updateQuery(this.parents.filter(p => p !== parent))
} else {
parent.children = parent.children.filter(childId_ => childId_ !== childId)
this.updateQuery(this.parents)
}
},
updateQuery (parents) {
// Update the route's query (will not reload the page) and let vue determine what changed.
this.$router.push({
query: {
mode: this.mode,
texts: parents.map(parent => [parent.id, ...parent.children])
}
})
},
onMainTextClick (mainTextIndex) {
if (mainTextIndex === this.texts.length - 1) return
this.parents.push(this.parents.splice(mainTextIndex, 1)[0])
@@ -118,7 +72,19 @@ export default {
if (needUpdate) {
this.updateQuery(this.parents)
}
},
openNode (parentId, childId) {
this.$store.dispatch('OPEN_NODE', [parentId, childId])
},
closeNode (parentId, childId) {
this.$store.dispatch('CLOSE_NODE', [parentId, childId])
}
},
created () {
this.$store.dispatch('UPDATE_NODEBOOK', this.query)
}
}
</script>
@@ -126,53 +92,13 @@ export default {
<style lang="scss" scoped>
.library {
height: 100%;
width: 100%;
overflow: hidden;
}
.main-texts-container {
position: relative;
top: -100%;
height: 100%;
pointer-events: none;
}
.main-text-container {
border-top: 2px solid $black;
display: flex;
width: 100%;
> * {
flex-basis: 50%;
&-node-book {
position: relative;
margin-bottom: -100%;
// compensate header border
height: calc(100% + 2px);
top: calc(-100% - 2px);
}
}
.sub-texts-container {
position: relative;
height: 100%;
}
.text-card {
pointer-events: auto;
width: 100%;
}
.text-break {
position: absolute;
height: calc(100% - (var(--n) * #{$text-card-header-height}));
top: calc(var(--n) * #{$text-card-header-height});
z-index: var(--n);
}
.text-blur::before {
content: '';
pointer-events: none;
position: absolute;
z-index: 1;
display: block;
width: 100%;
height: 100%;
background-color: rgba($white, .5);
}
</style>
+19 -20
View File
@@ -6,14 +6,14 @@
>
<b-form-radio-group
id="mode-select"
v-model="currentMode" :options="modes"
v-model="activeMode" :options="modes"
name="mode-select" :aria-describedby="ariaDescribedby"
buttons button-variant="outline-dark"
/>
</b-form-group>
<b-form-group
v-if="currentMode !== 'tree-map'"
v-if="mode !== 'tree'"
:label="$t('options.filters.title')"
>
<b-form-group
@@ -22,8 +22,7 @@
>
<multiple-tags-select
id="tags-select" :button-text="$t('options.filters.choices.tags')"
v-model="selectedTags" :options="tags"
:disabled="true"
v-model="selectedTags" :options="tagsOptions"
/>
</b-form-group>
@@ -80,20 +79,13 @@ export default {
MultipleTagsSelect
},
props: {
show: { type: Boolean, required: true },
mode: { type: String, required: true },
tags: { type: Array, default: () => ([]) }
},
data () {
return {
modes: [
{ text: this.$t('options.display.choices.tree-map'), value: 'tree-map' },
{ text: this.$t('options.display.choices.card-map'), value: 'card-map' },
{ text: this.$t('options.display.choices.card-list'), value: 'card-list' }
{ text: this.$t('options.display.choices.tree-map'), value: 'tree' },
{ text: this.$t('options.display.choices.card-map'), value: 'map' },
{ text: this.$t('options.display.choices.card-list'), value: 'list' }
],
currentMode: this.mode,
selectedTags: [],
strangeness: 0,
textDepartId: undefined,
@@ -102,7 +94,11 @@ export default {
},
computed: {
...mapGetters(['nodesDepartsOptions']),
...mapGetters(['mode', 'nodebook', 'nodesDepartsOptions', 'tagsOptions']),
show () {
return this.nodebook.length === 0
},
nodeDepartId: {
get () {
@@ -111,12 +107,15 @@ export default {
set (value) {
this.$store.dispatch('SET_NODE_DEPART_ID', value)
}
}
},
},
watch: {
currentMode (mode) {
this.$router.push({ query: { mode } })
activeMode: {
get () {
return this.mode
},
set (value) {
this.$store.dispatch('UPDATE_QUERY_MODE', value)
}
}
}
}