improve filter ui logic

This commit is contained in:
pa
2026-03-01 14:30:32 +09:00
parent 7a8e8e4a73
commit 8f60398cf5
+23 -18
View File
@@ -35,6 +35,9 @@
@update:model-value="handleFeedFilterChange" @update:model-value="handleFeedFilterChange"
class="w-full justify-start" class="w-full justify-start"
style="flex: 1"> style="flex: 1">
<ToggleGroupItem value="All">
{{ t('view.search.avatar.all') }}
</ToggleGroupItem>
<ToggleGroupItem v-for="type in feedFilterTypes" :key="type" :value="type"> <ToggleGroupItem v-for="type in feedFilterTypes" :key="type" :value="type">
{{ t('view.feed.filters.' + type) }} {{ t('view.feed.filters.' + type) }}
</ToggleGroupItem> </ToggleGroupItem>
@@ -48,12 +51,15 @@
@change="feedTableLookup" /> @change="feedTableLookup" />
<Popover v-model:open="popoverOpen"> <Popover v-model:open="popoverOpen">
<PopoverTrigger as-child> <PopoverTrigger as-child>
<Button <Button variant="outline" size="sm" class="ml-2 h-8 gap-1.5">
variant="ghost" <ListFilter class="size-4" />
size="icon-sm" {{ t('view.my_avatars.filter') }}
class="ml-2 text-muted-foreground" <Badge
:class="{ 'text-accent-foreground': hasDateFilter }"> v-if="activeFilterCount"
<Funnel /> variant="secondary"
class="ml-0.5 h-4.5 min-w-4.5 rounded-full px-1 text-xs">
{{ activeFilterCount }}
</Badge>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-auto" side="bottom" align="end"> <PopoverContent class="w-auto" side="bottom" align="end">
@@ -80,7 +86,7 @@
<script setup> <script setup>
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { Funnel, Star } from 'lucide-vue-next'; import { ListFilter, Star } from 'lucide-vue-next';
import { getLocalTimeZone, today } from '@internationalized/date'; import { getLocalTimeZone, today } from '@internationalized/date';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@@ -90,6 +96,7 @@
import { Popover, PopoverContent, PopoverTrigger } from '../../components/ui/popover'; import { Popover, PopoverContent, PopoverTrigger } from '../../components/ui/popover';
import { useAppearanceSettingsStore, useFeedStore, useVrcxStore } from '../../stores'; import { useAppearanceSettingsStore, useFeedStore, useVrcxStore } from '../../stores';
import { ToggleGroup, ToggleGroupItem } from '../../components/ui/toggle-group'; import { ToggleGroup, ToggleGroupItem } from '../../components/ui/toggle-group';
import { Badge } from '../../components/ui/badge';
import { Button } from '../../components/ui/button'; import { Button } from '../../components/ui/button';
import { DataTableLayout } from '../../components/ui/data-table'; import { DataTableLayout } from '../../components/ui/data-table';
import { InputGroupField } from '../../components/ui/input-group'; import { InputGroupField } from '../../components/ui/input-group';
@@ -111,6 +118,7 @@
const todayDate = today(getLocalTimeZone()); const todayDate = today(getLocalTimeZone());
const dateRange = ref(undefined); const dateRange = ref(undefined);
const hasDateFilter = computed(() => !!(feedTable.value.dateFrom || feedTable.value.dateTo)); const hasDateFilter = computed(() => !!(feedTable.value.dateFrom || feedTable.value.dateTo));
const activeFilterCount = computed(() => (hasDateFilter.value ? 1 : 0));
function applyDateFilter() { function applyDateFilter() {
if (dateRange.value?.start) { if (dateRange.value?.start) {
@@ -202,26 +210,23 @@
const activeFilterSelection = computed(() => { const activeFilterSelection = computed(() => {
const filter = feedTable.value.filter; const filter = feedTable.value.filter;
if (!Array.isArray(filter) || filter.length === 0) { if (!Array.isArray(filter) || filter.length === 0) {
return [...feedFilterTypes]; return ['All'];
} }
return filter; return filter;
}); });
function handleFeedFilterChange(value) { function handleFeedFilterChange(value) {
const selected = Array.isArray(value) ? value : []; const selected = Array.isArray(value) ? value : [];
const wasAllSelected = !Array.isArray(feedTable.value.filter) || feedTable.value.filter.length === 0; const wasAll = activeFilterSelection.value.includes('All');
const hasAll = selected.includes('All');
const types = selected.filter((v) => v !== 'All');
if (selected.length === 0) { if (hasAll && !wasAll) {
feedTable.value.filter = []; feedTable.value.filter = [];
} else if (wasAllSelected) { } else if (wasAll && types.length) {
const clicked = feedFilterTypes.filter((t) => !selected.includes(t)); feedTable.value.filter = types;
if (clicked.length === 1) {
feedTable.value.filter = clicked;
} else { } else {
feedTable.value.filter = selected.length === feedFilterTypes.length ? [] : selected; feedTable.value.filter = types.length === feedFilterTypes.length ? [] : types.length ? types : [];
}
} else {
feedTable.value.filter = selected.length === feedFilterTypes.length ? [] : selected;
} }
feedTableLookup(); feedTableLookup();
} }