kin: KIN-UI-026-frontend_dev
This commit is contained in:
parent
79ff03ab3d
commit
ca47f9c18b
1 changed files with 53 additions and 4 deletions
|
|
@ -22,6 +22,33 @@ const filteredProjects = computed(() => {
|
|||
)
|
||||
})
|
||||
|
||||
const SORT_OPTIONS = ['name', 'priority', 'active', 'cost'] as const
|
||||
type SortOption = typeof SORT_OPTIONS[number]
|
||||
const selectedSort = ref<SortOption>('name')
|
||||
const showSortMenu = ref(false)
|
||||
|
||||
const sortedProjects = computed(() => {
|
||||
const list = [...filteredProjects.value]
|
||||
switch (selectedSort.value) {
|
||||
case 'priority': return list.sort((a, b) => b.priority - a.priority)
|
||||
case 'active': return list.sort((a, b) => b.active_tasks - a.active_tasks)
|
||||
case 'cost': return list.sort((a, b) => (costMap.value[b.id] || 0) - (costMap.value[a.id] || 0))
|
||||
default: return list.sort((a, b) => a.name.localeCompare(b.name))
|
||||
}
|
||||
})
|
||||
|
||||
const GROUP_KEYS = ['development', 'operations', 'research'] as const
|
||||
|
||||
const groupedProjects = computed(() => {
|
||||
const groups: Record<string, Project[]> = { development: [], operations: [], research: [] }
|
||||
for (const p of sortedProjects.value) {
|
||||
const ptype = p.project_type || 'development'
|
||||
const key = ptype in groups ? ptype : 'development'
|
||||
groups[key].push(p)
|
||||
}
|
||||
return groups
|
||||
})
|
||||
|
||||
// Add project modal
|
||||
const showAdd = ref(false)
|
||||
const form = ref({
|
||||
|
|
@ -227,17 +254,36 @@ async function createNewProject() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!loading && !error" class="mb-3">
|
||||
<div v-if="!loading && !error" class="mb-3 flex gap-2">
|
||||
<input v-model="projectSearch"
|
||||
:placeholder="t('dashboard.search_placeholder')"
|
||||
class="w-full bg-gray-800 border border-gray-700 rounded px-3 py-1.5 text-sm text-gray-300 placeholder-gray-600 focus:border-gray-500 outline-none" />
|
||||
class="flex-1 bg-gray-800 border border-gray-700 rounded px-3 py-1.5 text-sm text-gray-300 placeholder-gray-600 focus:border-gray-500 outline-none" />
|
||||
<div class="relative">
|
||||
<div v-if="showSortMenu" class="fixed inset-0 z-[5]" @click="showSortMenu = false"></div>
|
||||
<button @click="showSortMenu = !showSortMenu"
|
||||
class="px-3 py-1.5 text-xs bg-gray-800 text-gray-400 border border-gray-700 rounded hover:bg-gray-700 flex items-center gap-1 whitespace-nowrap">
|
||||
↕ {{ selectedSort }} ▾
|
||||
</button>
|
||||
<div v-if="showSortMenu" class="absolute right-0 top-full mt-1 bg-gray-900 border border-gray-700 rounded shadow-lg z-10 min-w-[100px]">
|
||||
<button v-for="opt in SORT_OPTIONS" :key="opt"
|
||||
@click="selectedSort = opt; showSortMenu = false"
|
||||
class="w-full text-left px-3 py-2 text-xs hover:bg-gray-800"
|
||||
:class="selectedSort === opt ? 'text-blue-400' : 'text-gray-400'">
|
||||
{{ opt }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p v-if="loading" class="text-gray-500 text-sm">{{ t('dashboard.loading') }}</p>
|
||||
<p v-else-if="error" class="text-red-400 text-sm">{{ error }}</p>
|
||||
|
||||
<div v-else class="grid gap-3">
|
||||
<div v-for="p in filteredProjects" :key="p.id">
|
||||
<div v-else class="space-y-4">
|
||||
<template v-for="groupKey in GROUP_KEYS" :key="groupKey">
|
||||
<div v-if="groupedProjects[groupKey].length > 0">
|
||||
<p class="text-xs text-gray-600 mb-2 text-center tracking-wider">── {{ groupKey }} ({{ groupedProjects[groupKey].length }}) ──</p>
|
||||
<div class="grid gap-3">
|
||||
<div v-for="p in groupedProjects[groupKey]" :key="p.id">
|
||||
<!-- Inline delete confirmation -->
|
||||
<div v-if="confirmDeleteId === p.id"
|
||||
class="border border-red-800 rounded-lg p-4 bg-red-950/20">
|
||||
|
|
@ -305,6 +351,9 @@ async function createNewProject() {
|
|||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Add Project Modal -->
|
||||
<Modal v-if="showAdd" :title="t('dashboard.add_project_title')" @close="showAdd = false">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue