Skip to content

Commit 80236d1

Browse files
committed
fix: align settings model panels
1 parent a75cabf commit 80236d1

1 file changed

Lines changed: 26 additions & 13 deletions

File tree

frontend/src/pages/Settings.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ function ModelMappingEditor({ value, onChange }: { value: string; onChange: (v:
9797
}
9898

9999
return (
100-
<div className="space-y-3">
101-
<div className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2rem] gap-1.5 px-1 text-xs font-semibold text-muted-foreground">
100+
<div className="flex min-h-0 flex-1 flex-col gap-3">
101+
<div className="grid shrink-0 grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2rem] gap-1.5 px-1 text-xs font-semibold text-muted-foreground">
102102
<span>{t('settings2.anthropicModel')}</span>
103103
<span>{t('settings2.codexModel')}</span>
104104
<span />
105105
</div>
106-
<div className="max-h-[260px] space-y-1.5 overflow-y-auto pr-1">
106+
<div className="min-h-[180px] flex-1 space-y-1.5 overflow-y-auto pr-1">
107107
{mappings.map(([k, v], i) => (
108108
<div key={i} className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2rem] items-center gap-1.5">
109109
<Input
@@ -121,14 +121,15 @@ function ModelMappingEditor({ value, onChange }: { value: string; onChange: (v:
121121
<button
122122
type="button"
123123
onClick={() => handleRemove(i)}
124+
aria-label={t('common.delete')}
124125
className="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-red-50 hover:text-red-500 dark:hover:bg-red-500/10"
125126
>
126127
<Trash2 className="size-3.5" />
127128
</button>
128129
</div>
129130
))}
130131
</div>
131-
<Button type="button" variant="outline" size="sm" onClick={handleAdd}>
132+
<Button type="button" variant="outline" size="sm" className="self-start" onClick={handleAdd}>
132133
+ {t('settings2.addMapping')}
133134
</Button>
134135
</div>
@@ -140,18 +141,20 @@ function SettingsCard({
140141
description,
141142
children,
142143
className,
144+
contentClassName,
143145
footer,
144146
}: {
145147
title: string
146148
description?: string
147149
children: ReactNode
148150
className?: string
151+
contentClassName?: string
149152
footer?: ReactNode
150153
}) {
151154
return (
152155
<Card className={cn('py-0', className)}>
153-
<CardContent className="p-5">
154-
<div className="mb-4">
156+
<CardContent className={cn('p-5', contentClassName)}>
157+
<div className="mb-4 shrink-0">
155158
<h3 className="text-base font-semibold leading-tight text-foreground">{title}</h3>
156159
{description ? (
157160
<p className="mt-1 text-xs leading-relaxed text-muted-foreground">{description}</p>
@@ -647,9 +650,14 @@ export default function Settings() {
647650
</div>
648651
</SettingsCard>
649652

650-
<div className="grid items-start gap-4 xl:grid-cols-2">
651-
<SettingsCard title={t('settings.modelRegistry')} description={t('settings.modelRegistryDesc')}>
652-
<div className="space-y-4">
653+
<div className="grid items-stretch gap-4 xl:grid-cols-2">
654+
<SettingsCard
655+
title={t('settings.modelRegistry')}
656+
description={t('settings.modelRegistryDesc')}
657+
className="h-full xl:h-[430px]"
658+
contentClassName="flex h-full min-h-0 flex-col"
659+
>
660+
<div className="flex min-h-0 flex-1 flex-col gap-4">
653661
<div className="grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-3">
654662
<StatusTile label={t('settings.modelsEnabled')}>
655663
{enabledModelCount}
@@ -658,7 +666,7 @@ export default function Settings() {
658666
<span className="text-xs font-semibold">{modelsLastSyncedLabel}</span>
659667
</StatusTile>
660668
</div>
661-
<div className="flex flex-wrap items-center justify-between gap-2">
669+
<div className="flex shrink-0 flex-wrap items-center justify-between gap-2">
662670
<a
663671
href={modelsSourceLabel}
664672
target="_blank"
@@ -673,9 +681,9 @@ export default function Settings() {
673681
{syncingModels ? t('settings.modelsSyncing') : t('settings.syncUpstreamModels')}
674682
</Button>
675683
</div>
676-
<div className="flex max-h-[170px] flex-wrap gap-2 overflow-auto rounded-lg border border-border bg-muted/20 p-3">
684+
<div className="flex min-h-0 flex-1 flex-wrap content-start gap-2 overflow-auto rounded-lg border border-border bg-muted/20 p-3">
677685
{visibleModelItems.map((model) => (
678-
<div key={model.id} className="flex flex-wrap items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5">
686+
<div key={model.id} className="flex h-fit flex-wrap items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5">
679687
<span className="font-mono text-xs font-semibold text-foreground">{model.id}</span>
680688
<Badge variant={model.source === 'official_codex_docs' ? 'default' : 'secondary'} className="text-[11px]">
681689
{model.source === 'official_codex_docs' ? t('settings.modelSourceOfficial') : t('settings.modelSourceBuiltin')}
@@ -688,7 +696,12 @@ export default function Settings() {
688696
</div>
689697
</SettingsCard>
690698

691-
<SettingsCard title={t('settings2.modelMapping')} description={t('settings2.modelMappingDesc')}>
699+
<SettingsCard
700+
title={t('settings2.modelMapping')}
701+
description={t('settings2.modelMappingDesc')}
702+
className="h-full xl:h-[430px]"
703+
contentClassName="flex h-full min-h-0 flex-col"
704+
>
692705
<ModelMappingEditor
693706
value={settingsForm.model_mapping}
694707
onChange={(v) => setSettingsForm(f => ({ ...f, model_mapping: v }))}

0 commit comments

Comments
 (0)