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 }),
|
post<{ status: string; comment: string }>(`/tasks/${id}/revise`, { comment }),
|
||||||
runTask: (id: string) =>
|
runTask: (id: string) =>
|
||||||
post<{ status: string }>(`/tasks/${id}/run`, {}),
|
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 }) =>
|
bootstrap: (data: { path: string; id: string; name: string }) =>
|
||||||
post<{ project: Project }>('/bootstrap', data),
|
post<{ project: Project }>('/bootstrap', data),
|
||||||
auditProject: (projectId: string) =>
|
auditProject: (projectId: string) =>
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,9 @@
|
||||||
"priority_label": "Priority (1–10)",
|
"priority_label": "Priority (1–10)",
|
||||||
"title_label": "Title",
|
"title_label": "Title",
|
||||||
"acceptance_criteria_label": "Acceptance criteria",
|
"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": {
|
"projectView": {
|
||||||
"tasks_tab": "Tasks",
|
"tasks_tab": "Tasks",
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,9 @@
|
||||||
"priority_label": "Приоритет (1–10)",
|
"priority_label": "Приоритет (1–10)",
|
||||||
"title_label": "Заголовок",
|
"title_label": "Заголовок",
|
||||||
"acceptance_criteria_label": "Критерии приёмки",
|
"acceptance_criteria_label": "Критерии приёмки",
|
||||||
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?"
|
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?",
|
||||||
|
"create_followup": "🔗 Создать зависимости",
|
||||||
|
"generating_followup": "Создаём..."
|
||||||
},
|
},
|
||||||
"projectView": {
|
"projectView": {
|
||||||
"tasks_tab": "Задачи",
|
"tasks_tab": "Задачи",
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ const approveLoading = ref(false)
|
||||||
const followupResults = ref<{ id: string; title: string }[]>([])
|
const followupResults = ref<{ id: string; title: string }[]>([])
|
||||||
const pendingActions = ref<PendingAction[]>([])
|
const pendingActions = ref<PendingAction[]>([])
|
||||||
const resolvingAction = ref(false)
|
const resolvingAction = ref(false)
|
||||||
|
const followupLoading = ref(false)
|
||||||
|
|
||||||
// Reject modal
|
// Reject modal
|
||||||
const showReject = ref(false)
|
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() {
|
async function reject() {
|
||||||
if (!task.value || !rejectReason.value) return
|
if (!task.value || !rejectReason.value) return
|
||||||
try {
|
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>
|
<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') }}
|
{{ (polling || pipelineStarting) ? t('taskDetail.pipeline_running') : t('taskDetail.run_pipeline') }}
|
||||||
</button>
|
</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'"
|
<button v-if="isManualEscalation && task.status !== 'done' && task.status !== 'cancelled'"
|
||||||
@click="resolveManually"
|
@click="resolveManually"
|
||||||
:disabled="resolvingManually"
|
:disabled="resolvingManually"
|
||||||
|
|
@ -604,6 +629,21 @@ async function saveEdit() {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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 -->
|
<!-- 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 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">
|
<div class="flex items-start justify-between gap-2">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue