feat: update source files, Dockerfile, vite config and service worker
This commit is contained in:
@@ -42,10 +42,10 @@ import {
|
||||
Info as InfoIcon
|
||||
} from '@mui/icons-material';
|
||||
import { supabase } from '../../supabaseClient';
|
||||
import {
|
||||
pickDirectory,
|
||||
processDirectoryFiles,
|
||||
calculateDirectoryStats,
|
||||
import {
|
||||
pickDirectory,
|
||||
processDirectoryFiles,
|
||||
calculateDirectoryStats,
|
||||
formatFileSize,
|
||||
isDirectoryPickerSupported,
|
||||
FileWithPath
|
||||
@@ -104,7 +104,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
const [files, setFiles] = useState<FileRecord[]>([]);
|
||||
const [pagination, setPagination] = useState<PaginationInfo | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
// Pagination and filtering state
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(10);
|
||||
@@ -128,7 +128,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
const apiFetch = useCallback(async (url: string, init?: { method?: string; body?: FormData | string; headers?: Record<string, string> }) => {
|
||||
const session = await supabase.auth.getSession();
|
||||
const token = session?.data?.session?.access_token;
|
||||
|
||||
|
||||
if (!token) {
|
||||
throw new Error('No authentication token available');
|
||||
}
|
||||
@@ -140,12 +140,12 @@ const SimpleUploadTest: React.FC = () => {
|
||||
|
||||
const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`;
|
||||
const res = await fetch(fullUrl, { ...init, headers });
|
||||
|
||||
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text();
|
||||
throw new Error(`HTTP ${res.status}: ${errorText}`);
|
||||
}
|
||||
|
||||
|
||||
return res.json();
|
||||
}, [API_BASE]);
|
||||
|
||||
@@ -171,7 +171,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
|
||||
const loadFiles = useCallback(async (cabinetId: string, page: number = currentPage) => {
|
||||
if (!cabinetId) return;
|
||||
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
// Build query parameters for pagination, search, and sorting
|
||||
@@ -183,20 +183,20 @@ const SimpleUploadTest: React.FC = () => {
|
||||
sort_order: sortOrder,
|
||||
include_directories: 'true'
|
||||
});
|
||||
|
||||
|
||||
if (searchTerm) {
|
||||
params.append('search', searchTerm);
|
||||
}
|
||||
|
||||
|
||||
// Use the new simple upload endpoint for listing files with pagination
|
||||
const data: FileListResponse = await apiFetch(`/simple-upload/files?${params.toString()}`);
|
||||
|
||||
|
||||
setFiles(data.files || []);
|
||||
setPagination(data.pagination);
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `Loaded ${data.files?.length || 0} files (${data.pagination.total_count} total)`
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `Loaded ${data.files?.length || 0} files (${data.pagination.total_count} total)`
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
console.error('Failed to load files:', error);
|
||||
@@ -240,7 +240,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
// Single file upload
|
||||
const handleSingleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (!e.target.files || !selectedCabinet) return;
|
||||
|
||||
|
||||
const file = e.target.files[0];
|
||||
const formData = new FormData();
|
||||
formData.append('cabinet_id', selectedCabinet);
|
||||
@@ -250,22 +250,22 @@ const SimpleUploadTest: React.FC = () => {
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
|
||||
// Choose endpoint based on upload type
|
||||
const endpoint = uploadType === 'new' ? '/simple-upload/files/upload' : '/database/files/upload';
|
||||
|
||||
|
||||
const result = await apiFetch(endpoint, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
console.log('Upload result:', result);
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `File uploaded successfully using ${uploadType === 'new' ? 'NEW' : 'OLD'} endpoint: ${file.name}`
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `File uploaded successfully using ${uploadType === 'new' ? 'NEW' : 'OLD'} endpoint: ${file.name}`
|
||||
});
|
||||
|
||||
|
||||
await loadFiles(selectedCabinet);
|
||||
e.target.value = '';
|
||||
} catch (error: unknown) {
|
||||
@@ -311,14 +311,14 @@ const SimpleUploadTest: React.FC = () => {
|
||||
|
||||
setSelectedFiles(files);
|
||||
setDirectoryStats(calculateDirectoryStats(files));
|
||||
|
||||
|
||||
const progress: UploadProgress[] = files.map(file => ({
|
||||
path: file.relativePath,
|
||||
size: file.size,
|
||||
status: 'queued',
|
||||
progress: 0
|
||||
}));
|
||||
|
||||
|
||||
setUploadProgress(progress);
|
||||
setShowUploadDialog(true);
|
||||
};
|
||||
@@ -327,61 +327,61 @@ const SimpleUploadTest: React.FC = () => {
|
||||
if (!selectedCabinet || selectedFiles.length === 0) return;
|
||||
|
||||
setIsUploading(true);
|
||||
|
||||
|
||||
try {
|
||||
const firstFilePath = selectedFiles[0].relativePath;
|
||||
const directoryName = firstFilePath.split('/')[0] || 'uploaded-folder';
|
||||
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('cabinet_id', selectedCabinet);
|
||||
formData.append('scope', 'teacher');
|
||||
formData.append('directory_name', directoryName);
|
||||
|
||||
|
||||
selectedFiles.forEach(file => {
|
||||
formData.append('files', file);
|
||||
});
|
||||
|
||||
|
||||
const relativePaths = selectedFiles.map(f => f.relativePath);
|
||||
formData.append('file_paths', JSON.stringify(relativePaths));
|
||||
|
||||
const result = await apiFetch('/simple-upload/files/upload-directory', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
|
||||
const result = await apiFetch('/simple-upload/files/upload-directory', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
|
||||
console.log('Directory upload result:', result);
|
||||
|
||||
|
||||
setUploadProgress(prev => prev.map(item => ({
|
||||
...item,
|
||||
status: 'done',
|
||||
progress: 100
|
||||
})));
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `Directory uploaded successfully: ${directoryName} (${selectedFiles.length} files)`
|
||||
|
||||
setMessage({
|
||||
type: 'success',
|
||||
text: `Directory uploaded successfully: ${directoryName} (${selectedFiles.length} files)`
|
||||
});
|
||||
|
||||
|
||||
await loadFiles(selectedCabinet);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
setShowUploadDialog(false);
|
||||
setIsUploading(false);
|
||||
setSelectedFiles([]);
|
||||
setUploadProgress([]);
|
||||
}, 2000);
|
||||
|
||||
|
||||
} catch (error: unknown) {
|
||||
console.error('Directory upload failed:', error);
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
setMessage({ type: 'error', text: `Directory upload failed: ${errorMessage}` });
|
||||
|
||||
|
||||
setUploadProgress(prev => prev.map(item => ({
|
||||
...item,
|
||||
status: 'error',
|
||||
error: String(error)
|
||||
})));
|
||||
|
||||
|
||||
setIsUploading(false);
|
||||
}
|
||||
};
|
||||
@@ -404,12 +404,12 @@ const SimpleUploadTest: React.FC = () => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('processing_type', 'basic');
|
||||
|
||||
|
||||
const result = await apiFetch(`/simple-upload/files/${fileId}/process-manual`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
|
||||
console.log('Manual processing result:', result);
|
||||
setMessage({ type: 'info', text: 'Manual processing triggered (not yet implemented)' });
|
||||
} catch (error: unknown) {
|
||||
@@ -434,7 +434,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
<Typography variant="h4" gutterBottom>
|
||||
🧪 Simple Upload Test Page
|
||||
</Typography>
|
||||
|
||||
|
||||
<Alert severity="info" sx={{ mb: 3 }}>
|
||||
<Typography variant="body2">
|
||||
This page tests the NEW simple upload system (no auto-processing) vs the OLD system (with auto-processing).
|
||||
@@ -452,8 +452,8 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{/* Upload Controls */}
|
||||
<Grid item xs={12} md={6}>
|
||||
<Card>
|
||||
<CardHeader
|
||||
title="Upload Controls"
|
||||
<CardHeader
|
||||
title="Upload Controls"
|
||||
avatar={<UploadIcon />}
|
||||
/>
|
||||
<CardContent>
|
||||
@@ -504,15 +504,15 @@ const SimpleUploadTest: React.FC = () => {
|
||||
Upload File
|
||||
</Button>
|
||||
|
||||
<input
|
||||
<input
|
||||
ref={dirInputRef}
|
||||
type="file"
|
||||
style={{ display: 'none' }}
|
||||
type="file"
|
||||
style={{ display: 'none' }}
|
||||
{...({ webkitdirectory: '' } as any)}
|
||||
multiple
|
||||
multiple
|
||||
onChange={handleFallbackDirectorySelect}
|
||||
/>
|
||||
|
||||
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<FolderOpenIcon />}
|
||||
@@ -552,8 +552,8 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{/* System Info */}
|
||||
<Grid item xs={12} md={6}>
|
||||
<Card>
|
||||
<CardHeader
|
||||
title="System Info"
|
||||
<CardHeader
|
||||
title="System Info"
|
||||
avatar={<InfoIcon />}
|
||||
/>
|
||||
<CardContent>
|
||||
@@ -594,8 +594,8 @@ const SimpleUploadTest: React.FC = () => {
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
<strong>Upload Mode:</strong>
|
||||
</Typography>
|
||||
<Chip
|
||||
label={uploadType === 'new' ? 'NEW (Simple)' : 'OLD (Auto-Processing)'}
|
||||
<Chip
|
||||
label={uploadType === 'new' ? 'NEW (Simple)' : 'OLD (Auto-Processing)'}
|
||||
color={uploadType === 'new' ? 'success' : 'warning'}
|
||||
/>
|
||||
</Box>
|
||||
@@ -629,7 +629,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{/* File List */}
|
||||
<Grid item xs={12}>
|
||||
<Card>
|
||||
<CardHeader
|
||||
<CardHeader
|
||||
title={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
@@ -656,7 +656,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
sx={{ minWidth: 200 }}
|
||||
/>
|
||||
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 120 }}>
|
||||
<InputLabel>Sort by</InputLabel>
|
||||
<Select
|
||||
@@ -670,7 +670,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
<MenuItem value="processing_status">Status</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 100 }}>
|
||||
<InputLabel>Order</InputLabel>
|
||||
<Select
|
||||
@@ -682,7 +682,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
<MenuItem value="desc">Descending</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
|
||||
<FormControl size="small" sx={{ minWidth: 100 }}>
|
||||
<InputLabel>Per page</InputLabel>
|
||||
<Select
|
||||
@@ -702,12 +702,12 @@ const SimpleUploadTest: React.FC = () => {
|
||||
</Box>
|
||||
|
||||
{/* File List with Fixed Height */}
|
||||
<Box sx={{
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
borderRadius: 1,
|
||||
<Box sx={{
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
borderRadius: 1,
|
||||
height: 400, // Fixed height
|
||||
overflow: 'auto'
|
||||
overflow: 'auto'
|
||||
}}>
|
||||
{loading ? (
|
||||
<Box sx={{ p: 2 }}>
|
||||
@@ -757,9 +757,9 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{file.name}
|
||||
</Typography>
|
||||
{file.is_directory && <Chip label="Directory" size="small" />}
|
||||
<Chip
|
||||
label={file.processing_status || 'unknown'}
|
||||
size="small"
|
||||
<Chip
|
||||
label={file.processing_status || 'unknown'}
|
||||
size="small"
|
||||
color={getStatusColor(file.processing_status)}
|
||||
/>
|
||||
</Box>
|
||||
@@ -789,7 +789,7 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{pagination && pagination.total_pages > 1 && (
|
||||
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'center' }}>
|
||||
<Stack spacing={2} alignItems="center">
|
||||
<Pagination
|
||||
<Pagination
|
||||
count={pagination.total_pages}
|
||||
page={pagination.page}
|
||||
onChange={(event, value) => setCurrentPage(value)}
|
||||
@@ -817,18 +817,18 @@ const SimpleUploadTest: React.FC = () => {
|
||||
{isUploading && <LinearProgress sx={{ flexGrow: 1, ml: 2 }} />}
|
||||
</Box>
|
||||
</DialogTitle>
|
||||
|
||||
|
||||
<DialogContent>
|
||||
{directoryStats && (
|
||||
<Alert severity="info" sx={{ mb: 2 }}>
|
||||
<Typography variant="body2">
|
||||
<strong>{directoryStats.fileCount} files</strong> in{' '}
|
||||
<strong>{directoryStats.directoryCount} folders</strong><br/>
|
||||
<strong>{directoryStats.directoryCount} folders</strong><br />
|
||||
Total size: <strong>{directoryStats.formattedSize}</strong>
|
||||
</Typography>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
|
||||
<Paper variant="outlined" sx={{ p: 2, maxHeight: 300, overflow: 'auto' }}>
|
||||
{uploadProgress.map((item, i) => (
|
||||
<Box key={i} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', py: 0.5 }}>
|
||||
@@ -838,31 +838,31 @@ const SimpleUploadTest: React.FC = () => {
|
||||
<Typography variant="body2" sx={{ mr: 2, minWidth: 80 }}>
|
||||
{formatFileSize(item.size)}
|
||||
</Typography>
|
||||
<Chip
|
||||
<Chip
|
||||
label={item.status}
|
||||
size="small"
|
||||
color={
|
||||
item.status === 'done' ? 'success' :
|
||||
item.status === 'error' ? 'error' :
|
||||
item.status === 'uploading' ? 'primary' : 'default'
|
||||
item.status === 'done' ? 'success' :
|
||||
item.status === 'error' ? 'error' :
|
||||
item.status === 'uploading' ? 'primary' : 'default'
|
||||
}
|
||||
icon={
|
||||
item.status === 'done' ? <SuccessIcon /> :
|
||||
item.status === 'error' ? <ErrorIcon /> : undefined
|
||||
item.status === 'done' ? <SuccessIcon /> :
|
||||
item.status === 'error' ? <ErrorIcon /> : undefined
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Paper>
|
||||
</DialogContent>
|
||||
|
||||
|
||||
<DialogActions>
|
||||
<Button onClick={() => setShowUploadDialog(false)} disabled={isUploading}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={startDirectoryUpload}
|
||||
variant="contained"
|
||||
<Button
|
||||
onClick={startDirectoryUpload}
|
||||
variant="contained"
|
||||
disabled={isUploading || selectedFiles.length === 0}
|
||||
>
|
||||
{isUploading ? 'Uploading...' : 'Start Upload'}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { HEADER_HEIGHT } from './Layout';
|
||||
|
||||
const SearxngPage: React.FC = () => {
|
||||
return (
|
||||
<Box sx={{
|
||||
<Box sx={{
|
||||
position: 'absolute',
|
||||
top: HEADER_HEIGHT,
|
||||
left: 0,
|
||||
|
||||
Reference in New Issue
Block a user