kin: KIN-123-frontend_dev
This commit is contained in:
parent
03d49f42e6
commit
06c868b23a
4 changed files with 48 additions and 2 deletions
|
|
@ -350,6 +350,8 @@ export const api = {
|
|||
post<{ status: string; comment: string }>(`/tasks/${id}/revise`, { comment }),
|
||||
runTask: (id: string) =>
|
||||
post<{ status: string }>(`/tasks/${id}/run`, {}),
|
||||
followupTask: (id: string) =>
|
||||
post<{ created: Task[]; pending_actions: PendingAction[]; needs_decision: boolean }>(`/tasks/${id}/followup`, {}),
|
||||
bootstrap: (data: { path: string; id: string; name: string }) =>
|
||||
post<{ project: Project }>('/bootstrap', data),
|
||||
auditProject: (projectId: string) =>
|
||||
|
|
|
|||
|
|
@ -167,7 +167,9 @@
|
|||
"priority_label": "Priority (1–10)",
|
||||
"title_label": "Title",
|
||||
"acceptance_criteria_label": "Acceptance criteria",
|
||||
"acceptance_criteria_placeholder": "What should the output be? What result counts as success?"
|
||||
"acceptance_criteria_placeholder": "What should the output be? What result counts as success?",
|
||||
"create_followup": "🔗 Create Follow-up",
|
||||
"generating_followup": "Generating..."
|
||||
},
|
||||
"projectView": {
|
||||
"tasks_tab": "Tasks",
|
||||
|
|
|
|||
|
|
@ -167,7 +167,9 @@
|
|||
"priority_label": "Приоритет (1–10)",
|
||||
"title_label": "Заголовок",
|
||||
"acceptance_criteria_label": "Критерии приёмки",
|
||||
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?"
|
||||
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?",
|
||||
"create_followup": "🔗 Создать зависимости",
|
||||
"generating_followup": "Создаём..."
|
||||
},
|
||||
"projectView": {
|
||||
"tasks_tab": "Задачи",
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ const approveLoading = ref(false)
|
|||
const followupResults = ref<{ id: string; title: string }[]>([])
|
||||
const pendingActions = ref<PendingAction[]>([])
|
||||
const resolvingAction = ref(false)
|
||||
const followupLoading = ref(false)
|
||||
|
||||
// Reject modal
|
||||
const showReject = ref(false)
|
||||
|
|
@ -212,6 +213,23 @@ async function resolveAction(action: PendingAction, choice: string) {
|
|||
}
|
||||
}
|
||||
|
||||
async function runFollowup() {
|
||||
if (!task.value) return
|
||||
followupLoading.value = true
|
||||
followupResults.value = []
|
||||
try {
|
||||
const res = await api.followupTask(props.id)
|
||||
if (res.created?.length) {
|
||||
followupResults.value = res.created.map(ft => ({ id: ft.id, title: ft.title }))
|
||||
}
|
||||
await load()
|
||||
} catch (e: any) {
|
||||
error.value = e.message
|
||||
} finally {
|
||||
followupLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function reject() {
|
||||
if (!task.value || !rejectReason.value) return
|
||||
try {
|
||||
|
|
@ -588,6 +606,13 @@ async function saveEdit() {
|
|||
<span v-if="polling || pipelineStarting" class="inline-block w-3 h-3 border-2 border-blue-400 border-t-transparent rounded-full animate-spin mr-1"></span>
|
||||
{{ (polling || pipelineStarting) ? t('taskDetail.pipeline_running') : t('taskDetail.run_pipeline') }}
|
||||
</button>
|
||||
<button v-if="task.status === 'blocked'"
|
||||
@click="runFollowup"
|
||||
:disabled="followupLoading"
|
||||
class="px-4 py-2 text-sm bg-purple-900/50 text-purple-400 border border-purple-800 rounded hover:bg-purple-900 disabled:opacity-50">
|
||||
<span v-if="followupLoading" class="inline-block w-3 h-3 border-2 border-purple-400 border-t-transparent rounded-full animate-spin mr-1"></span>
|
||||
{{ followupLoading ? t('taskDetail.generating_followup') : t('taskDetail.create_followup') }}
|
||||
</button>
|
||||
<button v-if="isManualEscalation && task.status !== 'done' && task.status !== 'cancelled'"
|
||||
@click="resolveManually"
|
||||
:disabled="resolvingManually"
|
||||
|
|
@ -604,6 +629,21 @@ async function saveEdit() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Followup results block -->
|
||||
<div v-if="followupResults.length && !showApprove" class="mt-3 p-3 border border-purple-800 bg-purple-950/30 rounded">
|
||||
<p class="text-sm text-purple-400 mb-2">Создано {{ followupResults.length }} follow-up задач:</p>
|
||||
<div class="space-y-1">
|
||||
<router-link v-for="f in followupResults" :key="f.id" :to="`/task/${f.id}`"
|
||||
class="block px-3 py-2 border border-gray-800 rounded text-sm text-gray-300 hover:border-gray-600 no-underline">
|
||||
<span class="text-gray-500">{{ f.id }}</span> {{ f.title }}
|
||||
</router-link>
|
||||
</div>
|
||||
<button @click="followupResults = []"
|
||||
class="mt-2 w-full py-1.5 bg-gray-800 text-gray-400 border border-gray-700 rounded text-xs hover:bg-gray-700">
|
||||
{{ t('common.close') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Claude login error banner -->
|
||||
<div v-if="claudeLoginError" class="mt-3 px-4 py-3 border border-yellow-700 bg-yellow-950/30 rounded">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue