import { useEffect, useState } from 'react' import type React from 'react' import ModuleDeleteConfirm from './ModuleDeleteConfirm' import ModuleListEmptyState from './ModuleListEmptyState' import ModuleListHeader from './ModuleListHeader' import ModuleListRow from './ModuleListRow' import ModuleListToolbar, { type ModuleFilter } from './ModuleListToolbar' import ModuleParameterDialog from './ModuleParameterDialog' import { createParameterId, parseModuleParameters } from './moduleParameters' import type { ModuleParameterPair, ModuleRow } from './types' type ModuleListViewProps = { dark: boolean modules: ModuleRow[] loading: boolean installingModuleName: string | null controllingModuleNames: string[] listError: string | null installError: string | null allowRepositoryDeletion?: boolean onAddModuleTab: (module: ModuleRow) => void onOpenSource: (module: ModuleRow) => void onInstallModule: (module: ModuleRow) => void onDeleteModule: (module: ModuleRow, options: { deleteRepository: boolean }) => void onUpdateModuleParameters: (module: ModuleRow, parameters: ModuleParameterPair[]) => void onStartModule: (module: ModuleRow) => void onBuildModule: (module: ModuleRow) => void onStopModule: (module: ModuleRow) => void onRestartModule: (module: ModuleRow) => void onInstallAll: () => void onStartAll: () => void onStopAll: () => void onOpenWorldEditor: () => void } export default function ModuleListView({ dark, modules, loading, installingModuleName, controllingModuleNames, listError, installError, allowRepositoryDeletion = true, onAddModuleTab, onOpenSource, onInstallModule, onDeleteModule, onUpdateModuleParameters, onStartModule, onBuildModule, onStopModule, onRestartModule, onInstallAll, onStartAll, onStopAll, onOpenWorldEditor }: ModuleListViewProps): React.JSX.Element { const [moduleFilter, setModuleFilter] = useState('all') const [deleteConfirmModule, setDeleteConfirmModule] = useState(null) const [parameterDialog, setParameterDialog] = useState<{ module: ModuleRow; parameters: ModuleParameterPair[] } | null>(null) const filteredModuleRows = moduleFilter === 'all' ? modules : modules.filter((row) => row.state === moduleFilter) const uninstalledCount = modules.filter((row) => row.state === 'uninstalled').length const runningCount = modules.filter((row) => row.state === 'running').length const stoppedCount = modules.filter((row) => row.state === 'stopped').length const installingAll = installingModuleName === '__all__' const bulkControlling = installingModuleName === '__start_all__' || installingModuleName === '__stop_all__' useEffect(() => { const handleEscape = (event: KeyboardEvent): void => { if (event.key !== 'Escape') return if (parameterDialog) { event.preventDefault() setParameterDialog(null) return } if (deleteConfirmModule) { event.preventDefault() setDeleteConfirmModule(null) } } window.addEventListener('keydown', handleEscape) return () => window.removeEventListener('keydown', handleEscape) }, [deleteConfirmModule, parameterDialog]) return (
모듈 리스트 자율주행 알고리즘 모듈 관리
{(listError || installError) && (
{listError || installError}
)}
{loading ? ( ) : filteredModuleRows.length === 0 ? ( ) : filteredModuleRows.map((row) => ( { const parsedParameters = parseModuleParameters(module.parameters) setParameterDialog({ module, parameters: parsedParameters.length ? parsedParameters : [{ id: createParameterId(), name: '', value: '' }] }) }} onInstallModule={onInstallModule} onDeleteModule={setDeleteConfirmModule} onStartModule={onStartModule} onBuildModule={onBuildModule} onStopModule={onStopModule} onRestartModule={onRestartModule} /> ))}
{deleteConfirmModule && ( setDeleteConfirmModule(null)} onConfirm={(module, options) => { onDeleteModule(module, options) setDeleteConfirmModule(null) }} /> )} {parameterDialog && ( setParameterDialog(null)} onSave={(module, parameters) => { onUpdateModuleParameters(module, parameters) setParameterDialog(null) }} /> )}
) }