mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: add useInitialQueries composable to replace ViewBase queries handling
This commit is contained in:
parent
3c3f50ca60
commit
25482b67ca
2 changed files with 53 additions and 52 deletions
|
@ -1,22 +1,15 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Component } from 'vue'
|
import type { Component } from 'vue'
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
|
|
||||||
import api from '@/api'
|
defineOptions({ inheritAttrs: false })
|
||||||
|
withDefaults(
|
||||||
// FIXME type queries
|
|
||||||
const props = withDefaults(
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
queries?: any[]
|
|
||||||
queriesWait?: boolean
|
|
||||||
skeleton?: string | Component
|
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
|
skeleton?: string | Component
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
queries: undefined,
|
loading: false,
|
||||||
queriesWait: false,
|
skeleton: 'CardFormSkeleton',
|
||||||
skeleton: undefined,
|
|
||||||
loading: undefined,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,44 +17,11 @@ const slots = defineSlots<{
|
||||||
'top-bar-group-left': any
|
'top-bar-group-left': any
|
||||||
'top-bar-group-right': any
|
'top-bar-group-right': any
|
||||||
'top-bar': any
|
'top-bar': any
|
||||||
top(props: { loading: boolean }): any
|
top: any
|
||||||
default(props: { loading: boolean }): any
|
default: any
|
||||||
bot(props: { loading: boolean }): any
|
bot: any
|
||||||
skeleton: any
|
skeleton: any
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
'queries-response': any[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
defineExpose({ fetchQueries })
|
|
||||||
|
|
||||||
const fallbackLoading = ref(
|
|
||||||
props.loading === undefined && props.queries !== undefined ? true : null,
|
|
||||||
)
|
|
||||||
|
|
||||||
const isLoading = computed(() => {
|
|
||||||
if (props.loading !== undefined) return props.loading
|
|
||||||
return fallbackLoading.value
|
|
||||||
})
|
|
||||||
|
|
||||||
function fetchQueries({ triggerLoading = false } = {}) {
|
|
||||||
if (triggerLoading) {
|
|
||||||
fallbackLoading.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return api
|
|
||||||
.fetchAll(props.queries, { wait: props.queriesWait, initial: true })
|
|
||||||
.then((responses) => {
|
|
||||||
emit('queries-response', ...responses)
|
|
||||||
fallbackLoading.value = false
|
|
||||||
return responses
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.queries) {
|
|
||||||
fetchQueries()
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -76,9 +36,9 @@ if (props.queries) {
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<slot v-else name="top-bar" />
|
<slot v-else name="top-bar" />
|
||||||
|
|
||||||
<slot name="top" v-bind="{ loading: isLoading }" />
|
<slot name="top" />
|
||||||
|
|
||||||
<BSkeletonWrapper :loading="isLoading">
|
<BSkeletonWrapper :loading="loading">
|
||||||
<template #loading>
|
<template #loading>
|
||||||
<slot name="skeleton">
|
<slot name="skeleton">
|
||||||
<Component :is="skeleton" />
|
<Component :is="skeleton" />
|
||||||
|
@ -87,10 +47,10 @@ if (props.queries) {
|
||||||
|
|
||||||
<!-- Empty div to be able to receive multiple components -->
|
<!-- Empty div to be able to receive multiple components -->
|
||||||
<div>
|
<div>
|
||||||
<slot name="default" v-bind="{ loading: isLoading }" />
|
<slot name="default" />
|
||||||
</div>
|
</div>
|
||||||
</BSkeletonWrapper>
|
</BSkeletonWrapper>
|
||||||
|
|
||||||
<slot name="bot" v-bind="{ loading: isLoading }" />
|
<slot name="bot" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
41
app/src/composables/useInitialQueries.ts
Normal file
41
app/src/composables/useInitialQueries.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue'
|
||||||
|
import { ref, toValue } from 'vue'
|
||||||
|
|
||||||
|
import type { APIQuery } from '@/api/api'
|
||||||
|
import api from '@/api/api'
|
||||||
|
import type { Obj } from '@/types/commons'
|
||||||
|
|
||||||
|
export function useInitialQueries<
|
||||||
|
ResponsesType extends (Obj | string)[] = Obj[],
|
||||||
|
>(
|
||||||
|
queries: MaybeRefOrGetter<APIQuery[]> | ComputedRef<APIQuery[]>,
|
||||||
|
{
|
||||||
|
onQueriesResponse,
|
||||||
|
wait = false,
|
||||||
|
}: {
|
||||||
|
onQueriesResponse?: (...responses: ResponsesType) => Promise<void> | void
|
||||||
|
wait?: boolean
|
||||||
|
} = {},
|
||||||
|
) {
|
||||||
|
const loading = ref(true)
|
||||||
|
const responses: Ref<ResponsesType | null> = ref(null)
|
||||||
|
// FIXME watch `queries` to call on change?
|
||||||
|
|
||||||
|
function call(triggerLoading = true) {
|
||||||
|
if (triggerLoading) loading.value = true
|
||||||
|
return api
|
||||||
|
.fetchAll(toValue(queries), { wait, initial: true })
|
||||||
|
.then(async (responses_) => {
|
||||||
|
responses.value = responses_ as ResponsesType
|
||||||
|
if (onQueriesResponse) {
|
||||||
|
await onQueriesResponse(...(responses_ as ResponsesType))
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
return responses
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
call()
|
||||||
|
|
||||||
|
return { loading, responses, refetch: call }
|
||||||
|
}
|
Loading…
Reference in a new issue