Project

General

Profile

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

    
15

    
16
@Component({
17
  selector : 'form-repeat',
18
  template : `
19
<div [formGroup]="parentGroup"
20
     class="interfacesForm uk-margin uk-grid-match uk-child-width-1-1 uk-child-width-1-2@m
21
            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="far fa-plus-square" aria-hidden="true"></i>
28
        <span class="info">Add New {{ description.label }}</span>
29
      </a>
30
    </div>
31
  </div>
32
</div>
33
<confirmation-dialog #confirmDelete [title]="'Delete '+ description.label" [isModalShown]="isModalShown"
34
                     [confirmActionButton]="'Yes, delete it'" (emitObject)="confirmedRemove($event)">
35
  Are you sure you want to delete this {{description.label}}?
36
</confirmation-dialog>`
37

    
38
})
39
export class MyArray extends MyGroup {
40

    
41
  @Input() public component: Type<MyGroup>;
42

    
43
  @Input() public wrapper: Type<MyWrapper> = MyArrayWrapper;
44

    
45
  @Input() public initEmpty: boolean = false;
46

    
47
  @ViewChild(MyFormDirective, { static: true }) protected formComponents: MyFormDirective;
48

    
49
  protected _cfr: ComponentFactoryResolver;
50

    
51
  protected viewContainerRef: ViewContainerRef;
52

    
53
  arrayData_: Subject<any>[] = [];
54

    
55
  components: MyGroup[] = [];
56

    
57
  isModalShown: boolean = false;
58
  curIntrf: any;
59
  curIndex: number;
60

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

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

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

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

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

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

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

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

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

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

    
158
  @ViewChild('confirmDelete')
159
  public confirmDelete: ConfirmationDialogComponent;
160

    
161
  @Output() emitShowModal: EventEmitter<void> = new EventEmitter<void>();
162

    
163
  confirmRemoveInterface() {
164
    if (this.registerMode) {
165
      this.emitShowModal.emit();
166
    } else {
167
      this.confirmDelete.showModal();
168
    }
169
  }
170

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

    
182
  remove(i: number): void {
183
    this.viewContainerRef.remove(i);
184
  }
185

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

    
203
  }
204

    
205
  get valid() {
206
    return this.parentGroup.valid; // true; // this.registerGroup_.valid;
207
  }
208

    
209

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

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

    
235
})
236
export class MyArrayInline extends MyArray {
237
  @Input()
238
  public wrapper: Type<MyWrapper> = MyInlineArrayWrapper;
239

    
240
  @Input()
241
  public description: Description;
242
}
243

    
244

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

    
255
  `
256

    
257
})
258
export class MyArrayWrapper extends MyWrapper{
259

    
260
}
261

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

    
274
})
275
export class MyInlineArrayWrapper extends MyWrapper {
276
}
(1-1/4)