import { IListForm , IListFormAttachmentInfo , IListFormResult , IListFormProps } from "../../@types/helper" ; import { IODataQuery , SP } from "gd-sprest-def" ; import { SPTypes , Web } from ".." ; import { Types } from "../../@types" ; /**
 * List Form
 */ export const ListForm = { create : ( props ) => { let _info = null ; let _props = null ; let _reject = null ; let _resolve = null ; _props = props || { } as any ; _props . fields = _props . fields ; let load = ( ) => { _info = { item : _props . item , query : _props . query || { } } as any ; loadListData ( ) . then ( ( ) => { if ( _props . fields ) { processFields ( ) ; loadItem ( ) ; } else { loadContentType ( ) ; } } , _reject ) ; } ; let loadContentType = ( ) => { _info . list . ContentTypes ( ) . query ( { Filter : _props . contentType ? "Name eq '" + _props . contentType + "'" : null , Expand : [ "FieldLinks" ] , Select : [ "*" , "FieldLinks/DisplayName" , "FieldLinks/Hidden" , "FieldLinks/Name" , "FieldLinks/ReadOnly" , "FieldLinks/Required" ] , Top : 1 } ) . execute ( ct => { loadDefaultFields ( ct . results [ 0 ] ) ; } , _reject ) ; } ; let loadDefaultFields = ( ct ) => { let fields = ct ? ct . FieldLinks . results : [ ] ; let formFields = { } ; let formLinks = { } ; for ( let i = 0 ; i < fields . length ; i ++ ) { let fieldLink = fields [ i ] ; let field = _info . fields [ fieldLink . Name ] ; if ( field ) { if ( field . InternalName == "ContentType" ) { continue ; } if ( field . Hidden || fieldLink . Hidden ) { continue ; } formFields [ field . InternalName ] = field ; formLinks [ field . InternalName ] = fieldLink ; } } _info . contentType = ct as any ; _info . fields = formFields ; _info . fieldLinks = formLinks ; loadItem ( ) ; } ; let loadFieldData = ( fields ) => { _info . fields = { } ; for ( let i = 0 ; i < fields . results . length ; i ++ ) { let field = fields . results [ i ] ; if ( _props . excludeFields ) { let excludeField = false ; for ( let j = 0 ; j < _props . excludeFields . length ; j ++ ) { if ( _props . excludeFields [ j ] == field . InternalName ) { excludeField = true ; break ; } } if ( excludeField ) { continue ; } } _info . fields [ field . InternalName ] = field ; } } ; let loadItem = ( ) => { let reloadItem = false ; if ( _info . item ) { for ( let fieldName in _info . fields ) { let field = _info . fields [ fieldName ] ; switch ( field . FieldTypeKind ) { case SPTypes . FieldType . Lookup : case SPTypes . FieldType . User : let fieldValue = _info . item [ fieldName + "Id" ] ; if ( fieldValue ) { if ( fieldValue . results ? fieldValue . results . length > 0 : fieldValue > 0 ) { if ( _info . item [ fieldName ] == null ) { reloadItem = true ; } } } break ; default : if ( field . TypeAsString . indexOf ( "TaxonomyFieldType" ) == 0 ) { let fieldValue = _info . item [ fieldName + "Id" ] ; if ( fieldValue ) { if ( fieldValue . results ? fieldValue . results . length > 0 : fieldValue != null ) { for ( let fieldName in _info . fields ) { let valueField = _info . fields [ fieldName ] ; if ( valueField . InternalName == field . InternalName + "_0" || valueField . Title == field . InternalName + "_0" ) { if ( _info . item [ valueField . InternalName ] == null ) { reloadItem = true ; } break ; } } } } } break ; } if ( reloadItem ) { break ; } } } if ( _info . item && ! reloadItem ) { if ( _props . loadAttachments && _info . attachments == null ) { ListForm . loadAttachments ( _props ) . then ( attachments => { _info . attachments = attachments ; _resolve ( _info ) ; } , _reject ) ; } else { _resolve ( _info ) ; } } else if ( reloadItem || _props . itemId > 0 ) { _info . query = ListForm . generateODataQuery ( _info , _props . loadAttachments ) ; _info . list . Items ( reloadItem ? _props . item . Id : _props . itemId ) . query ( _info . query ) . execute ( item => { _info . attachments = item . AttachmentFiles . results ; _info . item = item ; ListForm . refreshItem ( _info ) . then ( info => { _info = info ; _resolve ( _info ) ; } , _reject ) ; } , _reject ) ; } else { _resolve ( _info ) ; } } ; let loadListData = ( ) : PromiseLike < void > => { return new Promise ( ( resolve , reject ) => { if ( _info . list && _info . fields ) { resolve ( ) ; return ; } Web ( _props . webUrl , { disableCache : true } ) . Lists ( _props . listName ) . execute ( list => { _info . list = list ; _info . webUrl = _props . webUrl ; } , reject ) . Fields ( ) . execute ( fields => { loadFieldData ( fields as any ) ; resolve ( ) ; } , reject , true ) ; } ) ; } ; let processFields = ( ) => { let formFields = { } ; for ( let i = 0 ; i < _props . fields . length ; i ++ ) { let field = _info . fields [ _props . fields [ i ] ] ; if ( field ) { formFields [ field . InternalName ] = field ; if ( field . TypeAsString . indexOf ( "TaxonomyFieldType" ) == 0 ) { for ( let fieldName in _info . fields ) { let valueField = _info . fields [ fieldName ] ; if ( valueField . InternalName == field . InternalName + "_0" || valueField . Title == field . InternalName + "_0" ) { formFields [ valueField . InternalName ] = valueField ; break ; } } } } } _info . fields = formFields ; } ; return new Promise ( ( resolve , reject ) => { _reject = reject ; _resolve = resolve ; load ( ) ; } ) as any ; } , generateODataQuery : ( info , loadAttachments = false ) : IODataQuery => { let query = info . query || { } ; query . Select = query . Select || [ "*" ] ; query . Expand = query . Expand || [ ] ; if ( loadAttachments ) { query . Expand . push ( "AttachmentFiles" ) ; query . Select . push ( "Attachments" ) ; query . Select . push ( "AttachmentFiles" ) ; } for ( let fieldName in info . fields ) { let field = info . fields [ fieldName ] ; if ( field . InternalName == "FileLeafRef" ) { query . Select . push ( "FileLeafRef" ) ; continue ; } switch ( field . FieldTypeKind ) { case SPTypes . FieldType . Lookup : let lookupField = field as Types . SP . FieldLookup ; if ( lookupField . PrimaryFieldId ) { for ( let parentFieldName in info . fields ) { let parentField = info . fields [ parentFieldName ] ; if ( parentField . Id == lookupField . PrimaryFieldId ) { query . Select . push ( parentField . InternalName + "/" + lookupField . LookupField ) ; break ; } } } else { query . Expand . push ( field . InternalName ) ; query . Select . push ( field . InternalName + "/Id" ) ; query . Select . push ( field . InternalName + "/" + ( field as SP . FieldLookup ) . LookupField ) ; } break ; case SPTypes . FieldType . User : query . Expand . push ( field . InternalName ) ; query . Select . push ( field . InternalName + "/Id" ) ; query . Select . push ( field . InternalName + "/Title" ) ; break ; default : if ( field . TypeAsString . indexOf ( "TaxonomyFieldType" ) == 0 ) { for ( let fieldName in info . fields ) { let valueField = info . fields [ fieldName ] ; if ( valueField . InternalName == field . InternalName + "_0" || valueField . Title == field . InternalName + "_0" ) { query . Select . push ( valueField . InternalName ) ; break ; } } } break ; } } return query ; } , loadAttachments : ( info ) : PromiseLike < Array < SP . Attachment > > => { return new Promise ( ( resolve , reject ) => { let itemId = info . item ? info . item . Id : info . itemId ; if ( itemId > 0 ) { Web ( info . webUrl ) . Lists ( info . listName ) . Items ( itemId ) . AttachmentFiles ( ) . execute ( attachments => { if ( ! attachments . existsFl ) { reject ( attachments . response ) ; return ; } resolve ( attachments . results || [ ] ) ; } , reject ) ; } else { resolve ( [ ] ) ; } } ) ; } , refreshItem : ( info ) : PromiseLike < IListFormResult > => { return new Promise ( ( resolve , reject ) => { info . query = ListForm . generateODataQuery ( info , info . attachments ? true : false ) ; info . list . Items ( info . item . Id ) . query ( info . query ) . execute ( item => { info . item = item ; info . list . Items ( item . Id ) . query ( { Expand : [ "FieldValuesAsText" , "Folder" ] } ) . execute ( item => { info . itemFolder = item . Folder ; info . fieldValuesAsText = item . FieldValuesAsText ; } ) ; info . list . Items ( item . Id ) . FieldValuesAsHtml ( ) . execute ( values => { info . fieldValuesAsHtml = values ; resolve ( info ) ; } , true ) ; } , reject ) ; } ) ; } , removeAttachment : ( info , fileName ) : PromiseLike < IListFormResult > => { return new Promise ( ( resolve , reject ) => { if ( info . attachments ) { for ( let i = 0 ; i < info . attachments . length ; i ++ ) { let attachment = info . attachments [ i ] ; if ( attachment . FileName == fileName ) { Web ( info . webUrl ) . getFileByServerRelativeUrl ( attachment . ServerRelativeUrl ) . delete ( ) . execute ( ( ) => { resolve ( info ) ; } , reject ) ; return ; } reject ( "Attachment '" + fileName + "' was not found." ) ; } } else { reject ( "Attachment '" + fileName + "' was not found." ) ; } } ) ; } , saveAttachments : ( info , attachmentInfo ) : PromiseLike < Array < SP . Attachment > > => { return new Promise ( ( resolve , reject ) => { let itemId = info . item ? info . item . Id : info . itemId ; if ( itemId > 0 ) { let attachments = Web ( info . webUrl ) . Lists ( info . listName ) . Items ( itemId ) . AttachmentFiles ( ) ; for ( let i = 0 ; i < attachmentInfo . length ; i ++ ) { let attachment = attachmentInfo [ i ] ; attachments . add ( attachment . name , attachment . data ) . execute ( true ) ; } attachments . done ( ( ... args ) => { resolve . apply ( args ) ; } ) ; } else { resolve ( null ) ; } } ) ; } , saveItem : ( info , formValues = { } ) : PromiseLike < IListFormResult > => { return new Promise ( ( resolve , reject ) => { if ( info . item && info . item . update ) { info . item . update ( formValues ) . execute ( response => { ListForm . refreshItem ( info ) . then ( info => { resolve ( info ) ; } , reject ) ; } ) ; } else { formValues [ "__metadata" ] = { type : info . list . ListItemEntityTypeFullName } ; info . list . Items ( ) . add ( formValues ) . execute ( item => { info . item = item ; ListForm . refreshItem ( info ) . then ( info => { resolve ( info ) ; } ) ; } , reject ) ; } } ) ; } , showFileDialog : ( info ? , onSave ? ) : PromiseLike < any > => { return new Promise ( ( resolve , reject ) => { let addAttachment = ( name , data ) => { onSave ? onSave ( { name , data } ) : null ; info . list . Items ( info . item . Id ) . AttachmentFiles ( ) . add ( name , data ) . execute ( ( ) => { ListForm . refreshItem ( info ) . then ( info => { document . body . removeChild ( el ) ; resolve ( info ) ; } ) ; } , reject ) ; } ; let readFile = ( ev ) => { let srcFile = ev . target [ "files" ] [ 0 ] ; if ( srcFile ) { let reader = new FileReader ( ) ; reader . onloadend = ( ev ) => { let attachment = null ; let ext = srcFile . name . split ( "." ) as any ; ext = ext [ ext . length - 1 ] . toLowerCase ( ) ; if ( info ) { addAttachment ( srcFile . name , ev . target . result ) ; } else { document . body . removeChild ( el ) ; resolve ( { data : ev . target . result , name : srcFile . name } ) ; } } ; reader . onerror = ( ev ) => { document . body . removeChild ( el ) ; reject ( ev . target . error ) ; } ; reader . readAsArrayBuffer ( srcFile ) ; } } ; let el = document . body . querySelector ( "#listform-attachment" ) as HTMLInputElement ; if ( el == null ) { el = document . createElement ( "input" ) ; el . id = "listform-attachment" ; el . type = "file" ; el . hidden = true ; el . onchange = readFile ; document . body . appendChild ( el ) ; } el . click ( ) ; } ) ; } } ;