2024-01-28 19:14:53 +01:00
import { Link } from "react-router-dom" ;
2024-02-25 20:55:48 +01:00
import { BaseSyntheticEvent , createContext , useRef , useState } from "react" ;
2024-02-04 17:01:50 +01:00
import { Operator } from "@stirling-pdf/shared-operations/src/functions" ;
import i18next from "i18next" ;
2024-02-23 23:48:03 +01:00
import Joi from "@stirling-tools/joi" ;
import { BuildFields } from "../components/fields/BuildFields" ;
2024-02-25 20:55:48 +01:00
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor" ;
import { PdfFile , RepresentationType } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile" ;
import { Action } from "@stirling-pdf/shared-operations/declarations/Action" ;
import { JoiPDFFileSchema } from "@stirling-pdf/shared-operations/src/wrappers/PdfFileJoi" ;
2024-01-28 19:14:53 +01:00
function Dynamic() {
2024-02-23 23:48:03 +01:00
const [ schemaDescription , setSchemaDescription ] = useState < Joi.Description > ( ) ;
2024-02-25 20:55:48 +01:00
const operators = listOperatorNames ( ) ;
const activeOperator = useRef < typeof Operator > ( ) ;
2024-02-05 13:28:46 -05:00
2024-01-28 19:14:53 +01:00
function selectionChanged ( s : BaseSyntheticEvent ) {
const selectedValue = s . target . value ;
2024-02-23 23:48:03 +01:00
if ( selectedValue == "none" ) {
setSchemaDescription ( undefined ) ;
return ;
}
2024-02-04 17:01:50 +01:00
2024-02-25 20:55:48 +01:00
i18next . loadNamespaces ( selectedValue , ( err , t ) = > {
2024-02-04 17:01:50 +01:00
if ( err ) throw err ;
const LoadingModule = import ( ` @stirling-pdf/shared-operations/src/functions/ ${ selectedValue } ` ) as Promise < { [ key : string ] : typeof Operator } > ;
LoadingModule . then ( ( Module ) = > {
const Operator = Module [ capitalizeFirstLetter ( selectedValue ) ] ;
2024-02-05 12:15:01 -05:00
const description = Operator . schema . describe ( ) ;
2024-02-25 20:55:48 +01:00
activeOperator . current = Operator ;
// This will update children
setSchemaDescription ( description ) ;
2024-02-05 13:28:46 -05:00
} ) ;
2024-02-04 17:01:50 +01:00
} ) ;
}
2024-02-25 20:55:48 +01:00
function formDataToObject ( formData : FormData ) : Record < string , string > {
const result : Record < string , string > = { } ;
formData . forEach ( ( value , key ) = > {
result [ key ] = value . toString ( ) ;
} ) ;
return result ;
}
async function handleSubmit ( e : BaseSyntheticEvent ) {
if ( ! activeOperator . current ) {
throw new Error ( "Please select an Operator in the Dropdown" ) ;
}
const formData = new FormData ( e . target ) ;
const action : Action = { type : activeOperator . current . constructor . name , values : formDataToObject ( formData ) } ;
// Validate PDF File
// Createing the pdffile before validation because joi cant handle it for some reason and I can't fix the underlying issue / I want to make progress, wasted like 3 hours on this already. TODO: The casting should be done in JoiPDFFileSchema.ts if done correctly...
const files = ( document . getElementById ( "pdfFile" ) as HTMLInputElement ) . files ;
const inputs : PdfFile [ ] = [ ] ;
if ( files ) {
const filesArray : File [ ] = Array . from ( files as any ) ;
for ( let i = 0 ; i < files . length ; i ++ ) {
const file = filesArray [ i ] ;
if ( file ) {
console . log ( new Uint8Array ( await file . arrayBuffer ( ) ) ) ;
inputs . push ( new PdfFile (
file . name . replace ( /\.[^/.]+$/ , "" ) , // Strip Extension
new Uint8Array ( await file . arrayBuffer ( ) ) ,
RepresentationType . Uint8Array
) ) ;
}
else
throw new Error ( "This should not happen. Contact maintainers." ) ;
}
}
const pdfValidationResults = await JoiPDFFileSchema . validate ( inputs ) ;
if ( pdfValidationResults . error ) {
console . log ( { error : "PDF validation failed" , details : pdfValidationResults.error.message } ) ;
}
const pdfFiles : PdfFile [ ] = pdfValidationResults . value ;
// Validate Action Values
const actionValidationResults = activeOperator . current . schema . validate ( { input : pdfFiles , values : action.values } ) ;
if ( actionValidationResults . error ) {
console . log ( { error : "Value validation failed" , details : actionValidationResults.error.message } ) ;
return ;
}
action . values = pdfValidationResults . value . values ;
const operation = new activeOperator . current ( action ) ;
operation . run ( pdfValidationResults . value , ( progress ) = > { } ) . then ( pdfFiles = > {
console . log ( "Done" ) ;
} ) ;
} ;
2024-02-04 17:01:50 +01:00
function capitalizeFirstLetter ( string : String ) {
return string . charAt ( 0 ) . toUpperCase ( ) + string . slice ( 1 ) ;
2024-01-28 19:14:53 +01:00
}
return (
< div >
< h2 > Dynamic test page for operators < / h2 >
< input type = "file" id = "pdfFile" accept = ".pdf" multiple / >
< br / >
< select id = "pdfOptions" onChange = { selectionChanged } >
< option value = "none" > none < / option >
2024-02-05 13:28:46 -05:00
{ operators . map ( ( operator , i ) = > {
2024-02-25 20:55:48 +01:00
return ( < option key = { operator } value = { operator } > { operator } < / option > )
2024-01-28 21:22:59 +01:00
} ) }
2024-01-28 19:14:53 +01:00
< / select >
2024-02-23 23:48:03 +01:00
< div id = "values" >
2024-02-25 20:55:48 +01:00
< BuildFields schemaDescription = { schemaDescription } onSubmit = { handleSubmit } > < / BuildFields >
2024-02-23 23:48:03 +01:00
< / div >
2024-02-05 13:28:46 -05:00
2024-01-28 19:14:53 +01:00
< p >
< Link to = "/" > Go back home . . . < / Link >
< / p >
< / div >
) ;
}
2024-02-05 13:28:46 -05:00
export default Dynamic ;