Add an import config button (#733)
This commit is contained in:
parent
7a0bbca5b1
commit
4ad14d211a
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import { defaultJobConfig, defaultDatasetConfig, migrateJobConfig } from './jobConfig';
|
||||
import { jobTypeOptions } from './options';
|
||||
|
|
@ -11,6 +11,7 @@ import { SelectInput } from '@/components/formInputs';
|
|||
import useSettings from '@/hooks/useSettings';
|
||||
import useGPUInfo from '@/hooks/useGPUInfo';
|
||||
import useDatasetList from '@/hooks/useDatasetList';
|
||||
import YAML from 'yaml';
|
||||
import path from 'path';
|
||||
import { TopBar, MainContent } from '@/components/layout';
|
||||
import { Button } from '@headlessui/react';
|
||||
|
|
@ -36,6 +37,49 @@ export default function TrainingForm() {
|
|||
|
||||
const [jobConfig, setJobConfig] = useNestedState<JobConfig>(objectCopy(defaultJobConfig));
|
||||
const [status, setStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle');
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const handleImportConfig = () => {
|
||||
fileInputRef.current?.click();
|
||||
};
|
||||
|
||||
const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
try {
|
||||
const text = reader.result as string;
|
||||
let parsed: any;
|
||||
if (file.name.endsWith('.json') || file.name.endsWith('.jsonc')) {
|
||||
parsed = JSON.parse(text.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, ''));
|
||||
} else {
|
||||
parsed = YAML.parse(text);
|
||||
}
|
||||
|
||||
// Set required fields (same pattern as AdvancedJob.handleChange)
|
||||
try {
|
||||
parsed.config.process[0].sqlite_db_path = './aitk_db.db';
|
||||
parsed.config.process[0].training_folder = settings.TRAINING_FOLDER;
|
||||
parsed.config.process[0].device = 'cuda';
|
||||
parsed.config.process[0].performance_log_every = 10;
|
||||
} catch (err) {
|
||||
console.warn('Could not set required fields on imported config:', err);
|
||||
}
|
||||
|
||||
migrateJobConfig(parsed);
|
||||
setJobConfig(parsed);
|
||||
} catch (err) {
|
||||
console.error('Failed to parse config file:', err);
|
||||
alert('Failed to parse config file. Please check the file format.');
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
|
||||
// Reset so the same file can be re-imported
|
||||
e.target.value = '';
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSettingsLoaded) return;
|
||||
|
|
@ -161,6 +205,15 @@ export default function TrainingForm() {
|
|||
/>
|
||||
</div>
|
||||
<div className="mx-4 bg-gray-200 dark:bg-gray-800 w-1 h-6"></div>
|
||||
<div>
|
||||
<Button
|
||||
className="text-gray-200 bg-gray-800 px-3 py-1 rounded-md"
|
||||
onClick={handleImportConfig}
|
||||
>
|
||||
Import Config
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mx-4 bg-gray-200 dark:bg-gray-800 w-1 h-6"></div>
|
||||
</>
|
||||
)}
|
||||
{!showAdvancedView && (
|
||||
|
|
@ -215,6 +268,14 @@ export default function TrainingForm() {
|
|||
</div>
|
||||
</TopBar>
|
||||
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept=".yaml,.yml,.json,.jsonc"
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileSelected}
|
||||
/>
|
||||
|
||||
{showAdvancedView ? (
|
||||
<div className="pt-[48px] absolute top-0 left-0 w-full h-full overflow-auto">
|
||||
<AdvancedJob
|
||||
|
|
|
|||
Loading…
Reference in New Issue