mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 08:06:43 +08:00
添加“综合筛选”和“清除全部”功能
This commit is contained in:
@@ -727,6 +727,8 @@ export default {
|
|||||||
filterResolution: 'Resolution',
|
filterResolution: 'Resolution',
|
||||||
filterReleaseGroup: 'Release Group',
|
filterReleaseGroup: 'Release Group',
|
||||||
noMatchingResults: 'No matching data',
|
noMatchingResults: 'No matching data',
|
||||||
|
allFilters: 'All Filters',
|
||||||
|
clearAll: 'Clear All',
|
||||||
},
|
},
|
||||||
calendar: {
|
calendar: {
|
||||||
episode: 'Episode {number}',
|
episode: 'Episode {number}',
|
||||||
@@ -1120,7 +1122,7 @@ export default {
|
|||||||
channelsDesc: 'Set message sending channel parameters.',
|
channelsDesc: 'Set message sending channel parameters.',
|
||||||
organizeSuccess: 'Media Import',
|
organizeSuccess: 'Media Import',
|
||||||
downloadAdded: 'Download Added',
|
downloadAdded: 'Download Added',
|
||||||
subscribeAdded: 'Subscribe Added',
|
subscribeAdded: 'Subscribe Added',
|
||||||
subscribeComplete: 'Subscribe Complete',
|
subscribeComplete: 'Subscribe Complete',
|
||||||
templateConfigTitle: 'Message Template',
|
templateConfigTitle: 'Message Template',
|
||||||
templateConfigDesc: 'Set message template, support Jinja2 syntax.',
|
templateConfigDesc: 'Set message template, support Jinja2 syntax.',
|
||||||
|
|||||||
@@ -724,6 +724,8 @@ export default {
|
|||||||
filterResolution: '分辨率',
|
filterResolution: '分辨率',
|
||||||
filterReleaseGroup: '制作组',
|
filterReleaseGroup: '制作组',
|
||||||
noMatchingResults: '没有数据',
|
noMatchingResults: '没有数据',
|
||||||
|
allFilters: '综合筛选',
|
||||||
|
clearAll: '清除全部',
|
||||||
},
|
},
|
||||||
calendar: {
|
calendar: {
|
||||||
episode: '第{number}集',
|
episode: '第{number}集',
|
||||||
|
|||||||
@@ -725,6 +725,8 @@ export default {
|
|||||||
filterResolution: '分辨率',
|
filterResolution: '分辨率',
|
||||||
filterReleaseGroup: '製作組',
|
filterReleaseGroup: '製作組',
|
||||||
noMatchingResults: '沒有數據',
|
noMatchingResults: '沒有數據',
|
||||||
|
allFilters: '綜合篩選',
|
||||||
|
clearAll: '清除全部',
|
||||||
},
|
},
|
||||||
calendar: {
|
calendar: {
|
||||||
episode: '第{number}集',
|
episode: '第{number}集',
|
||||||
|
|||||||
@@ -78,10 +78,9 @@ const groupedDataList = ref<Map<string, Context[]>>()
|
|||||||
// 过滤菜单相关
|
// 过滤菜单相关
|
||||||
const filterMenuOpen = ref(false)
|
const filterMenuOpen = ref(false)
|
||||||
const currentFilter = ref('site')
|
const currentFilter = ref('site')
|
||||||
const currentFilterTitle = computed(() => filterTitles[currentFilter.value])
|
|
||||||
const currentFilterOptions = computed(() => {
|
// 添加全部筛选菜单相关
|
||||||
return filterOptions[currentFilter.value]
|
const allFilterMenuOpen = ref(false)
|
||||||
})
|
|
||||||
|
|
||||||
// 初始化过滤选项
|
// 初始化过滤选项
|
||||||
function initOptions(data: Context) {
|
function initOptions(data: Context) {
|
||||||
@@ -303,6 +302,11 @@ function toggleFilterMenu(key: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 开关全部筛选菜单
|
||||||
|
function toggleAllFilterMenu() {
|
||||||
|
allFilterMenuOpen.value = !allFilterMenuOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
// 清除所有过滤条件
|
// 清除所有过滤条件
|
||||||
function clearAllFilters() {
|
function clearAllFilters() {
|
||||||
for (const key in filterForm) {
|
for (const key in filterForm) {
|
||||||
@@ -432,6 +436,22 @@ function loadMore({ done }: { done: any }) {
|
|||||||
</VMenu>
|
</VMenu>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
|
|
||||||
|
<!-- 全部筛选按钮 -->
|
||||||
|
<VBtn
|
||||||
|
variant="tonal"
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
class="filter-btn ms-2"
|
||||||
|
prepend-icon="mdi-filter-variant"
|
||||||
|
rounded="pill"
|
||||||
|
@click="toggleAllFilterMenu"
|
||||||
|
>
|
||||||
|
{{ t('torrent.allFilters') }}
|
||||||
|
<VChip v-if="getFilterCount > 0" size="small" color="primary" class="ms-1" variant="elevated">
|
||||||
|
{{ getFilterCount }}
|
||||||
|
</VChip>
|
||||||
|
</VBtn>
|
||||||
|
|
||||||
<!-- 清除全部筛选按钮 -->
|
<!-- 清除全部筛选按钮 -->
|
||||||
<VBtn
|
<VBtn
|
||||||
v-if="getFilterCount > 0"
|
v-if="getFilterCount > 0"
|
||||||
@@ -529,46 +549,73 @@ function loadMore({ done }: { done: any }) {
|
|||||||
</div>
|
</div>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|
||||||
<!-- 筛选弹窗 -->
|
<!-- 全部筛选弹窗 -->
|
||||||
<VDialog v-model="filterMenuOpen" max-width="25rem" max-height="80%" location="center">
|
<VDialog v-model="allFilterMenuOpen" max-width="50rem" location="center" scrollable>
|
||||||
<VCard>
|
<VCard>
|
||||||
|
<VDialogCloseBtn @click="allFilterMenuOpen = false" />
|
||||||
<VCardTitle class="py-3 d-flex align-center">
|
<VCardTitle class="py-3 d-flex align-center">
|
||||||
<VIcon :icon="getFilterIcon(currentFilter)" class="me-2"></VIcon>
|
<VIcon icon="mdi-filter-variant" class="me-2"></VIcon>
|
||||||
<span>{{ currentFilterTitle }}</span>
|
<span>{{ t('torrent.allFilters') }}</span>
|
||||||
<VSpacer />
|
<VSpacer />
|
||||||
<VBtn
|
<VBtn
|
||||||
v-if="filterForm[currentFilter].length > 0"
|
v-if="getFilterCount > 0"
|
||||||
|
class="me-10"
|
||||||
variant="text"
|
variant="text"
|
||||||
size="small"
|
size="small"
|
||||||
color="error"
|
color="error"
|
||||||
@click="clearFilter(currentFilter)"
|
@click="clearAllFilters"
|
||||||
>
|
>
|
||||||
{{ t('torrent.clear') }}
|
{{ t('torrent.clearAll') }}
|
||||||
</VBtn>
|
|
||||||
<VBtn variant="text" size="small" color="primary" @click="selectAll(currentFilter)">
|
|
||||||
{{ t('torrent.selectAll') }}
|
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText class="filter-menu-content pt-4">
|
<VCardText>
|
||||||
<VChipGroup v-model="filterForm[currentFilter]" column multiple class="filter-options">
|
<div class="all-filters-grid">
|
||||||
<VChip
|
<VCard
|
||||||
v-for="option in currentFilterOptions"
|
v-for="(title, key) in filterTitles"
|
||||||
:key="option"
|
variant="tonal"
|
||||||
:value="option"
|
:key="key"
|
||||||
filter
|
class="filter-section"
|
||||||
variant="elevated"
|
v-show="filterOptions[key].length > 0"
|
||||||
class="ma-1 filter-chip"
|
|
||||||
size="small"
|
|
||||||
>
|
>
|
||||||
{{ option }}
|
<VCardItem class="py-2">
|
||||||
</VChip>
|
<template #prepend>
|
||||||
</VChipGroup>
|
<VIcon :icon="getFilterIcon(key)" class="me-2"></VIcon>
|
||||||
|
</template>
|
||||||
|
<VCardTitle>{{ title }}</VCardTitle>
|
||||||
|
<template #append>
|
||||||
|
<VBtn variant="text" size="small" color="primary" @click="selectAll(key)">
|
||||||
|
{{ t('torrent.selectAll') }}
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
v-if="filterForm[key].length > 0"
|
||||||
|
variant="text"
|
||||||
|
size="small"
|
||||||
|
color="error"
|
||||||
|
@click="clearFilter(key)"
|
||||||
|
>
|
||||||
|
{{ t('torrent.clear') }}
|
||||||
|
</VBtn>
|
||||||
|
</template>
|
||||||
|
</VCardItem>
|
||||||
|
<VCardText>
|
||||||
|
<VChipGroup v-model="filterForm[key]" column multiple class="filter-options">
|
||||||
|
<VChip
|
||||||
|
v-for="option in filterOptions[key]"
|
||||||
|
:key="option"
|
||||||
|
:value="option"
|
||||||
|
filter
|
||||||
|
variant="elevated"
|
||||||
|
class="ma-1 filter-chip"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ option }}
|
||||||
|
</VChip>
|
||||||
|
</VChipGroup>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardActions>
|
|
||||||
<VSpacer />
|
|
||||||
<VBtn variant="elevated" color="primary" @click="filterMenuOpen = false"> {{ t('torrent.confirm') }} </VBtn>
|
|
||||||
</VCardActions>
|
|
||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
|
|
||||||
@@ -633,6 +680,7 @@ function loadMore({ done }: { done: any }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.filter-menu-content {
|
.filter-menu-content {
|
||||||
|
max-block-size: 50vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,4 +787,14 @@ function loadMore({ done }: { done: any }) {
|
|||||||
background-color: rgba(var(--v-theme-background), 0.95);
|
background-color: rgba(var(--v-theme-background), 0.95);
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.all-filters-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 24px;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section {
|
||||||
|
background-color: rgba(var(--v-theme-surface-variant), 0.08);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -277,10 +277,17 @@ const filterMenuOpen = ref(false)
|
|||||||
const currentFilter = ref('site')
|
const currentFilter = ref('site')
|
||||||
const currentFilterTitle = computed(() => filterTitles[currentFilter.value])
|
const currentFilterTitle = computed(() => filterTitles[currentFilter.value])
|
||||||
const currentFilterOptions = computed(() => {
|
const currentFilterOptions = computed(() => {
|
||||||
// 季集选项不再需要特殊处理,直接从 filterOptions 获取
|
|
||||||
return filterOptions[currentFilter.value]
|
return filterOptions[currentFilter.value]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 添加全部筛选菜单相关
|
||||||
|
const allFilterMenuOpen = ref(false)
|
||||||
|
|
||||||
|
// 开关全部筛选菜单
|
||||||
|
function toggleAllFilterMenu() {
|
||||||
|
allFilterMenuOpen.value = !allFilterMenuOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
// 给定过滤类型返回不同图标
|
// 给定过滤类型返回不同图标
|
||||||
function getFilterIcon(key: string) {
|
function getFilterIcon(key: string) {
|
||||||
const icons: Record<string, string> = {
|
const icons: Record<string, string> = {
|
||||||
@@ -361,6 +368,7 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
</VSelect>
|
</VSelect>
|
||||||
<div class="filter-divider"></div>
|
<div class="filter-divider"></div>
|
||||||
|
|
||||||
<!-- 筛选按钮 -->
|
<!-- 筛选按钮 -->
|
||||||
<VBtn
|
<VBtn
|
||||||
v-for="(title, key) in filterTitles"
|
v-for="(title, key) in filterTitles"
|
||||||
@@ -412,6 +420,22 @@ onMounted(() => {
|
|||||||
</VMenu>
|
</VMenu>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
|
|
||||||
|
<!-- 全部筛选按钮 -->
|
||||||
|
<VBtn
|
||||||
|
variant="tonal"
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
class="filter-btn me-2"
|
||||||
|
prepend-icon="mdi-filter-variant"
|
||||||
|
rounded="pill"
|
||||||
|
@click="toggleAllFilterMenu"
|
||||||
|
>
|
||||||
|
{{ t('torrent.allFilters') }}
|
||||||
|
<VChip v-if="getFilterCount > 0" size="small" color="primary" class="ms-1" variant="elevated">
|
||||||
|
{{ getFilterCount }}
|
||||||
|
</VChip>
|
||||||
|
</VBtn>
|
||||||
|
|
||||||
<!-- 清除全部筛选按钮 -->
|
<!-- 清除全部筛选按钮 -->
|
||||||
<VBtn
|
<VBtn
|
||||||
v-if="getFilterCount > 0"
|
v-if="getFilterCount > 0"
|
||||||
@@ -463,7 +487,7 @@ onMounted(() => {
|
|||||||
class="search-count me-auto"
|
class="search-count me-auto"
|
||||||
prepend-icon="mdi-magnify"
|
prepend-icon="mdi-magnify"
|
||||||
>
|
>
|
||||||
{{ props.items?.length || 0 }} 个资源
|
{{ props.items?.length || 0 }} {{ t('torrent.resources') }}
|
||||||
</VChip>
|
</VChip>
|
||||||
|
|
||||||
<!-- 排序选择 -->
|
<!-- 排序选择 -->
|
||||||
@@ -482,6 +506,22 @@ onMounted(() => {
|
|||||||
|
|
||||||
<!-- 筛选图标按钮区域 -->
|
<!-- 筛选图标按钮区域 -->
|
||||||
<div class="filter-buttons-grid w-100 mt-2">
|
<div class="filter-buttons-grid w-100 mt-2">
|
||||||
|
<!-- 全部筛选按钮 -->
|
||||||
|
<VBtn variant="text" color="primary" class="filter-btn-mobile" @click="toggleAllFilterMenu">
|
||||||
|
<VIcon icon="mdi-filter-variant" class="filter-icon me-1"></VIcon>
|
||||||
|
<span class="filter-label">
|
||||||
|
{{ t('torrent.allFilters') }}
|
||||||
|
</span>
|
||||||
|
<VBadge
|
||||||
|
v-if="getFilterCount > 0"
|
||||||
|
:content="getFilterCount"
|
||||||
|
color="primary"
|
||||||
|
location="top end"
|
||||||
|
offset-x="-10"
|
||||||
|
offset-y="-10"
|
||||||
|
></VBadge>
|
||||||
|
</VBtn>
|
||||||
|
|
||||||
<VBtn
|
<VBtn
|
||||||
v-for="(title, key) in filterTitles"
|
v-for="(title, key) in filterTitles"
|
||||||
v-show="filterOptions[key].length > 0"
|
v-show="filterOptions[key].length > 0"
|
||||||
@@ -508,6 +548,76 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|
||||||
|
<!-- 全部筛选弹窗 -->
|
||||||
|
<VDialog v-model="allFilterMenuOpen" max-width="50rem" location="center" scrollable>
|
||||||
|
<VCard>
|
||||||
|
<VDialogCloseBtn @click="allFilterMenuOpen = false" />
|
||||||
|
<VCardTitle class="py-3 d-flex align-center">
|
||||||
|
<VIcon icon="mdi-filter-variant" class="me-2"></VIcon>
|
||||||
|
<span>{{ t('torrent.allFilters') }}</span>
|
||||||
|
<VSpacer />
|
||||||
|
<VBtn
|
||||||
|
v-if="getFilterCount > 0"
|
||||||
|
class="me-10"
|
||||||
|
variant="text"
|
||||||
|
size="small"
|
||||||
|
color="error"
|
||||||
|
@click="clearAllFilters"
|
||||||
|
>
|
||||||
|
{{ t('torrent.clearAll') }}
|
||||||
|
</VBtn>
|
||||||
|
</VCardTitle>
|
||||||
|
<VDivider />
|
||||||
|
<VCardText>
|
||||||
|
<div class="all-filters-grid">
|
||||||
|
<VCard
|
||||||
|
v-for="(title, key) in filterTitles"
|
||||||
|
variant="tonal"
|
||||||
|
:key="key"
|
||||||
|
class="filter-section"
|
||||||
|
v-show="filterOptions[key].length > 0"
|
||||||
|
>
|
||||||
|
<VCardItem class="py-2">
|
||||||
|
<template #prepend>
|
||||||
|
<VIcon :icon="getFilterIcon(key)" class="me-2"></VIcon>
|
||||||
|
</template>
|
||||||
|
<VCardTitle>{{ title }}</VCardTitle>
|
||||||
|
<template #append>
|
||||||
|
<VBtn variant="text" size="small" color="primary" @click="selectAll(key)">
|
||||||
|
{{ t('torrent.selectAll') }}
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
v-if="filterForm[key].length > 0"
|
||||||
|
variant="text"
|
||||||
|
size="small"
|
||||||
|
color="error"
|
||||||
|
@click="clearFilter(key)"
|
||||||
|
>
|
||||||
|
{{ t('torrent.clear') }}
|
||||||
|
</VBtn>
|
||||||
|
</template>
|
||||||
|
</VCardItem>
|
||||||
|
<VCardText>
|
||||||
|
<VChipGroup v-model="filterForm[key]" column multiple class="filter-options">
|
||||||
|
<VChip
|
||||||
|
v-for="option in filterOptions[key]"
|
||||||
|
:key="option"
|
||||||
|
:value="option"
|
||||||
|
filter
|
||||||
|
variant="elevated"
|
||||||
|
class="ma-1 filter-chip"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ option }}
|
||||||
|
</VChip>
|
||||||
|
</VChipGroup>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VDialog>
|
||||||
|
|
||||||
<!-- 筛选弹窗 -->
|
<!-- 筛选弹窗 -->
|
||||||
<VDialog v-model="filterMenuOpen" max-width="25rem" max-height="80%" location="center">
|
<VDialog v-model="filterMenuOpen" max-width="25rem" max-height="80%" location="center">
|
||||||
<VCard>
|
<VCard>
|
||||||
@@ -522,12 +632,14 @@ onMounted(() => {
|
|||||||
color="error"
|
color="error"
|
||||||
@click="clearFilter(currentFilter)"
|
@click="clearFilter(currentFilter)"
|
||||||
>
|
>
|
||||||
清除
|
{{ t('torrent.clear') }}
|
||||||
|
</VBtn>
|
||||||
|
<VBtn variant="text" size="small" color="primary" @click="selectAll(currentFilter)">
|
||||||
|
{{ t('torrent.selectAll') }}
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VBtn variant="text" size="small" color="primary" @click="selectAll(currentFilter)"> 全选 </VBtn>
|
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText class="filter-menu-content pt-4">
|
<VCardText>
|
||||||
<VChipGroup v-model="filterForm[currentFilter]" column multiple class="filter-options">
|
<VChipGroup v-model="filterForm[currentFilter]" column multiple class="filter-options">
|
||||||
<VChip
|
<VChip
|
||||||
v-for="option in currentFilterOptions"
|
v-for="option in currentFilterOptions"
|
||||||
@@ -544,7 +656,9 @@ onMounted(() => {
|
|||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardActions>
|
<VCardActions>
|
||||||
<VSpacer />
|
<VSpacer />
|
||||||
<VBtn variant="elevated" color="primary" @click="filterMenuOpen = false"> {{ t('torrent.confirm') }} </VBtn>
|
<VBtn variant="elevated" color="primary" @click="filterMenuOpen = false">
|
||||||
|
{{ t('torrent.confirm') }}
|
||||||
|
</VBtn>
|
||||||
</VCardActions>
|
</VCardActions>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
@@ -729,4 +843,14 @@ onMounted(() => {
|
|||||||
max-inline-size: 130px;
|
max-inline-size: 130px;
|
||||||
min-inline-size: 110px;
|
min-inline-size: 110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.all-filters-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 24px;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section {
|
||||||
|
background-color: rgba(var(--v-theme-surface-variant), 0.08);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user