backend
This commit is contained in:
parent
a7c944621e
commit
8e2ac42410
@ -370,6 +370,9 @@ const documentSlice = createSlice({
|
|||||||
state.error = action.error.message || 'Erreur lors de la création du dossier par défaut'
|
state.error = action.error.message || 'Erreur lors de la création du dossier par défaut'
|
||||||
})
|
})
|
||||||
.addCase(loadFolderResults.fulfilled, (state, action) => {
|
.addCase(loadFolderResults.fulfilled, (state, action) => {
|
||||||
|
console.log(`[STORE] loadFolderResults.fulfilled appelé avec:`, action.payload)
|
||||||
|
console.log(`[STORE] Nombre de résultats reçus:`, action.payload.results?.length || 0)
|
||||||
|
|
||||||
state.folderResults = action.payload.results
|
state.folderResults = action.payload.results
|
||||||
state.currentFolderHash = action.payload.folderHash
|
state.currentFolderHash = action.payload.folderHash
|
||||||
state.loading = false
|
state.loading = false
|
||||||
@ -379,17 +382,31 @@ const documentSlice = createSlice({
|
|||||||
state.hasPending = action.payload.hasPending || false
|
state.hasPending = action.payload.hasPending || false
|
||||||
|
|
||||||
// Convertir les résultats en documents pour la compatibilité
|
// Convertir les résultats en documents pour la compatibilité
|
||||||
state.documents = action.payload.results.map((result, index) => ({
|
if (action.payload.results && action.payload.results.length > 0) {
|
||||||
id: result.fileHash,
|
state.documents = action.payload.results.map((result, index) => {
|
||||||
name: result.document.fileName,
|
console.log(`[STORE] Mapping résultat ${index}:`, {
|
||||||
mimeType: result.document.mimeType,
|
fileHash: result.fileHash,
|
||||||
size: 0, // Taille non disponible dans la structure actuelle
|
fileName: result.document?.fileName,
|
||||||
uploadDate: new Date(result.document.uploadTimestamp),
|
mimeType: result.document?.mimeType
|
||||||
status: 'completed' as const,
|
})
|
||||||
previewUrl: `blob:folder-${result.fileHash}`
|
|
||||||
}))
|
return {
|
||||||
|
id: result.fileHash,
|
||||||
|
name: result.document.fileName,
|
||||||
|
mimeType: result.document.mimeType,
|
||||||
|
size: 0, // Taille non disponible dans la structure actuelle
|
||||||
|
uploadDate: new Date(result.document.uploadTimestamp),
|
||||||
|
status: 'completed' as const,
|
||||||
|
previewUrl: `blob:folder-${result.fileHash}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log(`[STORE] Aucun résultat à mapper`)
|
||||||
|
state.documents = []
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`[STORE] Dossier chargé: ${action.payload.results.length} résultats, ${action.payload.pending?.length || 0} pending`)
|
console.log(`[STORE] Dossier chargé: ${action.payload.results.length} résultats, ${action.payload.pending?.length || 0} pending`)
|
||||||
|
console.log(`[STORE] Documents finaux:`, state.documents.length)
|
||||||
console.log(`[STORE] Documents mappés:`, state.documents.map(d => ({ id: d.id, name: d.name, status: d.status })))
|
console.log(`[STORE] Documents mappés:`, state.documents.map(d => ({ id: d.id, name: d.name, status: d.status })))
|
||||||
})
|
})
|
||||||
.addCase(loadFolderResults.pending, (state) => {
|
.addCase(loadFolderResults.pending, (state) => {
|
||||||
|
|||||||
@ -13,7 +13,14 @@ import {
|
|||||||
ListItemText,
|
ListItemText,
|
||||||
ListItemIcon,
|
ListItemIcon,
|
||||||
Divider,
|
Divider,
|
||||||
Card
|
Card,
|
||||||
|
TextField,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
IconButton,
|
||||||
|
Tooltip
|
||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import {
|
import {
|
||||||
CloudUpload,
|
CloudUpload,
|
||||||
@ -23,10 +30,13 @@ import {
|
|||||||
Visibility,
|
Visibility,
|
||||||
Description,
|
Description,
|
||||||
Image,
|
Image,
|
||||||
PictureAsPdf
|
PictureAsPdf,
|
||||||
|
FolderOpen,
|
||||||
|
Add,
|
||||||
|
ContentCopy
|
||||||
} from '@mui/icons-material'
|
} from '@mui/icons-material'
|
||||||
import { useAppDispatch, useAppSelector } from '../store'
|
import { useAppDispatch, useAppSelector } from '../store'
|
||||||
import { uploadFileToFolderThunk, loadFolderResults, removeDocument } from '../store/documentSlice'
|
import { uploadFileToFolderThunk, loadFolderResults, removeDocument, createDefaultFolderThunk, setCurrentFolderHash } from '../store/documentSlice'
|
||||||
import { Layout } from '../components/Layout'
|
import { Layout } from '../components/Layout'
|
||||||
import { FilePreview } from '../components/FilePreview'
|
import { FilePreview } from '../components/FilePreview'
|
||||||
import type { Document } from '../types'
|
import type { Document } from '../types'
|
||||||
@ -37,6 +47,42 @@ export default function UploadView() {
|
|||||||
|
|
||||||
console.log('🏠 [UPLOAD_VIEW] Component loaded, documents count:', documents.length)
|
console.log('🏠 [UPLOAD_VIEW] Component loaded, documents count:', documents.length)
|
||||||
const [previewDocument, setPreviewDocument] = useState<Document | null>(null)
|
const [previewDocument, setPreviewDocument] = useState<Document | null>(null)
|
||||||
|
const [dialogOpen, setDialogOpen] = useState(false)
|
||||||
|
const [newFolderHash, setNewFolderHash] = useState('')
|
||||||
|
|
||||||
|
// Fonction pour créer un nouveau dossier
|
||||||
|
const handleCreateNewFolder = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const result = await dispatch(createDefaultFolderThunk()).unwrap()
|
||||||
|
console.log('✅ [UPLOAD] Nouveau dossier créé:', result.folderHash)
|
||||||
|
setDialogOpen(false)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ [UPLOAD] Erreur lors de la création du dossier:', error)
|
||||||
|
}
|
||||||
|
}, [dispatch])
|
||||||
|
|
||||||
|
// Fonction pour charger un dossier existant
|
||||||
|
const handleLoadFolder = useCallback(async () => {
|
||||||
|
if (!newFolderHash.trim()) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
dispatch(setCurrentFolderHash(newFolderHash.trim()))
|
||||||
|
await dispatch(loadFolderResults(newFolderHash.trim())).unwrap()
|
||||||
|
console.log('✅ [UPLOAD] Dossier chargé:', newFolderHash.trim())
|
||||||
|
setDialogOpen(false)
|
||||||
|
setNewFolderHash('')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ [UPLOAD] Erreur lors du chargement du dossier:', error)
|
||||||
|
}
|
||||||
|
}, [dispatch, newFolderHash])
|
||||||
|
|
||||||
|
// Fonction pour copier le hash du dossier
|
||||||
|
const handleCopyFolderHash = useCallback(() => {
|
||||||
|
if (currentFolderHash) {
|
||||||
|
navigator.clipboard.writeText(currentFolderHash)
|
||||||
|
console.log('📋 [UPLOAD] Hash du dossier copié:', currentFolderHash)
|
||||||
|
}
|
||||||
|
}, [currentFolderHash])
|
||||||
|
|
||||||
const onDrop = useCallback(
|
const onDrop = useCallback(
|
||||||
async (acceptedFiles: File[]) => {
|
async (acceptedFiles: File[]) => {
|
||||||
@ -50,10 +96,10 @@ export default function UploadView() {
|
|||||||
try {
|
try {
|
||||||
console.log(`📤 [UPLOAD] Upload de ${file.name} dans le dossier ${currentFolderHash}`)
|
console.log(`📤 [UPLOAD] Upload de ${file.name} dans le dossier ${currentFolderHash}`)
|
||||||
await dispatch(uploadFileToFolderThunk({ file, folderHash: currentFolderHash })).unwrap()
|
await dispatch(uploadFileToFolderThunk({ file, folderHash: currentFolderHash })).unwrap()
|
||||||
|
|
||||||
// Recharger les résultats du dossier après upload
|
// Recharger les résultats du dossier après upload
|
||||||
await dispatch(loadFolderResults(currentFolderHash)).unwrap()
|
await dispatch(loadFolderResults(currentFolderHash)).unwrap()
|
||||||
|
|
||||||
console.log(`✅ [UPLOAD] ${file.name} uploadé avec succès`)
|
console.log(`✅ [UPLOAD] ${file.name} uploadé avec succès`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ [UPLOAD] Erreur lors du traitement de ${file.name}:`, error)
|
console.error(`❌ [UPLOAD] Erreur lors du traitement de ${file.name}:`, error)
|
||||||
@ -118,6 +164,57 @@ export default function UploadView() {
|
|||||||
Analyse de documents 4NK IA
|
Analyse de documents 4NK IA
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
{/* En-tête avec hash du dossier et boutons */}
|
||||||
|
<Box sx={{ mb: 3, p: 2, bgcolor: 'grey.50', borderRadius: 1, border: '1px solid', borderColor: 'grey.200' }}>
|
||||||
|
<Box display="flex" alignItems="center" justifyContent="space-between" flexWrap="wrap" gap={2}>
|
||||||
|
<Box display="flex" alignItems="center" gap={2}>
|
||||||
|
<Typography variant="h6" color="text.secondary">
|
||||||
|
Dossier actuel :
|
||||||
|
</Typography>
|
||||||
|
<Box display="flex" alignItems="center" gap={1}>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
sx={{
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
bgcolor: 'grey.100',
|
||||||
|
px: 1,
|
||||||
|
py: 0.5,
|
||||||
|
borderRadius: 1,
|
||||||
|
fontSize: '0.875rem'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentFolderHash || 'Aucun dossier sélectionné'}
|
||||||
|
</Typography>
|
||||||
|
{currentFolderHash && (
|
||||||
|
<Tooltip title="Copier le hash du dossier">
|
||||||
|
<IconButton size="small" onClick={handleCopyFolderHash}>
|
||||||
|
<ContentCopy fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box display="flex" gap={1}>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
onClick={handleCreateNewFolder}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
Nouveau dossier
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<FolderOpen />}
|
||||||
|
onClick={() => setDialogOpen(true)}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
Charger dossier
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
{/* Zone de drop */}
|
{/* Zone de drop */}
|
||||||
<Paper
|
<Paper
|
||||||
@ -244,6 +341,45 @@ export default function UploadView() {
|
|||||||
onClose={() => setPreviewDocument(null)}
|
onClose={() => setPreviewDocument(null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Dialogue pour charger un dossier existant */}
|
||||||
|
<Dialog open={dialogOpen} onClose={() => setDialogOpen(false)} maxWidth="sm" fullWidth>
|
||||||
|
<DialogTitle>
|
||||||
|
<Box display="flex" alignItems="center" gap={1}>
|
||||||
|
<FolderOpen />
|
||||||
|
Charger un dossier existant
|
||||||
|
</Box>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
|
||||||
|
Entrez le hash du dossier que vous souhaitez charger. Le hash est un identifiant unique de 32 caractères.
|
||||||
|
</Typography>
|
||||||
|
<TextField
|
||||||
|
autoFocus
|
||||||
|
margin="dense"
|
||||||
|
label="Hash du dossier"
|
||||||
|
placeholder="ex: 0e7ae08a4f14f3154be1bd69d5617c74"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={newFolderHash}
|
||||||
|
onChange={(e) => setNewFolderHash(e.target.value)}
|
||||||
|
sx={{ fontFamily: 'monospace' }}
|
||||||
|
helperText="Le hash doit contenir exactement 32 caractères hexadécimaux"
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setDialogOpen(false)}>
|
||||||
|
Annuler
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleLoadFolder}
|
||||||
|
variant="contained"
|
||||||
|
disabled={!newFolderHash.trim() || newFolderHash.trim().length !== 32}
|
||||||
|
>
|
||||||
|
Charger le dossier
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user