@@ -10,9 +10,11 @@ import { useDropzone } from 'react-dropzone';
10
10
import { AttachmentHelper } from '@/features/utils/attachment-helper' ;
11
11
import { useDebounceCallback } from '@/hooks/use-debounce-callback' ;
12
12
import { DropZone } from './dropzone' ;
13
+ import { DriveAttachmentPicker , DriveFile } from './drive-attachment-picker' ;
14
+ import { Icon } from '@gouvfr-lasuite/ui-kit' ;
13
15
14
16
interface AttachmentUploaderProps {
15
- initialAttachments ?: readonly Attachment [ ] ;
17
+ initialAttachments ?: ( DriveFile | Attachment ) [ ] ;
16
18
onChange : ( ) => void ;
17
19
}
18
20
@@ -25,7 +27,7 @@ export const AttachmentUploader = ({
25
27
const form = useFormContext ( ) ;
26
28
const { t, i18n } = useTranslation ( ) ;
27
29
const { selectedMailbox } = useMailboxContext ( ) ;
28
- const [ attachments , setAttachments ] = useState < Attachment [ ] > ( initialAttachments . map ( ( a ) => ( { ...a , state : 'idle' } ) ) ) ;
30
+ const [ attachments , setAttachments ] = useState < ( DriveFile | Attachment ) [ ] > ( initialAttachments . map ( ( a ) => ( { ...a , state : 'idle' } ) ) ) ;
29
31
const [ uploadingQueue , setUploadingQueue ] = useState < File [ ] > ( [ ] ) ;
30
32
const [ failedQueue , setFailedQueue ] = useState < File [ ] > ( [ ] ) ;
31
33
const { mutateAsync : uploadBlob } = useBlobUploadCreate ( ) ;
@@ -46,14 +48,18 @@ export const AttachmentUploader = ({
46
48
}
47
49
const removeToUploadingQueue = ( attachments : File [ ] ) => setUploadingQueue ( uploadingQueue => removeToQueue ( uploadingQueue , attachments ) ) ;
48
50
const removeToFailedQueue = ( attachments : File [ ] ) => setFailedQueue ( failedQueue => removeToQueue ( failedQueue , attachments ) ) ;
49
- const appendToAttachments = ( newAttachments : Attachment [ ] ) => {
51
+ const appendToAttachments = ( newAttachments : ( DriveFile | Attachment ) [ ] ) => {
50
52
// Append attachments to the end of the list and sort by descending created_at
51
53
setAttachments (
52
54
attachments => [ ...attachments , ...newAttachments ] . sort ( ( a , b ) => Number ( new Date ( b . created_at ) ) - Number ( new Date ( a . created_at ) ) )
53
55
) ;
54
56
}
55
- const removeToAttachments = ( entries : Attachment [ ] ) => {
56
- setAttachments ( attachments => attachments . filter ( ( a ) => ! entries . some ( e => e . blobId === a . blobId ) ) ) ;
57
+
58
+ const removeToAttachments = ( entries : ( DriveFile | Attachment ) [ ] ) => {
59
+ setAttachments ( attachments => attachments . filter ( ( a ) => ! entries . some ( e => {
60
+ if ( 'blobId' in a && 'blobId' in e ) return e . blobId === a . blobId ;
61
+ return e . id === a . id ;
62
+ } ) ) ) ;
57
63
}
58
64
59
65
/**
@@ -94,18 +100,24 @@ export const AttachmentUploader = ({
94
100
if ( ! hasClickInBucketList ) {
95
101
getRootProps ( ) . onClick ?.( event ) ;
96
102
}
103
+ }
97
104
105
+ const handleDriveAttachmentPick = ( attachments : DriveFile [ ] ) => {
106
+ appendToAttachments ( attachments ) ;
98
107
}
99
108
100
109
/**
101
- * Update the form value when the attachments change
102
- * Trigger the onChange callback to update the form each 1s
110
+ * Update the form value when the attachments change.
103
111
*/
104
112
useEffect ( ( ) => {
105
- form . setValue ( 'attachments' , attachments . map ( ( attachment ) => ( {
113
+ // Only keep local attachments
114
+ const localAttachments = attachments . filter ( attachment => 'blobId' in attachment ) ;
115
+ const driveAttachments = attachments . filter ( attachment => 'url' in attachment ) ;
116
+ form . setValue ( 'attachments' , localAttachments . map ( ( attachment ) => ( {
106
117
blobId : attachment . blobId ,
107
118
name : attachment . name
108
119
} ) ) , { shouldDirty : true } ) ;
120
+ form . setValue ( 'driveAttachments' , driveAttachments , { shouldDirty : true } ) ;
109
121
if ( form . formState . dirtyFields . attachments ) {
110
122
debouncedOnChange ( ) ;
111
123
}
@@ -122,11 +134,12 @@ export const AttachmentUploader = ({
122
134
< div className = "attachment-uploader__input" >
123
135
< Button
124
136
color = "tertiary"
125
- icon = { < span className = "material-icons" > attach_file</ span > }
137
+ icon = { < Icon name = " attach_file" / >}
126
138
type = "button"
127
139
>
128
140
{ t ( "message_form.attachments_uploader.input_label" ) }
129
141
</ Button >
142
+ < DriveAttachmentPicker onPick = { handleDriveAttachmentPick } />
130
143
< p className = "attachment-uploader__input__helper-text" >
131
144
{ t ( "message_form.attachments_uploader.or_drag_and_drop" ) }
132
145
</ p >
@@ -154,7 +167,11 @@ export const AttachmentUploader = ({
154
167
< AttachmentItem key = { `uploading-${ entry . name } -${ entry . size } -${ entry . lastModified } ` } attachment = { entry } isLoading />
155
168
) ) }
156
169
{ attachments . map ( ( entry ) => (
157
- < AttachmentItem key = { entry . blobId } attachment = { entry } onDelete = { ( ) => removeToAttachments ( [ entry ] ) } />
170
+ < AttachmentItem
171
+ key = { 'blobId' in entry ? entry . blobId : entry . id }
172
+ attachment = { entry }
173
+ onDelete = { ( ) => removeToAttachments ( [ entry ] ) }
174
+ />
158
175
) ) }
159
176
</ div >
160
177
</ div >
0 commit comments