import * as React from 'react' ; import { connect } from 'react-redux' ; import { ASSET_STATE , IAssetItem , IUploadAssetModalProps } from '../../interfaces' ; import { IApplicationState } from '../../store' ; import { samsApi , superdeskApi } from '../../apis' ; import { getActiveSets } from '../../store/sets/selectors' ; import { FileUploadModal , IContentPanelProps , IUploadFileListItemProps , IUploadItem , } from '../../containers/FileUploadModal' ; import { AssetGridItem } from './assetGridItem' ; import { AssetEditor } from './assetEditor' ; interface IState { assets : Dictionary < string , Partial < IAssetItem > > ; } const mapStateToProps = ( state ) => ( { sets : getActiveSets ( state ) , } ) ; export class UploadAssetModalComponent extends React . Component < IUploadAssetModalProps , IState > { onFieldChanged : Dictionary < string , ( field : keyof IAssetItem , value : any ) => void > ; constructor ( props ) { super ( props ) ; this . onFieldChanged = { } ; this . state = { assets : this . getInitialAssets ( ) , } ; this . onFileAdded = this . onFileAdded . bind ( this ) ; this . onFileRemoved = this . onFileRemoved . bind ( this ) ; this . uploadFile = this . uploadFile . bind ( this ) ; this . renderGridItem = this . renderGridItem . bind ( this ) ; this . renderRightPanel = this . renderRightPanel . bind ( this ) ; this . closeModal = this . closeModal . bind ( this ) ; } getInitialAssets ( ) { const assets = { } ; if ( this . props . initialFiles != null && this . props . initialFiles ?. length > 0 ) { this . props . initialFiles . forEach ( ( item ) => { assets [ item . id ] = { _id : item . id , state : this . props . defaultAssetState ?? ASSET_STATE . DRAFT , filename : item . file . name , length : item . file . size , mimetype : item . file . type , name : item . file . name , description : '' , set_id : this . props . sets [ 0 ] . _id , } ; this . onFieldChanged [ item . id ] = this . onChange . bind ( this , item . id ) ; } ) ; } return assets ; } closeModal ( ) { if ( this . props . onModalClosed != null ) { this . props . onModalClosed ( ) ; } this . props . closeModal ( ) ; } onFileAdded ( id , file ) { this . setState ( ( state ) => ( { assets : { ... state . assets , [ id ] : { _id : id , state : this . props . defaultAssetState ?? ASSET_STATE . DRAFT , filename : file . name , length : file . size , mimetype : file . type , name : file . name , description : '' , set_id : this . props . sets [ 0 ] . _id , } , } , } ) ) ; this . onFieldChanged [ id ] = this . onChange . bind ( this , id ) ; } onFileRemoved ( id ) { this . setState ( ( state ) => { const assets = { ... state . assets } ; delete assets [ id ] ; return { assets : assets } ; } ) ; delete this . onFieldChanged [ id ] ; } uploadFile ( item , onProgress ) { const { gettext } = superdeskApi . localization ; const { notify } = superdeskApi . ui ; const data = new FormData ( ) ; const asset = this . state . assets ?. [ item . id ] ; if ( asset == null ) { notify . error ( gettext ( 'Unable to find Asset associated with the file!' ) ) ; return Promise . reject ( ) ; } data . append ( 'binary' , item . binary , asset . filename ) ; let field ; for ( field in asset ) { if ( [ '_id' , 'length' ] . includes ( field ) === false ) { if ( typeof asset [ field ] === 'object' ) { data . append ( field , JSON . stringify ( asset [ field ] ) ) ; } else { data . append ( field , asset [ field ] as string ) ; } } } return samsApi . assets . upload ( data , onProgress ) . then ( ( newAsset ) => { if ( this . props . onAssetUploaded != null ) { return this . props . onAssetUploaded ( newAsset ) . then ( ( ) => newAsset ) ; } return newAsset ; } ) ; } onChange ( id , field , value ) { this . setState ( ( state ) => { const assets = { ... state . assets } ; assets [ id ] = { ... assets [ id ] , [ field ] : value , } ; return { assets : assets } ; } ) ; } renderGridItem ( { item , asset , selected , selectFile , removeFile } ) { return ( < AssetGridItem asset = { asset } file = { item . binary } onClick = { selectFile } onDoubleClick = { selectFile } selected = { selected } remove = { removeFile } uploadProgress = { item . uploadProgress } error = { item . error } / > ) ; } renderRightPanel ( { item , submitting } ) { return ( < AssetEditor key = { item . id } asset = { this . state . assets [ item . id ] } disabled = { submitting } onChange = { this . onFieldChanged [ item . id ] } allowedStates = { this . props . allowedStates } / > ) ; } render ( ) { const { gettext } = superdeskApi . localization ; return ( < FileUploadModal theme = "dark-ui" modalSize = "fill" initialFiles = { this . props . initialFiles } multiple = { true } closeModal = { this . closeModal } title = { gettext ( 'Upload New Asset(s)' ) } onFileAdded = { this . onFileAdded } onFileRemoved = { this . onFileRemoved } uploadFile = { this . uploadFile } assets = { this . state . assets } ListItemComponent = { this . renderGridItem } RightPanelComponent = { this . renderRightPanel } / > ) ; } } export const UploadAssetModal = connect ( mapStateToProps ) ( UploadAssetModalComponent ) ;