mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: rework useSearch and ViewSearch to no longer use ViewBase and expect defined data
This commit is contained in:
parent
da02692d93
commit
1f1dac1792
2 changed files with 43 additions and 49 deletions
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts" generic="T extends Obj | AnyTreeNode">
|
||||
import { computed, type Component } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type { AnyTreeNode } from '@/helpers/data/tree'
|
||||
|
@ -10,12 +10,10 @@ const props = withDefaults(
|
|||
items?: T[] | null
|
||||
itemsName: string | null
|
||||
modelValue?: string
|
||||
skeleton?: string | Component
|
||||
}>(),
|
||||
{
|
||||
items: undefined,
|
||||
modelValue: undefined,
|
||||
skeleton: 'ListGroupSkeleton',
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -24,6 +22,7 @@ const slots = defineSlots<{
|
|||
'top-bar-buttons': any
|
||||
top: any
|
||||
'alert-message': any
|
||||
'forced-default'?: any
|
||||
default: any
|
||||
bot: any
|
||||
skeleton: any
|
||||
|
@ -47,11 +46,10 @@ const noItemsMessage = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<ViewBase :skeleton="skeleton">
|
||||
<template v-if="slots['top-bar']" #top-bar>
|
||||
<slot name="top-bar" />
|
||||
</template>
|
||||
<template v-if="!slots['top-bar']" #top-bar-group-left>
|
||||
<div>
|
||||
<slot v-if="slots['top-bar']" name="top-bar" />
|
||||
<TopBar v-else>
|
||||
<template #group-left>
|
||||
<BInputGroup class="w-100">
|
||||
<BInputGroupText>
|
||||
<YIcon iname="search" />
|
||||
|
@ -60,36 +58,30 @@ const noItemsMessage = computed(() => {
|
|||
<BFormInput
|
||||
id="top-bar-search"
|
||||
v-model="model"
|
||||
:placeholder="t('search.for', { items: t('items.' + itemsName, 2) })"
|
||||
:disabled="!items"
|
||||
:placeholder="
|
||||
t('search.for', { items: t('items.' + itemsName, 2) })
|
||||
"
|
||||
:disabled="items === undefined"
|
||||
/>
|
||||
</BInputGroup>
|
||||
</template>
|
||||
<template v-if="!slots['top-bar']" #top-bar-group-right>
|
||||
<template #group-right>
|
||||
<slot name="top-bar-buttons" />
|
||||
</template>
|
||||
</TopBar>
|
||||
|
||||
<template #top>
|
||||
<slot name="top" />
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
<slot name="forced-default">
|
||||
<BAlert v-if="noItemsMessage" :model-value="true" variant="warning">
|
||||
<slot name="alert-message">
|
||||
<YIcon iname="exclamation-triangle" />
|
||||
{{ noItemsMessage }}
|
||||
</slot>
|
||||
</BAlert>
|
||||
|
||||
<slot v-else name="default" />
|
||||
</template>
|
||||
</slot>
|
||||
|
||||
<template #bot>
|
||||
<slot name="bot" />
|
||||
</template>
|
||||
|
||||
<template #skeleton>
|
||||
<slot name="skeleton" />
|
||||
</template>
|
||||
</ViewBase>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue'
|
||||
import { computed, ref, toValue, watch } from 'vue'
|
||||
import type {
|
||||
ComputedRef,
|
||||
MaybeRefOrGetter,
|
||||
Ref,
|
||||
WritableComputedRef,
|
||||
} from 'vue'
|
||||
import { computed, isRef, ref, toValue } from 'vue'
|
||||
|
||||
import type { AnyTreeNode, TreeRootNode } from '@/helpers/data/tree'
|
||||
|
||||
// Returns `undefined` when there's no items and `null` when there's no match
|
||||
export function useSearch<
|
||||
T extends any[] | TreeRootNode,
|
||||
V extends T extends (infer V)[] ? V : AnyTreeNode,
|
||||
>(
|
||||
items:
|
||||
| MaybeRefOrGetter<T | null | undefined>
|
||||
| ComputedRef<T | null | undefined>,
|
||||
items: MaybeRefOrGetter<T> | ComputedRef<T>,
|
||||
filterFn: (search: string, item: V, index: number, arr: T) => boolean,
|
||||
{
|
||||
externalSearch,
|
||||
|
@ -18,19 +22,17 @@ export function useSearch<
|
|||
}: {
|
||||
filterAllFn?: (search: string, items: T) => boolean | undefined
|
||||
filterIfNoSearch?: boolean
|
||||
externalSearch?: MaybeRefOrGetter<string>
|
||||
externalSearch?: Ref<string> | WritableComputedRef<string>
|
||||
} = {},
|
||||
): [search: Ref<string>, filteredItems: ComputedRef<T | undefined | null>] {
|
||||
const search = ref(toValue(externalSearch) ?? '')
|
||||
watch(
|
||||
() => toValue(externalSearch),
|
||||
(s) => (search.value = s ?? ''),
|
||||
)
|
||||
const search = isRef(externalSearch)
|
||||
? externalSearch
|
||||
: ref(toValue(externalSearch) ?? '')
|
||||
|
||||
const filteredItems = computed(() => {
|
||||
const items_ = toValue(items)
|
||||
const s = toValue(search.value).toLowerCase()
|
||||
if (!items_) return undefined
|
||||
if (!items_.length) return undefined
|
||||
if (filterAllFn) {
|
||||
const returnAll = filterAllFn(s, items_)
|
||||
if (returnAll !== undefined) {
|
||||
|
|
Loading…
Reference in a new issue