From ecc5253f3844a621d84d5ad7ca80e7395b39d85f Mon Sep 17 00:00:00 2001 From: axolotle Date: Thu, 10 Jun 2021 18:26:14 +0200 Subject: [PATCH] update library opening strategy --- src/App.vue | 4 + src/assets/scss/abstracts/_variables.scss | 4 +- src/main.js | 3 +- src/messages/fr.json | 3 +- src/pages/Library.vue | 166 ++++++---------------- src/pages/library/LibraryOptions.vue | 39 +++-- src/router/routes.js | 14 +- src/store/modules/library.js | 85 ++++++++++- src/store/utils.js | 11 ++ 9 files changed, 169 insertions(+), 160 deletions(-) diff --git a/src/App.vue b/src/App.vue index da4ba99..0ff2d7b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -79,4 +79,8 @@ export default { opacity: .25; } } + +#app > header { + border-bottom: $line; +} diff --git a/src/assets/scss/abstracts/_variables.scss b/src/assets/scss/abstracts/_variables.scss index 84075b3..01f718b 100644 --- a/src/assets/scss/abstracts/_variables.scss +++ b/src/assets/scss/abstracts/_variables.scss @@ -53,8 +53,8 @@ $grid-breakpoints: ( xs: 0, sm: 576px, md: 1024px, - // lg: 992px, - // xl: 1200px + lg: 1200px, + xl: 1440px, ); $layout-bp: md; diff --git a/src/main.js b/src/main.js index c328104..e9446e2 100644 --- a/src/main.js +++ b/src/main.js @@ -10,8 +10,7 @@ import store from './store' Vue.use(BootstrapVue, { BButton: { pill: true }, - BCardHeader: { headerBgVariant: 'white' }, - BCardFooter: { footerBgVariant: 'white' } + BOverlay: { blur: null, spinnerType: 'grow', opacity: 0 } }) Vue.use(Meta) Vue.use(Vue2TouchEvents) diff --git a/src/messages/fr.json b/src/messages/fr.json index ee870c3..b47156d 100644 --- a/src/messages/fr.json +++ b/src/messages/fr.json @@ -41,5 +41,6 @@ "siblings": "Textes rebonds", "text": { "read": "Voir le texte" - } + }, + "from": "à partir de :" } diff --git a/src/pages/Library.vue b/src/pages/Library.vue index 478b373..6a06dd0 100644 --- a/src/pages/Library.vue +++ b/src/pages/Library.vue @@ -1,101 +1,55 @@ @@ -126,53 +92,13 @@ export default { diff --git a/src/pages/library/LibraryOptions.vue b/src/pages/library/LibraryOptions.vue index bb60b5e..f3e17f4 100644 --- a/src/pages/library/LibraryOptions.vue +++ b/src/pages/library/LibraryOptions.vue @@ -6,14 +6,14 @@ > @@ -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) + } } } } diff --git a/src/router/routes.js b/src/router/routes.js index f7f7914..934b35d 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -28,19 +28,7 @@ export default [ options: () => import(/* webpackChunkName: "library" */ '@/pages/library/LibraryOptions') }, props: { - default: ({ query }) => { - let { mode = 'tree-map', texts = [] } = query - if (typeof texts === 'string') texts = [texts] - // In case of a reload or direct link, vue-router doesn't turn the query string into an array. - if (texts && texts.length && typeof texts[0] === 'string') { - texts = texts.map(text => text.split(',').map(id => parseInt(id))) - } - return { mode, texts } - }, - options: ({ query }) => ({ - show: !('texts' in query && query.texts.length), - mode: query.mode || 'tree-map' - }) + default: ({ query }) => ({ query }) } }, diff --git a/src/store/modules/library.js b/src/store/modules/library.js index d145a70..45b31df 100644 --- a/src/store/modules/library.js +++ b/src/store/modules/library.js @@ -1,10 +1,12 @@ import Vue from 'vue' +import router from '@/router' import api from '@/api' import { AllTags } from '@/api/queries' import { + parseNodesQueryParams, getUniqueNodesIds, getRelatedNodesIds, buildTree @@ -16,10 +18,38 @@ export default { tags: undefined, strangeness: [0, 1, 2, 3, 4], nodeDepartId: undefined, - trees: {} + trees: {}, + mode: undefined, + nodebook: undefined }, mutations: { + 'SET_MODE' (state, mode) { + state.mode = mode + }, + + 'SET_NODEBOOK' (state, nodes) { + state.nodebook = nodes + }, + + 'ADD_NODEBOOK_NODE' (state, [stack, parentId, childId]) { + console.log('ADD_NODEBOOK_NODE', stack, parentId, childId) + if (stack === undefined) { + stack = childId === undefined ? [parentId] : [parentId, childId] + state.nodebook.push(stack) + } else { + stack.push(childId) + } + }, + + 'REMOVE_NODEBOOK_NODE' (state, [stack, nodeId]) { + if (stack[0] === nodeId) { + state.nodebook.splice(state.nodebook.indexOf(stack), 1) + } else { + stack.splice(stack.indexOf(nodeId), 1) + } + }, + 'SET_TAGS' (state, tags) { state.tags = tags }, @@ -34,9 +64,30 @@ export default { }, actions: { + async 'UPDATE_NODEBOOK' ({ state, commit, dispatch }, query) { + const { mode = 'tree', nodebook } = parseNodesQueryParams(query) + commit('SET_MODE', mode) + await dispatch('GET_NODES', { ids: [].concat(...nodebook), dataLevel: 'full' }) + commit('SET_NODEBOOK', nodebook) + }, + + 'UPDATE_QUERY_NODES' ({ state }, from) { + const query = { + mode: state.mode, + nodes: [...state.nodebook.map(ids => ids.join(','))] + } + router.push({ query }) + }, + + 'UPDATE_QUERY_MODE' (store, mode) { + if (router.currentRoute.query.mode === mode) return + router.push({ query: { mode } }) + }, + async 'INIT_LIBRARY' ({ state, commit, dispatch, rootState }) { const departIds = await dispatch('GET_ALL_NODES_IDS', 'depart') await dispatch('GET_NODES', { ids: departIds, dataLevel: 'initial' }) + dispatch('GET_ALL_TAGS') return departIds }, @@ -78,12 +129,42 @@ export default { } return getters.nodeTree + }, + + async 'OPEN_NODE' ({ state, commit, dispatch }, [parentId, childId]) { + const stack = state.nodebook.find(stack => stack[0] === parentId) + if (stack && (childId === undefined || stack.includes(childId))) return + commit('ADD_NODEBOOK_NODE', [stack, parentId, childId]) + dispatch('UPDATE_QUERY_NODES') + }, + + 'CLOSE_NODE' ({ state, commit, dispatch }, [parentId, childId]) { + const stack = state.nodebook.find(stack => stack.includes(parentId) && (childId ? stack.includes(childId) : true)) + commit('REMOVE_NODEBOOK_NODE', [stack, childId || parentId]) + dispatch('UPDATE_QUERY_NODES') } }, getters: { + mode: (state) => state.mode, + + nodebook: (state, getters, rootState) => { + if (!state.nodebook) return [] + return state.nodebook.map(([parentId, ...childrenIds]) => { + return { + parent: rootState.nodes[parentId], + children: childrenIds.map(id => rootState.nodes[id]) + } + }) + }, + + activeNodes: (state) => { + if (!state.nodebook) return [] + return state.nodebook.reduce((acc, ids) => [...acc, ...ids], []) + }, + tagsOptions: state => { - if (state.tags === undefined) return + if (state.tags === undefined) return [] return state.tags.map(tag => ({ value: tag.id, text: tag.name })) }, diff --git a/src/store/utils.js b/src/store/utils.js index ecf7a96..ec72ffc 100644 --- a/src/store/utils.js +++ b/src/store/utils.js @@ -29,6 +29,17 @@ export const VARIANT_IDS = Object.fromEntries( ) +export function parseNodesQueryParams ({ mode, nodes = [] }) { + let nodebook = typeof nodes === 'string' ? [nodes] : nodes + nodebook = nodebook.map(ids => { + return typeof ids === 'string' + ? ids.split(',').map(id => parseInt(id)) + : [...ids] + }) + return { mode, nodebook } +} + + export function getUniqueNodesIds (tree) { function extractId (ids, node) { ids.add(node.id)