feat(web): AcpSessionListView (table with terminate action)

This commit is contained in:
2026-05-07 17:55:45 +08:00
parent 22e3c6cbf3
commit 2ca3a81838
+90
View File
@@ -0,0 +1,90 @@
<script setup lang="ts">
import { onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAcpStore } from '@/stores/acp'
import SessionStatusBadge from '@/components/acp/SessionStatusBadge.vue'
const route = useRoute()
const router = useRouter()
const store = useAcpStore()
onMounted(() => {
void store.listSessions(false)
})
function open(id: string) {
router.push(
`/p/${route.params.projectSlug}/workspaces/${route.params.wsSlug}/acp-sessions/${id}`,
)
}
function newSession() {
router.push(
`/p/${route.params.projectSlug}/workspaces/${route.params.wsSlug}/acp-sessions/new`,
)
}
async function terminate(id: string) {
if (!confirm('Terminate this session?')) return
try {
await store.terminateSession(id)
} catch (e) {
alert(e instanceof Error ? e.message : 'failed')
}
}
</script>
<template>
<div class="p-6 space-y-4">
<div class="flex items-center justify-between">
<h1 class="text-2xl font-semibold">ACP Sessions</h1>
<button
class="px-3 py-1 rounded text-sm font-medium bg-blue-600 text-white hover:bg-blue-700"
@click="newSession"
>
+ New
</button>
</div>
<div v-if="store.loading" class="text-gray-500">Loading...</div>
<div v-else-if="store.error" class="text-red-600">{{ store.error }}</div>
<div v-else-if="store.sessions.length === 0" class="text-gray-500">
No sessions yet. Click "+ New" to create one.
</div>
<table v-else class="w-full text-sm">
<thead class="text-left">
<tr class="border-b">
<th class="px-3 py-2">Branch</th>
<th class="px-3 py-2">Status</th>
<th class="px-3 py-2">Started</th>
<th class="px-3 py-2 text-right">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="s in store.sessions" :key="s.id" class="border-t hover:bg-gray-50">
<td class="px-3 py-2 font-mono text-xs">{{ s.branch }}</td>
<td class="px-3 py-2"><SessionStatusBadge :status="s.status" /></td>
<td class="px-3 py-2 text-xs text-gray-500">
{{ new Date(s.started_at).toLocaleString() }}
</td>
<td class="px-3 py-2 text-right space-x-2">
<button
class="text-blue-600 hover:underline"
@click="open(s.id)"
>
Open
</button>
<button
v-if="s.status === 'starting' || s.status === 'running'"
class="text-red-600 hover:underline"
@click="terminate(s.id)"
>
Terminate
</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>