mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
72 lines
1.7 KiB
Vue
72 lines
1.7 KiB
Vue
<!-- Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/ -->
|
|
|
|
<script setup lang="ts">
|
|
import { useEventListener } from '@vueuse/core'
|
|
import { markRaw, shallowRef } from 'vue'
|
|
|
|
import { Events } from './manage.ts'
|
|
|
|
import type { DestroyComponentData, PushComponentData } from './types.ts'
|
|
import type { TransitionProps } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
/**
|
|
* Name of a group of components that will be pushed to with unique ID.
|
|
*/
|
|
name: string
|
|
/**
|
|
* Transition, if any.
|
|
*/
|
|
transition?: TransitionProps
|
|
}>()
|
|
|
|
const components = shallowRef<PushComponentData[]>([])
|
|
|
|
useEventListener(window, Events.Push, ({ detail }: CustomEvent<PushComponentData>) => {
|
|
if (detail.name !== props.name) return
|
|
|
|
components.value = [
|
|
...components.value,
|
|
{
|
|
...detail,
|
|
cmp: markRaw(detail.cmp),
|
|
},
|
|
]
|
|
})
|
|
|
|
useEventListener(window, Events.Destroy, ({ detail }: CustomEvent<DestroyComponentData>) => {
|
|
if (detail.name !== props.name) return
|
|
|
|
if (!detail.id) {
|
|
components.value = []
|
|
|
|
return
|
|
}
|
|
|
|
components.value = components.value.filter(
|
|
(item) => !(item.name === detail.name && item.id === detail.id),
|
|
)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<TransitionGroup v-if="transition" v-bind="transition">
|
|
<Component
|
|
:is="cmp"
|
|
v-for="{ cmp, name: cmpName, id, props: cmpProps } in components"
|
|
:key="`${cmpName}-${id}`"
|
|
v-bind="cmpProps"
|
|
/>
|
|
</TransitionGroup>
|
|
|
|
<template v-else-if="!$slots.default">
|
|
<Component
|
|
:is="cmp"
|
|
v-for="{ cmp, name: cmpName, id, props: cmpProps } in components"
|
|
:key="`${cmpName}-${id}`"
|
|
v-bind="cmpProps"
|
|
/>
|
|
</template>
|
|
|
|
<slot v-else :components="components" />
|
|
</template>
|