import * as XrmMock from "../xrm-mock/index" ; import Control , { CreateMethods as ControlCreateMethods } from "./control" ; export type BooleanControlComponent = XrmMock . IAttBooleanControlComponents | XrmMock . IAttBooleanControlComponents [ ] ; export type DateControlComponent = XrmMock . IAttDateControlComponents | XrmMock . IAttDateControlComponents [ ] ; export type LookupControlComponent = XrmMock . IAttLookupControlComponents | XrmMock . IAttLookupControlComponents [ ] ; export type NumberControlComponent = XrmMock . IAttNumberControlComponents | XrmMock . IAttNumberControlComponents [ ] ; export type OptionSetControlComponent = XrmMock . IAttOptionSetControlComponents | XrmMock . IAttOptionSetControlComponents [ ] ; export type StringControlComponent = XrmMock . IAttStringControlComponents | XrmMock . IAttStringControlComponents [ ] ; export default class Attribute { private Control = new Control ( ) ; public createBoolean ( attComponents , controlComponents ? ) ; public createBoolean ( name , value ? ) ; public createBoolean ( nameOrComponents , valueOrControlComponents ) { if ( typeof ( nameOrComponents ) === "string" ) { const components = { name : nameOrComponents , value : valueOrControlComponents as boolean } ; const controls = [ { name : nameOrComponents } ] ; return this . associateAttribute ( new XrmMock . BooleanAttributeMock ( components ) , controls , "createBoolean" ) ; } else { return this . associateAttribute ( new XrmMock . BooleanAttributeMock ( nameOrComponents ) , this . arrayify ( valueOrControlComponents as BooleanControlComponent ) , "createBoolean" ) ; } } public createDate ( attComponents , controlComponents ? ) ; public createDate ( name , value ? ) ; public createDate ( nameOrComponents , valueOrControlComponents ? ) { if ( typeof ( nameOrComponents ) === "string" ) { const components = { name : nameOrComponents , value : valueOrControlComponents as Date } ; const controls = [ { name : nameOrComponents } ] ; return this . associateAttribute ( new XrmMock . DateAttributeMock ( components ) , controls , "createDate" ) ; } else { return this . associateAttribute ( new XrmMock . DateAttributeMock ( nameOrComponents ) , this . arrayify ( valueOrControlComponents as StringControlComponent ) , "createDate" ) ; } } public createLookup ( attComponents , controlComponents ? ) ; public createLookup ( name , lookup ) ; public createLookup ( nameOrComponents , valueOrControlComponents ? ) { if ( typeof ( nameOrComponents ) === "string" ) { const components = { isPartyList : valueOrControlComponents && Array . isArray ( valueOrControlComponents ) , name : nameOrComponents , value : this . arrayify ( valueOrControlComponents as Xrm . LookupValue ) } ; const controls = [ { name : nameOrComponents } ] ; return this . associateAttribute ( new XrmMock . LookupAttributeMock ( components ) , controls , "createLookup" ) ; } else { return this . associateAttribute ( new XrmMock . LookupAttributeMock ( nameOrComponents ) , this . arrayify ( valueOrControlComponents as LookupControlComponent ) , "createLookup" ) ; } } public createNumber ( attComponents , controlComponents ? ) ; public createNumber ( name , value ? ) ; public createNumber ( nameOrComponents , valueOrControlComponents ) { if ( typeof ( nameOrComponents ) === "string" ) { const components = { name : nameOrComponents , value : valueOrControlComponents as number } ; const controls = [ { name : nameOrComponents } ] ; return this . associateAttribute ( new XrmMock . NumberAttributeMock ( components ) , controls , "createNumber" ) ; } else { return this . associateAttribute ( new XrmMock . NumberAttributeMock ( nameOrComponents ) , this . arrayify ( valueOrControlComponents as NumberControlComponent ) , "createNumber" ) ; } } public createOptionSet ( attComponents , controlComponents ? ) ; public createOptionSet ( name , value ? , options ? ) ; public createOptionSet ( nameOrComponents , valueOrControlComponents ? , options ? ) { return typeof ( nameOrComponents ) === "string" ? this . createOptionSetFromParameters ( nameOrComponents , valueOrControlComponents as string | number , options ) : this . createOptionSetFromComponents ( nameOrComponents , this . arrayify ( valueOrControlComponents as OptionSetControlComponent ) ) ; } public createString ( attComponents , controlComponents ? ) ; public createString ( name , value ? ) ; public createString ( nameOrComponents , valueOrControlComponents = "" ) { if ( typeof ( nameOrComponents ) === "string" ) { const components = { name : nameOrComponents , value : valueOrControlComponents as string } ; const controls = [ { name : nameOrComponents } ] ; return this . associateAttribute ( new XrmMock . StringAttributeMock ( components ) , controls , "createString" ) ; } else { return this . associateAttribute ( new XrmMock . StringAttributeMock ( nameOrComponents ) , this . arrayify ( valueOrControlComponents as StringControlComponent ) , "createString" ) ; } } private createOptionSetFromParameters ( name , value , options ) { let num ; if ( value !== null && value !== undefined ) { if ( ! options ) { options = [ typeof value === "string" ? { text : value , value : 0 } : { text : value . toString ( ) , value } ] ; } if ( typeof value === "string" ) { const option = options . filter ( ( o ) => o . text === value ) [ 0 ] ; num = option . value ; } else { num = value ; } } else { num = undefined ; } const components = { name , options , } ; if ( num || num === 0 ) { components . value = num ; } const controls = [ { name , options } ] ; return this . associateAttribute ( new XrmMock . OptionSetAttributeMock ( components ) , controls , "createOptionSet" ) ; } private createOptionSetFromComponents ( components , controls ) { if ( components . options && components . options . length > 0 ) { controls . filter ( ( c ) => ! c . options ) . forEach ( ( c ) => { c . options = components . options ; } ) ; } return this . associateAttribute ( new XrmMock . OptionSetAttributeMock ( components ) , controls , "createOptionSet" ) ; } private createStringFromParameters ( name , value ) { const components = { name , value } ; const controls = [ { name } ] ; return this . associateAttribute ( new XrmMock . StringAttributeMock ( components ) , controls , "createString" ) ; } private createAttribute ( name , value ) { const attribute = new XrmMock . AttributeMock ( { isDirty : false , name , submitMode : "dirty" , value , } ) ; return attribute ; } private addAttribute ( attribute ) { ( Xrm . Page . data . entity as XrmMock . EntityMock ) . attributes . push ( attribute ) ; } param attribute param controls param controlCreateFunction private associateAttribute < TAtt extends Xrm . Attributes . Attribute > ( attribute , controls , controlCreateFunction ) { this . addAttribute ( attribute ) ; controls . forEach ( ( c ) => { c . attribute = attribute ; this . defaultName ( c , attribute ) ; ( this . Control [ controlCreateFunction ] as any ) ( c ) ; } ) ; return attribute ; } private defaultName ( control , attribute ) { const names = [ ] ; attribute . controls . forEach ( ( c ) => { names . push ( c . getName ( ) ) ; } ) ; if ( ! control . name ) { control . name = attribute . getName ( ) ; } else if ( names . indexOf ( control . name ) >= 0 ) { throw new Error ( `Name ${ control . name } has already been defined for a control for attribute ${ attribute . getName ( ) }` ) ; } let i = 1 ; while ( names . indexOf ( control . name ) >= 0 ) { control . name = attribute . getName ( ) + i ++ ; } } private arrayify < T > ( possibleArray ) { if ( ! possibleArray ) { return [ ] ; } else if ( possibleArray instanceof Array ) { return possibleArray ; } else { return [ possibleArray ] ; } } }