import { Component, Input, Output, EventEmitter, Attribute, ChangeDetectorRef } from '@angular/core';
import { CoreServicesProvider } from '../../provider/core-services-provider';
import { Metas, Meta } from '../../../http-module/models/meta';
import { FormGroup, ValidatorFn } from '@angular/forms';
import { BaseComponent } from '../../classes/base-component';

import { DragDropFileComponent } from '../drag-drop-file/drag-drop-file.component';
import { MsFormOption, MsFormProperty } from '../../services/forms.service';
import { BaseViewInterface } from '../../interfaces/base-view.interface';
import { AdresseComponent, MsAdresseConf } from '../adresse/adresse.component';
import { Subscription } from 'rxjs';
import { DataControllerRegisterEvent } from '../../models/data-controller-register-event';
import { MsActionEvent } from '../../models/ms-action-event';
import { DateTimeUtils } from '../../../utils/date-time-utils';
import { TypeHtml } from '../../../http-module/models/type-html';
import { MsFormComponent } from '../../../http-module/models/form-component';
import { InputComponent } from '../input/input.component';

@Component({
  selector: 'ms-form',
  templateUrl: './form.component.jade'
})
/**
 * Composant de gestion d'un formulaire
 */
export class FormComponent extends BaseComponent {

  metasOK : boolean=false;

  protected _metas: Metas;

  @Input()
  flatForm : boolean=false;

  @Input()
  isSaving: boolean = false;

  public get metas(): Metas {
    return this._metas;
  }
  @Input()
  public set metas(value: Metas) {
    this._metas = value;
    let l_metasOK=false;
    if (this._metas) {
      for (let prop in this._metas) {
        if (this._metas[prop].ls!=='1') {
          l_metasOK=true;
          break;
        }
      }
    }
    this.metasOK=l_metasOK;
  }

  protected _data: any;

  public get data(): any {
    return this._data;
  }
  @Input()
  public set data(value: any) {
    this._data = value;
  }

  /** classe CSS pour les icônes */
  @Input()
  iconClass: string;

  /**
   * actions personnalisées (actions, icons, template)
   */
  private _formActions: any;
  public get formActions(): any {
    return this._formActions;
  }
  @Input()
  public set formActions(value: any) {
    this._formActions = value;
  }

  @Output()
  onActionClick: EventEmitter<MsActionEvent> = new EventEmitter<MsActionEvent>();

  public components : Array<InputComponent|DragDropFileComponent|AdresseComponent>=[];
  private _state: MsFormState = MsFormState.EDITING;
  public get state(): MsFormState {
    return this._state;
  }
  public set state(value: MsFormState) {
    if ((this._state!==value)) {
      if ((value==MsFormState.SHOWING)&&(this.form)&&(this.editConfig)) {
        this._state = value;
        this.changeDetector.detectChanges;
        setTimeout(()=> {
          for (let l_col of this.editConfig.cols) {
            for (let l_row of l_col.rows) {
              for (let l_component of l_row.components) {
                this.form.removeControl(l_component.name);
              }
            }
          }
          this.form.reset();          
        }
        );

      } else {
        this._state = value;
      }
      this.onStateChange.emit(value);
      

    }
   
  }
  @Output()
  public onStateChange : EventEmitter<MsFormState> = new EventEmitter<MsFormState>();

  @Output()
  public onCancel: EventEmitter<any> = new EventEmitter<any>();

  public formTitle: string;

  private _form: FormGroup;
  public get form(): FormGroup {
    return this._form;
  }
  @Input()
  public set form(value: FormGroup) {
    this._form = value;
    if ((this._config)&&(this._form)) {
      if (this._config.noStatusVerif) {
        this._form['noStatusVerif']=true;
        this.coreServicesProvider.formsService.onFormOptionUpdate.emit(MsFormOption.STATUSVERIF);
      }
      if (this._config.isStandAlone) {
        this._form['isStandAlone']=true;
        this.coreServicesProvider.formsService.onFormOptionUpdate.emit(MsFormOption.STANDALONE);
        this.state=MsFormState.SHOWING;
      }
      this.doUpdateValidators();
      /**
       * on récupère la configuration en mode édition
       */
      for (let l_stateConfig of this._config.statesConfigs) {
        if (l_stateConfig.states.indexOf(MsFormState.EDITING)>-1) {
          this.editConfig=l_stateConfig;
          break;
        }
      }
      /**
       * on récupère la configuration en mode visu
       */
      for (let l_stateConfig of this._config.statesConfigs) {
        if (l_stateConfig.states.indexOf(MsFormState.SHOWING)>-1) {
          this.showConfig=l_stateConfig;
          break;
        }
      }
    }
  }

  public doUpdateValidators() {
    if ((this.validators)&&(this.validators.length>0)) {
        this.form.removeValidators(this.validators);
        this.validators=undefined;
    }
    // on en créé de nouveaux...
    if ((this.config.formValidators)&&(this.config.formValidators.length>0)) {
      let l_validators:ValidatorFn[]=[];
      for(let l_validator of this.config.formValidators) {
        if ((<MsFormDateRangeValidator>l_validator).dateDeb) {
          l_validators=l_validators.concat(DateTimeUtils.getPeriodValidators((<MsFormDateRangeValidator>l_validator).dateDeb,(<MsFormDateRangeValidator>l_validator).dateFin,
          (<MsFormDateRangeValidator>l_validator).typeDate,
          (<MsFormDateRangeValidator>l_validator).diffMax));
        } else {
          l_validators.push(<ValidatorFn>l_validator);
        }
      }
      this.form.addValidators(l_validators);
      this.validators=l_validators;
    }

  }

  validators : ValidatorFn[];

  public editConfig: MsFormStateConfig;
  public showConfig: MsFormStateConfig;

  private _config: MsFormConfig;
  public get config(): MsFormConfig {
    return this._config;
  }
  @Input()
  public set config(value: MsFormConfig) {
    this._config = value;
    if ((this._config)&&(this._form)) {
      if (this._config.noStatusVerif) {
        this._form['noStatusVerif']=true;
        this.coreServicesProvider.formsService.onFormOptionUpdate.emit(MsFormOption.STATUSVERIF);
      }
      /**
       * on récupère la configuration en mode édition
       */
      for (let l_stateConfig of this._config.statesConfigs) {
        if (l_stateConfig.states.indexOf(MsFormState.EDITING)>-1) {
          this.editConfig=l_stateConfig;
          break;
        }
      }
      /**
       * on récupère la configuration en mode visu
       */
      for (let l_stateConfig of this._config.statesConfigs) {
        if (l_stateConfig.states.indexOf(MsFormState.SHOWING)>-1) {
          this.showConfig=l_stateConfig;
          break;
        }
      }
      this.doUpdateValidators();
      if (this._config.isStandAlone) {
        this._form['isStandAlone']=true;
        this.coreServicesProvider.formsService.onFormOptionUpdate.emit(MsFormOption.STANDALONE);
        this.state=this.showConfig?MsFormState.SHOWING:MsFormState.EDITING;
      }
    }
  }
  private _inputTemplates: any;
  public get inputTemplates(): any {
    return this._inputTemplates;
  }
  @Input()
  public set inputTemplates(value: any) {
    this._inputTemplates=value;
  }

  public getDatasMetas(component : MsFormComponent) {
    let l_datas : any;
    let l_metas : Meta|Metas;
    if (component.data instanceof Array) {
      l_datas={};
      for (let l_data of component.data) {
        l_datas[l_data]=this.data[l_data];
      }
    } else {
      l_datas=this.data[component.data];
    }
    if (component.meta instanceof Array) {
      l_metas={};
      for (let l_meta of component.meta) {
        l_metas[l_meta]=this.metas[l_meta];
      }
    } else {
      l_metas=this.metas[<string>component.meta];
    }

    return {datas:l_datas,metas:l_metas,firstMeta:(component.meta instanceof Array?component.meta[0]:component.meta)};
  }

  /**
   * Vérifie si data est un tableau
   * @param component
   * @returns
   */
  public isArrayElement(component: MsFormComponent): boolean {
    return (component.data instanceof Array) ? true : false;
  }

  @Input()
  visuTemplates : any;

  public get parent(): BaseViewInterface {
    return this._parent;
  }
  @Input()
  public set parent(value: BaseViewInterface) {
    this._parent=value;
  }

  public doRegisterController(a_event: DataControllerRegisterEvent): void {
    this.parent.doRegisterController(a_event);
  }

  forceCancelSub : Subscription;

  ngOnInit() {
    this.forceCancelSub=this.coreServicesProvider.formsService.onForceCancel.subscribe(result => {
      if ((this.form)&&((<any>this.form).isStandAlone)&&(this.parent)&&(this.parent.forms[result])) {
        if (this.coreServicesProvider.formsService.getFormsModified({form:this.form})) {
            // si besoin d'intervenir sur les données du form avant le refresh
            this.onCancel.emit({data: this.data, meta: this.metas});
            this.state=MsFormState.SHOWING;
            this.parent.doLoadData();
        }
      }
    });
    super.ngOnInit();
  }

  ngOnDestroy() {
    this.forceCancelSub.unsubscribe();
    super.ngOnDestroy();
  }

  public doSave(a_event : MouseEvent) {
    a_event.preventDefault();
    if (!this.getFormKO()) {
      this.parent.doSave().subscribe(
        result => {
          if (result) {
            this.state=MsFormState.SHOWING;
            if (this.parent.doAfterSave) {
              this.parent.doAfterSave(result);
            }
            this.parent.doLoadData();
          }
        }
      )
    }
  }

  public doCancel(a_event : MouseEvent) {
    a_event.preventDefault();
    if (this.coreServicesProvider.formsService.getFormsModified({form:this.form})) {
      let l_result=true;
      l_result=confirm(this.coreServicesProvider.libelleService.getCoreLib("core.common.msg.ChgRouteLib"));
      if (l_result) {
        // si besoin d'intervenir sur les données du form avant le refresh
        this.onCancel.emit({data: this.data, meta: this.metas});
        this.state=MsFormState.SHOWING;
        this.parent.doLoadData();
      }
    } else {
      this.onCancel.emit({data: this.data, meta: this.metas, modified: false});
      this.state=MsFormState.SHOWING;
    }

  }

  public getFormKO() : boolean {
    let l_result=(this.coreServicesProvider.formsService.getFormsProp(MsFormProperty.INVALID,{form:this.form}));
    if (!l_result) {
      l_result=this.coreServicesProvider.formsService.getFormsUnmodified({form:this.form});
    }
    return l_result;
  }

  constructor(coreServicesProvider : CoreServicesProvider,
    private changeDetector : ChangeDetectorRef,
    @Attribute('formTitle')
    a_title : string) {
    super(coreServicesProvider);
    if ((a_title !== null) && (a_title !== undefined)) {
      this.coreServicesProvider.libelleService.getLibelleDivers(a_title).subscribe(
        result => {
          this.formTitle=result;
        }
      );
    }
  }

  @Output()
  onDataChange : EventEmitter<MsFormDataChange> = new EventEmitter<MsFormDataChange>();

}

export interface MsFormDataChange {
  name : string,
  data : any;
}

export enum MsFormState {SHOWING='showing',EDITING='editing'}

/**
 * Configuration formulaire
 */
export interface MsFormConfig {
  statesConfigs : Array<MsFormStateConfig>;
  /**
   * Permet d'indiquer que l'on souhaite qu'il soit validable a l'ouverture
   */
  noStatusVerif?:boolean;
  /**
   * Indique si le formulaire est autonome
   * Dans le sens ou il intègre son propre bouton
   * modifier / annuler / valider
   */
  isStandAlone?:boolean;
  /**
   * Indique le champ sur lequel mettre le focus a l'ouverture
   */
  autoFocusOn?:string;
  /**
   * Indique si l'on désire sauvegarder ou annuler via les touches du clavier
   */
  useKeyboard?:boolean;
  /**
   * Pour virer le card quand on est déjà dans un card...
   */
  noCard?:boolean;
  /**
   * Validators de formulaire, basés sur un ou plusieurs champs, potentiellement
   */
  formValidators?:Array<ValidatorFn | MsFormDateRangeValidator>
}
/**
 * Une config par state
 */
export interface MsFormStateConfig {
  /**
   * Définition des colonnes
   */
  cols : Array<MsFormCol>;
  /**
   * Etat associé a la config
   */
  states : Array<MsFormState>;
}
/**
 * ajout d'une colonne
 */
export interface MsFormCol {
  /**
   * taille d'une colonne 1->12
   */
  width : number;
  /**
   * Déifnition des lignes
   */
  rows : Array<MsFormRow>;
}
/**
 * ajout d'une ligne
 */
export interface MsFormRow {
  /**
   * Une ligne est composée de composants
   */
  components : Array<MsFormComponent>;
}

/**
 * Période de date
 */
export interface MsFormDateRangeValidator {
  /**
   * Id du chamtp de date date
   */
  dateDeb : string;
  /**
   * id du champ de date de fin
   */
  dateFin : string;
  /**
   * Type de date, pour déterminer comment calculer
   */
  typeDate : TypeHtml.DATE|TypeHtml.DATETIME;
  /**
   * diffMax : nombre de jours max d'écart tolérés
   */
  diffMax?:number;
}
ng-template(#btnEdition)
    ng-container(*ngIf='formActions && formActions.actions && (formActions.actions.length>0) && (!formActions.template) || !formActions')
        span.cliquable.fa-stack(*ngIf='state==="showing"',(click)='$event.stopPropagation();state="editing";',
                                [title]="coreServicesProvider.libelleService.getCoreLib('core.formulaireConfig.droit.modifier')", [ngClass]='{"fa-xs": !iconClass}')
            i.fa-circle.fa-stack-2x([ngClass]='iconClass?iconClass:"fal"')
            i.fa-pen.fa-stack-1x([ngClass]='iconClass?iconClass:"far"')
        span.cliquable.fa-stack(*ngIf='state==="editing"',(click)='$event.stopPropagation();doCancel($event);',
                                [title]='coreServicesProvider.libelleService.getCoreLib("core.common.btn.annulerLib")', [ngClass]='{"fa-xs": !iconClass}')
            i.fa-circle.fa-stack-2x([ngClass]='iconClass?iconClass:"fal"')
            i.fa-times.fa-stack-1x([ngClass]='iconClass?iconClass:"far"')
        span.fa-stack(*ngIf='state==="editing"',(click)='$event.stopPropagation();isSaving?undefined:doSave($event);',
                      [ngClass]='{"cliquable":!getFormKO(),"disabled":getFormKO(), "fa-xs": !iconClass}',
                      [title]="coreServicesProvider.libelleService.getCoreLib('core.common.btn.enregistrerLib')")
            i.fa-circle.fa-stack-2x([ngClass]='iconClass?iconClass:"fal"')
            i.fa-check.fa-stack-1x([ngClass]='iconClass?iconClass:"far"')
        .actions(*ngIf='formActions && (!formActions.template) && (formActions.actions.length>0) && state==="showing"')
                ng-container(*ngFor='let action of formActions.actions')
                    span.cliquable.fa-stack((click)='onActionClick.emit({action: action, data: data, event: $event})',
                                            [title]='action?.libelle', *ngIf='droits && (droits.U==="1")')
                        i.fas.fa-circle.fa-stack-2x
                        i([ngClass]='formActions.icons[action.code]+" fa-stack-1x"')
    ng-container(*ngIf='formActions && formActions.template && formActions.actions && (formActions.actions.length>0)')
        .actions
            ng-container(*ngFor='let action of formActions.actions')
                ng-container([ngTemplateOutlet]='formActions.template',
                             [ngTemplateOutletContext]='{$implicit:self, action:action, icons: formActions.icons}')
ng-template(#edition)
    div(*ngFor='let col of editConfig.cols',[ngClass]='"col-md-"+col.width')
        .row(*ngFor='let row of col.rows')
            div(*ngFor='let component of row.components',[ngClass]='"col-md-"+component.width',[ngSwitch]='metas[component.meta]?.type')

                ng-container(*ngIf="inputTemplates && inputTemplates[component.name]",[ngTemplateOutlet]="inputTemplates[component.name]",[ngTemplateOutletContext]='{meta:metas[component.meta],data:data[component.data], form:form,state:state,component:component,$implicit : self}')

                ng-container(*ngIf='(data[component.data]!==undefined) && (metas[component.meta]!==undefined) && (!(inputTemplates && inputTemplates[component.name]))')

                    ms-drag-drop-file(*ngSwitchCase='"Document"',[(data)]='data[component.data]',[(meta)]='metas[component.meta]',[form]='form',name='{{component.name}}',
                        [formComponent]='self', (dataChange)='onDataChange.emit({name:component.name,data:$event})')
                    ms-adresse(*ngSwitchCase='"Adresse"',
                        [form]='form', [(data)]='data[component.data]',
                        [viewDataType]='component.configAdr.viewDataType ? component.configAdr.viewDataType : undefined',
                        [isLs]='component.configAdr.isLs?component.configAdr.isLs:((droits && droits.U==="0")?"1":"0")', name='{{component.name}}',
                        [isRefPersonne]='component.configAdr.isRefPersonne ? component.configAdr.isRefPersonne: false',
                        [apiParam]='component.configAdr.apiParam ? component.configAdr.apiParam : null',
                        [allowShowDetail]='component.configAdr.allowShowDetail?component.configAdr.allowShowDetail:false',
                        (onRegisterController)='component.configAdr.onRegisterController ? doRegisterController($event) : undefined',
                        [formComponent]='self', [droits]='droits', [addCommuneOptions]='component.configAdr.addCommuneOptions ? component.configAdr.addCommuneOptions : undefined')
                    ms-input(*ngSwitchDefault,[(data)]='data[component.data]',[(meta)]='metas[component.meta]',[form]='form',[config]='component.config',name='{{component.name}}',type='{{component.type}}',
                    [formComponent]='self',(onDataChange)='onDataChange.emit({name:component.name,data:$event})',[autoFocus]='config.autoFocusOn===component.name')

ng-template(#showing)
    div(*ngFor='let col of showConfig.cols',[ngClass]='"col-md-"+col.width')
        .row(*ngFor='let row of col.rows')
            div(*ngFor='let component of row.components',[ngClass]='"col-md-"+component.width')

                ng-container(*ngIf="((state==='showing') && inputTemplates && inputTemplates[component.name])",[ngTemplateOutlet]="inputTemplates[component.name]",[ngTemplateOutletContext]='{meta:metas[component.meta],data:data[component.data], form:form,state:state,component:component,$implicit : self}')

                ng-container(*ngIf='getDatasMetas(component) as datasMetas')
                    ng-container([ngSwitch]='datasMetas.metas?.type')
                        ms-adresse(*ngSwitchCase='"Adresse"',
                                  [form]='form', [(data)]='datasMetas.datas',
                                  [viewDataType]='component.configAdr.viewDataType ? component.configAdr.viewDataType : undefined',
                                  [isLs]='"1"', name='{{component.name}}',
                                  [isRefPersonne]='component.configAdr.isRefPersonne ? component.configAdr.isRefPersonne: false',
                                  [apiParam]='component.configAdr.apiParam ? component.configAdr.apiParam : null',
                                  [allowShowDetail]='component.configAdr.allowShowDetail?component.configAdr.allowShowDetail:false',
                                  [isStandAlone]='true',[formComponent]='self',[droits]='droits', [addCommuneOptions]='component.configAdr.addCommuneOptions ? component.configAdr.addCommuneOptions : undefined')
                        ng-container(*ngIf='(datasMetas.datas!==undefined) && (datasMetas.metas!==undefined) && (datasMetas.metas!==null) && (!(inputTemplates && inputTemplates[component.name]))')
                            ng-container(*ngIf='isArrayElement(component) && datasMetas.datas[datasMetas.firstMeta]!==undefined || (!isArrayElement(component))')
                                ms-visu-only-input(*ngSwitchDefault, id='{{component.name}}', [datas]='datasMetas.datas',[metas]='datasMetas.metas',[config]='component.config',name='{{component.name}}',type='{{component.type}}',[dataTemplate]='visuTemplates?visuTemplates[datasMetas.firstMeta]:undefined', [isDataArray]='isArrayElement(component)')
.card(*ngIf='(data)&&(metas)&&(config)&&(form)&&(!config.noCard)',[ngClass]='{"flat-form":flatForm}',
        (keyup.esc)='(!config.useKeyboard)?undefined:doCancel($event);',
        (keyup.enter)='(!config.useKeyboard)?undefined:doSave($event);')
    .card-header(*ngIf='formTitle && (!flatForm)')
        .caption
            span.caption-subject.text-uppercase.text-primary {{formTitle}}
        .pull-right(*ngIf='(config.isStandAlone) && (metasOK) && (droits) && (droits.U==="1"||droits.C==="1") && (parent)')
            ng-container(*ngTemplateOutlet='btnEdition')
    .card-body(*ngIf='(flatForm)')
        .edit-bar(*ngIf='(config.isStandAlone) && (!formTitle) && (metasOK) && (droits) && (droits.U==="1"||droits.C==="1") && (parent)')
            ng-container(*ngTemplateOutlet='btnEdition')
        form(*ngIf='(!config.isStandAlone) || (config.isStandAlone && state==="editing")',[formGroup]="form",autocomplete="off")
            .row
                div(*ngFor='let component of editConfig.cols[0].rows[0].components',[ngClass]='"col-md-"+component.width',[ngSwitch]='metas[component.meta]?.type')
                    ng-container(*ngIf='(data[component.data]!==undefined) && (metas[component.meta]!==undefined)')
                        ms-drag-drop-file(*ngSwitchCase='"Document"',[(data)]='data[component.data]',[(meta)]='metas[component.meta]',[form]='form',name='{{component.name}}',
                            [formComponent]='self', (dataChange)='onDataChange.emit({name:component.name,data:$event})')
                        ms-adresse(*ngSwitchCase='"Adresse"',
                                  [form]='form', [(data)]='data[component.data]',
                                  [viewDataType]='component.configAdr.viewDataType ? component.configAdr.viewDataType : undefined',
                                  [isLs]='component.configAdr.isLs?component.configAdr.isLs:((droits && droits.U==="0")?"1":"0")', name='{{component.name}}',
                                  [isRefPersonne]='component.configAdr.isRefPersonne ? component.configAdr.isRefPersonne: false',
                                  [apiParam]='component.configAdr.apiParam ? component.configAdr.apiParam : null',
                                  [allowShowDetail]='component.configAdr.allowShowDetail?component.configAdr.allowShowDetail:false',
                                  (onRegisterController)='component.configAdr.onRegisterController ? doRegisterController($event) : undefined',
                                  [formComponent]='self', [droits]='droits', [addCommuneOptions]='component.configAdr.addCommuneOptions ? component.configAdr.addCommuneOptions : undefined')
                        ms-input(*ngSwitchDefault,[(data)]='data[component.data]',[(meta)]='metas[component.meta]',[form]='form',[config]='component.config',name='{{component.name}}',type='{{component.type}}',
                        [formComponent]='self',(onDataChange)='onDataChange.emit({name:component.name,data:$event})',[autoFocus]='config.autoFocusOn===component.name',
                        (keyup.enter)='(config.useKeyboard  && (component.type==="HTMLCOMMENT"))?$event.stopPropagation():undefined')
        .row(*ngIf='(config.isStandAlone && state==="showing")')
            div(*ngFor='let component of showConfig.cols[0].rows[0].components',[ngClass]='"col-md-"+component.width')
                ng-container(*ngIf='getDatasMetas(component) as datasMetas')
                    ms-visu-only-input(id='{{component.name}}', [datas]='datasMetas.datas',[metas]='datasMetas.metas',[config]='component.config',name='{{component.name}}',type='{{component.type}}',[dataTemplate]='visuTemplates?visuTemplates[datasMetas.firstMeta]:undefined')

    .card-body(*ngIf='(!flatForm)')
        .row(*ngIf='(config.isStandAlone) && (!formTitle) && (metasOK) && (droits) && (droits.U==="1"||droits.C==="1") && (parent)')
            .col-md-12.edit-bar
                .pull-right
                    ng-container(*ngTemplateOutlet='btnEdition')
        form(*ngIf='(!config.isStandAlone) || (config.isStandAlone && state==="editing")',[formGroup]="form",autocomplete="off")
            .row
                ng-container(*ngTemplateOutlet='edition')
        .row(*ngIf='(config.isStandAlone && state==="showing")')
            ng-container(*ngTemplateOutlet='showing')
div(*ngIf='(data)&&(metas)&&(config)&&(form)&&(config.noCard)',
    (keyup.esc)='(!config.useKeyboard)?undefined:doCancel($event);',
    (keyup.enter)='(!config.useKeyboard)?undefined:doSave($event);')
    .row
        .col-md-12.edit-bar
            .caption(*ngIf='formTitle')
                span.caption-subject.text-uppercase.text-primary {{formTitle}}
            .pull-right(*ngIf='(config.isStandAlone) && (metasOK) && (droits) && (droits.U==="1"||droits.C==="1") && (parent)')
                ng-container(*ngTemplateOutlet='btnEdition')
    form(*ngIf='(!config.isStandAlone) || (config.isStandAlone && state==="editing")',[formGroup]="form",autocomplete="off")
        .row
            ng-container(*ngTemplateOutlet='edition')
    .row(*ngIf='(config.isStandAlone && state==="showing")')
        ng-container(*ngTemplateOutlet='showing')

UTILISATION

ms-standard-modal([bodyTemplate]='bodyTemplate')
ng-template(#bodyTemplate, let-modal)
    ms-form([form]='modal.forms?.defaultForm', [(data)]='modal.data', [(metas)]='modal.metas', [config]='formConfig', (onDataChange)='onDataChange($event)')
MsArrayUtils.findObjects(<any[]>this.formConfig.statesConfigs[0].cols, 'name', 'donnee', true)[0].config.needsApiParam = true;
MsArrayUtils.findObjects(<any[]>this.formConfig.statesConfigs[0].cols, 'name', 'donnee', true)[0].config.apiParam = a_result.data.refTypeDonneeSante_BenefDonneeSanteR;

this.formConfig = {
      statesConfigs: [{
        states: [MsFormState.EDITING],
        cols: [{
          width: 12,
          rows: [{
            components: [{
              width: 5,
              name: 'type',
              meta: 'refTypeDonneeSante_BenefDonneeSanteR',
              data: 'refTypeDonneeSante_BenefDonneeSanteR',
              type: MsInputType.SELECT,
              config: { id: 'id_TypeR', lib: 'lib_TypeR', needsApiParam: false, api: this.donneesSanteTypeService }
            }, {
              width: 7,
              name: 'donnee',
              meta: 'refParamDonneeSante_BenefDonneeSanteR',
              data: 'refParamDonneeSante_BenefDonneeSanteR',
              type: MsInputType.SELECT,
              config: { id: 'id_ParamDonneeSanteR', lib: 'lib_ParamDonneeSanteR', needsApiParam: false, api: this.paramDonneesSanteTypeService, searchable: true }
            }]
          }, {
            components: [{
              width: 12,
              name: 'datedebut',
              meta: 'comment_BenefDonneeSanteR',
              data: 'comment_BenefDonneeSanteR',
              type: MsInputType.HTMLCOMMENT
            }]
          }, {
            components: [{
              width: 4,
              name: 'mois',
              meta: 'refTypeMois_BenefDonneeSanteR',
              data: 'refTypeMois_BenefDonneeSanteR'
            }, {
              width: 4,
              name: 'annee',
              meta: 'annee_BenefDonneeSanteR',
              data: 'annee_BenefDonneeSanteR',
              type: MsInputType.SELECT,
              config: { id: 'id_AnneeAPI', lib: 'lib_AnneeAPI', searchable: true, needsApiParam: true, api: this.timeCoreAnneeService, apiParam: '100/0' }
            }, {
              width: 4,
              name: 'important',
              meta: 'importante_BenefDonneeSanteR',
              data: 'importante_BenefDonneeSanteR',
              type: MsInputType.CHECKBOX
            }]
          }]
        }]
      }]
    }
  }