refactor(links): extract sort menu and fix sort logic
- Extracts dropdown sort menu into separate DashboardLinksSort component - Fixes incorrect sort order for newest/oldest links - Adds internationalization support for sort options - Updates QR code download button size for consistency - Adds helpful tooltip about sort limitation for loaded links The sort logic was reversed where newest/oldest were concerned, this fixes that while making the sorting feature more maintainable through component extraction.
This commit is contained in:
parent
71c726ab9b
commit
5118201911
5 changed files with 75 additions and 40 deletions
|
|
@ -1,27 +1,22 @@
|
|||
<script setup>
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '#components'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { ArrowUpDown, Loader } from 'lucide-vue-next'
|
||||
import { Loader } from 'lucide-vue-next'
|
||||
|
||||
const links = ref([])
|
||||
const limit = 24
|
||||
let cursor = ''
|
||||
let listComplete = false
|
||||
let listError = false
|
||||
const sortBy = ref('newest')
|
||||
|
||||
const sortBy = ref('az')
|
||||
|
||||
const displayedLinks = computed(() => {
|
||||
const sorted = [...links.value]
|
||||
switch (sortBy.value) {
|
||||
case 'newest':
|
||||
return sorted.sort((a, b) => b.createdAt - a.createdAt)
|
||||
case 'oldest':
|
||||
return sorted.sort((a, b) => a.createdAt - b.createdAt)
|
||||
case 'oldest':
|
||||
return sorted.sort((a, b) => b.createdAt - a.createdAt)
|
||||
case 'az':
|
||||
return sorted.sort((a, b) => a.slug.localeCompare(b.slug))
|
||||
case 'za':
|
||||
|
|
@ -83,33 +78,7 @@ function updateLinkList(link, type) {
|
|||
<DashboardNav class="flex-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<DashboardLinksEditor @update:link="updateLinkList" />
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<Button variant="outline" size="sm">
|
||||
<ArrowUpDown class="mr-2 h-4 w-4" />
|
||||
Sort by: {{
|
||||
sortBy === 'newest' ? 'Newest First'
|
||||
: sortBy === 'oldest' ? 'Oldest First'
|
||||
: sortBy === 'az' ? 'Slug A-Z'
|
||||
: 'Slug Z-A'
|
||||
}}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem @click="sortBy = 'newest'">
|
||||
Newest First
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="sortBy = 'oldest'">
|
||||
Oldest First
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="sortBy = 'az'">
|
||||
A to Z
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="sortBy = 'za'">
|
||||
Z to A
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<DashboardLinksSort v-model:sort-by="sortBy" />
|
||||
</div>
|
||||
</DashboardNav>
|
||||
<LazyDashboardLinksSearch />
|
||||
|
|
|
|||
|
|
@ -118,7 +118,11 @@ onMounted(() => {
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<Button variant="outline" @click="downloadQRCode">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
@click="downloadQRCode"
|
||||
>
|
||||
<Download class="w-4 h-4 mr-2" />
|
||||
{{ $t('links.download_qr_code') }}
|
||||
</Button>
|
||||
|
|
|
|||
48
components/dashboard/links/Sort.vue
Normal file
48
components/dashboard/links/Sort.vue
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<script setup>
|
||||
import { ArrowUpDown } from 'lucide-vue-next'
|
||||
|
||||
defineProps({
|
||||
sortBy: {
|
||||
type: String,
|
||||
default: 'az',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:sortBy'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<Button variant="outline">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger class="flex items-center">
|
||||
<ArrowUpDown class="h-4 w-4 sm:mr-2" />
|
||||
<span class="hidden sm:inline">
|
||||
{{ $t('links.sort.newest') }}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{{ $t('links.sort.tip') }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem @click="emit('update:sortBy', 'newest')">
|
||||
{{ $t('links.sort.newest') }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="emit('update:sortBy', 'oldest')">
|
||||
{{ $t('links.sort.oldest') }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="emit('update:sortBy', 'az')">
|
||||
{{ $t('links.sort.az') }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="emit('update:sortBy', 'za')">
|
||||
{{ $t('links.sort.za') }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</template>
|
||||
|
|
@ -157,6 +157,13 @@
|
|||
"expires_at": "Expires At",
|
||||
"no_more": "No more links",
|
||||
"load_failed": "Loading links failed,",
|
||||
"download_qr_code": "Download QR Code"
|
||||
"download_qr_code": "Download QR Code",
|
||||
"sort": {
|
||||
"newest": "Newest First",
|
||||
"oldest": "Oldest First",
|
||||
"az": "Slug A-Z",
|
||||
"za": "Slug Z-A",
|
||||
"tip": "Experience: Only for loaded links"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,6 +157,13 @@
|
|||
"expires_at": "过期时间",
|
||||
"no_more": "没有更多链接",
|
||||
"load_failed": "加载链接失败,",
|
||||
"download_qr_code": "下载二维码"
|
||||
"download_qr_code": "下载二维码",
|
||||
"sort": {
|
||||
"newest": "最新",
|
||||
"oldest": "最旧",
|
||||
"az": "字母(A-Z)",
|
||||
"za": "字母(Z-A)",
|
||||
"tip": "体验功能: 仅对已经加载的链接有效"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue