Jelajahi Sumber

service check editor: implemented data collection for save(); enabled save()

Christian Kahlau 2 tahun lalu
induk
melakukan
25c2c3f586

+ 15 - 1
ng/src/app/components/service-check-editor/service-check-adapter/service-check-adapter.component.ts

@@ -1,4 +1,7 @@
-import { Component, Input } from '@angular/core';
+import { Component, Input, ViewChild } from '@angular/core';
+import { ServiceCheckConjunctionComponent } from 'src/app/components/service-check-editor/service-check-conjunction/service-check-conjunction.component';
+import { ServiceCheckDisjunctionComponent } from 'src/app/components/service-check-editor/service-check-disjunction/service-check-disjunction.component';
+import { ServiceCheckStringComponent } from 'src/app/components/service-check-editor/service-check-string/service-check-string.component';
 
 @Component({
   selector: 'app-service-check-adapter',
@@ -6,6 +9,9 @@ import { Component, Input } from '@angular/core';
   styleUrls: ['./service-check-adapter.component.scss']
 })
 export class ServiceCheckAdapterComponent {
+  @ViewChild(ServiceCheckDisjunctionComponent) disCmp?: ServiceCheckDisjunctionComponent;
+  @ViewChild(ServiceCheckConjunctionComponent) conCmp?: ServiceCheckConjunctionComponent;
+  @ViewChild(ServiceCheckStringComponent) expCmp?: ServiceCheckStringComponent;
   @Input() set model(model: string | CheckDisjunction | CheckConjunction) {
     if (typeof model === 'string') {
       this.stringModel = model;
@@ -27,4 +33,12 @@ export class ServiceCheckAdapterComponent {
   public stringModel?: string;
   public disjunction?: CheckDisjunction;
   public conjunction?: CheckConjunction;
+
+  public collect(): string | CheckDisjunction | CheckConjunction {
+    if (this.expCmp) return this.expCmp.collect();
+    else if (this.conCmp) return this.conCmp.collect();
+    else if (this.disCmp) return this.disCmp.collect();
+
+    throw new Error('Collect in adapter failed: not type detected');
+  }
 }

+ 17 - 13
ng/src/app/components/service-check-editor/service-check-conjunction/service-check-conjunction.component.html

@@ -1,18 +1,22 @@
-<table *ngIf="model?.and" class="check-conjunction border w-100">
+<table *ngIf="model?.and" class="check-conjunction w-100">
   <colgroup>
     <col width="20" />
     <col width="*" />
   </colgroup>
-  <tr>
-    <td [attr.rowspan]="(model?.and?.length || 1) + 1" class="bg-max label-upright-vertical">AND</td>
-    <td *ngIf="model?.and?.length" class="ps-2"><app-service-check-adapter [model]="model?.and?.[0] ?? ''"></app-service-check-adapter></td>
-  </tr>
-  <tr *ngFor="let check of model?.and | slice : 1">
-    <td class="ps-2"><app-service-check-adapter [model]="check"></app-service-check-adapter></td>
-  </tr>
-  <tr>
-    <td class="ps-2">
-      <app-service-check-button-controls (create)="model?.and?.push($event)"></app-service-check-button-controls>
-    </td>
-  </tr>
+  <tbody>
+    <tr>
+      <td [attr.rowspan]="(model?.and?.length || 1) + 1" class="bg-max label-upright-vertical">AND</td>
+      <td *ngIf="model?.and?.length" class="p-0">
+        <app-service-check-adapter [model]="model?.and?.[0] ?? ''"></app-service-check-adapter>
+      </td>
+    </tr>
+    <tr *ngFor="let check of model?.and | slice : 1">
+      <td class="p-0"><app-service-check-adapter [model]="check"></app-service-check-adapter></td>
+    </tr>
+    <tr>
+      <td class="ps-2">
+        <app-service-check-button-controls (create)="model?.and?.push($event)"></app-service-check-button-controls>
+      </td>
+    </tr>
+  </tbody>
 </table>

+ 7 - 1
ng/src/app/components/service-check-editor/service-check-conjunction/service-check-conjunction.component.ts

@@ -1,4 +1,5 @@
-import { Component, Input } from '@angular/core';
+import { Component, Input, QueryList, ViewChildren } from '@angular/core';
+import { ServiceCheckAdapterComponent } from 'src/app/components/service-check-editor/service-check-adapter/service-check-adapter.component';
 
 @Component({
   selector: 'app-service-check-conjunction',
@@ -6,5 +7,10 @@ import { Component, Input } from '@angular/core';
   styleUrls: ['./service-check-conjunction.component.scss']
 })
 export class ServiceCheckConjunctionComponent {
+  @ViewChildren(ServiceCheckAdapterComponent) adapters!: QueryList<ServiceCheckAdapterComponent>;
   @Input() model?: CheckConjunction;
+
+  public collect() {
+    return this.adapters.map(adpt => adpt.collect());
+  }
 }

+ 15 - 13
ng/src/app/components/service-check-editor/service-check-disjunction/service-check-disjunction.component.html

@@ -1,18 +1,20 @@
-<table *ngIf="model" class="check-disjunction border w-100">
+<table *ngIf="model" class="check-disjunction w-100">
   <colgroup>
     <col width="20" />
     <col width="*" />
   </colgroup>
-  <tr>
-    <td [attr.rowspan]="(model.length || 1) + 1" class="bg-peak label-upright-vertical">OR</td>
-    <td *ngIf="model.length" class="ps-2"><app-service-check-adapter [model]="model[0]"></app-service-check-adapter></td>
-  </tr>
-  <tr *ngFor="let check of model | slice : 1">
-    <td class="ps-2"><app-service-check-adapter [model]="check"></app-service-check-adapter></td>
-  </tr>
-  <tr>
-    <td class="ps-2">
-      <app-service-check-button-controls (create)="model.push($event)"></app-service-check-button-controls>
-    </td>
-  </tr>
+  <tbody>
+    <tr>
+      <td [attr.rowspan]="(model.length || 1) + 1" class="bg-peak label-upright-vertical">OR</td>
+      <td *ngIf="model.length" class="p-0"><app-service-check-adapter [model]="model[0]"></app-service-check-adapter></td>
+    </tr>
+    <tr *ngFor="let check of model | slice : 1">
+      <td class="p-0"><app-service-check-adapter [model]="check"></app-service-check-adapter></td>
+    </tr>
+    <tr>
+      <td class="ps-2">
+        <app-service-check-button-controls (create)="model.push($event)"></app-service-check-button-controls>
+      </td>
+    </tr>
+  </tbody>
 </table>

+ 7 - 1
ng/src/app/components/service-check-editor/service-check-disjunction/service-check-disjunction.component.ts

@@ -1,4 +1,5 @@
-import { Component, Input } from '@angular/core';
+import { Component, Input, QueryList, ViewChildren } from '@angular/core';
+import { ServiceCheckAdapterComponent } from 'src/app/components/service-check-editor/service-check-adapter/service-check-adapter.component';
 
 @Component({
   selector: 'app-service-check-disjunction',
@@ -6,5 +7,10 @@ import { Component, Input } from '@angular/core';
   styleUrls: ['./service-check-disjunction.component.scss']
 })
 export class ServiceCheckDisjunctionComponent {
+  @ViewChildren(ServiceCheckAdapterComponent) adapters!: QueryList<ServiceCheckAdapterComponent>;
   @Input() model?: CheckDisjunction;
+
+  public collect() {
+    return this.adapters.map(adpt => adpt.collect());
+  }
 }

+ 4 - 0
ng/src/app/components/service-check-editor/service-check-string/service-check-string.component.ts

@@ -7,4 +7,8 @@ import { Component, Input } from '@angular/core';
 })
 export class ServiceCheckStringComponent {
   @Input() model?: string;
+
+  public collect() {
+    return this.model ?? '';
+  }
 }

+ 1 - 1
ng/src/app/components/service-check-form/service-check-form.component.html

@@ -79,7 +79,7 @@
   <div class="row border-top">
     <div class="col-12">
       <label class="mt-2">Check</label>
-      <div class="mt-2 position-relative">
+      <div class="mt-2 position-relative border">
         <app-service-check-disjunction [model]="serviceCheck.checks"></app-service-check-disjunction>
       </div>
     </div>

+ 11 - 36
ng/src/app/components/service-check-form/service-check-form.component.ts

@@ -1,25 +1,21 @@
-import { Component, ElementRef, Input, OnInit, QueryList, ViewChildren } from '@angular/core';
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
 import { FormControl, FormGroup, FormArray, FormBuilder } from '@angular/forms';
 import { faMinusSquare, faPlusSquare } from '@fortawesome/free-solid-svg-icons';
-import { ServiceApiService } from '../../services/service-api.service';
+
 import { deepCopy } from '../../../../../common/util/object-utils';
 
+import { ServiceCheckDisjunctionComponent } from 'src/app/components/service-check-editor/service-check-disjunction/service-check-disjunction.component';
+import { ServiceApiService } from 'src/app/services/service-api.service';
+
 @Component({
   selector: 'app-service-check-form',
   templateUrl: './service-check-form.component.html',
   styleUrls: ['./service-check-form.component.scss']
 })
 export class ServiceCheckFormComponent implements OnInit {
-  @ViewChildren('checkInput')
-  set checkRows(childs: QueryList<ElementRef<HTMLInputElement>>) {
-    if (childs?.length && childs.get(0)?.nativeElement.value === '') {
-      //new added children via addPattern without value gets focus
-      childs.get(0)?.nativeElement.focus();
-    }
-  }
+  @ViewChild(ServiceCheckDisjunctionComponent) checkEditor!: ServiceCheckDisjunctionComponent;
 
-  @Input()
-  serviceCheck!: HttpCheckConfig;
+  @Input() serviceCheck!: HttpCheckConfig;
   public fa = { plus: faPlusSquare, delete: faMinusSquare };
 
   serviceCheckForm: FormGroup = this.formBuilder.group({
@@ -29,45 +25,24 @@ export class ServiceCheckFormComponent implements OnInit {
     url: '', //constant for defaultValues
     interval: 10, //constant for defaultValues
     timeout: 10, //constant for defaultValuess
-    checks: this.formBuilder.array([]),
     notify: true,
     notifyThreshold: 3
   });
 
   constructor(private formBuilder: FormBuilder, private serviceApi: ServiceApiService) {}
 
-  get checks(): FormArray {
-    return this.serviceCheckForm.controls['checks'] as FormArray;
-  }
-
   ngOnInit(): void {
-    this.patchForm(this.serviceCheck);
-  }
-
-  private patchForm(serviceCheck: HttpCheckConfig) {
-    this.checks.controls = [];
-    serviceCheck.checks.reverse().forEach(e => {
-      this.checks.controls.push(new FormControl(e));
-    });
-    this.serviceCheckForm.patchValue(serviceCheck);
-  }
-
-  addPattern() {
-    this.checks.controls.unshift(new FormControl(''));
-    //focus set via viewChildren setter, here is too early
-  }
-
-  removePattern(index: number) {
-    this.checks.controls.splice(index, 1);
+    this.serviceCheckForm.patchValue(this.serviceCheck);
   }
 
   async save() {
     try {
       this.serviceCheckForm.updateValueAndValidity();
       const copy = deepCopy(this.serviceCheckForm.value as HttpCheckConfig);
-      copy.checks = this.checks.controls.map(e => e.value).reverse();
+      copy.checks = this.checkEditor.collect();
       const savedCheck = await this.serviceApi.saveServiceCheck(this.serviceCheck.serverId as number, copy);
-      this.patchForm(savedCheck);
+      this.serviceCheckForm.patchValue(savedCheck);
+      this.serviceCheck = savedCheck;
     } catch (error: any) {
       console.error(error);
     }

+ 2 - 2
ng/src/app/pages/admin-panel/admin-panel.component.html

@@ -16,12 +16,12 @@
             </button>
           </div>
           <ngb-accordion #acc="ngbAccordion" className="flex-fill">
-            <ngb-panel *ngFor="let serviceCheck of serviceChecks; let i = index">
+            <ngb-panel *ngFor="let serviceCheck of serviceChecks">
               <ng-template ngbPanelHeader let-opened="opened">
                 <button class="accordion-button" ngbPanelToggle [class.collapsed]="!opened" [ngClass]="{ 'bg-primary text-white': opened }">
                   <p class="flex-fill m-0">{{ serviceCheck.title }}</p>
 
-                  <fa-icon class="me-1" (click)="saveServiceCheck(i, $event)" *ngIf="opened" [icon]="fa.save"></fa-icon>
+                  <fa-icon class="me-1" (click)="saveServiceCheck($event)" *ngIf="opened" [icon]="fa.save"></fa-icon>
                 </button>
               </ng-template>
               <ng-template ngbPanelContent>

+ 4 - 4
ng/src/app/pages/admin-panel/admin-panel.component.ts

@@ -1,4 +1,4 @@
-import { Component, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
+import { Component, OnInit, QueryList, ViewChild } from '@angular/core';
 import { faAngleRight, faPlus, faSave, faServer } from '@fortawesome/free-solid-svg-icons';
 import { ServiceApiService } from '../../services/service-api.service';
 import { ServerApiService } from '../../services/server-api.service';
@@ -11,7 +11,7 @@ import { ServiceCheckFormComponent } from '../../components/service-check-form/s
   host: { class: 'd-flex flex-column h-100' }
 })
 export class AdminPanelComponent implements OnInit {
-  @ViewChildren(ServiceCheckFormComponent) formChilds!: QueryList<ServiceCheckFormComponent>;
+  @ViewChild(ServiceCheckFormComponent) formRef!: ServiceCheckFormComponent;
   public serverConfigs: ServerConfig[] = [];
   public serviceChecks: HttpCheckConfig[] = [];
   public fa = { save: faSave, server: faServer, angleRight: faAngleRight, plus: faPlus };
@@ -37,9 +37,9 @@ export class AdminPanelComponent implements OnInit {
     }
   }
 
-  saveServiceCheck(index: number, event: Event) {
+  saveServiceCheck(event: Event) {
     event.stopPropagation();
-    this.formChilds.get(index)?.save();
+    this.formRef?.save();
   }
 
   addServiceCheck(serverId: number) {