Project switching (#206)

* Register notice component globally

* Render button as flex in full width

* Add buttons to / route

* Rename block->full-width

* Add hyrate overlay / project chooser placeholder

* Make routes named

* Dehydrate / hydrate when switching projects

* Add choose project buttons to / route

* Add main app component and hydration loader effect

* Improve routing flow

* Remove unused import statement

* Fix test
This commit is contained in:
Rijk van Zanten
2020-03-17 16:25:43 -04:00
committed by GitHub
parent b26b91f785
commit 346e6f95ce
23 changed files with 252 additions and 55 deletions

View File

@@ -0,0 +1,4 @@
import ProjectChooser from './project-chooser.vue';
export { ProjectChooser };
export default ProjectChooser;

View File

@@ -0,0 +1,65 @@
<template>
<div class="project-chooser">
<span>{{ currentProjectKey }}</span>
<select :value="currentProjectKey" @change="navigateToProject">
<option v-for="project in projects" :key="project.key" :value="project.key">
{{ (project.api && project.api.project_name) || project.key }}
</option>
</select>
</div>
</template>
<script lang="ts">
import { defineComponent, toRefs } from '@vue/composition-api';
import { useProjectsStore } from '@/stores/projects';
import router from '@/router';
export default defineComponent({
setup() {
const projectsStore = useProjectsStore();
const { projects, currentProjectKey } = toRefs(projectsStore.state);
return {
projects,
currentProjectKey,
navigateToProject,
projectsStore
};
function navigateToProject(event: InputEvent) {
router
.push(`/${(event.target as HTMLSelectElement).value}/collections`)
/** @NOTE
* Vue Router considers a navigation change _in_ the navigation guard a rejection
* so when this push goes from /collections to /login, it will throw.
* In order to prevent a useless uncaught exception to show up in the console,
* we have to catch it here with a no-op. See
* https://github.com/vuejs/vue-router/issues/2881#issuecomment-520554378
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
.catch(() => {});
}
}
});
</script>
<style lang="scss" scoped>
.project-chooser {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 64px;
background-color: var(--highlight);
select {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0;
}
}
</style>

View File

@@ -2,10 +2,12 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueCompositionAPI from '@vue/composition-api';
import PrivateView from './private-view.vue';
import VOverlay from '@/components/v-overlay';
import VProgressCircular from '@/components/v-progress/circular';
const localVue = createLocalVue();
localVue.use(VueCompositionAPI);
localVue.component('v-overlay', VOverlay);
localVue.component('v-progress-circular', VProgressCircular);
describe('Views / Private', () => {
it('Adds the is-open class to the nav', async () => {

View File

@@ -8,11 +8,8 @@
>
<module-bar />
<div class="module-nav alt-colors">
<div
style="height: 64px; padding: 20px; color: red; font-family: 'Comic Sans MS', cursive;"
>
PROJECT CHOOSER
</div>
<project-chooser />
<div class="module-nav-content">
<slot name="navigation" />
</div>
@@ -58,13 +55,15 @@ import { defineComponent, ref, provide, computed } from '@vue/composition-api';
import ModuleBar from './components/module-bar/';
import DrawerDetailGroup from './components/drawer-detail-group/';
import HeaderBar from './components/header-bar';
import ProjectChooser from './components/project-chooser';
import { throttle } from 'lodash';
export default defineComponent({
components: {
ModuleBar,
DrawerDetailGroup,
HeaderBar
HeaderBar,
ProjectChooser
},
props: {
title: {