summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-28 03:19:15 +0000
committersoryu <soryu@soryu.co>2026-01-28 03:19:15 +0000
commit72c4b46590f702497182c38ee1db2baad8485ef5 (patch)
tree42d8cf053431ebe2d4f28dc6b681601a041f1cfb
parentf6b4d06a0158fb7803a2d7a861cf891cb3b202b4 (diff)
downloadsoryu-makima/fix-phase-names-dropdown.tar.gz
soryu-makima/fix-phase-names-dropdown.zip
Fix starting phase dropdown to show correct phase names from templatesmakima/fix-phase-names-dropdown
Add phaseNames map to ContractTypeTemplate to preserve display names from custom templates loaded from localStorage. The dropdown now uses the template's phase name (e.g., 'Design & Architecture') instead of naive capitalization of the phase ID. Falls back to capitalization for built-in templates that don't provide phaseNames. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--makima/frontend/src/lib/api.ts2
-rw-r--r--makima/frontend/src/routes/contracts.tsx19
2 files changed, 15 insertions, 6 deletions
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index 7c9fcd6..cc412fd 100644
--- a/makima/frontend/src/lib/api.ts
+++ b/makima/frontend/src/lib/api.ts
@@ -1631,6 +1631,8 @@ export interface ContractTypeTemplate {
defaultPhase: ContractPhase;
/** Whether this is a built-in type (always available) */
isBuiltin: boolean;
+ /** Optional mapping from phase ID to display name */
+ phaseNames?: Record<string, string>;
}
/** Response from list contract types endpoint */
diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx
index aa62bd9..9891f29 100644
--- a/makima/frontend/src/routes/contracts.tsx
+++ b/makima/frontend/src/routes/contracts.tsx
@@ -108,11 +108,12 @@ function ContractsPageContent() {
// Convert user templates to ContractTypeTemplate format, excluding built-ins
return templates
.filter((t: { isBuiltIn?: boolean }) => !t.isBuiltIn)
- .map((t: { id: string; name: string; description: string; phases: { id: string }[] }) => ({
+ .map((t: { id: string; name: string; description: string; phases: { id: string; name: string }[] }) => ({
id: t.id,
name: t.name,
description: t.description,
phases: t.phases.map((p: { id: string }) => p.id) as ContractPhase[],
+ phaseNames: Object.fromEntries(t.phases.map((p: { id: string; name: string }) => [p.id, p.name])),
defaultPhase: (t.phases[0]?.id || "execute") as ContractPhase,
isBuiltin: false,
}));
@@ -652,11 +653,17 @@ function ContractsPageContent() {
onChange={(e) => setInitialPhase(e.target.value as ContractPhase)}
className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] font-mono text-sm focus:outline-none focus:border-[#75aafc]"
>
- {(contractTypes.find((t) => t.id === contractType)?.phases || []).map((phase) => (
- <option key={phase} value={phase}>
- {phase.charAt(0).toUpperCase() + phase.slice(1)}
- </option>
- ))}
+ {(() => {
+ const template = contractTypes.find((t) => t.id === contractType);
+ return (template?.phases || []).map((phase) => {
+ const displayName = template?.phaseNames?.[phase] || (phase.charAt(0).toUpperCase() + phase.slice(1));
+ return (
+ <option key={phase} value={phase}>
+ {displayName}
+ </option>
+ );
+ });
+ })()}
</select>
<p className="mt-1 font-mono text-xs text-[#8b949e]">
{contractType === "simple"