import { IContentType , FieldLink , FieldLinkProps } from "gd-sprest-def/lib/SP" ; import { IsetContentTypeFields } from "../../../@types/helper/methods" ; import { ContextInfo , Web } from "../../lib" ; declare var SP ; param ctInfo export const setContentTypeFields = ( ctInfo ) : PromiseLike < void > => { let clearLinks = ( ) : PromiseLike < Array < FieldLink > > => { return new Promise ( ( resolve , reject ) => { getLinks ( ) . then ( fieldLinks => { let skipFields = [ ] ; if ( fieldLinks . length > 0 ) { let updateFl = false ; let ctx = ctInfo . webUrl ? new SP . ClientContext ( ctInfo . webUrl ) : new SP . ClientContext ( ContextInfo . webServerRelativeUrl ) ; let src = ctInfo . listName ? ctx . get_web ( ) . get_lists ( ) . getByTitle ( ctInfo . listName ) : ctx . get_web ( ) ; let contentType = src . get_contentTypes ( ) . getById ( ctInfo . id ) ; for ( let i = 0 ; i < fieldLinks . length ; i ++ ) { let fieldLink = fieldLinks [ i ] ; let removeFl = true ; for ( let j = 0 ; j < ctInfo . fields . length ; j ++ ) { let field = ctInfo . fields [ j ] ; let fieldName = typeof ( field ) === "string" ? field : field . Name || field . FieldInternalName ; if ( fieldName == fieldLink . Name ) { let propUpdateFl = false ; let updateField = ( oldValue , newValue ) => { if ( newValue == null ) { return ; } if ( oldValue == newValue ) { return ; } propUpdateFl = true ; } ; updateField ( fieldLink . DisplayName , ( field as FieldLinkProps ) . DisplayName ) ; updateField ( fieldLink . Hidden , ( field as FieldLinkProps ) . Hidden ) ; updateField ( fieldLink . ReadOnly , ( field as FieldLinkProps ) . ReadOnly ) ; updateField ( fieldLink . Required , ( field as FieldLinkProps ) . Required ) ; updateField ( fieldLink . ShowInDisplayForm , ( field as FieldLinkProps ) . ShowInDisplayForm ) ; if ( ! propUpdateFl ) { removeFl = false ; skipFields . push ( fieldLink ) ; } break ; } } if ( removeFl ) { contentType . get_fieldLinks ( ) . getById ( fieldLink . Id ) . deleteObject ( ) ; updateFl = true ; console . log ( "[gd-sprest][Set Content Type Fields] Removing the field link: " + fieldLink . Name ) ; } } if ( updateFl ) { contentType . update ( false ) ; ctx . executeQueryAsync ( ( ) => { console . log ( "[gd-sprest][Set Content Type Fields] Removed the field links successfully." ) ; resolve ( skipFields ) ; } , ( sender , args ) => { console . log ( "[gd-sprest][Set Content Type Fields] Error removing the field links." ) ; reject ( ) ; } ) ; } else { console . log ( "[gd-sprest][Set Content Type Fields] No fields need to be removed." ) ; resolve ( skipFields ) ; } } else { resolve ( skipFields ) ; } } , reject ) ; } ) ; } ; let createLinks = ( skipFields ) : PromiseLike < void > => { return new Promise ( ( resolve , reject ) => { let ctx = ctInfo . webUrl ? new SP . ClientContext ( ctInfo . webUrl ) : new SP . ClientContext ( ContextInfo . webServerRelativeUrl ) ; let src = ctInfo . listName ? ctx . get_web ( ) . get_lists ( ) . getByTitle ( ctInfo . listName ) : ctx . get_web ( ) ; let skipField = ( fieldName , fields ) : boolean => { for ( let i = 0 ; i < fields . length ; i ++ ) { if ( fields [ i ] . Name == fieldName ) { return true ; } } } ; let fields = [ ] ; for ( let i = 0 ; i < ctInfo . fields . length ; i ++ ) { let fieldInfo = ctInfo . fields [ i ] ; let fieldName = typeof ( fieldInfo ) === "string" ? fieldInfo : fieldInfo . Name || fieldInfo . FieldInternalName ; if ( skipField ( fieldName , skipFields ) ) { continue ; } let field = src . get_fields ( ) . getByInternalNameOrTitle ( fieldName ) ; ctx . load ( field ) ; console . log ( "[gd-sprest][Set Content Type Fields] Adding the field link: " + fieldName ) ; fields . push ( { ref : field , info : fieldInfo } ) ; } if ( fields . length > 0 ) { ctx . executeQueryAsync ( ( ) => { let contentType = src . get_contentTypes ( ) . getById ( ctInfo . id ) ; ctx . load ( contentType ) ; for ( let i = 0 ; i < fields . length ; i ++ ) { let field = fields [ i ] ; /**
                         * The field link set_[property] methods don't seem to work. Setting the field information seems to be the only way.
                         * The read only property is the only one that doesn't seem to work.
                         */ if ( typeof ( field . info ) !== "string" ) { field . info . DisplayName != null ? field . ref . set_title ( field . info . DisplayName ) : null ; field . info . Hidden != null ? field . ref . set_hidden ( field . info . Hidden ) : null ; field . info . ReadOnly != null ? field . ref . set_readOnlyField ( field . info . ReadOnly ) : null ; field . info . Required != null ? field . ref . set_required ( field . info . Required ) : null ; field . info . ShowInDisplayForm != null ? field . ref . setShowInDisplayForm ( field . info . ShowInDisplayForm ) : null ; } let fieldLink = new SP . FieldLinkCreationInformation ( ) ; fieldLink . set_field ( field . ref ) ; contentType . get_fieldLinks ( ) . add ( fieldLink ) ; } contentType . update ( false ) ; ctx . executeQueryAsync ( ( ) => { console . log ( "[gd-sprest][Set Content Type Fields] Added the field links successfully." ) ; resolve ( ) ; } , ( sender , args ) => { console . log ( "[gd-sprest][Set Content Type Fields] Error adding field references." , args . get_message ( ) ) ; reject ( ) ; } ) ; } , ( sender , args ) => { console . log ( "[gd-sprest][Set Content Type Fields] Error getting field references." , args . get_message ( ) ) ; resolve ( ) ; } ) ; } else { console . log ( "[gd-sprest][Set Content Type Fields] No fields need to be added." ) ; resolve ( ) ; } } ) ; } ; let getLinks = ( ) : PromiseLike < Array < FieldLink > > => { return new Promise ( ( resolve , reject ) => { let ct = null ; if ( ctInfo . listName ) { ct = Web ( ctInfo . webUrl ) . Lists ( ctInfo . listName ) . ContentTypes ( ctInfo . id ) ; } else { ct = Web ( ctInfo . webUrl ) . ContentTypes ( ctInfo . id ) ; } ct . FieldLinks ( ) . query ( { Select : [ "DisplayName" , "Id" , "Name" , "Required" , "ReadOnly" , "ShowInDisplayForm" ] } ) . execute ( fieldLinks => { resolve ( fieldLinks . results ) ; } , reject ) ; } ) ; } ; let setOrder = ( ) : PromiseLike < void > => { return new Promise ( ( resolve , reject ) => { let ctx = ctInfo . webUrl ? new SP . ClientContext ( ctInfo . webUrl ) : new SP . ClientContext ( ContextInfo . webServerRelativeUrl ) ; let src = ctInfo . listName ? ctx . get_web ( ) . get_lists ( ) . getByTitle ( ctInfo . listName ) : ctx . get_web ( ) ; let contentType = src . get_contentTypes ( ) . getById ( ctInfo . id ) ; let fieldNames = [ ] ; for ( let i = 0 ; i < ctInfo . fields . length ; i ++ ) { let fieldInfo = ctInfo . fields [ i ] ; let fieldName = typeof ( fieldInfo ) === "string" ? fieldInfo : fieldInfo . Name || fieldInfo . FieldInternalName ; fieldNames . push ( fieldName ) ; } contentType . get_fieldLinks ( ) . reorder ( fieldNames ) ; contentType . update ( ctInfo . listName ? false : true ) ; ctx . executeQueryAsync ( ( ) => { console . log ( "[gd-sprest][Set Content Type Fields] Updated the field order successfully." ) ; resolve ( ) ; } , ( sender , args ) => { console . log ( "[gd-sprest][Set Content Type Fields] Error updating the field order." , args . get_message ( ) ) ; reject ( ) ; } ) ; } ) ; } ; return new Promise ( ( resolve , reject ) => { if ( window [ "SP" ] ) { if ( ctInfo . fields ) { clearLinks ( ) . then ( skipFields => { createLinks ( skipFields ) . then ( ( ) => { setOrder ( ) . then ( resolve , reject ) ; } , reject ) ; } , reject ) ; } else { resolve ( ) ; } } else { resolve ( ) ; } } ) ; } ;