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" ;
61import { If } from "@mendix/widget-plugin-component-kit/If" ;
2+ import classNames from "classnames" ;
3+ import { ChangeEvent , createElement , ReactElement , useEffect , useRef , useState } from "react" ;
74import { 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" ;
98
109type imageListType = {
1110 id : string ;
1211 url : string ;
1312 thumbnailUrl ?: string ;
1413} ;
1514
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" > {
1724 onSubmit ( value : imageConfigType ) : void ;
1825 onClose ( ) : void ;
1926 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 ;
7928}
8029
8130export default function ImageDialog ( props : ImageDialogProps ) : ReactElement {
82- const { onClose, defaultValue, onSubmit, imageSource } = props ;
31+ const { onClose, defaultValue, onSubmit, imageSource, imageSourceContent , enableDefaultUpload } = props ;
8332 const [ activeTab , setActiveTab ] = useState ( "general" ) ;
8433 const [ selectedImageEntity , setSelectedImageEntity ] = useState < imageListType > ( ) ;
34+ const imageUploadElementRef = useRef < HTMLDivElement > ( null ) ;
8535 // disable embed tab if it is about modifying current video
8636 const disableEmbed =
8737 ( defaultValue ?. src && defaultValue . src . length > 0 ) ||
@@ -117,11 +67,30 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
11767 setActiveTab ( "general" ) ;
11868 } ;
11969
70+ const handleImageSelected = ( event : CustomEvent < imageListType > ) : void => {
71+ const image = event . detail ;
72+ onEmbedSelected ( image ) ;
73+ } ;
74+
12075 const onEmbedDeleted = ( ) : void => {
12176 setFormState ( { ...formState , entityGuid : undefined , src : undefined } ) ;
12277 setSelectedImageEntity ( undefined ) ;
12378 } ;
12479
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+
12594 return (
12695 < DialogContent className = "video-dialog" >
12796 < DialogHeader onClose = { onClose } > { activeTab === "general" ? "Insert/Edit" : "Embed" } Images</ DialogHeader >
@@ -149,12 +118,12 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
149118 e . preventDefault ( ) ;
150119 } }
151120 >
152- < a href = "#" > From datasource </ a >
121+ < a href = "#" > Attachments </ a >
153122 </ li >
154123 </ ul >
155124 </ div >
156125 ) }
157- < div >
126+ < div ref = { imageUploadElementRef } >
158127 < If condition = { activeTab === "general" } >
159128 < FormControl label = "Source" >
160129 { defaultValue ?. src ? (
@@ -174,15 +143,15 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
174143 < span className = "icons icon-Delete" onClick = { onEmbedDeleted } > </ span >
175144 </ span >
176145 </ div >
177- ) : (
146+ ) : enableDefaultUpload ? (
178147 < input
179148 name = "files"
180149 className = "form-control mx-textarea-input mx-textarea-noresize code-input"
181150 type = "file"
182151 accept = { IMG_MIME_TYPES . join ( ", " ) }
183152 onChange = { onFileChange }
184153 > </ input >
185- ) }
154+ ) : undefined }
186155 </ FormControl >
187156 < FormControl label = "Alternative description" >
188157 < input
@@ -217,7 +186,7 @@ export default function ImageDialog(props: ImageDialogProps): ReactElement {
217186 < DialogFooter onSubmit = { ( ) => onSubmit ( formState ) } onClose = { onClose } > </ DialogFooter >
218187 </ If >
219188 < If condition = { activeTab === "embed" } >
220- < EntityImageDialog { ... props } onSelect = { onEmbedSelected } / >
189+ < div > { imageSourceContent } </ div >
221190 </ If >
222191 </ div >
223192 </ DialogBody >
0 commit comments