@cat-factory/app 0.138.1 → 0.139.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/brainstorm/BrainstormWindow.vue +338 -374
- package/app/components/clarity/ClarityReviewWindow.vue +323 -353
- package/app/components/consensus/ConsensusSessionWindow.vue +138 -150
- package/app/components/docs/DocInterviewWindow.vue +108 -136
- package/app/components/followUp/FollowUpWindow.vue +3 -5
- package/app/components/forkDecision/ForkDecisionWindow.vue +1 -3
- package/app/components/gates/GateResultView.vue +3 -5
- package/app/components/humanTest/HumanTestWindow.vue +3 -5
- package/app/components/initiative/InitiativePlanningWindow.vue +89 -112
- package/app/components/initiative/InitiativeTrackerWindow.vue +389 -424
- package/app/components/panels/GenericStructuredResultView.vue +3 -5
- package/app/components/panels/MergerResultView.vue +3 -5
- package/app/components/panels/ResultWindowShell.vue +1 -1
- package/app/components/prReview/PrReviewWindow.vue +181 -205
- package/app/components/ralph/RalphLoopResultView.vue +3 -5
- package/app/components/requirements/RequirementsReviewWindow.vue +512 -557
- package/app/components/spec/ServiceSpecWindow.vue +235 -266
- package/app/components/testing/TestReportWindow.vue +4 -6
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +3 -5
- package/app/composables/useResultView.ts +10 -21
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { computed, reactive, watch } from 'vue'
|
|
11
11
|
import ClarificationItem from '~/components/common/ClarificationItem.vue'
|
|
12
12
|
import { INITIATIVE_STATUS_LABEL_KEYS } from '~/utils/initiative'
|
|
13
|
+
import ResultWindowShell from '~/components/panels/ResultWindowShell.vue'
|
|
13
14
|
|
|
14
15
|
const board = useBoardStore()
|
|
15
16
|
const initiatives = useInitiativesStore()
|
|
@@ -103,122 +104,98 @@ const onProceed = () => flushThen((id) => initiatives.proceedPlanning(id))
|
|
|
103
104
|
</script>
|
|
104
105
|
|
|
105
106
|
<template>
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
<ResultWindowShell
|
|
108
|
+
:open="open"
|
|
109
|
+
icon="i-lucide-messages-square"
|
|
110
|
+
icon-class="bg-indigo-500/15 text-indigo-300"
|
|
111
|
+
:title="initiative?.title ?? block?.title ?? t('initiative.planning.title')"
|
|
112
|
+
:subtitle="t('initiative.planning.subtitle')"
|
|
113
|
+
width="3xl"
|
|
114
|
+
testid="initiative-planning-window"
|
|
115
|
+
@close="close"
|
|
116
|
+
>
|
|
117
|
+
<template v-if="initiative" #header-extras>
|
|
118
|
+
<UBadge color="primary" variant="subtle" size="sm">
|
|
119
|
+
{{ t(INITIATIVE_STATUS_LABEL_KEYS[initiative.status]) }}
|
|
120
|
+
</UBadge>
|
|
121
|
+
</template>
|
|
122
|
+
|
|
123
|
+
<div class="min-h-0 flex-1 overflow-y-auto px-5 py-4">
|
|
124
|
+
<!-- No entity yet -->
|
|
112
125
|
<div
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
aria-modal="true"
|
|
116
|
-
data-testid="initiative-planning-window"
|
|
126
|
+
v-if="!initiative"
|
|
127
|
+
class="flex h-full flex-col items-center justify-center gap-2 text-center text-slate-400"
|
|
117
128
|
>
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
{{ t(INITIATIVE_STATUS_LABEL_KEYS[initiative.status]) }}
|
|
135
|
-
</UBadge>
|
|
136
|
-
<button
|
|
137
|
-
class="rounded-md p-1.5 text-slate-400 hover:bg-slate-800 hover:text-slate-200"
|
|
138
|
-
@click="close"
|
|
139
|
-
>
|
|
140
|
-
<UIcon name="i-lucide-x" class="h-4 w-4" />
|
|
141
|
-
</button>
|
|
142
|
-
</header>
|
|
143
|
-
|
|
144
|
-
<div class="min-h-0 flex-1 overflow-y-auto px-5 py-4">
|
|
145
|
-
<!-- No entity yet -->
|
|
146
|
-
<div
|
|
147
|
-
v-if="!initiative"
|
|
148
|
-
class="flex h-full flex-col items-center justify-center gap-2 text-center text-slate-400"
|
|
149
|
-
>
|
|
150
|
-
<UIcon name="i-lucide-messages-square" class="h-8 w-8 opacity-40" />
|
|
151
|
-
<p class="text-sm">{{ t('initiative.planning.empty') }}</p>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<template v-else>
|
|
155
|
-
<p class="mb-4 text-[13px] leading-relaxed text-slate-300">
|
|
156
|
-
{{ t('initiative.planning.intro') }}
|
|
157
|
-
</p>
|
|
158
|
-
|
|
159
|
-
<!-- Converged / no pending questions -->
|
|
160
|
-
<div
|
|
161
|
-
v-if="converged || questions.length === 0"
|
|
162
|
-
class="rounded-lg border border-slate-800 bg-slate-950/40 p-4 text-center text-[13px] text-slate-400"
|
|
163
|
-
data-testid="initiative-planning-converged"
|
|
164
|
-
>
|
|
165
|
-
{{ t('initiative.planning.converged') }}
|
|
166
|
-
</div>
|
|
167
|
-
|
|
168
|
-
<!-- Interview questions — the shared clarification surface (answer / not-relevant /
|
|
169
|
-
recommend), reused with the requirements-review window. -->
|
|
170
|
-
<ul v-else class="space-y-4">
|
|
171
|
-
<li v-for="q in questions" :key="q.key" data-testid="initiative-planning-question">
|
|
172
|
-
<ClarificationItem
|
|
173
|
-
v-model:answer="drafts[q.key]"
|
|
174
|
-
:prompt="q.question"
|
|
175
|
-
:dismissed="q.status === 'dismissed'"
|
|
176
|
-
:recommendation="q.recommendation"
|
|
177
|
-
:recommending="!!q.id && initiatives.recommending.has(q.id)"
|
|
178
|
-
:answer-placeholder="t('initiative.planning.answerPlaceholder')"
|
|
179
|
-
@persist="persist(q)"
|
|
180
|
-
@dismiss="setStatus(q, 'dismissed')"
|
|
181
|
-
@reopen="setStatus(q, 'open')"
|
|
182
|
-
@recommend="recommend(q)"
|
|
183
|
-
@use-recommendation="useRecommendation(q)"
|
|
184
|
-
/>
|
|
185
|
-
</li>
|
|
186
|
-
</ul>
|
|
187
|
-
</template>
|
|
129
|
+
<UIcon name="i-lucide-messages-square" class="h-8 w-8 opacity-40" />
|
|
130
|
+
<p class="text-sm">{{ t('initiative.planning.empty') }}</p>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<template v-else>
|
|
134
|
+
<p class="mb-4 text-[13px] leading-relaxed text-slate-300">
|
|
135
|
+
{{ t('initiative.planning.intro') }}
|
|
136
|
+
</p>
|
|
137
|
+
|
|
138
|
+
<!-- Converged / no pending questions -->
|
|
139
|
+
<div
|
|
140
|
+
v-if="converged || questions.length === 0"
|
|
141
|
+
class="rounded-lg border border-slate-800 bg-slate-950/40 p-4 text-center text-[13px] text-slate-400"
|
|
142
|
+
data-testid="initiative-planning-converged"
|
|
143
|
+
>
|
|
144
|
+
{{ t('initiative.planning.converged') }}
|
|
188
145
|
</div>
|
|
189
146
|
|
|
190
|
-
<!--
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
147
|
+
<!-- Interview questions — the shared clarification surface (answer / not-relevant /
|
|
148
|
+
recommend), reused with the requirements-review window. -->
|
|
149
|
+
<ul v-else class="space-y-4">
|
|
150
|
+
<li v-for="q in questions" :key="q.key" data-testid="initiative-planning-question">
|
|
151
|
+
<ClarificationItem
|
|
152
|
+
v-model:answer="drafts[q.key]"
|
|
153
|
+
:prompt="q.question"
|
|
154
|
+
:dismissed="q.status === 'dismissed'"
|
|
155
|
+
:recommendation="q.recommendation"
|
|
156
|
+
:recommending="!!q.id && initiatives.recommending.has(q.id)"
|
|
157
|
+
:answer-placeholder="t('initiative.planning.answerPlaceholder')"
|
|
158
|
+
@persist="persist(q)"
|
|
159
|
+
@dismiss="setStatus(q, 'dismissed')"
|
|
160
|
+
@reopen="setStatus(q, 'open')"
|
|
161
|
+
@recommend="recommend(q)"
|
|
162
|
+
@use-recommendation="useRecommendation(q)"
|
|
163
|
+
/>
|
|
164
|
+
</li>
|
|
165
|
+
</ul>
|
|
166
|
+
</template>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<!-- Action rail -->
|
|
170
|
+
<footer
|
|
171
|
+
v-if="initiative && !converged && questions.length > 0"
|
|
172
|
+
class="flex items-center justify-between gap-3 border-t border-slate-800 px-5 py-3"
|
|
173
|
+
>
|
|
174
|
+
<p class="text-[11px] text-slate-500">
|
|
175
|
+
{{ t('initiative.planning.hint') }}
|
|
176
|
+
</p>
|
|
177
|
+
<div class="flex items-center gap-2">
|
|
178
|
+
<UButton
|
|
179
|
+
color="neutral"
|
|
180
|
+
variant="ghost"
|
|
181
|
+
size="sm"
|
|
182
|
+
:loading="resuming"
|
|
183
|
+
data-testid="initiative-planning-proceed"
|
|
184
|
+
@click="onProceed"
|
|
185
|
+
>
|
|
186
|
+
{{ t('initiative.planning.proceed') }}
|
|
187
|
+
</UButton>
|
|
188
|
+
<UButton
|
|
189
|
+
color="primary"
|
|
190
|
+
size="sm"
|
|
191
|
+
:loading="resuming"
|
|
192
|
+
:disabled="!allAnswered"
|
|
193
|
+
data-testid="initiative-planning-continue"
|
|
194
|
+
@click="onContinue"
|
|
194
195
|
>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
</p>
|
|
198
|
-
<div class="flex items-center gap-2">
|
|
199
|
-
<UButton
|
|
200
|
-
color="neutral"
|
|
201
|
-
variant="ghost"
|
|
202
|
-
size="sm"
|
|
203
|
-
:loading="resuming"
|
|
204
|
-
data-testid="initiative-planning-proceed"
|
|
205
|
-
@click="onProceed"
|
|
206
|
-
>
|
|
207
|
-
{{ t('initiative.planning.proceed') }}
|
|
208
|
-
</UButton>
|
|
209
|
-
<UButton
|
|
210
|
-
color="primary"
|
|
211
|
-
size="sm"
|
|
212
|
-
:loading="resuming"
|
|
213
|
-
:disabled="!allAnswered"
|
|
214
|
-
data-testid="initiative-planning-continue"
|
|
215
|
-
@click="onContinue"
|
|
216
|
-
>
|
|
217
|
-
{{ t('initiative.planning.continue') }}
|
|
218
|
-
</UButton>
|
|
219
|
-
</div>
|
|
220
|
-
</footer>
|
|
196
|
+
{{ t('initiative.planning.continue') }}
|
|
197
|
+
</UButton>
|
|
221
198
|
</div>
|
|
222
|
-
</
|
|
223
|
-
</
|
|
199
|
+
</footer>
|
|
200
|
+
</ResultWindowShell>
|
|
224
201
|
</template>
|