feat: refactor parsing and scanning logic for test files
- Updated `parseFilename` to `parseTargetFilename` and modified its return structure to include `test_id` instead of `file_id`. - Introduced `parseResultFilename` to extract `test_id` and `device` from result file names. - Enhanced `fullScan` to separately handle target and results directories, improving clarity and functionality. - Updated database interactions to use `test_id` instead of `file_id` across various modules. - Added a new `/rescan` endpoint to trigger a full scan of target and results directories. - Improved logging and error handling throughout the scanning process. - Introduced `parseTputRssi` to extract throughput and RSSI data from log files.
This commit is contained in:
@@ -17,6 +17,9 @@ export default function ConfigModal({ onClose }) {
|
||||
const [scanResult, setScanResult] = useState(null) // { testCount, completedCount } | null
|
||||
const [saveError, setSaveError] = useState(null)
|
||||
|
||||
// Directories are locked once both are saved — restart server to change them
|
||||
const dirsLocked = !!(config?.target_dir && config?.results_dir)
|
||||
|
||||
useEffect(() => {
|
||||
if (config) {
|
||||
setForm({
|
||||
@@ -99,7 +102,12 @@ export default function ConfigModal({ onClose }) {
|
||||
<>
|
||||
{/* Directories */}
|
||||
<section>
|
||||
<h3 className="text-slate-300 text-xs uppercase tracking-widest mb-3">Directories</h3>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="text-slate-300 text-xs uppercase tracking-widest">Directories</h3>
|
||||
{dirsLocked && (
|
||||
<span className="text-xs text-slate-500">🔒 Restart server to change directories</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{[
|
||||
{ key: 'target_dir', label: 'Target Tests Directory' },
|
||||
@@ -108,19 +116,30 @@ export default function ConfigModal({ onClose }) {
|
||||
<div key={key}>
|
||||
<label className="text-slate-400 text-xs block mb-1">{label}</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={form[key] ?? ''}
|
||||
onChange={e => setForm(f => ({ ...f, [key]: e.target.value }))}
|
||||
placeholder="C:\path\to\folder"
|
||||
className="flex-1 bg-slate-800 border border-slate-700 text-slate-200 text-sm rounded-lg px-3 py-2 focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setBrowser(key)}
|
||||
className="px-3 py-2 text-sm rounded-lg border border-slate-700 text-slate-300 hover:bg-slate-800 transition-colors whitespace-nowrap"
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
{dirsLocked ? (
|
||||
<div
|
||||
title={form[key] ?? ''}
|
||||
className="flex-1 border border-slate-700/50 bg-slate-800/40 text-slate-500 text-sm rounded-lg px-3 py-2 truncate cursor-default select-all font-mono"
|
||||
>
|
||||
{(form[key] ?? '').replace(/^(.+[/\\])([^/\\]+[/\\][^/\\]*)$/, '…$2')}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
value={form[key] ?? ''}
|
||||
onChange={e => setForm(f => ({ ...f, [key]: e.target.value }))}
|
||||
placeholder="C:\path\to\folder"
|
||||
className="flex-1 bg-slate-800 border border-slate-700 text-slate-200 text-sm rounded-lg px-3 py-2 focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setBrowser(key)}
|
||||
className="px-3 py-2 text-sm rounded-lg border border-slate-700 text-slate-300 hover:bg-slate-800 transition-colors whitespace-nowrap"
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user