Project

General

Profile

1
/**
2
 * Created by stefanos on 15/5/2017.
3
 */
4
import { FormArray, FormGroup } from "@angular/forms";
5
import {
6
  Component, ComponentFactoryResolver, EventEmitter, Injector, Input, Output, Type, ViewChild,
7
  ViewContainerRef
8
} from "@angular/core";
9
import { MyFormDirective } from "./my-form.directive";
10
import { MyGroup } from "./my-group.interface";
11
import { MyWrapper } from "./my-wrapper.interface";
12
import { Description } from '../../../domain/oa-description';
13
import { Subject } from "rxjs/Subject";
14
import {ConfirmationDialogComponent} from "../confirmation-dialog.component";
15
import {nonRemovableInterface} from "../../../domain/shared-messages";
16

    
17

    
18
@Component({
19
  selector : 'form-repeat',
20
  template : `
21
    <div [formGroup]="parentGroup" class="interfacesForm uk-margin uk-grid-match uk-child-width-1-1 uk-child-width-1-2@m uk-grid-small uk-grid uk-scrollspy-inview uk-animation-fade">
22
      <!--<div formArrayName="{{name}}">-->
23
      <ng-template my-form></ng-template>
24
      <!--</div>-->
25
      <div class="el-item uk-card uk-card-default uk-card-body uk-scrollspy-inview uk-animation-fade">
26
        <div class="interface-box new" style="text-align: center">
27
          <a class="add-new-element add-new-group" (click)="push()"><i class="fa fa-plus-square-o" aria-hidden="true"></i>
28
            <span class="info">Add New {{ description.label }}</span></a>
29
        </div>
30
      </div>
31
    </div>
32

    
33

    
34
    <confirmation-dialog #confirmDelete [title]="'Delete '+ description.label" [isModalShown]="isModalShown"
35
                         [confirmActionButton]="'Yes, delete it'" (emitObject)="confirmedRemove($event)">
36
      Are you sure you want to delete this {{description.label}}?
37
    </confirmation-dialog>
38

    
39
  `
40

    
41
})
42
export class MyArray extends MyGroup {
43

    
44
  @Input() public component : Type<MyGroup>;
45

    
46
  @Input() public wrapper : Type<MyWrapper> = MyArrayWrapper;
47

    
48
  @Input() public initEmpty : boolean = false;
49

    
50
  @ViewChild(MyFormDirective) protected formComponents: MyFormDirective;
51

    
52
  protected _cfr : ComponentFactoryResolver;
53

    
54
  protected viewContainerRef : ViewContainerRef;
55

    
56
  arrayData_ : Subject<any>[] = [];
57

    
58
  components : MyGroup[] = [];
59

    
60
  push() {
61
    this.createView();
62
  }
63

    
64
  constructor(injector : Injector) {
65
    super(injector);
66
    this._cfr = injector.get(ComponentFactoryResolver);
67
  }
68

    
69
  protected createView() : void {
70
    let componentFactory = this._cfr.resolveComponentFactory(this.component);
71
    let wrapperFactory = this._cfr.resolveComponentFactory(this.wrapper);
72
    let wrapperView = wrapperFactory.create(this.viewContainerRef.injector);
73
    let componentView = componentFactory.create(this.viewContainerRef.injector);
74
    (<MyGroup>componentView.instance).index = this.viewContainerRef.length;
75
    (<MyGroup>componentView.instance).required = this.required;
76
    (<MyGroup>componentView.instance).data = this.data;
77
    (<MyGroup>componentView.instance).otherData = this.otherData;
78
    if (this.registerMode) {
79
      (<MyGroup>componentView.instance).inRegister = true;
80
    }
81
    this.components.push(<MyGroup>componentView.instance);
82
    this.arrayData_.push((<MyGroup>componentView.instance).patchData);
83
    (<MyGroup>componentView.instance).description = this.description;
84
    let arrayGroup = (<MyGroup>componentView.instance).generate();
85
    (<MyGroup>componentView.instance).parentGroup = arrayGroup as FormGroup;
86
    (<MyWrapper>wrapperView.instance).component = componentView.hostView;
87
    (<MyWrapper>wrapperView.instance).viewRef = wrapperView.hostView;
88
    (<MyWrapper>wrapperView.instance).description = this.description;
89

    
90
    (<MyWrapper>wrapperView.instance).first = this.viewContainerRef.length == 0;
91

    
92
    (<MyWrapper>wrapperView.instance).deleteNotifier.subscribe($event => {
93
      let index = this.viewContainerRef.indexOf($event);
94
      console.log(index);
95
      if( this.viewContainerRef.length == 1 && this.description.mandatory==true) {
96
        console.log(this.viewContainerRef.get(0));
97
        ((this.parentGroup as FormArray).controls[this.name].at(0).corpus((<MyGroup>componentView.instance).generate().value));
98
      } else {
99
        if (index>0){
100
          if (this.registerMode || !(<MyGroup>componentView.instance).wasSaved ) {
101
            this.remove(index);
102
            (this.parentGroup as FormArray).controls[this.name].removeAt(index - 1);
103
            this.components.splice(index, 1);
104
            this.arrayData_.splice(index - 1, 1);
105
          } else {
106
            this.curIntrf = <MyGroup>componentView.instance;
107
            this.curIndex = index;
108
            this.components.splice(index, 1);
109
            this.confirmRemoveInterface();
110
          }
111
        } else {
112
          (<MyGroup>componentView.instance).groupErrorMessage = nonRemovableInterface;
113
        }
114
        /*(<MyGroup>componentView.instance).toBeDeleted = true;
115
        this.remove(index);
116
        (this.parentGroup as FormArray).controls[this.name].removeAt(index-1);
117
        this.arrayData_.splice(index-1,1);*/
118
      }
119
    });
120

    
121
    ((this.parentGroup as FormArray).controls[this.name]).push(arrayGroup);
122

    
123
    this.viewContainerRef.insert(wrapperView.hostView);
124
    console.log("ADDED NEW GROUP IN CREATEVIEW");
125
  }
126

    
127
  @Input() registerMode: boolean;
128
  @Output() emitDataArray: EventEmitter<any[]> = new EventEmitter<any[]>();
129

    
130
  public checkIfOneElementExists() {
131
    console.log(`searching`);
132
    if ( this.components.some(data => data.wasSaved) ) {
133
      let array_to_emit = [];
134
      this.components.forEach(element => {
135
        if (element.exportedData) {
136
          array_to_emit.push(element.exportedData);
137
        }
138
      });
139
      this.emitDataArray.emit(array_to_emit);
140
      return true;
141
    }
142
    return false;
143
  }
144

    
145
  public emitExportedDataArray() {
146
    let array_to_emit = [];
147
    this.components.forEach(element => {
148
      if (element.exportedData) {
149
        array_to_emit.push(element.exportedData);
150
        console.log(element.exportedData);
151
      }
152
    });
153
    this.emitDataArray.emit(array_to_emit);
154
    console.log(`emitted ${array_to_emit.length} interfaces`);
155
  }
156

    
157
  isModalShown: boolean = false;
158
  curIntrf: any;
159
  curIndex: number;
160

    
161
  @ViewChild('confirmDelete')
162
  public confirmDelete: ConfirmationDialogComponent;
163

    
164
  @Output() emitShowModal: EventEmitter<void> = new EventEmitter<void>();
165

    
166
  confirmRemoveInterface(){
167
    if (this.registerMode){
168
      this.emitShowModal.emit();
169
    } else {
170
      this.confirmDelete.showModal();
171
    }
172
  }
173

    
174
  public confirmedRemove(event: any){
175
    if (this.curIndex > 0) {
176
      this.curIntrf.toBeDeleted = true;
177
      this.remove(this.curIndex);
178
      (this.parentGroup as FormArray).controls[this.name].removeAt(this.curIndex - 1);
179
      this.arrayData_.splice(this.curIndex - 1, 1);
180
      this.curIndex = -1;
181
      this.curIntrf = null;
182
    }
183
  }
184

    
185
  remove(i : number) : void {
186
    this.viewContainerRef.remove(i);
187
  }
188

    
189
  ngOnInit(): void {
190
    // super.ngOnInit();
191
    this.viewContainerRef = this.formComponents.viewContainerRef;
192
    (<FormGroup>this.parentGroup).addControl(<string>this.name, this._fb.array([]));
193
/*    (<FormGroup>this.parentGroup).addControl(<string>this.name, this._fb.array([]));
194
    !this.initEmpty && this.createView();
195
    this.parentGroup.get(this.name as string).patchValue = this.patchValue();*/
196
    if (this.data && this.data.length) {
197
      for (let i=0; i<this.data.length; i++ ) {
198
        !this.initEmpty && this.createView();
199
        this.parentGroup.get(this.name as string).patchValue = this.patchValue();
200
      }
201
    } else {
202
      !this.initEmpty && this.createView();
203
      this.parentGroup.get(this.name as string).patchValue = this.patchValue();
204
    }
205

    
206
  }
207

    
208
  get valid() {
209
    return this.parentGroup.valid;//true;//this.registerGroup_.valid;
210
  }
211

    
212

    
213
  protected patchValue() {
214
    let self = this;
215
    return (value: {[key: string]: any}, {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}) => {
216
      for (let i = (<FormArray>self.parentGroup.get(this.name as string)).length; i < Object.keys(value).length; i++) {
217
        self.createView();
218
        console.log("ADDED NEW GROUP");
219
      }
220
      for (let i = 0; i < Object.keys(value).length; i++) {
221
        self.arrayData_[i].next(value[i]);
222
      }
223
    };
224
  }
225
}
226

    
227
@Component({
228
  selector : 'form-repeat-inline',
229
  template : `
230
    <form-inline [description]="description" [valid]="valid">
231
      <ng-template my-form></ng-template>
232
      <a class="add-new-element" (click)="push()">
233
        <i class="fa fa-plus" aria-hidden="true"></i> Add another
234
      </a>
235
    </form-inline>
236
  `
237

    
238
})
239
export class MyArrayInline extends MyArray {
240
  @Input()
241
  public wrapper : Type<MyWrapper> = MyInlineArrayWrapper;
242

    
243
  @Input()
244
  public description : Description;
245
}
246

    
247

    
248
@Component({
249
  selector : 'form-repeat-wrapper',
250
  template : `
251
    <div class="el-item uk-card uk-card-default uk-card-body uk-scrollspy-inview uk-animation-fade">
252
      <div class="interfaceActionsPanel" style="margin-left: 5px;">
253
        <a (click)="remove()"><i class="fa fa-remove fa-lg"></i></a>
254
      </div>
255
      <ng-template my-form></ng-template>
256
    </div>
257

    
258
  `
259

    
260
})
261
export class MyArrayWrapper extends MyWrapper{
262

    
263
}
264

    
265
@Component({
266
  selector : 'form-inline-repeat-wrapper',
267
  template : `
268
    <div class="uk-grid uk-margin">
269
      <div class="uk-width-5-6">
270
        <ng-template my-form></ng-template>
271
      </div>
272
      <a *ngIf="canDelete" class="remove-element uk-width-1-6" (click)="remove()"><i
273
        class="fa fa-times" aria-hidden="true"></i></a>
274
    </div>
275
  `
276

    
277
})
278
export class MyInlineArrayWrapper extends MyWrapper {
279
}
(1-1/4)