[SI-67]: Total Commit (without unit tests) Signed-off-by: Dennis Schmitt <dennis.schmitt@pta.de>
diff --git a/angular.json b/angular.json index 0b2bcf9..504753f 100644 --- a/angular.json +++ b/angular.json
@@ -47,7 +47,13 @@ "output": "/i18n" } ], - "styles": ["projects/grid-failure-information-app/src/styles.scss"], + "styles": [ + "projects/grid-failure-information-app/src/styles.scss", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fontawesome.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-regular.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-brands.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-solid.css" + ], "scripts": [ { "input": "node_modules/document-register-element/build/document-register-element.js" @@ -164,7 +170,10 @@ "styles": [ "./node_modules/leaflet/dist/leaflet.css", "./node_modules/bootstrap/dist/css/bootstrap.css", - "./node_modules/font-awesome/css/font-awesome.min.css" + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fontawesome.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-regular.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-brands.css", + "node_modules/@fortawesome/fontawesome-free-webfonts/css/fa-solid.css" ], "scripts": [
diff --git a/package.json b/package.json index 767021e..9b708a8 100644 --- a/package.json +++ b/package.json
@@ -38,6 +38,7 @@ "@angular/router": "^8.2.14", "@auth0/angular-jwt": "^3.0.1", "@ng-bootstrap/ng-bootstrap": "^5.1.5", + "@fortawesome/fontawesome-free-webfonts": "^1.0.9", "@ngrx/core": "^1.2.0", "@ngrx/effects": "^8.6.0", "@ngrx/store": "^8.6.0",
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts index 7d1b338..23ac12a 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-api-client.ts
@@ -10,8 +10,9 @@ * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ +import { Action } from '@ngrx/store'; import { Injectable } from '@angular/core'; -import { HttpService, GET, Adapter, DefaultHeaders } from '@app/shared/async-services/http'; +import { HttpService, Query, GET, Path, Adapter, PUT, Body, DefaultHeaders } from '@app/shared/async-services/http'; import { Observable } from 'rxjs'; import { GridFailureService } from '@pages/grid-failure/grid-failure.service'; import { GridFailure } from '@shared/models'; @@ -24,7 +25,13 @@ export class GridFailureApiClient extends HttpService { @GET('/grid-failure-informations') @Adapter(GridFailureService.gridAdapter) - public getGridFailures(): Observable<GridFailure[]> { + public getAddressTypes(): Observable<GridFailure[]> { + return null; + } + + @GET('/grid-failure-informations/{gridFailureId}') + @Adapter(GridFailureService.itemAdapter) + public getGridFailureDetails(@Path('gridFailureId') gridFailureId: string): Observable<GridFailure> { return null; } }
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html new file mode 100644 index 0000000..6901809 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html
@@ -0,0 +1,417 @@ +<!-- /******************************************************************************** +* Copyright (c) 2020 Contributors to the Eclipse Foundation +* +* See the NOTICE file(s) distributed with this work for additional +* information regarding copyright ownership. +* +* This program and the accompanying materials are made available under the +* terms of the Eclipse Public License v. 2.0 which is available at +* http://www.eclipse.org/legal/epl-2.0. +* +* SPDX-License-Identifier: EPL-2.0 +********************************************************************************/ --> +<app-card-layout> + <div header> + <span>{{ 'GridFailure.Title' | translate }}</span> + </div> + <div class="grid-failure-grid-wrapper" body> + <form [ngrxFormState]="gridFailureSandbox.gridFailureDetailsFormState$ | async"> + <div> + <div class="section"> + <label class="heading">Störungsinformation</label> + <!-- failureClassification --> + <div class="form-group row"> + <label for="failureClassification" class="col-sm-2 col-form-label">{{ 'GridFailure.FailureClassification' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="failureClassification" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureClassification']" + autocomplete="off" + /> + </div> + </div> + + <!-- failureType --> + <div class="form-group row"> + <label for="failureType" class="col-sm-2 col-form-label">{{ 'GridFailure.FailureType' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="failureType" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureType']" + autocomplete="off" + /> + </div> + </div> + + <!-- responsibility --> + <div class="form-group row"> + <label for="responsibility" class="col-sm-2 col-form-label">{{ 'GridFailure.Responsibility' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="responsibility" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['responsibility']" + autocomplete="off" + /> + </div> + </div> + + <!-- internExtern --> + <div class="form-group row"> + <label for="internExtern" class="col-sm-2 col-form-label">{{ 'GridFailure.InternExtern' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="internExtern" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['internExtern']" + autocomplete="off" + /> + </div> + </div> + + <!-- statusIntern --> + <div class="form-group row"> + <label for="statusIntern" class="col-sm-2 col-form-label">{{ 'GridFailure.StatusIntern' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="statusIntern" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['statusIntern']" + autocomplete="off" + /> + </div> + </div> + + <!-- statusExtern --> + <div class="form-group row"> + <label for="statusExtern" class="col-sm-2 col-form-label">{{ 'GridFailure.StatusExtern' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="statusExtern" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['statusExtern']" + autocomplete="off" + /> + </div> + </div> + </div> + + <div class="section"> + <label class="heading">Störungsdetails</label> + + <!-- branch --> + <div class="form-group row"> + <label for="branch" class="col-sm-2 col-form-label">{{ 'GridFailure.Branch' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="branch" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['branch']" + autocomplete="off" + /> + </div> + </div> + + <!-- voltageLevel --> + <div class="form-group row"> + <label for="voltageLevel" class="col-sm-2 col-form-label">{{ 'GridFailure.VoltageLevel' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="voltageLevel" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['voltageLevel']" + autocomplete="off" + /> + </div> + </div> + + <!-- pressureLevel --> + <div class="form-group row"> + <label for="pressureLevel" class="col-sm-2 col-form-label">{{ 'GridFailure.PressureLevel' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="pressureLevel" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['pressureLevel']" + autocomplete="off" + /> + </div> + </div> + + <!-- failureBegin --> + <div class="form-group row"> + <label for="failureBegin" class="col-sm-2 col-form-label">{{ 'GridFailure.FailureBegin' | translate }}</label> + <div class="input-group col-sm-4"> + <div class="input-group-prepend"> + <button class="btn btn-outline-primary calendar" (click)="failureBeginCalendar.toggle()" type="button"> + <em class="fa fa-calendar"></em> + </button> + </div> + <input + class="form-control" + type="text" + placeholder="tt.mm.jjjj" + ngbDatepicker + #failureBeginCalendar="ngbDatepicker" + id="failureBegin" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureBegin']" + [ngrxValueConverter]="gridFailureSandbox.dateValueConverter" + readonly + /> + <div class="input-group-append"> + <button class="btn btn-outline-primary calendar" (click)="reset('failureBegin')" type="button"> + <em class="fa fa-times-circle" aria-hidden="true"></em> + </button> + </div> + </div> + </div> + + <!-- failureEndPlanned --> + <div class="form-group row"> + <label for="failureEndPlanned" class="col-sm-2 col-form-label">{{ 'GridFailure.FailureEndPlanned' | translate }}</label> + <div class="input-group col-sm-4"> + <div class="input-group-prepend"> + <button class="btn btn-outline-primary calendar" (click)="failureEndPlannedCalendar.toggle()" type="button"> + <em class="fa fa-calendar"></em> + </button> + </div> + <input + class="form-control" + type="text" + placeholder="tt.mm.jjjj" + ngbDatepicker + #failureEndPlannedCalendar="ngbDatepicker" + id="failureEndPlanned" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndPlanned']" + [ngrxValueConverter]="gridFailureSandbox.dateValueConverter" + readonly + /> + <div class="input-group-append"> + <button class="btn btn-outline-primary calendar" (click)="reset('failureEndPlanned')" type="button"> + <em class="fa fa-times-circle" aria-hidden="true"></em> + </button> + </div> + </div> + </div> + + <!-- failureEndResupplied --> + <div class="form-group row"> + <label for="failureEndResupplied" class="col-sm-2 col-form-label">{{ 'GridFailure.FailureEndResupplied' | translate }}</label> + <div class="input-group col-sm-4"> + <div class="input-group-prepend"> + <button class="btn btn-outline-primary calendar" (click)="failureEndResuppliedCalendar.toggle()" type="button"> + <em class="fa fa-calendar"></em> + </button> + </div> + <input + class="form-control" + type="text" + placeholder="tt.mm.jjjj" + ngbDatepicker + #failureEndResuppliedCalendar="ngbDatepicker" + id="failureEndResupplied" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndResupplied']" + [ngrxValueConverter]="gridFailureSandbox.dateValueConverter" + readonly + /> + <div class="input-group-append"> + <button class="btn btn-outline-primary calendar" (click)="reset('failureEndResupplied')" type="button"> + <em class="fa fa-times-circle" aria-hidden="true"></em> + </button> + </div> + </div> + </div> + + <!-- probableReason --> + <div class="form-group row"> + <label for="probableReason" class="col-sm-2 col-form-label">{{ 'GridFailure.ProbableReason' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="probableReason" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['probableReason']" + autocomplete="off" + /> + </div> + </div> + + <!-- internalRemark --> + <div class="form-group row"> + <label for="internalRemark" class="col-sm-2 col-form-label">{{ 'GridFailure.InternalRemark' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="internalRemark" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['internalRemark']" + autocomplete="off" + /> + </div> + </div> + </div> + + <div class="section"> + <label class="heading">Störungsort [NS]</label> + <!-- postcode --> + <div class="form-group row"> + <label for="postcode" class="col-sm-2 col-form-label">{{ 'GridFailure.Postcode' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="postcode" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['postcode']" + autocomplete="off" + /> + </div> + </div> + + <!-- district --> + <div class="form-group row"> + <label for="district" class="col-sm-2 col-form-label">{{ 'GridFailure.District' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="district" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['district']" + autocomplete="off" + /> + </div> + </div> + + <!-- city --> + <div class="form-group row"> + <label for="city" class="col-sm-2 col-form-label">{{ 'GridFailure.City' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="city" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['city']" + autocomplete="off" + /> + </div> + </div> + + <!-- street --> + <div class="form-group row"> + <label for="street" class="col-sm-2 col-form-label">{{ 'GridFailure.Street' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="street" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['street']" + autocomplete="off" + /> + </div> + </div> + + <!-- housenumber --> + <div class="form-group row"> + <label for="housenumber" class="col-sm-2 col-form-label">{{ 'GridFailure.Housenumber' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="housenumber" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['housenumber']" + autocomplete="off" + /> + </div> + </div> + </div> + + <div class="section"> + <label class="heading">Stationsattribute [MS]</label> + + <!-- stationDescription --> + <div class="form-group row"> + <label for="stationDescription" class="col-sm-2 col-form-label">{{ 'GridFailure.StationDescription' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="stationDescription" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['stationDescription']" + autocomplete="off" + /> + </div> + </div> + + <!-- stationCoords --> + <div class="form-group row"> + <label for="stationCoords" class="col-sm-2 col-form-label">{{ 'GridFailure.StationCoords' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="stationCoords" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['stationCoords']" + autocomplete="off" + /> + </div> + </div> + + <!-- radius --> + <div class="form-group row"> + <label for="radius" class="col-sm-2 col-form-label">{{ 'GridFailure.Radius' | translate }}</label> + <div class="col-sm-4"> + <input + type="text" + maxlength="255" + class="form-control" + id="radius" + [ngrxFormControlState]="((gridFailureSandbox.gridFailureDetailsFormState$ | async)?.controls)['radius']" + autocomplete="off" + /> + </div> + </div> + </div> + + <!-- buttons --> + <div class="row justify-content-between"> + <div> + <!-- <button type="button" class="btn btn-success person-buttons" (click)="gridFailureSandbox.persistGridFailure()"> + {{ 'SaveBtn' | translate }} + </button> --> + <button type="button" class="btn btn-primary person-buttons cancel-button" routerLink="/grid-failures"> + {{ 'CancelBtn' | translate }} + </button> + </div> + </div> + </div> + </form> + </div> +</app-card-layout>
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss new file mode 100644 index 0000000..871c81f --- /dev/null +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss
@@ -0,0 +1,48 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +.heading { + margin: 8px 0px 16px 0px; + font-weight: bold; +} + +.grid-failure-grid-wrapper { + margin: 10px; +} +.section { + padding: 10px; + margin: 25px 0px; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.section:first-child { + margin: 5px 0px 25px 0px; +} +.input-group-prepend > button { + height: 34px; + padding: 1px 10px; + margin: 0px; + border: 1px solid rgba(0, 0, 0, 0.15); +} +.input-group-append > button { + height: 34px; + padding: 1px 10px; + margin: 0px; + border: 1px solid rgba(0, 0, 0, 0.15); +} +.input-group > input { + padding-left: 16px; + width: 247px; +} +.cancel-button { + margin-left: 15px; +}
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts new file mode 100644 index 0000000..09edda5 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts
@@ -0,0 +1,36 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GridFailureDetailsComponent } from './grid-failure-details.component'; + +describe('GridFailureDetailsComponent', () => { + let component: GridFailureDetailsComponent; + let fixture: ComponentFixture<GridFailureDetailsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [GridFailureDetailsComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GridFailureDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +});
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.ts new file mode 100644 index 0000000..953c802 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.ts
@@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +import { Component, OnInit } from '@angular/core'; +import { GridFailureSandbox } from '@pages/grid-failure/grid-failure.sandbox'; + +@Component({ + selector: 'app-grid-failure-details', + templateUrl: './grid-failure-details.component.html', + styleUrls: ['./grid-failure-details.component.scss'], +}) +export class GridFailureDetailsComponent implements OnInit { + constructor(public gridFailureSandbox: GridFailureSandbox) {} + + ngOnInit() {} + + reset(resetProperty: string) { + this.gridFailureSandbox.clearGridFailurePropertyData(resetProperty); + } +}
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.ts index 8b61429..2654d66 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list.component.ts
@@ -15,6 +15,7 @@ import { SetFilterComponent } from '@shared/filters/ag-grid/set-filter/set-filter.component'; import { GRID_FAILURE_COLDEF } from '@pages/grid-failure/grid-failure-list/grid-failure-list-column-definition'; import { GridFailureSandbox } from '@pages/grid-failure/grid-failure.sandbox'; +import { Router } from '@angular/router'; @Component({ selector: 'app-grid-failure-list', @@ -25,7 +26,7 @@ public columnDefinition: any = GRID_FAILURE_COLDEF; public frameworkComponents: { setFilterComponent: any }; - constructor(public sandbox: GridFailureSandbox) { + constructor(public sandbox: GridFailureSandbox, private router: Router) { super(); this.frameworkComponents = { setFilterComponent: SetFilterComponent }; } @@ -35,5 +36,11 @@ ...this.gridOptions.context, icons: { edit: true }, }; + + this.gridOptions.context.eventSubject.subscribe(event => { + if (event.type === 'edit' || event.type === 'readonly') { + this.router.navigate(['/grid-failures', event.data.id]); + } + }); } }
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-routing.module.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-routing.module.ts index f8839d4..239c31c 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-routing.module.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-routing.module.ts
@@ -13,10 +13,18 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { GridFailureListComponent } from '@pages/grid-failure/grid-failure-list/grid-failure-list.component'; +import { GridFailureDetailsComponent } from '@pages/grid-failure/grid-failure-details/grid-failure-details.component'; import { GridFailuresResolver } from '@pages/grid-failure/grid-failure.resolver'; const gridFailureRoutes: Routes = [ { + path: 'grid-failures/:gridFailureId', + component: GridFailureDetailsComponent, + resolve: { + gridFailureDetails: GridFailuresResolver, + }, + }, + { path: 'grid-failures', component: GridFailureListComponent, resolve: {
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts index ab879eb..858060b 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.module.ts
@@ -13,6 +13,7 @@ import { GridFailureSandbox } from '@pages/grid-failure/grid-failure.sandbox'; import { GridFailureRoutingModule } from '@pages/grid-failure/grid-failure-routing.module'; import { GridFailureListComponent } from '@pages/grid-failure/grid-failure-list/grid-failure-list.component'; +import { GridFailureDetailsComponent } from '@pages/grid-failure/grid-failure-details/grid-failure-details.component'; import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; @@ -35,6 +36,7 @@ import { GridFailuresResolver } from '@pages/grid-failure//grid-failure.resolver'; import { StoreModule } from '@ngrx/store'; import { gridFailureReducers } from '@app/shared/store'; +import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ imports: [ @@ -47,13 +49,14 @@ RouterModule, NgrxFormsModule, FormsModule, + NgbDatepickerModule, StoreModule.forFeature('grid-failure', gridFailureReducers), AgGridModule.withComponents([SetFilterComponent]), EffectsModule.forFeature([GridFailuresEffects]), ContainersModule, GridFailureRoutingModule, ], - declarations: [GridFailureListComponent], + declarations: [GridFailureListComponent, GridFailureDetailsComponent], providers: [GridFailureSandbox, GridFailureService, GridFailureApiClient, GridFailuresResolver], }) export class GridFailureModule {}
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.ts index d98e653..779c2d4 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.ts
@@ -13,14 +13,19 @@ import { GridFailureSandbox } from '@pages/grid-failure/grid-failure.sandbox'; import { Observable } from 'rxjs'; import { Injectable } from '@angular/core'; -import { Resolve } from '@angular/router'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; import { ILoadGridFailuresSuccess } from '@shared/store/actions/grid-failures.action'; @Injectable() export class GridFailuresResolver implements Resolve<any> { constructor(private sandbox: GridFailureSandbox) {} - public resolve(): Observable<ILoadGridFailuresSuccess> { - return this.sandbox.loadGridFailures(); + public resolve(route: ActivatedRouteSnapshot): Observable<any> { + const gridFailureId: string = route.params['gridFailureId']; + if (gridFailureId) { + return this.sandbox.loadGridFailure(gridFailureId); + } else { + return this.sandbox.loadGridFailures(); + } } }
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.sandbox.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.sandbox.ts index d107389..c1bd335 100644 --- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.sandbox.ts +++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.sandbox.ts
@@ -13,24 +13,55 @@ import { BaseListSandbox } from '@shared/sandbox/base-list.sandbox'; import { Injectable } from '@angular/core'; import { Store, ActionsSubject } from '@ngrx/store'; +import { FormGroupState, NgrxValueConverter, SetValueAction } from 'ngrx-forms'; import * as store from '@shared/store'; +import * as gridFailuresDetailFormReducer from '@shared/store/reducers/grid-failures/grid-failure-details-form.reducer'; import { Observable } from 'rxjs'; -import { ILoadGridFailuresSuccess } from '@shared/store/actions/grid-failures.action'; -import * as gridFailureActions from '@shared/store/actions/grid-failures.action'; -import { take } from 'rxjs/operators'; +import { ILoadGridFailuresSuccess, ILoadGridFailureSuccess } from '@shared/store/actions/grid-failures.action'; +import * as gridFailureActions from '@app/shared/store/actions/grid-failures.action'; +import { takeUntil, take } from 'rxjs/operators'; import { ofType } from '@ngrx/effects'; +import { GridFailure } from './../../shared/models/grid-failure.model'; +import { dateValueConverter } from '@shared/utility'; +import { Moment } from 'moment'; @Injectable() export class GridFailureSandbox extends BaseListSandbox { public gridFailureList$ = this.appState$.select(store.getGridFailuresData); public gridFailureListLoading$: Observable<boolean> = this.appState$.select(store.getGridFailuresLoading); + public gridFailureDetailsFormState$: Observable<FormGroupState<GridFailure>> = this.appState$.select(store.getGridFailuresDetails); + constructor(protected appState$: Store<store.State>, protected actionsSubject: ActionsSubject) { super(appState$); } + public dateValueConverter: NgrxValueConverter<Date | null | Moment, string | null> = dateValueConverter; + public loadGridFailures(): Observable<ILoadGridFailuresSuccess> { this.appState$.dispatch(gridFailureActions.loadGridFailures()); return this.actionsSubject.pipe(ofType(gridFailureActions.loadGridFailuresSuccess), take(1)); } + + public loadGridFailure(gridFailureId: string): Observable<ILoadGridFailureSuccess> { + this.appState$.dispatch(gridFailureActions.loadGridFailureDetail({ payload: gridFailureId })); + return this.actionsSubject.pipe(ofType(gridFailureActions.loadGridFailureDetailSuccess), take(1)); + } + + public clearGridFailurePropertyData(property: string): void { + switch (property) { + case 'failureBegin': + this.appState$.dispatch(new SetValueAction(gridFailuresDetailFormReducer.INITIAL_STATE.controls.failureBegin.id, null)); + break; + case 'failureEndPlanned': + this.appState$.dispatch(new SetValueAction(gridFailuresDetailFormReducer.INITIAL_STATE.controls.failureEndPlanned.id, null)); + break; + case 'failureEndResupplied': + this.appState$.dispatch(new SetValueAction(gridFailuresDetailFormReducer.INITIAL_STATE.controls.failureEndResupplied.id, null)); + break; + + default: + break; + } + } }
diff --git a/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts b/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts index 59fc040..818ca78 100644 --- a/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts +++ b/projects/grid-failure-information-app/src/app/shared/store/actions/grid-failures.action.ts
@@ -17,9 +17,17 @@ payload: Array<GridFailure>; } +export interface ILoadGridFailureSuccess { + payload: GridFailure; +} + export interface ILoadGridFailuresFail { payload: string; } export const loadGridFailures = createAction('[GridFailures] Load Page'); export const loadGridFailuresSuccess = createAction('[GridFailures] Load Page Success', props<ILoadGridFailuresSuccess>()); export const loadGridFailuresFail = createAction('[GridFailures] Load Page Fail', props<ILoadGridFailuresFail>()); + +export const loadGridFailureDetail = createAction('[GridFailure Details] Load', props<{ payload: string }>()); +export const loadGridFailureDetailSuccess = createAction('[GridFailure Details] Load Success', props<ILoadGridFailureSuccess>()); +export const loadGridFailureDetailFail = createAction('[GridFailure Details] Load Fail', props<{ payload: string }>());
diff --git a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts index e566510..d5f7ebb 100644 --- a/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts +++ b/projects/grid-failure-information-app/src/app/shared/store/effects/grid-failures.effect.ts
@@ -1,3 +1,4 @@ +import { loadGridFailureDetailSuccess } from './../actions/grid-failures.action'; /******************************************************************************** * Copyright (c) 2020 Contributors to the Eclipse Foundation * @@ -16,9 +17,10 @@ import { Injectable } from '@angular/core'; import { createEffect, Actions, ofType } from '@ngrx/effects'; import { of } from 'rxjs/observable/of'; -import * as gridFailureActions from '@shared/store/actions/grid-failures.action'; +import * as gridFailureActions from '@app/shared/store/actions/grid-failures.action'; import { GridFailureApiClient } from '@pages/grid-failure/grid-failure-api-client'; import { catchError, map, switchMap } from 'rxjs/operators'; +import { GridFailure } from '@shared/models'; import { Store } from '@ngrx/store'; @Injectable() @@ -27,7 +29,7 @@ this._actions$.pipe( ofType(gridFailureActions.loadGridFailures), switchMap(() => { - return this._apiClient.getGridFailures().pipe( + return this._apiClient.getAddressTypes().pipe( map(item => gridFailureActions.loadGridFailuresSuccess({ payload: item })), catchError(error => of(gridFailureActions.loadGridFailuresFail({ payload: error }))) ); @@ -35,5 +37,20 @@ ) ); + /** + * Load gridFailure details + */ + getGridFailureDetails$: any = createEffect(() => + this._actions$.pipe( + ofType(gridFailureActions.loadGridFailureDetail), + switchMap(action => { + return this._apiClient + .getGridFailureDetails(action.payload) + .map((gridFailureDetails: GridFailure) => gridFailureActions.loadGridFailureDetailSuccess({ payload: gridFailureDetails })) + .catch(error => of(gridFailureActions.loadGridFailureDetailFail({ payload: error }))); + }) + ) + ); + constructor(private _actions$: Actions, private _apiClient: GridFailureApiClient, private _store: Store<any>) {} }
diff --git a/projects/grid-failure-information-app/src/app/shared/store/index.ts b/projects/grid-failure-information-app/src/app/shared/store/index.ts index 03dcc98..0427250 100644 --- a/projects/grid-failure-information-app/src/app/shared/store/index.ts +++ b/projects/grid-failure-information-app/src/app/shared/store/index.ts
@@ -19,8 +19,11 @@ */ import * as fromSettings from '@shared/store/reducers/settings.reducer'; import * as fromGridFailures from '@shared/store/reducers/grid-failures/grid-failures.reducer'; +import * as fromGridFailuresDetailForm from '@shared/store/reducers/grid-failures/grid-failure-details-form.reducer'; import { createFeatureSelector } from '@ngrx/store'; import { createSelector } from 'reselect'; +import { GridFailure } from '@shared/models'; +import { FormGroupState } from 'ngrx-forms'; /** * We treat each reducer like a table in a database. This means @@ -32,6 +35,7 @@ export interface GridFailureState { gridFailures: fromGridFailures.State; + gridFailuresDetailForm: FormGroupState<GridFailure>; } /** * Because metareducers take a reducer function and return a new reducer, @@ -46,6 +50,7 @@ export const gridFailureReducers = { gridFailures: fromGridFailures.reducer, + gridFailuresDetailForm: fromGridFailuresDetailForm.reducer, }; /** @@ -78,3 +83,7 @@ export const getGridFailuresLoading = createSelector(selectGridFailures, fromGridFailures.getLoading); export const getGridFailuresFailed = createSelector(selectGridFailures, fromGridFailures.getFailed); export const getGridFailuresData = createSelector(selectGridFailures, fromGridFailures.getData); + +// GridFailures details +export const selectGridFailuresDetails = createSelector(selectGridFailuresState, (state: GridFailureState) => state.gridFailuresDetailForm); +export const getGridFailuresDetails = createSelector(selectGridFailuresDetails, fromGridFailuresDetailForm.getFormState);
diff --git a/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.spec.ts b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.spec.ts new file mode 100644 index 0000000..8d51ae1 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.spec.ts
@@ -0,0 +1,86 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +import { + GridFailuresReducer, + INITIAL_STATE, + getData, + getLoading, + getLoaded, + getFailed, + reducer, +} from '@app/shared/store/reducers/grid-failures/grid-failures.reducer'; +import * as gridFailureActions from '@shared/store/actions/grid-failures.action'; +import { GridFailure } from '@shared/models'; + +describe('AddressTypes reducer', () => { + it('should return the initial state', () => { + const action = { type: 'NOOP' } as any; + const result = reducer(undefined, action); + + expect(result).toBe(INITIAL_STATE); + }); + + it('should trigger loading state', () => { + const action = gridFailureActions.loadGridFailures(); + const result = GridFailuresReducer(INITIAL_STATE, action); + + expect(result).toEqual({ + ...INITIAL_STATE, + loading: true, + }); + }); + + it('should trigger loaded state', () => { + const items: gridFailureActions.ILoadGridFailuresSuccess = { payload: [new GridFailure()] }; + items.payload[0].id = 'testme'; + const action = gridFailureActions.loadGridFailuresSuccess(items); + const result = GridFailuresReducer(INITIAL_STATE, action); + + expect(result.loaded).toBe(true); + }); + + it('should trigger failed state', () => { + const error: gridFailureActions.ILoadGridFailuresFail = { payload: 'err_msg' }; + const action = gridFailureActions.loadGridFailuresFail(error); + const result = GridFailuresReducer(INITIAL_STATE, action); + + expect(result).toEqual({ + ...INITIAL_STATE, + failed: true, + }); + }); + + it('getData return state.data', () => { + const state = { ...INITIAL_STATE }; + const result = getData(state); + expect(result).toBe(state.data); + }); + + it('getLoading return state.loading', () => { + const state = { ...INITIAL_STATE }; + const result = getLoading(state); + expect(result).toBe(state.loading); + }); + + it('getLoaded return state.loaded', () => { + const state = { ...INITIAL_STATE }; + const result = getLoaded(state); + expect(result).toBe(state.loaded); + }); + + it('getFailed return state.failed', () => { + const state = { ...INITIAL_STATE }; + const result = getFailed(state); + expect(result).toBe(state.failed); + }); +});
diff --git a/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.ts b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.ts new file mode 100644 index 0000000..e81c7b6 --- /dev/null +++ b/projects/grid-failure-information-app/src/app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer.ts
@@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2020 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ********************************************************************************/ +import { Action, ActionReducer, INIT } from '@ngrx/store'; +import * as gridFailureActions from '@app/shared/store/actions/grid-failures.action'; +import { createFormGroupState, createFormStateReducerWithUpdate, updateGroup, FormGroupState, FormState, SetValueAction, validate } from 'ngrx-forms'; +import { GridFailure } from '@shared/models'; +import { required } from 'ngrx-forms/validation'; + +export const FORM_ID = 'gridFailureDetailsForm'; + +export const INITIAL_STATE: FormGroupState<GridFailure> = createFormGroupState<GridFailure>(FORM_ID, new GridFailure()); + +export const validateForm: ActionReducer<FormState<GridFailure>> = createFormStateReducerWithUpdate<GridFailure>( + updateGroup<GridFailure>({ + // companyName: validate(required), + }) +); + +export function reducer(state: FormGroupState<GridFailure> = INITIAL_STATE, action: Action): FormGroupState<GridFailure> { + if (!action || action.type === INIT) { + return INITIAL_STATE; + } + + if (action.type === gridFailureActions.loadGridFailureDetailSuccess.type) { + const gridFailure: GridFailure = <GridFailure>action['payload']; + const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, gridFailure); + + return validateForm(state, setValueAction); + } + + return validateForm(state, action); +} + +export const getFormState = (state: FormGroupState<GridFailure>) => state;