From e0b56962d260563ce285c96207e573fe8806d251 Mon Sep 17 00:00:00 2001 From: xaralis <filip.varecha@fragaria.cz> Date: Sun, 2 Aug 2020 13:19:42 +0200 Subject: [PATCH] Persist selected view in URL on elections page --- .../_patterns/03-templates/elections.mustache | 2 +- source/js/components/ViewProvider.vue | 54 +++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/source/_patterns/03-templates/elections.mustache b/source/_patterns/03-templates/elections.mustache index d335c82..85451e5 100644 --- a/source/_patterns/03-templates/elections.mustache +++ b/source/_patterns/03-templates/elections.mustache @@ -2,7 +2,7 @@ {{> organisms-elections-hero }} <div class="__js-root"> - <ui-view-provider :initial="{candidates: true, program: false}" v-slot="{ isCurrentView, toggleView }"> + <ui-view-provider :initial="{candidates: true, program: false}" :sync-location="true" v-slot="{ isCurrentView, toggleView }"> <main> <div class="container container--default pt-8 lg:py-24"> <div class="text-center"> diff --git a/source/js/components/ViewProvider.vue b/source/js/components/ViewProvider.vue index 2aeb094..9b66dd3 100644 --- a/source/js/components/ViewProvider.vue +++ b/source/js/components/ViewProvider.vue @@ -4,6 +4,7 @@ v-bind:views="views" v-bind:isCurrentView="isCurrentView" v-bind:toggleView="toggleView" + v-bind:showView="showView" v-bind:setView="setView" ></slot> </div> @@ -14,11 +15,20 @@ export default { props: { initial: { default: () => {} + }, + syncLocation: { + type: Boolean, + default: false, + }, + locationParam: { + type: String, + default: "view", } }, data() { return { views: this.$props.initial, + queryParams: null, keyListener: e => { // Esc if (e.keyCode === 27) { @@ -27,21 +37,38 @@ export default { } }; }, + watch: { + routeView() { + const queryParams = new URLSearchParams(window.location.search); + } + }, methods: { - setView(viewId, show) { + setView(viewId, show, hideOthers = false) { + if (hideOthers) { + Object.keys(this.$data.views).forEach(key => { + if (key !== viewId) { + this.setView(key, false); + } + }); + } + this.$data.views[viewId] = show; + + if (show && this.$props.syncLocation) { + const queryParams = new URLSearchParams(window.location.search); + + queryParams.set(this.$props.locationParam, viewId); + history.pushState(null, null, "?" + queryParams.toString()); + } }, setViews(updates) { this.$data.views = Object.assign({}, this.data.views, updates); }, toggleView(viewId) { - Object.keys(this.$data.views).forEach(key => { - if (key !== viewId) { - this.setView(key, false); - } - }); - - this.setView(viewId, !this.isCurrentView(viewId)); + this.setView(viewId, !this.isCurrentView(viewId), true); + }, + showView(viewId) { + this.setView(viewId, true, true); }, isCurrentView(viewId) { return this.$data.views[viewId]; @@ -53,7 +80,16 @@ export default { } }, mounted() { - window.addEventListener('keydown', this.$data.keyListener);; + window.addEventListener('keydown', this.$data.keyListener); + + if (this.$props.syncLocation) { + const queryParams = new URLSearchParams(window.location.search); + const locationView = queryParams.get(this.$props.locationParam); + + if (Object.keys(this.$data.views).indexOf(locationView) !== -1) { + this.showView(locationView); + } + } }, destroyed() { window.removeEventListener('keydown', this.$data.keyListener); -- GitLab