mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-04 23:18:44 +08:00
feat:人物搜索
This commit is contained in:
@@ -17,15 +17,13 @@ const isImageLoaded = ref(false)
|
|||||||
|
|
||||||
// 人物图片地址
|
// 人物图片地址
|
||||||
function getPersonImage() {
|
function getPersonImage() {
|
||||||
if (!personInfo.value?.profile_path)
|
if (!personInfo.value?.profile_path) return personIcon
|
||||||
return personIcon
|
|
||||||
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personInfo.value?.profile_path}`
|
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personInfo.value?.profile_path}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 人物详情
|
// 人物详情
|
||||||
function goPersonDetail() {
|
function goPersonDetail() {
|
||||||
if (!personInfo.value?.id)
|
if (!personInfo.value?.id) return
|
||||||
return
|
|
||||||
router.push({
|
router.push({
|
||||||
path: '/person',
|
path: '/person',
|
||||||
query: {
|
query: {
|
||||||
@@ -51,7 +49,7 @@ function goPersonDetail() {
|
|||||||
<div
|
<div
|
||||||
class="person-card relative transform-gpu cursor-pointer rounded shadow ring-1 transition duration-150 ease-in-out scale-100 ring-gray-700"
|
class="person-card relative transform-gpu cursor-pointer rounded shadow ring-1 transition duration-150 ease-in-out scale-100 ring-gray-700"
|
||||||
>
|
>
|
||||||
<div style="padding-bottom: 150%;">
|
<div style="padding-block-end: 150%">
|
||||||
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
||||||
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
||||||
<VAvatar
|
<VAvatar
|
||||||
@@ -60,17 +58,16 @@ function goPersonDetail() {
|
|||||||
'ring-1 ring-gray-700': isImageLoaded,
|
'ring-1 ring-gray-700': isImageLoaded,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<VImg
|
<VImg :src="getPersonImage()" cover @load="isImageLoaded = true" />
|
||||||
:src="getPersonImage()"
|
|
||||||
cover
|
|
||||||
@load="isImageLoaded = true"
|
|
||||||
/>
|
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full truncate text-center font-bold">
|
<div class="w-full truncate text-center font-bold">
|
||||||
{{ personInfo?.name }}
|
{{ personInfo?.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden whitespace-normal text-center text-sm" style=" display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical;-webkit-line-clamp: 2;">
|
<div
|
||||||
|
class="overflow-hidden whitespace-normal text-center text-sm"
|
||||||
|
style="display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2"
|
||||||
|
>
|
||||||
{{ personInfo?.character }}
|
{{ personInfo?.character }}
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
||||||
|
|||||||
@@ -11,20 +11,28 @@ const searchDialog = ref(false)
|
|||||||
// ref
|
// ref
|
||||||
const searchWordInput = ref<HTMLElement | null>(null)
|
const searchWordInput = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
// 当前的搜索类型 media/person
|
||||||
|
const searchType = ref('media')
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
function search() {
|
function search() {
|
||||||
if (!searchWord.value)
|
if (!searchWord.value) return
|
||||||
return
|
|
||||||
|
|
||||||
searchDialog.value = false
|
searchDialog.value = false
|
||||||
router.push({
|
router.push({
|
||||||
path: '/browse/media/search',
|
path: '/browse/media/search',
|
||||||
query: {
|
query: {
|
||||||
title: searchWord.value,
|
title: searchWord.value,
|
||||||
|
type: searchType.value,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换搜索类型
|
||||||
|
function switchSearchType() {
|
||||||
|
searchType.value = searchType.value === 'media' ? 'person' : 'media'
|
||||||
|
}
|
||||||
|
|
||||||
// 打开搜索弹窗
|
// 打开搜索弹窗
|
||||||
function openSearchDialog() {
|
function openSearchDialog() {
|
||||||
searchDialog.value = true
|
searchDialog.value = true
|
||||||
@@ -36,15 +44,8 @@ function openSearchDialog() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 👉 Search Button -->
|
<!-- 👉 Search Button -->
|
||||||
<div
|
<div class="d-flex align-center cursor-pointer" style="user-select: none">
|
||||||
class="d-flex align-center cursor-pointer"
|
<VDialog v-model="searchDialog" max-width="50rem" transition="dialog-top-transition">
|
||||||
style="user-select: none;"
|
|
||||||
>
|
|
||||||
<VDialog
|
|
||||||
v-model="searchDialog"
|
|
||||||
max-width="50rem"
|
|
||||||
transition="dialog-top-transition"
|
|
||||||
>
|
|
||||||
<!-- Dialog Content -->
|
<!-- Dialog Content -->
|
||||||
<VCard title="搜索">
|
<VCard title="搜索">
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -53,8 +54,10 @@ function openSearchDialog() {
|
|||||||
<VTextField
|
<VTextField
|
||||||
ref="searchWordInput"
|
ref="searchWordInput"
|
||||||
v-model="searchWord"
|
v-model="searchWord"
|
||||||
label="电影、电视剧名称"
|
:prepend-inner-icon="searchType == 'person' ? 'mdi-account' : 'mdi-movie-roll'"
|
||||||
|
:label="searchType == 'person' ? '演员名称' : '电影、电视剧名称'"
|
||||||
@keydown.enter="search"
|
@keydown.enter="search"
|
||||||
|
@click:prepend-inner="switchSearchType"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
@@ -62,21 +65,13 @@ function openSearchDialog() {
|
|||||||
|
|
||||||
<VCardActions>
|
<VCardActions>
|
||||||
<VSpacer />
|
<VSpacer />
|
||||||
<VBtn
|
<VBtn variant="tonal" @click="search"> 搜索 </VBtn>
|
||||||
variant="tonal"
|
|
||||||
@click="search"
|
|
||||||
>
|
|
||||||
搜索
|
|
||||||
</VBtn>
|
|
||||||
</VCardActions>
|
</VCardActions>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</div>
|
</div>
|
||||||
<!-- 👉 Search Icon -->
|
<!-- 👉 Search Icon -->
|
||||||
<IconBtn
|
<IconBtn class="d-lg-none" @click="openSearchDialog">
|
||||||
class="d-lg-none"
|
|
||||||
@click="openSearchDialog"
|
|
||||||
>
|
|
||||||
<VIcon icon="mdi-magnify" />
|
<VIcon icon="mdi-magnify" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
<!-- 👉 Search Textfield -->
|
<!-- 👉 Search Textfield -->
|
||||||
@@ -87,20 +82,22 @@ function openSearchDialog() {
|
|||||||
class="d-none d-lg-block text-disabled search-box"
|
class="d-none d-lg-block text-disabled search-box"
|
||||||
density="compact"
|
density="compact"
|
||||||
variant="solo"
|
variant="solo"
|
||||||
label="搜索电影、电视剧"
|
:prepend-inner-icon="searchType == 'person' ? 'mdi-account' : 'mdi-movie-roll'"
|
||||||
|
:label="searchType == 'person' ? '演员名称' : '电影、电视剧名称'"
|
||||||
append-inner-icon="mdi-magnify"
|
append-inner-icon="mdi-magnify"
|
||||||
single-line
|
single-line
|
||||||
hide-details
|
hide-details
|
||||||
flat
|
flat
|
||||||
rounded
|
rounded
|
||||||
@click:append-inner="search"
|
@click:append-inner="search"
|
||||||
|
@click:prepend-inner="switchSearchType"
|
||||||
@keydown.enter="search"
|
@keydown.enter="search"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.search-box div.v-input__control div[role="textbox"] {
|
.search-box div.v-input__control div[role='textbox'] {
|
||||||
border: 1px solid rgb(var(--v-theme-background));
|
border: 1px solid rgb(var(--v-theme-background));
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+17
-7
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import MediaCardListView from '@/views/discover/MediaCardListView.vue'
|
import MediaCardListView from '@/views/discover/MediaCardListView.vue'
|
||||||
|
import PersonCardListView from '@/views/discover/PersonCardListView.vue'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -11,14 +12,17 @@ const props = defineProps({
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
// 标题
|
// 标题
|
||||||
const title = route.query?.title?.toString()
|
let title = route.query?.title?.toString()
|
||||||
|
|
||||||
|
// 类型
|
||||||
|
const type = route.query?.type?.toString()
|
||||||
|
|
||||||
|
if (type === 'person') title = '演员:' + title
|
||||||
|
|
||||||
// 计算API路径
|
// 计算API路径
|
||||||
function getApiPath(paths: string[] | string) {
|
function getApiPath(paths: string[] | string) {
|
||||||
if (Array.isArray(paths))
|
if (Array.isArray(paths)) return paths.join('/')
|
||||||
return paths.join('/')
|
else return paths
|
||||||
else
|
|
||||||
return paths
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -26,14 +30,20 @@ function getApiPath(paths: string[] | string) {
|
|||||||
<div>
|
<div>
|
||||||
<div v-if="title" class="mt-3 md:flex md:items-center md:justify-between">
|
<div v-if="title" class="mt-3 md:flex md:items-center md:justify-between">
|
||||||
<div class="min-w-0 flex-1 mx-0">
|
<div class="min-w-0 flex-1 mx-0">
|
||||||
<h2 class="mb-4 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-4xl sm:leading-9 md:mb-0" data-testid="page-header">
|
<h2
|
||||||
|
class="mb-4 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-4xl sm:leading-9 md:mb-0"
|
||||||
|
data-testid="page-header"
|
||||||
|
>
|
||||||
<span class="text-moviepilot">{{ title }}</span>
|
<span class="text-moviepilot">{{ title }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MediaCardListView
|
<PersonCardListView
|
||||||
|
v-if="type === 'person'"
|
||||||
:apipath="getApiPath(props.paths || '')"
|
:apipath="getApiPath(props.paths || '')"
|
||||||
|
type="tmdb"
|
||||||
:params="route.query"
|
:params="route.query"
|
||||||
/>
|
/>
|
||||||
|
<MediaCardListView v-else :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
// 判断是否有滚动条
|
// 判断是否有滚动条
|
||||||
function hasScroll() {
|
function hasScroll() {
|
||||||
return (
|
return document.body.scrollHeight - (window.innerHeight || document.documentElement.clientHeight) > 2
|
||||||
document.body.scrollHeight
|
|
||||||
- (window.innerHeight || document.documentElement.clientHeight)
|
|
||||||
> 2
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前页码
|
// 当前页码
|
||||||
@@ -37,8 +33,7 @@ function getParams() {
|
|||||||
let params = {
|
let params = {
|
||||||
page: page.value,
|
page: page.value,
|
||||||
}
|
}
|
||||||
if (props.params)
|
if (props.params) params = { ...params, ...props.params }
|
||||||
params = { ...params, ...props.params }
|
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
@@ -46,8 +41,7 @@ function getParams() {
|
|||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
async function fetchData({ done }: { done: any }) {
|
async function fetchData({ done }: { done: any }) {
|
||||||
try {
|
try {
|
||||||
if (!props.apipath)
|
if (!props.apipath) return
|
||||||
return
|
|
||||||
|
|
||||||
// 如果正在加载中,直接返回
|
// 如果正在加载中,直接返回
|
||||||
if (loading.value) {
|
if (loading.value) {
|
||||||
@@ -81,8 +75,7 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
// 返回加载成功
|
// 返回加载成功
|
||||||
done('ok')
|
done('ok')
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// 加载一次
|
// 加载一次
|
||||||
// 设置加载中
|
// 设置加载中
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -106,8 +99,7 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
}
|
}
|
||||||
// 取消加载中
|
// 取消加载中
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
// 返回加载失败
|
// 返回加载失败
|
||||||
done('error')
|
done('error')
|
||||||
@@ -116,29 +108,12 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<LoadingBanner
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
v-if="!isRefreshed"
|
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
||||||
class="mt-12"
|
|
||||||
/>
|
|
||||||
<VInfiniteScroll
|
|
||||||
mode="intersect"
|
|
||||||
side="end"
|
|
||||||
:items="dataList"
|
|
||||||
class="overflow-hidden"
|
|
||||||
@load="fetchData"
|
|
||||||
>
|
|
||||||
<template #loading />
|
<template #loading />
|
||||||
<template #empty />
|
<template #empty />
|
||||||
<div
|
<div v-if="dataList.length > 0" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
||||||
v-if="dataList.length > 0"
|
<MediaCard v-for="data in dataList" :key="data.tmdb_id || data.douban_id" :media="data" />
|
||||||
class="grid gap-4 grid-media-card mx-3"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<MediaCard
|
|
||||||
v-for="data in dataList"
|
|
||||||
:key="data.tmdb_id || data.douban_id"
|
|
||||||
:media="data"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="dataList.length === 0 && isRefreshed"
|
v-if="dataList.length === 0 && isRefreshed"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import DoubanPersonCard from '@/components/cards/DoubanPersonCard.vue'
|
import DoubanPersonCard from '@/components/cards/DoubanPersonCard.vue'
|
||||||
import TmdbPersonCard from '@/components/cards/TmdbPersonCard.vue'
|
import TmdbPersonCard from '@/components/cards/TmdbPersonCard.vue'
|
||||||
|
import BangumiPersonCard from '@/components/cards/BangumiPersonCard.vue'
|
||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
@@ -13,11 +14,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
// 判断是否有滚动条
|
// 判断是否有滚动条
|
||||||
function hasScroll() {
|
function hasScroll() {
|
||||||
return (
|
return document.body.scrollHeight - (window.innerHeight || document.documentElement.clientHeight) > 2
|
||||||
document.body.scrollHeight
|
|
||||||
- (window.innerHeight || document.documentElement.clientHeight)
|
|
||||||
> 2
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前页码
|
// 当前页码
|
||||||
@@ -33,11 +30,20 @@ const isRefreshed = ref(false)
|
|||||||
const dataList = ref<any>([])
|
const dataList = ref<any>([])
|
||||||
const currData = ref<any>([])
|
const currData = ref<any>([])
|
||||||
|
|
||||||
|
// 拼装参数
|
||||||
|
function getParams() {
|
||||||
|
let params = {
|
||||||
|
page: page.value,
|
||||||
|
}
|
||||||
|
if (props.params) params = { ...params, ...props.params }
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
async function fetchData({ done }: { done: any }) {
|
async function fetchData({ done }: { done: any }) {
|
||||||
try {
|
try {
|
||||||
if (!props.apipath)
|
if (!props.apipath) return
|
||||||
return
|
|
||||||
|
|
||||||
// 如果正在加载中,直接返回
|
// 如果正在加载中,直接返回
|
||||||
if (loading.value) {
|
if (loading.value) {
|
||||||
@@ -53,9 +59,7 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
// 请求API
|
// 请求API
|
||||||
currData.value = await api.get(props.apipath, {
|
currData.value = await api.get(props.apipath, {
|
||||||
params: {
|
params: getParams(),
|
||||||
page: page.value,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
// 取消加载中
|
// 取消加载中
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -64,6 +68,7 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
if (currData.value.length === 0) {
|
if (currData.value.length === 0) {
|
||||||
// 如果没有数据,跳出
|
// 如果没有数据,跳出
|
||||||
done('empty')
|
done('empty')
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
// 合并数据
|
// 合并数据
|
||||||
dataList.value = [...dataList.value, ...currData.value]
|
dataList.value = [...dataList.value, ...currData.value]
|
||||||
@@ -73,16 +78,13 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
done('ok')
|
done('ok')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// 加载一次
|
// 加载一次
|
||||||
// 设置加载中
|
// 设置加载中
|
||||||
loading.value = true
|
loading.value = true
|
||||||
// 请求API
|
// 请求API
|
||||||
currData.value = await api.get(props.apipath, {
|
currData.value = await api.get(props.apipath, {
|
||||||
params: {
|
params: getParams(),
|
||||||
page: page.value,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
// 标计为已请求完成
|
// 标计为已请求完成
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
@@ -100,8 +102,7 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
// 取消加载中
|
// 取消加载中
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
// 返回加载失败
|
// 返回加载失败
|
||||||
done('error')
|
done('error')
|
||||||
@@ -110,40 +111,18 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<LoadingBanner
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
v-if="!isRefreshed"
|
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
||||||
class="mt-12"
|
|
||||||
/>
|
|
||||||
<VInfiniteScroll
|
|
||||||
mode="intersect"
|
|
||||||
side="end"
|
|
||||||
:items="dataList"
|
|
||||||
class="overflow-hidden"
|
|
||||||
@load="fetchData"
|
|
||||||
>
|
|
||||||
<template #loading />
|
<template #loading />
|
||||||
<template #empty />
|
<template #empty />
|
||||||
<div
|
<div v-if="dataList.length > 0 && props.type === 'tmdb'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
||||||
v-if="dataList.length > 0 && props.type === 'tmdb'"
|
<TmdbPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
||||||
class="grid gap-4 grid-media-card mx-3"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<TmdbPersonCard
|
|
||||||
v-for="data in dataList"
|
|
||||||
:key="data.id"
|
|
||||||
:person="data"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="dataList.length > 0 && props.type === 'douban'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
||||||
v-if="dataList.length > 0 && props.type === 'douban'"
|
<DoubanPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
||||||
class="grid gap-4 grid-media-card mx-3"
|
</div>
|
||||||
tabindex="0"
|
<div v-if="dataList.length > 0 && props.type === 'bangumi'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
||||||
>
|
<BangumiPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
||||||
<DoubanPersonCard
|
|
||||||
v-for="data in dataList"
|
|
||||||
:key="data.id"
|
|
||||||
:person="data"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="dataList.length === 0 && isRefreshed"
|
v-if="dataList.length === 0 && isRefreshed"
|
||||||
|
|||||||
Reference in New Issue
Block a user