Skip to content

Commit

Permalink
feat(pmp): edit repository in settings - front
Browse files Browse the repository at this point in the history
refs #107
  • Loading branch information
ABartoszko authored and MaciejSikorski committed May 20, 2020
1 parent 69c3522 commit 8b0ebe8
Show file tree
Hide file tree
Showing 23 changed files with 314 additions and 122 deletions.
1 change: 1 addition & 0 deletions apps/pmp-web/src/assets/styles/_global.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@import 'components/add-edit-repository-dialog';
@import 'components/content-loader';
@import 'components/spinner-wrapper';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.add-edit-repository-dialog {
max-width: 500px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Action } from '@ngrx/store';
import {
AddRepositoryPayload,
DeleteRepositoryPayload,
EditRepositoryPayload,
Repository
} from '@pimp-my-pr/pmp-web/repository/domain';

Expand All @@ -16,7 +17,10 @@ export namespace fromRepositoryActions {
AddRepositorySuccess = '[Repository] Add Repository Success',
DeleteRepository = '[Repository] Delete Repository',
DeleteRepositoryFail = '[Repository] Delete Repository Fail',
DeleteRepositorySuccess = '[Repository] Delete Repository Success'
DeleteRepositorySuccess = '[Repository] Delete Repository Success',
EditRepository = '[Repository] Edit Repository',
EditRepositoryFail = '[Repository] Edit Repository Fail',
EditRepositorySuccess = '[Repository] Edit Repository Success'
}

export class GetRepositoryCollection implements Action {
Expand Down Expand Up @@ -67,6 +71,22 @@ export namespace fromRepositoryActions {
readonly type = Types.DeleteRepositorySuccess;
}

export class EditRepository implements Action {
readonly type = Types.EditRepository;

constructor(public payload: EditRepositoryPayload) {}
}

export class EditRepositoryFail implements Action {
readonly type = Types.EditRepositoryFail;

constructor(public payload: HttpErrorResponse) {}
}

export class EditRepositorySuccess implements Action {
readonly type = Types.EditRepositorySuccess;
}

export type CollectiveType =
| GetRepositoryCollection
| GetRepositoryCollectionFail
Expand All @@ -76,5 +96,8 @@ export namespace fromRepositoryActions {
| AddRepositorySuccess
| DeleteRepository
| DeleteRepositoryFail
| DeleteRepositorySuccess;
| DeleteRepositorySuccess
| EditRepository
| EditRepositoryFail
| EditRepositorySuccess;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ export class RepositoryEffects {
ofType(fromRepositoryActions.Types.DeleteRepositorySuccess),
map(() => new fromRepositoryActions.GetRepositoryCollection())
);
@Effect()
editRepository$ = this.dp.fetch(fromRepositoryActions.Types.EditRepository, {
run: (action: fromRepositoryActions.EditRepository) => {
return this.repositoryDataService
.editRepository(action.payload)
.pipe(map(() => new fromRepositoryActions.EditRepositorySuccess()));
},
onError: (action: fromRepositoryActions.EditRepository, error: HttpErrorResponse) => {
return new fromRepositoryActions.EditRepositoryFail(error);
}
});
@Effect()
editRepositorySuccess$ = this.actions$.pipe(
ofType(fromRepositoryActions.Types.EditRepositorySuccess),
map(() => new fromRepositoryActions.GetRepositoryCollection())
);

constructor(
private dp: DataPersistence<RepositoryPartialState>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Injectable } from '@angular/core';
import { select, Store } from '@ngrx/store';
import {
AddRepositoryPayload,
DeleteRepositoryPayload
DeleteRepositoryPayload,
EditRepositoryPayload
} from '@pimp-my-pr/pmp-web/repository/domain';
import { fromRepositoryActions } from './repository.actions';
import { RepositoryPartialState } from './repository.reducer';
Expand Down Expand Up @@ -40,4 +41,12 @@ export class RepositoryFacade {
fromRepositoryActions.Types.DeleteRepositoryFail
);
}

editRepository(data: EditRepositoryPayload): Observable<void> {
return this.actionStatusResolverService.resolve(
new fromRepositoryActions.EditRepository(data),
fromRepositoryActions.Types.EditRepositorySuccess,
fromRepositoryActions.Types.EditRepositoryFail
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HttpClient } from '@angular/common/http';
import {
AddRepositoryPayload,
DeleteRepositoryPayload,
EditRepositoryPayload,
Repository
} from '@pimp-my-pr/pmp-web/repository/domain';
import { IResponse } from '@pimp-my-pr/shared/domain';
Expand All @@ -13,7 +14,8 @@ export class RepositoryDataService {
readonly endpoints = {
getRepositoryCollection: urlFactory('/api/repository'),
addRepository: urlFactory('/api/repository'),
deleteRepository: urlFactory<'id'>('/api/repository/:id', true)
deleteRepository: urlFactory<'id'>('/api/repository/:id', true),
editRepository: urlFactory<'id'>('/api/repository/:id', true)
};

constructor(private http: HttpClient) {}
Expand All @@ -31,4 +33,11 @@ export class RepositoryDataService {
deleteRepository(data: DeleteRepositoryPayload): Observable<void> {
return this.http.delete<void>(this.endpoints.deleteRepository.url({ id: data.repositoryId }));
}

editRepository(data: EditRepositoryPayload): Observable<void> {
return this.http.put<void>(this.endpoints.editRepository.url({ id: data.repositoryId }), {
maxLines: data.maxLines,
maxWaitingTime: data.maxWaitingTime
});
}
}
2 changes: 2 additions & 0 deletions libs/pmp-web/repository/domain/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './lib/interfaces/repository.model';
export * from './lib/interfaces/add-edit-repository-dialog-data.interface';
export * from './lib/payloads/get-repository-collection.payload';
export * from './lib/payloads/get-repository-statistics.payload';
export * from './lib/payloads/get-reviewers-statistics-collection.payload';
export * from './lib/payloads/add-repository.payload';
export * from './lib/payloads/delete-repository.payload';
export * from './lib/payloads/edit-repository.payload';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Repository } from './repository.model';

export interface AddEditRepositoryDialogData {
submitMsg: string;
dialogTitle: string;
isEditMode: boolean;
repositoryToEdit?: Repository;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface EditRepositoryPayload {
repositoryId: string;
maxLines?: number;
maxWaitingTime?: number;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h1 mat-dialog-title>Add repository</h1>
<h1 mat-dialog-title>{{ dialogTitle }}</h1>
<div mat-dialog-content>
<form [formGroup]="form" class="form--container">
<mat-form-field>
<mat-form-field *ngIf="!isEditMode">
<mat-label>Repository Url</mat-label>
<input formControlName="repositoryUrl" matInput />
<mat-error>
Expand Down Expand Up @@ -33,7 +33,13 @@ <h1 mat-dialog-title>Add repository</h1>
</div>
<div mat-dialog-actions>
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button color="primary" type="submit" [disabled]="form.invalid" (click)="submit()">
Add
<button
mat-button
color="primary"
type="submit"
[disabled]="form.invalid || !form.dirty"
(click)="submit()"
>
{{ submitMsg }}
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { RepositoryFacade } from '@pimp-my-pr/pmp-web/repository/data-access';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { TimeUnit } from '@pimp-my-pr/shared/domain';
import { untilDestroyed } from 'ngx-take-until-destroy';
import { AddEditRepositoryDialogData, Repository } from '@pimp-my-pr/pmp-web/repository/domain';
import { SnackbarService } from '@pimp-my-pr/pmp-web/shared/domain';
import { AddEditRepositoryDialogService } from './add-edit-repository-dialog.service';

@Component({
selector: 'pmp-add-repository-dialog',
templateUrl: './add-edit-repository-dialog.component.html',
styleUrls: ['./add-edit-repository-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AddEditRepositoryDialogComponent implements OnInit, OnDestroy {
dialogTitle: string;
form: FormGroup;
isEditMode: boolean;
maxWaitingTimeFormControl: FormControl;
repositoryToEdit: Repository;
submitMsg: string;
timeUnitFormControl: FormControl;
TimeUnit = TimeUnit;

constructor(
@Inject(MAT_DIALOG_DATA) data: AddEditRepositoryDialogData,
private repoFacade: RepositoryFacade,
private fb: FormBuilder,
private dialogRef: MatDialogRef<AddEditRepositoryDialogComponent>,
private snackbarService: SnackbarService,
private addEditRepositoryDialogService: AddEditRepositoryDialogService
) {
if (!!data) {
this.dialogTitle = data.dialogTitle;
this.isEditMode = data.isEditMode;
this.repositoryToEdit = data.repositoryToEdit;
this.submitMsg = data.submitMsg;
}
}

ngOnDestroy(): void {}

ngOnInit(): void {
this.initForm();
this.initializeMaxWaitingTimeDefinitionControls();
}

initForm(): void {
this.form = this.addEditRepositoryDialogService.initForm(
this.isEditMode,
this.repositoryToEdit
);
this.form
.get('maxWaitingTimeDefinition')
.get('timeUnit')
.setValue(TimeUnit.Hour);
}

initializeMaxWaitingTimeDefinitionControls(): void {
this.maxWaitingTimeFormControl = (this.form.controls.maxWaitingTimeDefinition as FormGroup)
.controls.maxWaitingTime as FormControl;
this.timeUnitFormControl = (this.form.controls.maxWaitingTimeDefinition as FormGroup).controls
.timeUnit as FormControl;

this.maxWaitingTimeFormControl.valueChanges
.pipe(untilDestroyed(this))
.subscribe(this.updateTimeUnitValidation);
}

submit(): void {
if (this.form.valid) {
const { repositoryUrl, maxLines } = this.form.value;
const maxWaitingTime = this.maxWaitingTimeFormControl.value
? this.maxWaitingTimeFormControl.value * this.timeUnitFormControl.value
: null;
if (this.isEditMode) {
this.editRepository(maxLines, maxWaitingTime);
} else {
this.addRepository(repositoryUrl, maxLines, maxWaitingTime);
}
}
}

updateTimeUnitValidation = (maxWaitingTime: number) => {
if (maxWaitingTime && maxWaitingTime > 0) {
this.timeUnitFormControl.setValidators(Validators.required);
this.timeUnitFormControl.markAsTouched();
this.timeUnitFormControl.enable();
} else {
this.timeUnitFormControl.markAsUntouched();
this.timeUnitFormControl.disable();
this.timeUnitFormControl.clearValidators();
}

this.timeUnitFormControl.updateValueAndValidity();
};

private addRepository(repositoryUrl: string, maxLines: number, maxWaitingTime: number): void {
this.repoFacade
.addRepository({
repositoryUrl,
maxLines,
maxWaitingTime
})
.subscribe(
() => {
this.snackbarService.open('Repository has been added');
this.dialogRef.close();
},
error => {
this.snackbarService.open('Something went wrong. Repository was not added');
}
);
}

private editRepository(maxLines: number, maxWaitingTime: number): void {
this.repoFacade
.editRepository({
repositoryId: this.repositoryToEdit.id,
maxLines,
maxWaitingTime
})
.subscribe(
() => {
this.snackbarService.open('Repository has been updated');
this.dialogRef.close();
},
error => {
this.snackbarService.open('Something went wrong. Repository was not updated');
}
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Repository } from '@pimp-my-pr/pmp-web/repository/domain';

@Injectable()
export class AddEditRepositoryDialogService {
constructor(private fb: FormBuilder) {}

initForm(isEditMode: boolean, repositoryToEdit: Repository): FormGroup {
return this.fb.group({
repositoryUrl: ['', isEditMode ? null : Validators.required],
maxLines: [repositoryToEdit ? repositoryToEdit.maxLines : null],
maxWaitingTimeDefinition: this.fb.group({
maxWaitingTime: [repositoryToEdit ? repositoryToEdit.maxWaitingTime : ''],
timeUnit: [{ value: '' }]
})
});
}
}
Loading

0 comments on commit 8b0ebe8

Please sign in to comment.