You've already forked agentic-coding-workflow
feat(web): AcpSessionListView (table with terminate action)
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user