57 lines
1.6 KiB
Vue
57 lines
1.6 KiB
Vue
<script setup lang="ts" generic="R, E">
|
|
import type { UseQueryReturnType } from '@tanstack/vue-query'
|
|
import { ROUTE_NAMES } from '@/constants/routes'
|
|
|
|
type Props = {
|
|
query: UseQueryReturnType<R, E>
|
|
}
|
|
|
|
const slots = defineSlots<{
|
|
default?: (slotBindings: { data: R }) => void
|
|
notFound?: (slotBindings: { error: E; reload: typeof refetch }) => void
|
|
error?: (slotBindings: { error: E; reload: typeof refetch }) => void
|
|
loading?: () => void
|
|
}>()
|
|
|
|
const { query } = defineProps<Props>()
|
|
|
|
const { data, error, refetch, isSuccess, isError, isLoading } = query
|
|
</script>
|
|
|
|
<template>
|
|
<slot v-if="isSuccess && data" name="default" :data />
|
|
<slot v-else-if="isLoading" name="loading">
|
|
<div class="text-center text-gray-500" v-if="!slots.loading">
|
|
<ProgressSpinner styleClass="mt-4" />
|
|
</div>
|
|
</slot>
|
|
|
|
<slot
|
|
v-else-if="
|
|
isError &&
|
|
error &&
|
|
typeof error === 'object' &&
|
|
'error' in error &&
|
|
error.error === 'not_found'
|
|
"
|
|
name="notFound"
|
|
:error="error!"
|
|
:reload="refetch"
|
|
>
|
|
<template v-if="!slots.notFound">
|
|
Страница не найдена<br />
|
|
<RouterLink
|
|
:to="{ name: ROUTE_NAMES.HOME }"
|
|
class="underline text-blue-600 dark:text-blue-400"
|
|
>Перейти на главную</RouterLink
|
|
></template
|
|
>
|
|
</slot>
|
|
<slot v-else-if="isError" name="error" :error="error!" :reload="refetch">
|
|
<template v-if="!slots.error">
|
|
Ошибка загрузки данных:
|
|
{{ error && typeof error === 'object' && 'message' in error ? error.message : error }}
|
|
</template>
|
|
</slot>
|
|
</template>
|