kin: KIN-UI-028-frontend_dev
This commit is contained in:
parent
d5125793d0
commit
e143a5a0da
3 changed files with 78 additions and 3 deletions
|
|
@ -175,7 +175,9 @@
|
||||||
"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",
|
"create_followup": "🔗 Create Follow-up",
|
||||||
"generating_followup": "Generating..."
|
"generating_followup": "Generating...",
|
||||||
|
"review_required": "Review required:",
|
||||||
|
"banner_auto_mode": "🔓 Auto mode"
|
||||||
},
|
},
|
||||||
"projectView": {
|
"projectView": {
|
||||||
"tasks_tab": "Tasks",
|
"tasks_tab": "Tasks",
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,9 @@
|
||||||
"acceptance_criteria_label": "Критерии приёмки",
|
"acceptance_criteria_label": "Критерии приёмки",
|
||||||
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?",
|
"acceptance_criteria_placeholder": "Что должно быть на выходе? Какой результат считается успешным?",
|
||||||
"create_followup": "🔗 Создать зависимости",
|
"create_followup": "🔗 Создать зависимости",
|
||||||
"generating_followup": "Создаём..."
|
"generating_followup": "Создаём...",
|
||||||
|
"review_required": "Требует проверки:",
|
||||||
|
"banner_auto_mode": "🔓 Авто режим"
|
||||||
},
|
},
|
||||||
"projectView": {
|
"projectView": {
|
||||||
"tasks_tab": "Задачи",
|
"tasks_tab": "Задачи",
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,24 @@ async function runPipeline() {
|
||||||
const hasSteps = computed(() => (task.value?.pipeline_steps?.length ?? 0) > 0)
|
const hasSteps = computed(() => (task.value?.pipeline_steps?.length ?? 0) > 0)
|
||||||
const isRunning = computed(() => task.value?.status === 'in_progress')
|
const isRunning = computed(() => task.value?.status === 'in_progress')
|
||||||
const isManualEscalation = computed(() => task.value?.brief?.task_type === 'manual_escalation')
|
const isManualEscalation = computed(() => task.value?.brief?.task_type === 'manual_escalation')
|
||||||
|
const useVerticalPipeline = computed(() => (task.value?.pipeline_steps?.length ?? 0) > 5)
|
||||||
|
|
||||||
|
const expandedSteps = ref<Record<number, boolean>>({})
|
||||||
|
function toggleStepExpand(id: number) {
|
||||||
|
expandedSteps.value = { ...expandedSteps.value, [id]: !expandedSteps.value[id] }
|
||||||
|
}
|
||||||
|
|
||||||
|
function verticalStepIcon(step: PipelineStep) {
|
||||||
|
if (step.success === true || step.success === 1) return '\u2713'
|
||||||
|
if (step.success === false || step.success === 0) return '\u2717'
|
||||||
|
return '\u25CF'
|
||||||
|
}
|
||||||
|
|
||||||
|
function verticalStepIconColor(step: PipelineStep) {
|
||||||
|
if (step.success === true || step.success === 1) return 'text-green-400'
|
||||||
|
if (step.success === false || step.success === 0) return 'text-red-400'
|
||||||
|
return 'text-blue-400'
|
||||||
|
}
|
||||||
|
|
||||||
const resolvingManually = ref(false)
|
const resolvingManually = ref(false)
|
||||||
|
|
||||||
|
|
@ -482,13 +500,36 @@ async function saveEdit() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Review action-banner -->
|
||||||
|
<div v-if="task.status === 'review' && !autoMode"
|
||||||
|
class="mb-4 flex flex-wrap items-center gap-2 px-4 py-2 border border-yellow-800/60 bg-yellow-950/20 rounded-lg">
|
||||||
|
<span class="text-xs font-semibold text-yellow-400 shrink-0">{{ t('taskDetail.review_required') }}</span>
|
||||||
|
<button @click="showApprove = true"
|
||||||
|
class="px-3 py-1.5 text-sm bg-green-900/50 text-green-400 border border-green-800 rounded hover:bg-green-900">
|
||||||
|
{{ t('taskDetail.approve_task') }}
|
||||||
|
</button>
|
||||||
|
<button @click="showRevise = true"
|
||||||
|
class="px-3 py-1.5 text-sm bg-orange-900/50 text-orange-400 border border-orange-800 rounded hover:bg-orange-900">
|
||||||
|
{{ t('taskDetail.revise_task') }}
|
||||||
|
</button>
|
||||||
|
<button @click="showReject = true"
|
||||||
|
class="px-3 py-1.5 text-sm bg-red-900/50 text-red-400 border border-red-800 rounded hover:bg-red-900">
|
||||||
|
{{ t('taskDetail.reject_task') }}
|
||||||
|
</button>
|
||||||
|
<button @click="toggleMode"
|
||||||
|
class="ml-auto px-3 py-1.5 text-sm bg-gray-800/50 text-gray-400 border border-gray-700 rounded hover:bg-gray-800">
|
||||||
|
{{ t('taskDetail.banner_auto_mode') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Pipeline Graph -->
|
<!-- Pipeline Graph -->
|
||||||
<div v-if="hasSteps || isRunning" class="mb-6">
|
<div v-if="hasSteps || isRunning" class="mb-6">
|
||||||
<h2 class="text-sm font-semibold text-gray-300 mb-3">
|
<h2 class="text-sm font-semibold text-gray-300 mb-3">
|
||||||
{{ t('taskDetail.pipeline') }}
|
{{ t('taskDetail.pipeline') }}
|
||||||
<span v-if="isRunning" class="text-blue-400 text-xs font-normal ml-2 animate-pulse">{{ t('taskDetail.running') }}</span>
|
<span v-if="isRunning" class="text-blue-400 text-xs font-normal ml-2 animate-pulse">{{ t('taskDetail.running') }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex items-center gap-1 overflow-x-auto pb-2">
|
<!-- Horizontal pipeline (≤5 steps) -->
|
||||||
|
<div v-if="!useVerticalPipeline" class="flex items-center gap-1 overflow-x-auto pb-2">
|
||||||
<template v-for="(step, i) in task.pipeline_steps" :key="step.id">
|
<template v-for="(step, i) in task.pipeline_steps" :key="step.id">
|
||||||
<div v-if="i > 0" class="text-gray-600 text-lg shrink-0 px-1">→</div>
|
<div v-if="i > 0" class="text-gray-600 text-lg shrink-0 px-1">→</div>
|
||||||
<button
|
<button
|
||||||
|
|
@ -512,6 +553,36 @@ async function saveEdit() {
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Vertical timeline (>5 steps) -->
|
||||||
|
<div v-else class="space-y-1">
|
||||||
|
<div v-for="step in task.pipeline_steps" :key="step.id"
|
||||||
|
class="border border-gray-800 rounded-lg overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-2 px-3 py-2 cursor-pointer hover:bg-gray-800/30 transition-colors select-none"
|
||||||
|
@click="toggleStepExpand(step.id)"
|
||||||
|
>
|
||||||
|
<span class="text-xs font-mono w-4 text-center shrink-0" :class="verticalStepIconColor(step)">{{ verticalStepIcon(step) }}</span>
|
||||||
|
<span class="text-base shrink-0">{{ roleIcons[step.agent_role] || '\u{1F916}' }}</span>
|
||||||
|
<span class="text-xs font-medium text-gray-300 flex-1">{{ step.agent_role }}</span>
|
||||||
|
<span v-if="step.duration_seconds" class="text-[10px] text-gray-500">{{ step.duration_seconds }}s</span>
|
||||||
|
<span v-if="step.cost_usd" class="text-[10px] text-gray-500">${{ step.cost_usd?.toFixed(3) }}</span>
|
||||||
|
<span class="text-[10px] text-gray-600 ml-1">{{ expandedSteps[step.id] ? '▲' : '▼' }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="expandedSteps[step.id]" class="border-t border-gray-800 bg-gray-900/50 p-3">
|
||||||
|
<template v-if="parseAgentOutput(step.output_summary).verdict !== null">
|
||||||
|
<p class="text-xs text-gray-300 whitespace-pre-wrap leading-relaxed">{{ parseAgentOutput(step.output_summary).verdict }}</p>
|
||||||
|
<details v-if="parseAgentOutput(step.output_summary).details !== null" class="mt-2">
|
||||||
|
<summary class="text-[10px] text-gray-500 cursor-pointer hover:text-gray-400 select-none">{{ t('taskDetail.more_details') }}</summary>
|
||||||
|
<pre class="mt-1 text-[10px] text-gray-500 overflow-x-auto whitespace-pre-wrap max-h-[300px] overflow-y-auto">{{ parseAgentOutput(step.output_summary).details }}</pre>
|
||||||
|
</details>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<pre class="text-[10px] text-gray-300 overflow-x-auto whitespace-pre-wrap max-h-[300px] overflow-y-auto">{{ formatOutput(step.output_summary) }}</pre>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- No pipeline -->
|
<!-- No pipeline -->
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue