Files
kanban/components/panels/HistoryPanel.vue
xiaomai 485d75820b feat(ui): overhaul interface with Nuxt UI
Integrate the Nuxt UI component library and completely revamp the application's user interface to improve usability, aesthetics, and maintainability.

- Replace all custom components and native browser dialogs (`alert`, `prompt`, `confirm`) with Nuxt UI components like `UCard`, `UButton`, `UModal`, and `UNotifications`.
- Refactor the main page by extracting the sidebar into dedicated panel components: `CategoryPanel`, `BoardSummaryPanel`, and `HistoryPanel`.
- Redesign all major components (Toolbar, Board, Stage, Task) for a cleaner layout and improved information hierarchy.
- Implement user-friendly modals for all creation, editing, and deletion flows, providing a more consistent user experience.
- Add toast notifications to provide immediate feedback for user actions.
2025-10-22 17:52:17 +08:00

93 lines
2.9 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<UCard>
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<UIcon name="i-heroicons-clock-20-solid" class="h-5 w-5 text-amber-400" />
<span class="font-semibold">历史记录</span>
</div>
<UButton
size="2xs"
color="neutral"
variant="ghost"
icon="i-heroicons-trash-20-solid"
@click="clearOpen = true"
>
清空
</UButton>
</div>
</template>
<div class="space-y-2">
<div v-if="!entries.length" class="rounded border border-slate-800 bg-slate-900/70 px-3 py-4 text-sm text-slate-400">
暂无历史记录
</div>
<div v-else class="max-h-72 space-y-2 overflow-auto pr-1 text-xs">
<div
v-for="entry in entries"
:key="entry.id"
class="rounded border border-slate-800 bg-slate-900/70 px-3 py-3"
>
<div class="flex items-center justify-between gap-2">
<span class="font-medium text-slate-200">{{ entry.type }}</span>
<span class="text-[10px] text-slate-500">{{ formatTime(entry.ts) }}</span>
</div>
<div class="mt-1 flex items-center gap-2 text-[11px] text-slate-400">
<UIcon name="i-heroicons-user-20-solid" class="h-3.5 w-3.5" />
<span>{{ entry.actor || '系统' }}</span>
</div>
</div>
</div>
</div>
</UCard>
<UModal v-model="clearOpen">
<UCard>
<template #header>
<div class="flex items-center gap-2">
<UIcon name="i-heroicons-exclamation-triangle-20-solid" class="h-5 w-5 text-amber-400" />
<span class="font-semibold">清空历史</span>
</div>
</template>
<p class="text-sm text-slate-300">
清空后将只能在本地重新积累记录仍然继续吗
</p>
<div class="mt-6 flex justify-end gap-2">
<UButton color="neutral" variant="ghost" @click="clearOpen = false">取消</UButton>
<UButton color="rose" @click="clearHistory">确认清空</UButton>
</div>
</UCard>
</UModal>
</template>
<script setup lang="ts">
import { useBoardStore } from '~/stores/board'
const store = useBoardStore()
const toast = useToast()
const entries = computed(() => {
const list = store.board.meta?.history || []
return list.slice(-200).reverse()
})
function formatTime(ts: string) {
try {
return new Intl.DateTimeFormat('zh-CN', { dateStyle: 'short', timeStyle: 'short' }).format(new Date(ts))
} catch {
return ts
}
}
const clearOpen = ref(false)
function clearHistory() {
clearOpen.value = false
if (!store.board.meta) return
store.board.meta.history = []
store.board.meta.modifiedAt = new Date().toISOString()
store.log('history-clear', {})
toast.add({ color: 'neutral', title: '历史记录已清空' })
}
</script>