Skip to content

Commit

Permalink
external notifications (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Feb 9, 2021
1 parent 2cc3542 commit 9f6d815
Show file tree
Hide file tree
Showing 28 changed files with 507 additions and 56 deletions.
10 changes: 0 additions & 10 deletions src/app/administration/administration.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ a {
font-size: 12px;
}

.head {
font-size: 12px;
padding-bottom: 5px;
border-top: 0px;
width: 30rem;
height: 43px;
color: #343a40;
}

.card-body {
padding: 0px;
}
Expand Down Expand Up @@ -65,7 +56,6 @@ a {

th {
padding-left: 20px;
color: #888888c7;
}

td {
Expand Down
10 changes: 5 additions & 5 deletions src/app/administration/api-token/api-keys.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
<table class="table items">
<thead>
<tr>
<th scope="col" class="head">token</th>
<th scope="col" class="head">description</th>
<th scope="col" class="head">created at</th>
<th scope="col" class="head">created by</th>
<th scope="col" class="head"></th>
<th scope="col" class="jtl-head">token</th>
<th scope="col" class="jtl-head">description</th>
<th scope="col" class="jtl-head">created at</th>
<th scope="col" class="jtl-head">created by</th>
<th scope="col" class="jtl-head"></th>
</tr>
</thead>
<tbody>
Expand Down
10 changes: 5 additions & 5 deletions src/app/administration/projects/administration.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
<table class="table items">
<thead>
<tr>
<th scope="col" class="head">project name</th>
<th scope="col" class="head">number of launches</th>
<th scope="col" class="head">number of scenarios</th>
<th scope="col" class="head">last run</th>
<th scope="col" class="head"></th>
<th scope="col" class="jtl-head">project name</th>
<th scope="col" class="jtl-head">number of launches</th>
<th scope="col" class="jtl-head">number of scenarios</th>
<th scope="col" class="jtl-head">last run</th>
<th scope="col" class="jtl-head"></th>
</tr>
</thead>
<tbody>
Expand Down
8 changes: 4 additions & 4 deletions src/app/administration/users/users.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<table class="table items">
<thead>
<tr>
<th scope="col" class="head">username</th>
<th scope="col" class="head">create date</th>
<th scope="col" class="head"># of tokens</th>
<th scope="col" class="head"></th>
<th scope="col" class="jtl-head">username</th>
<th scope="col" class="jtl-head">create date</th>
<th scope="col" class="jtl-head"># of tokens</th>
<th scope="col" class="jtl-head"></th>
</tr>
</thead>
<tbody>
Expand Down
8 changes: 8 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ import { MyProfileComponent } from './administration/my-profile/my-profile.compo
import { UsersComponent } from './administration/users/users.component';
import { AddUserComponent } from './administration/users/add-user/add-user.component';
import { DeleteUserComponent } from './administration/users/delete-user/delete-user.component';
import { ExternalNotificationComponent } from './scenario/external-notification/external-notification.component';
// tslint:disable-next-line:max-line-length
import { AddNewExternalNotificationComponent } from './scenario/external-notification/add-new-external-notification/add-new-external-notification.component';
// tslint:disable-next-line:max-line-length
import { DeleteExternalNotificationComponent } from './scenario/external-notification/delete-external-notification/delete-external-notification.component';

const appRoutes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
Expand Down Expand Up @@ -122,6 +127,9 @@ const appRoutes: Routes = [
UsersComponent,
AddUserComponent,
DeleteUserComponent,
ExternalNotificationComponent,
AddNewExternalNotificationComponent,
DeleteExternalNotificationComponent,
],
imports: [
RouterModule.forRoot(
Expand Down
7 changes: 0 additions & 7 deletions src/app/dashboard/dashboard.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ a {
font-size: 12px;
}

.head {
font-size: 12px;
color: #888888c7;
border-top: 0px;
min-width: 8rem;
}

.recent-runs .card-body {
padding-top: 0.2rem;
}
Expand Down
10 changes: 5 additions & 5 deletions src/app/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ <h6 class="card-header bg-transparent">Recent Test Runs</h6>
<table class="table items">
<thead>
<tr>
<th scope="col" class="head">scenario</th>
<th scope="col" class="head">project name</th>
<th scope="col" class="head">environment</th>
<th scope="col" class="head">start time</th>
<th scope="col" class="head">status</th>
<th scope="col" class="jtl-head">scenario</th>
<th scope="col" class="jtl-head">project name</th>
<th scope="col" class="jtl-head">environment</th>
<th scope="col" class="jtl-head">start time</th>
<th scope="col" class="jtl-head">status</th>
</tr>
</thead>
<tbody>
Expand Down
7 changes: 7 additions & 0 deletions src/app/items.service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,10 @@ export interface LabelMaxVu {
count: number;
}];
}

export interface ScenarioNotifications {
id: string;
url: string;
type: string;
}

8 changes: 8 additions & 0 deletions src/app/notification/notification-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ export class NotificationMessage {
return this.statusCodeMessage(response, 'User has been deleted');
}

deleteScenarioNotification(response) {
return this.statusCodeMessage(response, 'Notification has been deleted');
}

createScenarioNotification(response) {
return this.statusCodeMessage(response, 'Notification has been created');
}

private statusCodeMessage(response, succesMessgae) {
let message = { success: false, message: `Something went wrong` };
if (response.status >= 200 && response.status < 300) {
Expand Down
18 changes: 15 additions & 3 deletions src/app/scenario-api.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { IScenarios } from './items.service.model';
import {IScenarios, ScenarioNotifications} from './items.service.model';

@Injectable({
providedIn: 'root'
Expand All @@ -11,8 +11,7 @@ export class ScenarioApiService {
private response = new BehaviorSubject<any>({});
public response$ = this.response.asObservable();

constructor(private http: HttpClient) {
}
constructor(private http: HttpClient) {}

updateScenario(projectName, scenarioName, body): Observable<{}> {
return this.http.put(`projects/${projectName}/scenarios/${scenarioName}`, body, { observe: 'response'});
Expand All @@ -35,6 +34,19 @@ export class ScenarioApiService {
return this.http.post(`projects/${projectName}/scenarios`, body, { observe: 'response'});
}

fetchScenarioNotification(projectName, scenarioName): Observable<ScenarioNotifications[]> {
return this.http.get<ScenarioNotifications[]>(`projects/${projectName}/scenarios/${scenarioName}/notifications`);
}

deleteScenarioNotification(projectName, scenarioName, id): Observable<{}> {
return this.http.delete<{}>(`projects/${projectName}/scenarios/${scenarioName}/notifications/${id}`, { observe: 'response'});
}

createNewScenarioNotification(projectName, scenarioName, body): Observable<{}> {
return this.http.post(`projects/${projectName}/scenarios/${scenarioName}/notifications`, body, { observe: 'response' });

}

setData(data) {
this.response.next(data);
}
Expand Down
9 changes: 9 additions & 0 deletions src/app/scenario.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, interval } from 'rxjs';
import { scenarioHistoryGraphs } from './graphs/scenario-trends';
import { ScenarioNotifications } from './items.service.model';
import { ScenarioApiService } from './scenario-api.service';

@Injectable({
Expand All @@ -12,6 +13,9 @@ export class ScenarioService {
private trends = new BehaviorSubject<{}>({});
public trends$ = this.trends.asObservable();

private notifications = new BehaviorSubject<ScenarioNotifications[]>([]);
public notifications$ = this.notifications.asObservable();

constructor(
private scenarioApiService: ScenarioApiService
) { }
Expand All @@ -22,4 +26,9 @@ export class ScenarioService {
.subscribe(_ => this.trends.next(scenarioHistoryGraphs(_, projectName, scenarioName)));
}

fetchScenarioNotifications(projectName, scenarioName) {
this.scenarioApiService.fetchScenarioNotification(projectName, scenarioName)
.subscribe(_ => this.notifications.next(_));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">MS Teams Webhook</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form [formGroup]="myform" (ngSubmit)="onSubmit()">
<div class="modal-body">
<div class="alert alert-primary" role="alert">
<i class="fas fa-info-circle"> </i>
Follow the instructions on how to set up <a href="https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook#add-an-incoming-webhook-to-a-teams-channel">Incoming Webhook</a> for a channel.
</div>
<p class="text-secondary"></p>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Webhook Url</span>
</div>
<input type="input" class="form-control" formControlName="url" aria-label="Default" aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Name</span>
</div>
<input type="input" class="form-control" formControlName="name" aria-label="Default" aria-describedby="inputGroup-sizing-default">
</div>
<div class="form-control-feedback" *ngIf="url.errors && (url.dirty || url.touched)">
<p class="alert alert-danger" *ngIf="url.errors.required">Webhook Url required</p>
<p class="alert alert-danger" *ngIf="url.errors.maxlength">The url is too long.</p>
</div>
<div class="form-control-feedback" *ngIf="name.errors && (name.dirty || name.touched)">
<p class="alert alert-danger" *ngIf="name.errors.required">Name required</p>
<p class="alert alert-danger" *ngIf="name.errors.maxlength">Name is too long.</p>
</div>
</div>

<div class="modal-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>

</ng-template>

<button class="notification btn btn-sm btn-primary" (click)="open(content)"><i class="fas fa-bell"></i> new MS Teams notification</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';

import { AddNewExternalNotificationComponent } from './add-new-external-notification.component';

describe('AddNewExternalNotificationComponent', () => {
let component: AddNewExternalNotificationComponent;
let fixture: ComponentFixture<AddNewExternalNotificationComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddNewExternalNotificationComponent ],
imports: [RouterTestingModule, ReactiveFormsModule, HttpClientModule],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AddNewExternalNotificationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, Validators, FormGroup } from '@angular/forms';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { NotificationMessage } from 'src/app/notification/notification-messages';
import { ScenarioApiService } from 'src/app/scenario-api.service';
import { ScenarioService } from 'src/app/scenario.service';

@Component({
selector: 'app-add-new-external-notification',
templateUrl: './add-new-external-notification.component.html',
styleUrls: ['./add-new-external-notification.component.css']
})
export class AddNewExternalNotificationComponent implements OnInit {

myform: FormGroup;
url;
name;
modal: NgbActiveModal;
@Input() params;

constructor(
private modalService: NgbModal,
private notification: NotificationMessage,
private scenarioApiService: ScenarioApiService,
private scenarioService: ScenarioService,
) { }

ngOnInit() {
this.createFormControls();
this.createForm();
}

open(content) {
this.modal = this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' });
}

createFormControls() {
this.url = new FormControl('', [
Validators.maxLength(400),
Validators.required
]);
this.name = new FormControl('', [
Validators.maxLength(100),
Validators.required
]);
}

createForm() {
this.myform = new FormGroup({
url: this.url,
name: this.name
});
}

onSubmit() {
if (this.myform.valid) {
const { projectName, scenarioName } = this.params;
const body = {
...this.myform.value,
type: 'ms-teams'
};

this.scenarioApiService.createNewScenarioNotification(projectName, scenarioName, body)
.pipe(catchError(r => of(r)))
.subscribe(_ => {
const message = this.notification.createScenarioNotification(_);
this.scenarioApiService.setData(message);
this.scenarioService.fetchScenarioNotifications(projectName, scenarioName);
});
this.myform.reset();
this.modal.close();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Delete Notification</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form [formGroup]="myform" (ngSubmit)="onSubmit()">
<div class="modal-body">

<div class="alert alert-primary" role="alert">
Are you sure you want to delete <strong>{{notificationInput.name}} </strong> notification?
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" (click)="modal.dismiss('Cross click')">Close</button>
<button type="submit" class="btn btn-danger float-left">Delete</button>
</div>
</form>

</ng-template>

<button class="btn btn-link btn-sm text-danger float-right" (click)="open(content)">
<i class="fas fa-trash-alt"></i>
</button>
Loading

0 comments on commit 9f6d815

Please sign in to comment.