fix: close modal
This commit is contained in:
parent
b264065d7e
commit
345542cbbd
|
@ -5,12 +5,7 @@ export default { inheritAttrs: false }
|
|||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAttrs } from 'vue'
|
||||
|
||||
defineProps<{ is: any }>()
|
||||
|
||||
const attrs = useAttrs()
|
||||
console.log(JSON.parse(JSON.stringify(attrs)))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -32,16 +32,14 @@
|
|||
|
||||
<quick-actions/>
|
||||
|
||||
<router-view :route="routeWithModal" v-slot="{ Component }">
|
||||
<keep-alive :include="['list.list', 'list.gantt', 'list.table', 'list.kanban']">
|
||||
<router-view v-if="routeWithModal" :route="routeWithModal" v-slot="{ Component }">
|
||||
<!-- <keep-alive :include="['list.list', 'list.gantt', 'list.table', 'list.kanban']"> -->
|
||||
<component :is="Component"/>
|
||||
</keep-alive>
|
||||
<!-- test -->
|
||||
<!-- </keep-alive> -->
|
||||
</router-view>
|
||||
|
||||
<component
|
||||
:is="currentModal"
|
||||
@close="closeModal()"
|
||||
/>
|
||||
<component :is="currentModal" />
|
||||
|
||||
<BaseButton
|
||||
class="keyboard-shortcuts-button d-print-none"
|
||||
|
@ -69,7 +67,7 @@ import {useLabelStore} from '@/stores/labels'
|
|||
import {useRouteWithModal} from '@/composables/useRouteWithModal'
|
||||
import {useRenewTokenOnFocus} from '@/composables/useRenewTokenOnFocus'
|
||||
|
||||
const {routeWithModal, currentModal, closeModal} = useRouteWithModal()
|
||||
const {routeWithModal, currentModal} = useRouteWithModal()
|
||||
|
||||
const baseStore = useBaseStore()
|
||||
const background = computed(() => baseStore.background)
|
||||
|
|
|
@ -1,56 +1,112 @@
|
|||
import { computed, shallowRef, watchEffect, h, type VNode } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { computed, shallowRef, watch, h, type VNode, ref } from 'vue'
|
||||
import { useRoute, useRouter, loadRouteLocation, type RouteLocationNormalizedLoaded, type RouteLocationRaw } from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
// this is adapted from vue-router
|
||||
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
|
||||
function getRouteProps(route: RouteLocationNormalizedLoaded) {
|
||||
const routePropsOption = route.matched[0]?.props.default
|
||||
return routePropsOption
|
||||
? routePropsOption === true
|
||||
? route.params
|
||||
: typeof routePropsOption === 'function'
|
||||
? routePropsOption(route)
|
||||
: routePropsOption
|
||||
: {}
|
||||
}
|
||||
|
||||
function resolveAndLoadRoute(route: RouteLocationRaw) {
|
||||
return loadRouteLocation(router.resolve(route))
|
||||
}
|
||||
|
||||
export function useRouteWithModal() {
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const backdropView = computed(() => route.fullPath && window.history.state.backdropView)
|
||||
|
||||
const routeWithModal = computed(() => {
|
||||
return backdropView.value
|
||||
? router.resolve(backdropView.value)
|
||||
: route
|
||||
|
||||
const backdropView = computed<RouteLocationRaw | undefined>(() => {
|
||||
// every time the fullPath changes we check the history state
|
||||
// this happens also initially
|
||||
return route.fullPath
|
||||
? window.history.state?.backdropView
|
||||
: undefined
|
||||
})
|
||||
|
||||
const routerIsReady = ref(false)
|
||||
router.isReady().then(() => {
|
||||
routerIsReady.value = true
|
||||
})
|
||||
|
||||
const baseRoute = shallowRef<RouteLocationNormalizedLoaded>()
|
||||
watch(
|
||||
[backdropView, routerIsReady],
|
||||
async () => {
|
||||
if (routerIsReady.value === false || !route.fullPath) {
|
||||
return
|
||||
}
|
||||
|
||||
if (backdropView.value === undefined) {
|
||||
if (route.meta?.showAsModal !== true) {
|
||||
baseRoute.value = route
|
||||
return
|
||||
}
|
||||
// TODO: maybe load parent route here in the future,
|
||||
// via: route.matched[route.matched.length - 2]
|
||||
// see: https://router.vuejs.org/guide/migration/#removal-of-parent-from-route-locations
|
||||
baseRoute.value = await resolveAndLoadRoute({ name: 'home' })
|
||||
return
|
||||
}
|
||||
|
||||
// we get the resolved route from the fullpath
|
||||
// and wait for the route component to be loaded before we assign it
|
||||
baseRoute.value = await resolveAndLoadRoute(backdropView.value)
|
||||
},
|
||||
{immediate: true},
|
||||
)
|
||||
|
||||
const backdropRoute = computed(() => route.fullPath !== baseRoute.value?.fullPath ? baseRoute.value : undefined)
|
||||
|
||||
const currentModal = shallowRef<VNode>()
|
||||
watchEffect(() => {
|
||||
if (!backdropView.value) {
|
||||
currentModal.value = undefined
|
||||
return
|
||||
watch(
|
||||
[backdropRoute, baseRoute, route],
|
||||
() => {
|
||||
if (routerIsReady.value === false || !route.fullPath || !backdropRoute.value) {
|
||||
currentModal.value = undefined
|
||||
return
|
||||
}
|
||||
|
||||
const props = getRouteProps(route)
|
||||
|
||||
props.backdropView = backdropRoute.value
|
||||
props.onClose = closeModal
|
||||
|
||||
const component = route.matched[0]?.components?.default
|
||||
|
||||
if (!component) {
|
||||
currentModal.value = undefined
|
||||
return
|
||||
}
|
||||
currentModal.value = h(component, props)
|
||||
},
|
||||
{immediate: true},
|
||||
)
|
||||
|
||||
async function closeModal() {
|
||||
await router.isReady()
|
||||
if (backdropRoute.value !== undefined) {
|
||||
// TODO: Dialog modals might want to replace the route here via router.replace()
|
||||
return router.push(backdropRoute.value)
|
||||
}
|
||||
|
||||
// this is adapted from vue-router
|
||||
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
|
||||
const routePropsOption = route.matched[0]?.props.default
|
||||
const routeProps = routePropsOption
|
||||
? routePropsOption === true
|
||||
? route.params
|
||||
: typeof routePropsOption === 'function'
|
||||
? routePropsOption(route)
|
||||
: routePropsOption
|
||||
: {}
|
||||
|
||||
routeProps.backdropView = backdropView.value
|
||||
|
||||
const component = route.matched[0]?.components?.default
|
||||
|
||||
if (!component) {
|
||||
currentModal.value = undefined
|
||||
return
|
||||
}
|
||||
currentModal.value = h(component, routeProps)
|
||||
})
|
||||
|
||||
function closeModal() {
|
||||
const historyState = computed(() => route.fullPath && window.history.state)
|
||||
|
||||
if (historyState.value === undefined) {
|
||||
router.back()
|
||||
if (window.history.state === undefined) {
|
||||
return router.push({ name: 'home' })
|
||||
} else {
|
||||
const backdropRoute = historyState.value.backdropView && router.resolve(historyState.value.backdropView)
|
||||
router.push(backdropRoute)
|
||||
router.back()
|
||||
throw new Error('')
|
||||
}
|
||||
}
|
||||
|
||||
return {routeWithModal, currentModal, closeModal}
|
||||
return {
|
||||
routeWithModal: baseRoute,
|
||||
currentModal,
|
||||
closeModal,
|
||||
}
|
||||
}
|
|
@ -240,7 +240,7 @@ const router = createRouter({
|
|||
meta: {
|
||||
showAsModal: true,
|
||||
},
|
||||
props: route => ({ namespaceId: parseInt(route.params.id as string) }),
|
||||
props: route => ({ namespaceId: Number(route.params.id as string) }),
|
||||
},
|
||||
{
|
||||
path: '/namespaces/:id/settings/delete',
|
||||
|
@ -468,6 +468,9 @@ const router = createRouter({
|
|||
path: '/about',
|
||||
name: 'about',
|
||||
component: About,
|
||||
meta: {
|
||||
showAsModal: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
|
|
@ -512,9 +512,6 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
|
||||
defineEmits(['close'])
|
||||
const attrs = useAttrs()
|
||||
console.log(JSON.parse(JSON.stringify(attrs)))
|
||||
const router = useRouter()
|
||||
const {t} = useI18n({useScope: 'global'})
|
||||
|
||||
|
|
Reference in New Issue