Skip to content

Commit 3d60707

Browse files
committed
feat: decouple base directory from file paths for flexible path management
1 parent 7b5772a commit 3d60707

5 files changed

Lines changed: 85 additions & 35 deletions

File tree

src/components/User/Dashboard/DatasetOrganizer/DropZone.tsx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { FileItem } from "redux/projects/types/projects.interface";
99
interface DropZoneProps {
1010
files: FileItem[];
1111
setFiles: React.Dispatch<React.SetStateAction<FileItem[]>>;
12+
baseDirectoryPath: string; // ✅ ADD this line
13+
setBaseDirectoryPath: React.Dispatch<React.SetStateAction<string>>; // ✅ ADD this line
1214
selectedIds: Set<string>;
1315
setSelectedIds: React.Dispatch<React.SetStateAction<Set<string>>>;
1416
expandedIds: Set<string>;
@@ -18,14 +20,16 @@ interface DropZoneProps {
1820
const DropZone: React.FC<DropZoneProps> = ({
1921
files,
2022
setFiles,
23+
baseDirectoryPath, // ✅ ADD this line
24+
setBaseDirectoryPath, // ✅ ADD this line
2125
selectedIds,
2226
setSelectedIds,
2327
expandedIds,
2428
setExpandedIds,
2529
}) => {
2630
const [isDragging, setIsDragging] = useState(false);
2731
const fileInputRef = useRef<HTMLInputElement>(null);
28-
const [basePath, setBasePath] = useState<string>("");
32+
// const [basePath, setBasePath] = useState<string>(""); // change
2933

3034
const handleDragOver = (e: React.DragEvent) => {
3135
e.preventDefault();
@@ -59,17 +63,24 @@ const DropZone: React.FC<DropZoneProps> = ({
5963

6064
// Process folders
6165
for (const folderEntry of folderEntries) {
62-
const folderFiles = await processFolder(folderEntry, null, basePath);
66+
// const folderFiles = await processFolder(folderEntry, null, basePath);// change
67+
const folderFiles = await processFolder(
68+
folderEntry,
69+
null,
70+
baseDirectoryPath
71+
); // add
6372
setFiles((prev) => [...prev, ...folderFiles]);
6473
}
6574

6675
// Process files
6776
for (const file of fileItems) {
6877
if (file.name.toLowerCase().endsWith(".zip")) {
69-
const zipFiles = await processZip(file, basePath);
78+
// const zipFiles = await processZip(file, basePath);//change
79+
const zipFiles = await processZip(file, baseDirectoryPath); //add
7080
setFiles((prev) => [...prev, ...zipFiles]);
7181
} else {
72-
const fileItem = await processFile(file, basePath);
82+
// const fileItem = await processFile(file, basePath);//change
83+
const fileItem = await processFile(file, baseDirectoryPath); //add
7384
setFiles((prev) => [...prev, fileItem]);
7485
}
7586
}
@@ -80,10 +91,12 @@ const DropZone: React.FC<DropZoneProps> = ({
8091

8192
for (const file of selectedFiles) {
8293
if (file.name.toLowerCase().endsWith(".zip")) {
83-
const zipFiles = await processZip(file, basePath);
94+
// const zipFiles = await processZip(file, basePath);//change
95+
const zipFiles = await processZip(file, baseDirectoryPath); //add
8496
setFiles((prev) => [...prev, ...zipFiles]);
8597
} else {
86-
const fileItem = await processFile(file, basePath);
98+
// const fileItem = await processFile(file, basePath); //change
99+
const fileItem = await processFile(file, baseDirectoryPath); //add
87100
setFiles((prev) => [...prev, fileItem]);
88101
}
89102
}
@@ -176,8 +189,10 @@ const DropZone: React.FC<DropZoneProps> = ({
176189
<TextField
177190
label="Base Directory Path (optional)"
178191
placeholder="example: /Users/username/Desktop/Downloads"
179-
value={basePath}
180-
onChange={(e) => setBasePath(e.target.value)}
192+
// value={basePath} // change
193+
// onChange={(e) => setBasePath(e.target.value)} //change
194+
value={baseDirectoryPath} // ✅ CHANGE: Use prop
195+
onChange={(e) => setBaseDirectoryPath(e.target.value)} // ✅ CHANGE: Use prop setter
181196
fullWidth
182197
size="small"
183198
sx={{ mb: 2 }}

src/components/User/Dashboard/DatasetOrganizer/LLMPanel.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { FileItem } from "redux/projects/types/projects.interface";
1919

2020
interface LLMPanelProps {
2121
files: FileItem[];
22+
baseDirectoryPath: string; // ✅ ADD this line
23+
setBaseDirectoryPath: (path: string) => void; // ✅ ADD this line
2224
onClose: () => void;
2325
}
2426

@@ -86,7 +88,12 @@ const llmProviders: Record<string, LLMProvider> = {
8688
},
8789
};
8890

89-
const LLMPanel: React.FC<LLMPanelProps> = ({ files, onClose }) => {
91+
const LLMPanel: React.FC<LLMPanelProps> = ({
92+
files,
93+
baseDirectoryPath, // ✅ ADD this line
94+
setBaseDirectoryPath, // ✅ ADD this line
95+
onClose,
96+
}) => {
9097
const [provider, setProvider] = useState<string>("ollama");
9198
const [model, setModel] = useState<string>("qwen3-coder:30b");
9299
const [ollamaUrl, setOllamaUrl] = useState<string>(
@@ -97,7 +104,7 @@ const LLMPanel: React.FC<LLMPanelProps> = ({ files, onClose }) => {
97104
const [loading, setLoading] = useState(false);
98105
const [error, setError] = useState<string | null>(null);
99106
const [status, setStatus] = useState<string>("");
100-
const [baseDirectoryPath, setBaseDirectoryPath] = useState<string>(""); // ✅ Add this
107+
// const [baseDirectoryPath, setBaseDirectoryPath] = useState<string>(""); // change
101108

102109
const [panelHeight, setPanelHeight] = useState<number>(350);
103110
const [isResizing, setIsResizing] = useState(false);

src/components/User/Dashboard/DatasetOrganizer/index.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const DatasetOrganizer: React.FC = () => {
3838
const [showLLMPanel, setShowLLMPanel] = useState(false);
3939
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
4040
const [error, setError] = useState<string | null>(null);
41+
const [baseDirectoryPath, setBaseDirectoryPath] = useState<string>(""); // ✅ ADD this line
4142
// Helper to mark as changed
4243
const markAsChanged = () => {
4344
setHasUnsavedChanges(true);
@@ -73,6 +74,7 @@ const DatasetOrganizer: React.FC = () => {
7374
setFiles(state.files || []);
7475
setSelectedIds(new Set(state.selectedIds || []));
7576
setExpandedIds(new Set(state.expandedIds || []));
77+
setBaseDirectoryPath(state.baseDirectoryPath || ""); // ✅ ADD this line
7678
setHasUnsavedChanges(false);
7779
}
7880
}, [currentProject]);
@@ -88,6 +90,7 @@ const DatasetOrganizer: React.FC = () => {
8890
files,
8991
selectedIds: Array.from(selectedIds),
9092
expandedIds: Array.from(expandedIds),
93+
baseDirectoryPath, // ✅ ADD this line
9194
},
9295
})
9396
).unwrap();
@@ -108,15 +111,29 @@ const DatasetOrganizer: React.FC = () => {
108111
if (child.type === "folder" || child.type === "zip") {
109112
result[child.name] = {
110113
_type: child.type,
111-
_sourcePath: child.sourcePath || "",
114+
// _sourcePath: child.sourcePath || "", //change
115+
//add
116+
_sourcePath: baseDirectoryPath
117+
? `${baseDirectoryPath}/${
118+
child.sourcePath || child.name
119+
}`.replace(/\/+/g, "/")
120+
: child.sourcePath || "",
112121
_children: buildTree(child.id),
113122
};
114123
} else {
115124
const fileData: any = {
116125
_type: "file",
117126
_fileType: child.fileType || "other",
118127
};
119-
if (child.sourcePath) fileData._sourcePath = child.sourcePath;
128+
// if (child.sourcePath) fileData._sourcePath = child.sourcePath; // change
129+
//add
130+
if (child.sourcePath || baseDirectoryPath) {
131+
fileData._sourcePath = baseDirectoryPath
132+
? `${baseDirectoryPath}/${
133+
child.sourcePath || child.name
134+
}`.replace(/\/+/g, "/")
135+
: child.sourcePath;
136+
}
120137
if (child.isUserMeta) fileData._isUserMeta = true;
121138
if (child.content) fileData._content = child.content;
122139
if (child.contentType) fileData._contentType = child.contentType;
@@ -307,6 +324,8 @@ const DatasetOrganizer: React.FC = () => {
307324
<DropZone
308325
files={files}
309326
setFiles={updateFiles} // Pass wrapper
327+
baseDirectoryPath={baseDirectoryPath} // ✅ ADD this line
328+
setBaseDirectoryPath={setBaseDirectoryPath} // ✅ ADD this line
310329
selectedIds={selectedIds}
311330
setSelectedIds={setSelectedIds}
312331
expandedIds={expandedIds}
@@ -327,7 +346,12 @@ const DatasetOrganizer: React.FC = () => {
327346

328347
{/* LLM Panel */}
329348
{showLLMPanel && (
330-
<LLMPanel files={files} onClose={() => setShowLLMPanel(false)} />
349+
<LLMPanel
350+
files={files}
351+
baseDirectoryPath={baseDirectoryPath} // ✅ ADD this line
352+
setBaseDirectoryPath={setBaseDirectoryPath} // ✅ ADD this line
353+
onClose={() => setShowLLMPanel(false)}
354+
/>
331355
)}
332356
</Box>
333357
);

src/components/User/Dashboard/DatasetOrganizer/utils/fileProcessors.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,18 @@ export const processFile = async (
7272
basePath?: string
7373
): Promise<FileItem> => {
7474
const relativePath = file.webkitRelativePath || file.name;
75-
const fullPath = basePath
76-
? `${basePath}/${relativePath}`.replace(/\/+/g, "/") // Clean up double slashes
77-
: relativePath;
75+
// const fullPath = basePath
76+
// ? `${basePath}/${relativePath}`.replace(/\/+/g, "/") // Clean up double slashes
77+
// : relativePath;
7878
const entry: FileItem = {
7979
id: generateId(),
8080
name: file.name,
8181
type: "file",
8282
parentId: null,
8383
fileType: getFileType(file.name) as any,
8484
// sourcePath: file.name,
85-
sourcePath: fullPath, // ← Now includes base path if provided
85+
// sourcePath: fullPath, // ← Now includes base path if provided
86+
sourcePath: relativePath, //add
8687
};
8788

8889
// Only extract content for text files
@@ -199,16 +200,17 @@ export const processZip = async (
199200
if (!pathMap[folderPath]) {
200201
const folderId = generateId();
201202
pathMap[folderPath] = folderId;
202-
const folderSourcePath = basePath
203-
? `${basePath}/${zipName}/${folderPath}`.replace(/\/+/g, "/")
204-
: `${zipName}/${folderPath}`;
203+
// const folderSourcePath = basePath
204+
// ? `${basePath}/${zipName}/${folderPath}`.replace(/\/+/g, "/")
205+
// : `${zipName}/${folderPath}`;
205206
entries.push({
206207
id: folderId,
207208
name: part,
208209
type: "folder",
209210
parentId: parentId,
210211
// sourcePath: `${zipName}/${folderPath}`,
211-
sourcePath: folderSourcePath,
212+
// sourcePath: folderSourcePath,
213+
sourcePath: `${zipName}/${folderPath}`, //add
212214
});
213215
}
214216
parentId = pathMap[folderPath];
@@ -221,18 +223,18 @@ export const processZip = async (
221223
const ext = fileName.toLowerCase().split(".").pop();
222224

223225
// Add basePath to file sourcePath
224-
const fileSourcePath = basePath
225-
? `${basePath}/${zipName}/${path}`.replace(/\/+/g, "/")
226-
: `${zipName}/${path}`;
226+
// const fileSourcePath = basePath
227+
// ? `${basePath}/${zipName}/${path}`.replace(/\/+/g, "/")
228+
// : `${zipName}/${path}`;
227229

228230
const entry: FileItem = {
229231
id: fileId,
230232
name: fileName,
231233
type: "file",
232234
parentId: parentId,
233235
fileType: fileType as any,
234-
// sourcePath: `${zipName}/${path}`,
235-
sourcePath: fileSourcePath,
236+
sourcePath: `${zipName}/${path}`, // only relative path
237+
// sourcePath: fileSourcePath,//change
236238
};
237239

238240
// Extract content based on file type
@@ -356,9 +358,9 @@ export const processFolder = async (
356358
const folderName = folderEntry.name;
357359

358360
// Add basePath to root folder sourcePath
359-
const rootSourcePath = basePath
360-
? `${basePath}/${folderName}`.replace(/\/+/g, "/")
361-
: folderName;
361+
// const rootSourcePath = basePath
362+
// ? `${basePath}/${folderName}`.replace(/\/+/g, "/")
363+
// : folderName;
362364

363365
// Add the folder itself
364366
entries.push({
@@ -367,7 +369,8 @@ export const processFolder = async (
367369
type: "folder",
368370
parentId: parentId,
369371
// sourcePath: basePath,
370-
sourcePath: rootSourcePath,
372+
// sourcePath: rootSourcePath,
373+
sourcePath: folderName, //add
371374
});
372375

373376
// Helper: Promisify readEntries
@@ -408,19 +411,19 @@ export const processFolder = async (
408411

409412
// Process each entry
410413
for (const entry of allEntries) {
411-
// const entryPath = `${currentPath}/${entry.name}`;
414+
const entryPath = `${currentPath}/${entry.name}`;
412415
// Construct full path with basePath
413-
const entryPath = basePath
414-
? `${basePath}/${currentPath}/${entry.name}`.replace(/\/+/g, "/")
415-
: `${currentPath}/${entry.name}`;
416+
// const entryPath = basePath
417+
// ? `${basePath}/${currentPath}/${entry.name}`.replace(/\/+/g, "/")
418+
// : `${currentPath}/${entry.name}`;
416419

417420
if (entry.isFile) {
418421
// Process file
419422
const fileEntry = entry as FileSystemFileEntry;
420423
const file = await getFile(fileEntry);
421424
const fileItem = await processFile(file);
422425
fileItem.parentId = currentParentId;
423-
fileItem.sourcePath = entryPath;
426+
fileItem.sourcePath = entryPath; // only relative path
424427
entries.push(fileItem);
425428
} else if (entry.isDirectory) {
426429
// Process subfolder

src/redux/projects/types/projects.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface ExtractorState {
2525
files: FileItem[];
2626
selectedIds: string[];
2727
expandedIds: string[];
28+
baseDirectoryPath?: string; //add
2829
}
2930

3031
// Project Interface

0 commit comments

Comments
 (0)