fix: Fix group section accordion not working

This commit is contained in:
2026-03-06 22:17:24 +09:00
parent 4473bca7ca
commit 83cf8330b5

View File

@@ -11,7 +11,7 @@ import {
getPresetDiff, getPresetDiff,
} from '../utils/strategyPresets' } from '../utils/strategyPresets'
// ── 타입 ────────────────────────────────────── // ── 타입 ──────────────────────────────────────────────
interface StrategyConfig { interface StrategyConfig {
id: number id: number
@@ -28,7 +28,7 @@ interface StrategyConfig {
updated_by: string | null updated_by: string | null
} }
// ── 그룹 한글 레이블 ──────────────────────────── // ── 그룹 한글 레이블 ────────────────────────────────────────
const GROUP_LABELS: Record<string, string> = { const GROUP_LABELS: Record<string, string> = {
INDICATOR: '기술 지표', INDICATOR: '기술 지표',
@@ -59,7 +59,7 @@ const CORE_PARAMS = [
'DAY_TRADE_ENABLED', 'DAY_TRADE_ENABLED',
] ]
// ── 프리셋 카드 컴포넌트 ──────────────────────────── // ── 프리셋 카드 컴포넌트 ────────────────────────────────────────
interface PresetCardProps { interface PresetCardProps {
presetKey: PresetKey presetKey: PresetKey
@@ -113,7 +113,7 @@ function PresetCard({ presetKey, isSelected, onSelect }: PresetCardProps) {
) )
} }
// ── 개별 파라미터 행 컴포넌트 ──────────────────────── // ── 개별 파라미터 행 컴포넌트 ────────────────────────────────
interface ConfigRowProps { interface ConfigRowProps {
cfg: StrategyConfig cfg: StrategyConfig
@@ -233,7 +233,7 @@ function ConfigRow({ cfg, onSave, onToggle, onReset, isSaving }: ConfigRowProps)
) )
} }
// ── 그룹 섹션 컴포넌트 ────────────────────────────── // ── 그룹 섹션 컴포넌트 ──────────────────────────────────────────────
interface GroupSectionProps { interface GroupSectionProps {
groupKey: string groupKey: string
@@ -242,19 +242,33 @@ interface GroupSectionProps {
onToggle: (key: string) => void onToggle: (key: string) => void
onReset: (key: string) => void onReset: (key: string) => void
isSaving: boolean isSaving: boolean
defaultExpanded?: boolean isExpanded: boolean
onToggleExpand: () => void
} }
function GroupSection({ groupKey, configs, onSave, onToggle, onReset, isSaving, defaultExpanded = false }: GroupSectionProps) { function GroupSection({
const [collapsed, setCollapsed] = useState(!defaultExpanded) groupKey,
configs,
onSave,
onToggle,
onReset,
isSaving,
isExpanded,
onToggleExpand
}: GroupSectionProps) {
const modifiedCount = configs.filter(c => c.value !== c.default_value).length const modifiedCount = configs.filter(c => c.value !== c.default_value).length
return ( return (
<div> <div>
{/* 그룹 헤더 */} {/* 그룹 헤더 */}
<button <button
onClick={() => setCollapsed(!collapsed)} onClick={(e) => {
className="w-full flex items-center justify-between py-2 mb-3 group" e.preventDefault()
e.stopPropagation()
onToggleExpand()
}}
type="button"
className="w-full flex items-center justify-between py-2 mb-3 group hover:bg-slate-800/30 rounded px-2 transition-colors"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span>{GROUP_ICONS[groupKey] || '📁'}</span> <span>{GROUP_ICONS[groupKey] || '📁'}</span>
@@ -268,14 +282,14 @@ function GroupSection({ groupKey, configs, onSave, onToggle, onReset, isSaving,
</span> </span>
)} )}
</div> </div>
{collapsed {isExpanded
? <ChevronRight size={15} className="text-slate-500" /> ? <ChevronDown size={15} className="text-slate-500 group-hover:text-slate-300 transition-colors" />
: <ChevronDown size={15} className="text-slate-500" /> : <ChevronRight size={15} className="text-slate-500 group-hover:text-slate-300 transition-colors" />
} }
</button> </button>
{/* 파라미터 카드 그리드 */} {/* 파라미터 카드 그리드 */}
{!collapsed && ( {isExpanded && (
<div className="grid grid-cols-3 gap-2 mb-4"> <div className="grid grid-cols-3 gap-2 mb-4">
{configs.map((cfg) => ( {configs.map((cfg) => (
<ConfigRow <ConfigRow
@@ -293,18 +307,31 @@ function GroupSection({ groupKey, configs, onSave, onToggle, onReset, isSaving,
) )
} }
// ── 메인 페이지 ────────────────────────────────────── // ── 메인 페이지 ──────────────────────────────────────────────────────
const StrategySettings = () => { const StrategySettings = () => {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const [notification, setNotification] = useState<{ type: 'success' | 'error'; msg: string } | null>(null) const [notification, setNotification] = useState<{ type: 'success' | 'error'; msg: string } | null>(null)
const [showPresets, setShowPresets] = useState(true) const [showPresets, setShowPresets] = useState(true)
const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set())
const showNotification = (type: 'success' | 'error', msg: string) => { const showNotification = (type: 'success' | 'error', msg: string) => {
setNotification({ type, msg }) setNotification({ type, msg })
setTimeout(() => setNotification(null), 3000) setTimeout(() => setNotification(null), 3000)
} }
const toggleGroupExpand = (groupKey: string) => {
setExpandedGroups(prev => {
const next = new Set(prev)
if (next.has(groupKey)) {
next.delete(groupKey)
} else {
next.add(groupKey)
}
return next
})
}
// 전략 파라미터 목록 조회 // 전략 파라미터 목록 조회
const { data: configs = [], isLoading, refetch } = useQuery<StrategyConfig[]>({ const { data: configs = [], isLoading, refetch } = useQuery<StrategyConfig[]>({
queryKey: ['strategy-config'], queryKey: ['strategy-config'],
@@ -558,7 +585,8 @@ const StrategySettings = () => {
onToggle={(key) => toggleMutation.mutate(key)} onToggle={(key) => toggleMutation.mutate(key)}
onReset={(key) => resetOneMutation.mutate(key)} onReset={(key) => resetOneMutation.mutate(key)}
isSaving={updateMutation.isPending} isSaving={updateMutation.isPending}
defaultExpanded={false} isExpanded={expandedGroups.has(groupKey)}
onToggleExpand={() => toggleGroupExpand(groupKey)}
/> />
))} ))}
</div> </div>