1
- import { ChangeEvent , createElement , Fragment , ReactElement , useEffect , useRef , useState } from "react" ;
2
- import { type imageConfigType } from "../../utils/formats" ;
3
- import { DialogBody , DialogContent , DialogFooter , DialogHeader , FormControl } from "./DialogContent" ;
4
- import { IMG_MIME_TYPES } from "../CustomToolbars/constants" ;
5
- import classNames from "classnames" ;
6
1
import { If } from "@mendix/widget-plugin-component-kit/If" ;
2
+ import classNames from "classnames" ;
3
+ import { ChangeEvent , createElement , ReactElement , useEffect , useRef , useState } from "react" ;
7
4
import { RichTextContainerProps } from "../../../typings/RichTextProps" ;
8
- import { fetchDocumentUrl , fetchImageThumbnail } from "../../utils/mx-data" ;
5
+ import { type imageConfigType } from "../../utils/formats" ;
6
+ import { IMG_MIME_TYPES } from "../CustomToolbars/constants" ;
7
+ import { DialogBody , DialogContent , DialogFooter , DialogHeader , FormControl } from "./DialogContent" ;
9
8
10
9
type imageListType = {
11
10
id : string ;
12
11
url : string ;
13
12
thumbnailUrl ?: string ;
14
13
} ;
15
14
16
- export interface ImageDialogProps extends Pick < RichTextContainerProps , "imageSource" > {
15
+ interface CustomEvent < T = any > extends Event {
16
+ /**
17
+ * Returns any custom data event was created with. Typically used for synthetic events.
18
+ */
19
+ readonly detail : T ;
20
+ initCustomEvent ( typeArg : string , canBubbleArg : boolean , cancelableArg : boolean , detailArg : T ) : void ;
21
+ }
22
+
23
+ export interface ImageDialogProps extends Pick < RichTextContainerProps , "imageSource" | "imageSourceContent" > {
17
24
onSubmit ( value : imageConfigType ) : void ;
18
25
onClose ( ) : void ;
19
26
defaultValue ?: imageConfigType ;
20
- }
21
-
22
- export interface EntityImageDialogProps extends ImageDialogProps {
23
- onSelect ( image : imageListType ) : void ;
24
- }
25
-
26
- function EntityImageDialog ( props : EntityImageDialogProps ) : ReactElement {
27
- const { imageSource, onSelect } = props ;
28
- const [ images , setImages ] = useState < imageListType [ ] > ( [ ] ) ;
29
-
30
- useEffect ( ( ) => {
31
- if ( imageSource && imageSource . items && imageSource . items . length > 0 && imageSource . status === "available" ) {
32
- const newImages : imageListType [ ] = imageSource . items . map ( item => {
33
- const guid = item . id ;
34
- const src = fetchDocumentUrl ( item . id ) ;
35
- return {
36
- id : guid ,
37
- url : src
38
- } ;
39
- } ) ;
40
-
41
- Promise . all (
42
- newImages . map ( async image => {
43
- if ( image . url ) {
44
- const thumbnailUrl = await fetchImageThumbnail ( image . url ) ;
45
- console . log ( "Fetched thumbnail for image:" , image . id , thumbnailUrl ) ;
46
- return { ...image , thumbnailUrl } ;
47
- }
48
- return image ;
49
- } )
50
- ) . then ( fetchedImages => {
51
- setImages ( fetchedImages ) ;
52
- } ) ;
53
- }
54
- } , [ imageSource , imageSource ?. status , imageSource ?. items ] ) ;
55
-
56
- if ( ! imageSource || imageSource . status !== "available" ) {
57
- return < div className = "mx-text mx-text-error" > Image source is not available</ div > ;
58
- }
59
-
60
- return (
61
- < Fragment >
62
- { images . length > 0 ? (
63
- < div className = "mx-image-dialog-list" >
64
- { images . map ( image => (
65
- < div key = { image . id } className = "mx-image-dialog-item" onClick = { ( ) => onSelect ( image ) } >
66
- < img
67
- src = { image . thumbnailUrl || image . url }
68
- alt = { image . id }
69
- className = "mx-image-dialog-thumbnail"
70
- />
71
- </ div >
72
- ) ) }
73
- </ div >
74
- ) : (
75
- < div className = "mx-text mx-text-error" > No images found in the datasource</ div >
76
- ) }
77
- </ Fragment >
78
- ) ;
27
+ enableDefaultUpload ?: boolean ;
79
28
}
80
29
81
30
export default function ImageDialog ( props : ImageDialogProps ) : ReactElement {
82
- const { onClose, defaultValue, onSubmit, imageSource } = props ;
31
+ const { onClose, defaultValue, onSubmit, imageSource, imageSourceContent , enableDefaultUpload } = props ;
83
32
const [ activeTab , setActiveTab ] = useState ( "general" ) ;
84
33
const [ selectedImageEntity , setSelectedImageEntity ] = useState < imageListType > ( ) ;
34
+ const imageUploadElementRef = useRef < HTMLDivElement > ( null ) ;
85
35
// disable embed tab if it is about modifying current video
86
36
const disableEmbed =
87
37
( defaultValue ?. src && defaultValue . src . length > 0 ) ||
@@ -117,11 +67,30 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
117
67
setActiveTab ( "general" ) ;
118
68
} ;
119
69
70
+ const handleImageSelected = ( event : CustomEvent < imageListType > ) : void => {
71
+ const image = event . detail ;
72
+ onEmbedSelected ( image ) ;
73
+ } ;
74
+
120
75
const onEmbedDeleted = ( ) : void => {
121
76
setFormState ( { ...formState , entityGuid : undefined , src : undefined } ) ;
122
77
setSelectedImageEntity ( undefined ) ;
123
78
} ;
124
79
80
+ useEffect ( ( ) => {
81
+ const imgRef = imageUploadElementRef . current ;
82
+
83
+ // const element = ref.current;
84
+ if ( imgRef !== null ) {
85
+ imgRef . addEventListener ( "imageSelected" , handleImageSelected ) ;
86
+ }
87
+ // element.addEventListener("click", handleClick);
88
+
89
+ return ( ) => {
90
+ imgRef ?. removeEventListener ( "imageSelected" , handleImageSelected ) ;
91
+ } ;
92
+ } , [ imageUploadElementRef . current ] ) ;
93
+
125
94
return (
126
95
< DialogContent className = "video-dialog" >
127
96
< DialogHeader onClose = { onClose } > { activeTab === "general" ? "Insert/Edit" : "Embed" } Images</ DialogHeader >
@@ -149,12 +118,12 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
149
118
e . preventDefault ( ) ;
150
119
} }
151
120
>
152
- < a href = "#" > From datasource </ a >
121
+ < a href = "#" > Attachments </ a >
153
122
</ li >
154
123
</ ul >
155
124
</ div >
156
125
) }
157
- < div >
126
+ < div ref = { imageUploadElementRef } >
158
127
< If condition = { activeTab === "general" } >
159
128
< FormControl label = "Source" >
160
129
{ defaultValue ?. src ? (
@@ -174,15 +143,15 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
174
143
< span className = "icons icon-Delete" onClick = { onEmbedDeleted } > </ span >
175
144
</ span >
176
145
</ div >
177
- ) : (
146
+ ) : enableDefaultUpload ? (
178
147
< input
179
148
name = "files"
180
149
className = "form-control mx-textarea-input mx-textarea-noresize code-input"
181
150
type = "file"
182
151
accept = { IMG_MIME_TYPES . join ( ", " ) }
183
152
onChange = { onFileChange }
184
153
> </ input >
185
- ) }
154
+ ) : undefined }
186
155
</ FormControl >
187
156
< FormControl label = "Alternative description" >
188
157
< input
@@ -217,7 +186,7 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
217
186
< DialogFooter onSubmit = { ( ) => onSubmit ( formState ) } onClose = { onClose } > </ DialogFooter >
218
187
</ If >
219
188
< If condition = { activeTab === "embed" } >
220
- < EntityImageDialog { ... props } onSelect = { onEmbedSelected } / >
189
+ < div > { imageSourceContent } </ div >
221
190
</ If >
222
191
</ div >
223
192
</ DialogBody >
0 commit comments