Files
automaker/apps/ui/src/components/shared/model-override-trigger.tsx
Shirone 006152554b chore: Fix all lint errors and remove unused code
- Fix 75 ESLint errors by updating eslint.config.mjs:
  - Add missing browser globals (MouseEvent, AbortController, Response, etc.)
  - Add Vite define global (__APP_VERSION__)
  - Configure @ts-nocheck to require descriptions
  - Add no-unused-vars rule for .mjs scripts

- Fix runtime bug in agent-output-modal.tsx (setOutput -> setStreamedContent)

- Remove ~120 unused variable warnings across 97 files:
  - Remove unused imports (React hooks, lucide icons, types)
  - Remove unused constants and variables
  - Remove unused function definitions
  - Prefix intentionally unused parameters with underscore

- Add descriptions to all @ts-nocheck comments (25 files)

- Clean up misc issues:
  - Remove invalid deprecation plugin comments
  - Fix eslint-disable comment placement
  - Add missing RefreshCw import in code-view.tsx

Reduces lint warnings from ~300 to 67 (all remaining are no-explicit-any)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 17:33:45 +01:00

117 lines
3.8 KiB
TypeScript

import { cn } from '@/lib/utils';
import { useAppStore } from '@/store/app-store';
import type { ModelAlias, CursorModelId, PhaseModelKey, PhaseModelEntry } from '@automaker/types';
import { PhaseModelSelector } from '@/components/views/settings-view/model-defaults/phase-model-selector';
/**
* Normalize PhaseModelEntry or string to PhaseModelEntry
*/
function normalizeEntry(entry: PhaseModelEntry | string): PhaseModelEntry {
if (typeof entry === 'string') {
return { model: entry as ModelAlias | CursorModelId };
}
return entry;
}
export interface ModelOverrideTriggerProps {
/** Current effective model entry (from global settings or explicit override) */
currentModelEntry: PhaseModelEntry;
/** Callback when user selects override */
onModelChange: (entry: PhaseModelEntry | null) => void;
/** Optional: which phase this is for (shows global default) */
phase?: PhaseModelKey;
/** Size variants for different contexts */
size?: 'sm' | 'md' | 'lg';
/** Show as icon-only or with label */
variant?: 'icon' | 'button' | 'inline';
/** Whether the model is currently overridden from global */
isOverridden?: boolean;
/** Optional class name */
className?: string;
}
export function ModelOverrideTrigger({
currentModelEntry,
onModelChange,
phase,
size = 'sm',
variant = 'icon',
isOverridden = false,
className,
}: ModelOverrideTriggerProps) {
const { phaseModels } = useAppStore();
const handleChange = (entry: PhaseModelEntry) => {
// If the new entry matches the global default, clear the override
// Otherwise, set it as override
if (phase) {
const globalDefault = phaseModels[phase];
const normalizedGlobal = normalizeEntry(globalDefault);
// Compare models (and thinking levels if both have them)
const modelsMatch = entry.model === normalizedGlobal.model;
const thinkingMatch =
(entry.thinkingLevel || 'none') === (normalizedGlobal.thinkingLevel || 'none');
if (modelsMatch && thinkingMatch) {
onModelChange(null); // Clear override
} else {
onModelChange(entry); // Set override
}
} else {
onModelChange(entry);
}
};
// Size classes for icon variant
const sizeClasses = {
sm: 'h-6 w-6',
md: 'h-8 w-8',
lg: 'h-10 w-10',
};
// For icon variant, wrap PhaseModelSelector and hide text/chevron with CSS
if (variant === 'icon') {
return (
<div className={cn('relative inline-block', className)}>
<div className="relative [&_button>span]:hidden [&_button>svg:last-child]:hidden [&_button]:p-0 [&_button]:min-w-0 [&_button]:w-auto [&_button]:h-auto [&_button]:border-0 [&_button]:bg-transparent">
<PhaseModelSelector
value={currentModelEntry}
onChange={handleChange}
compact
triggerClassName={cn(
'relative rounded-md',
'transition-colors duration-150',
'text-muted-foreground hover:text-foreground',
'hover:bg-accent/50',
sizeClasses[size],
className
)}
disabled={false}
align="end"
/>
</div>
{isOverridden && (
<div className="absolute -top-0.5 -right-0.5 w-2 h-2 bg-brand-500 rounded-full z-10 pointer-events-none" />
)}
</div>
);
}
// For button and inline variants, use PhaseModelSelector in compact mode
return (
<div className={cn('relative', className)}>
<PhaseModelSelector
value={currentModelEntry}
onChange={handleChange}
compact
triggerClassName={variant === 'button' ? className : undefined}
disabled={false}
/>
{isOverridden && (
<div className="absolute -top-0.5 -right-0.5 w-2 h-2 bg-brand-500 rounded-full z-10" />
)}
</div>
);
}