@@ -4,14 +4,17 @@ import WebViewerModuleClient from "../clients/WebViewerModuleClient";
44
55export interface InputProps {
66 containerHeight : string ;
7- file ?: string ;
7+ fileUrl ?: string ;
88 fileId ?: string ;
99 enableFilePicker ?: boolean ;
1010 annotationUser ?: string ;
1111 accessibleMode ?: boolean ;
1212 enableMeasurement ?: boolean ;
1313 enableRedaction ?: boolean ;
1414 enableAnnotations ?: boolean ;
15+ xfdfAttribute ?: any ;
16+ enableXfdfExportButton : boolean ;
17+ enableAutoXfdfExport : boolean ;
1518 loadAsPDF ?: boolean ;
1619 highContrastMode ?: boolean ;
1720 notesInLeftPanel ?: boolean ;
@@ -90,6 +93,7 @@ const PDFViewer: React.FC<InputProps> = props => {
9093 if ( props . enableDocumentUpdates ) {
9194 header . push ( {
9295 type : "actionButton" ,
96+ title : "Save document" ,
9397 img : '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>' ,
9498 onClick : async ( ) => {
9599 // Export annotation XFDF
@@ -102,7 +106,9 @@ const PDFViewer: React.FC<InputProps> = props => {
102106 const fileData = await Core . documentViewer . getDocument ( ) . getFileData ( { xfdfString } ) ;
103107
104108 // Send it merged with the document data to REST API to update
105- const updateTask = currentFileId ? WebViewerModuleClient . updateFile ( props . fileId || "" , fileData ) : WebViewerModuleClient . saveFile ( fileData ) ;
109+ const updateTask = currentFileId
110+ ? WebViewerModuleClient . updateFile ( props . fileId || "" , fileData )
111+ : WebViewerModuleClient . saveFile ( fileData ) ;
106112
107113 // Add minimum artificial delay to make it look like work is being done
108114 // Otherwise, requests may complete too fast
@@ -128,9 +134,42 @@ const PDFViewer: React.FC<InputProps> = props => {
128134 } ) ;
129135 }
130136 } ) ;
137+
138+ if ( props . xfdfAttribute ) {
139+ if ( props . xfdfAttribute . readOnly && ( props . enableXfdfExportButton || props . enableAutoXfdfExport ) ) {
140+ console . warn (
141+ "The XFDF attribute is read-only. Please check the user permissions or allow the data source to be editable."
142+ ) ;
143+ } else {
144+ const updateXfdfAttribute = async ( ) : Promise < void > => {
145+ const doc = Core . documentViewer . getDocument ( ) ;
146+ if ( ! doc ) {
147+ return ;
148+ }
149+
150+ const xfdfString = await Core . annotationManager . exportAnnotations ( ) ;
151+ props . xfdfAttribute . setValue ( xfdfString ) ;
152+ } ;
153+
154+ if ( props . enableXfdfExportButton ) {
155+ UI . setHeaderItems ( header => {
156+ header . push ( {
157+ type : "actionButton" ,
158+ title : "Save XFDF" ,
159+ img : '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>' ,
160+ onClick : updateXfdfAttribute
161+ } ) ;
162+ } ) ;
163+ }
164+
165+ if ( props . enableAutoXfdfExport ) {
166+ Core . annotationManager . addEventListener ( "annotationsChanged" , updateXfdfAttribute ) ;
167+ }
168+ }
169+ }
131170 } ) ;
132171
133- Core . documentViewer . addEventListener ( ' documentLoaded' , ( ) => {
172+ Core . documentViewer . addEventListener ( " documentLoaded" , ( ) => {
134173 documentLoadCount ++ ;
135174 if ( documentLoadCount > 1 && currentFileId ) {
136175 currentFileId = null ;
@@ -143,10 +182,10 @@ const PDFViewer: React.FC<InputProps> = props => {
143182
144183 // Attributes in Mendix may update later, this will load the file after the update
145184 useEffect ( ( ) => {
146- if ( wvInstance && props . file ) {
147- wvInstance . UI . loadDocument ( props . file ) ;
185+ if ( wvInstance && props . fileUrl ) {
186+ wvInstance . UI . loadDocument ( props . fileUrl ) ;
148187 }
149- } , [ wvInstance , props . file ] ) ;
188+ } , [ wvInstance , props . fileUrl ] ) ;
150189
151190 // Attributes in Mendix may update later, this will load the file after the update
152191 useEffect ( ( ) => {
0 commit comments