feat: wrap projects navigation in a <Suspense> so that we can use top level await
This commit is contained in:
parent
6f1baa3219
commit
2579c33ee1
36
src/components/home/ProjectsNavigationWrapper.vue
Normal file
36
src/components/home/ProjectsNavigationWrapper.vue
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<nav class="menu" v-if="favoriteProjects">
|
||||||
|
<ProjectsNavigation v-model="favoriteProjects" :can-edit-order="false"/>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="menu">
|
||||||
|
<ProjectsNavigation v-model="projects" :can-edit-order="true"/>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {computed} from 'vue'
|
||||||
|
import {useProjectStore} from '@/stores/projects'
|
||||||
|
import ProjectsNavigation from '@/components/home/ProjectsNavigation.vue'
|
||||||
|
|
||||||
|
const projectStore = useProjectStore()
|
||||||
|
|
||||||
|
await projectStore.loadProjects()
|
||||||
|
|
||||||
|
const projects = computed(() => projectStore.projectsArray
|
||||||
|
.filter(p => p.parentProjectId === 0 && !p.isArchived)
|
||||||
|
.sort((a, b) => a.position - b.position))
|
||||||
|
const favoriteProjects = computed(() => projectStore.projectsArray
|
||||||
|
.filter(p => !p.isArchived && p.isFavorite)
|
||||||
|
.map(p => ({
|
||||||
|
...p,
|
||||||
|
childProjects: [],
|
||||||
|
}))
|
||||||
|
.sort((a, b) => a.position - b.position))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.menu {
|
||||||
|
padding-top: math.div($navbar-padding, 2);
|
||||||
|
}
|
||||||
|
</style>
|
@ -16,7 +16,12 @@
|
|||||||
:class="{'is-visible': background}"
|
:class="{'is-visible': background}"
|
||||||
class="app-container-background background-fade-in d-print-none"
|
class="app-container-background background-fade-in d-print-none"
|
||||||
:style="{'background-image': background && `url(${background})`}"></div>
|
:style="{'background-image': background && `url(${background})`}"></div>
|
||||||
|
<Suspense>
|
||||||
<navigation class="d-print-none"/>
|
<navigation class="d-print-none"/>
|
||||||
|
<template #fallback>
|
||||||
|
Loading...
|
||||||
|
</template>
|
||||||
|
</Suspense>
|
||||||
<main
|
<main
|
||||||
class="app-content"
|
class="app-content"
|
||||||
:class="[
|
:class="[
|
||||||
|
@ -48,47 +48,30 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<nav class="menu" v-if="favoriteProjects">
|
<Suspense>
|
||||||
<ProjectsNavigation v-model="favoriteProjects" :can-edit-order="false"/>
|
<ProjectsNavigationWrapper/>
|
||||||
</nav>
|
|
||||||
|
|
||||||
<nav class="menu">
|
<template #fallback>
|
||||||
<ProjectsNavigation v-model="projects" :can-edit-order="true"/>
|
<Loading/>
|
||||||
</nav>
|
</template>
|
||||||
|
</Suspense>
|
||||||
|
|
||||||
<PoweredByLink/>
|
<PoweredByLink/>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, onBeforeMount} from 'vue'
|
import {computed} from 'vue'
|
||||||
|
|
||||||
import PoweredByLink from '@/components/home/PoweredByLink.vue'
|
import PoweredByLink from '@/components/home/PoweredByLink.vue'
|
||||||
import Logo from '@/components/home/Logo.vue'
|
import Logo from '@/components/home/Logo.vue'
|
||||||
|
import Loading from '@/components/misc/loading.vue'
|
||||||
|
|
||||||
import {useBaseStore} from '@/stores/base'
|
import {useBaseStore} from '@/stores/base'
|
||||||
import {useProjectStore} from '@/stores/projects'
|
import ProjectsNavigationWrapper from '@/components/home/ProjectsNavigationWrapper.vue'
|
||||||
import ProjectsNavigation from '@/components/home/ProjectsNavigation.vue'
|
|
||||||
|
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
const projectStore = useProjectStore()
|
|
||||||
const menuActive = computed(() => baseStore.menuActive)
|
const menuActive = computed(() => baseStore.menuActive)
|
||||||
|
|
||||||
// FIXME: async action will be unfinished when component mounts
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
await projectStore.loadProjects()
|
|
||||||
})
|
|
||||||
|
|
||||||
const projects = computed(() => projectStore.projectsArray
|
|
||||||
.filter(p => p.parentProjectId === 0 && !p.isArchived)
|
|
||||||
.sort((a, b) => a.position - b.position))
|
|
||||||
const favoriteProjects = computed(() => projectStore.projectsArray
|
|
||||||
.filter(p => !p.isArchived && p.isFavorite)
|
|
||||||
.map(p => ({
|
|
||||||
...p,
|
|
||||||
childProjects: [],
|
|
||||||
}))
|
|
||||||
.sort((a, b) => a.position - b.position))
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -150,7 +133,16 @@ const favoriteProjects = computed(() => projectStore.projectsArray
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.loader-container {
|
||||||
padding-top: math.div($navbar-padding, 2);
|
min-width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
|
||||||
|
&.is-loading::after {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
top: calc(50% - 1.5rem);
|
||||||
|
left: calc(50% - 1.5rem);
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user