feat(FN-3005): merge fusion/fn-3005

Commits merged:
- fix(FN-3005): restore dashboard typecheck for custom providers
- feat(FN-3005): complete Step 1 — use explicit mode labels
- test(FN-3005): complete Step 3 — assert explicit mode toggle labels
- feat(FN-3005): complete Step 2 — fit explicit mode labels in header

Files changed:
packages/dashboard/app/components/ModelOnboardingModal.tsx        | 2 +-
 packages/dashboard/app/components/QuickChatFAB.css                | 4 ++--
 packages/dashboard/app/components/QuickChatFAB.tsx                | 4 ++--
 packages/dashboard/app/components/SettingsModal.tsx               | 6 +++---
 packages/dashboard/app/components/__tests__/QuickChatFAB.test.tsx | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-3005
This commit is contained in:
Fusion
2026-04-29 22:23:11 -07:00
committed by gsxdsm
parent c5de7e183b
commit e3c99ef290
5 changed files with 10 additions and 10 deletions

View File

@@ -605,7 +605,7 @@ export function ModelOnboardingModal({
const [apiKeyInputs, setApiKeyInputs] = useState<Record<string, string>>({});
const [apiKeyErrors, setApiKeyErrors] = useState<Record<string, string>>({});
const [apiKeySuccess, setApiKeySuccess] = useState<Record<string, string | null>>({});
const [customProviders, setCustomProviders] = useState<CustomProvider[]>([]);
const [customProviders, setCustomProviders] = useState<CustomProviderConfig[]>([]);
const [showCustomProviderForm, setShowCustomProviderForm] = useState(false);
const [customProviderSaving, setCustomProviderSaving] = useState(false);
const [customProviderError, setCustomProviderError] = useState<string | undefined>();

View File

@@ -239,11 +239,10 @@
}
.quick-chat-mode-btn {
width: var(--quick-chat-header-control-size);
min-width: var(--quick-chat-header-control-size);
height: var(--quick-chat-header-control-size);
min-height: var(--quick-chat-header-control-size);
padding: 0;
padding: 0 var(--space-sm);
display: inline-flex;
align-items: center;
justify-content: center;
@@ -256,6 +255,7 @@
line-height: 1;
cursor: pointer;
transition: var(--transition-fast);
white-space: nowrap;
}
.quick-chat-new-chat-btn {

View File

@@ -1559,7 +1559,7 @@ export function QuickChatFAB({
aria-label="Switch to agent mode"
title="Agent mode"
>
A
Agent
</button>
<button
type="button"
@@ -1572,7 +1572,7 @@ export function QuickChatFAB({
aria-label="Switch to model mode"
title="Model mode"
>
M
Model
</button>
</div>
)}

View File

@@ -415,7 +415,7 @@ export function SettingsModal({
const [loginInstructions, setLoginInstructions] = useState<Record<string, string>>({});
const [apiKeyInputs, setApiKeyInputs] = useState<Record<string, string>>({});
const [apiKeyErrors, setApiKeyErrors] = useState<Record<string, string>>({});
const [customProviders, setCustomProviders] = useState<CustomProvider[]>([]);
const [customProviders, setCustomProviders] = useState<CustomProviderConfig[]>([]);
const [customProviderEditing, setCustomProviderEditing] = useState<CustomProviderConfig | null>(null);
const [showCustomProviderForm, setShowCustomProviderForm] = useState(false);
const [customProviderSaving, setCustomProviderSaving] = useState(false);
@@ -833,7 +833,7 @@ export function SettingsModal({
}
}, [customProviderEditing, loadCustomProviders]);
const handleDeleteCustomProvider = useCallback(async (provider: CustomProvider) => {
const handleDeleteCustomProvider = useCallback(async (provider: CustomProviderConfig) => {
const ok = await confirm({
title: "Delete custom provider",
message: `Delete custom provider '${provider.id}'?`,
@@ -4719,7 +4719,7 @@ export function SettingsModal({
id: provider.id,
name: provider.name,
baseUrl: provider.baseUrl,
api: provider.apiType === "anthropic-compatible" ? "anthropic-messages" : "openai-completions",
api: provider.api,
apiKey: provider.apiKey,
models: provider.models?.map((model) => ({ id: model.id, name: model.name })) ?? [],
});

View File

@@ -647,8 +647,8 @@ describe("QuickChatFAB", () => {
expect(scoped.getByTestId("quick-chat-mode-toggle")).toBeDefined();
const agentModeBtn = scoped.getByTestId("quick-chat-mode-agent");
const modelModeBtn = scoped.getByTestId("quick-chat-mode-model");
expect(agentModeBtn).toHaveTextContent("A");
expect(modelModeBtn).toHaveTextContent("M");
expect(agentModeBtn).toHaveTextContent("Agent");
expect(modelModeBtn).toHaveTextContent("Model");
expect(agentModeBtn).toHaveAttribute("aria-label", "Switch to agent mode");
expect(modelModeBtn).toHaveAttribute("aria-label", "Switch to model mode");