Skip to content
Snippets Groups Projects
Commit c48214ee authored by kbeyro's avatar kbeyro
Browse files

webhooks and small fixes

parent b99a9235
No related branches found
No related tags found
1 merge request!187Resolve "Add webhooks management view in the admin panel"
Showing
with 433 additions and 4 deletions
...@@ -2,8 +2,14 @@ import {Route} from "@angular/router"; ...@@ -2,8 +2,14 @@ import {Route} from "@angular/router";
import {AuthGuard} from "../../../auth/auth.guard"; import {AuthGuard} from "../../../auth/auth.guard";
import {RoleGuard} from "../../../auth/role.guard"; import {RoleGuard} from "../../../auth/role.guard";
import {ConfigurationDetailsComponent} from "./index"; import {ConfigurationDetailsComponent} from "./index";
import { WebhookListComponent } from "../webhook/webhook-list/webhook-list.component";
import { WebhookDetailsComponent } from "../webhook/webhook-details/webhook-details.component";
export const ConfigurationRoutes: Route[] = [ export const ConfigurationRoutes: Route[] = [
{path: 'configuration', component: ConfigurationDetailsComponent, canActivate: [AuthGuard, RoleGuard], {path: 'configuration', component: ConfigurationDetailsComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} },
{path: 'webhooks', component: WebhookListComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} },
{path: 'webhooks/:id', component: WebhookDetailsComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} } data:{roles: ['ROLE_SYSTEM_ADMIN']} }
]; ];
<div class="">
<div class="background-section">
<h4 style="font-size:15px; font-weight: bold">{{ 'WEBHOOKS.TITLE' | translate }}</h4>
<div class="panel-body">
<form *ngIf="webhook" (submit)="submit()" class="form-horizontal" #webhookForm="ngForm">
<div class="panel-default panel-heading">{{ 'CLUSTERS.GENERAL' | translate }} </div>
<div class="panel-body">
<div class="form-group">
<label for="clusterId" class="col-sm-2 control-label">{{ 'WEBHOOKS.ID' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterId" name="clusterId"
[(ngModel)]="webhook.id" [disabled]="true">
</div>
</div>
</div>
<div class="form-group">
<label for="clusterName" class="col-sm-2 control-label">{{ 'WEBHOOKS.NAME' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterName" name="clusterName"
[(ngModel)]="webhook.name" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="targetUrl" class="col-sm-2 control-label">{{ 'WEBHOOKS.TARGEt_URL' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="targetUrl" name="targetUrl"
[(ngModel)]="webhook.targetUrl" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="clusterDescription" class="col-sm-2 control-label">{{ 'WEBHOOKS.TYPE' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterDescription" name="clusterDescription"
placeholder="{{webhook.eventType | translate}}" [disabled]="true">
</div>
</div>
</div>
<div class="form-group">
<label for="token" class="col-sm-2 control-label">{{ 'WEBHOOKS.TOKEN' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="token" name="token"
[(ngModel)]="webhook.tokenValue" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="auth" class="col-sm-2 control-label">{{ 'WEBHOOKS.AUTH' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="auth" name="auth"
[(ngModel)]="webhook.authorizationHeader" [disabled]="false">
</div>
</div>
</div>
<div class="flex justify-content-end">
<button [disabled]="!webhookForm.form.valid" type="submit" class="btn btn-primary"
type="submit">{{ 'PORTAL_CONFIGURATION.SUBMIT_BUTTON' | translate }}</button>
</div>
</div>
</form>
</div>
</div>
</div>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WebhookDetailsComponent } from './webhook-details.component';
describe('WebhookDetailsComponent', () => {
let component: WebhookDetailsComponent;
let fixture: ComponentFixture<WebhookDetailsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [WebhookDetailsComponent]
})
.compileComponents();
fixture = TestBed.createComponent(WebhookDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { WebhookService } from '../../../../service/webhook.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Webhook } from '../../../../model/webhook';
import { BaseComponent } from '../../../../shared/common/basecomponent/base.component';
@Component({
selector: 'app-webhook-details',
templateUrl: './webhook-details.component.html',
styleUrl: './webhook-details.component.css'
})
export class WebhookDetailsComponent extends BaseComponent implements OnInit {
public webhooksId: number;
public webhook: Webhook;
constructor(private service: WebhookService,
public router: Router,
private route: ActivatedRoute) {
super();
}
ngOnInit(): void {
this.route.params.subscribe(params => {
this.webhooksId = +params['id'];
this.service.getOne(this.webhooksId).subscribe(result => {
console.log(result);
this.webhook = result;
} )
})
}
public submit(): void {
console.log(this.webhook);
this.service.update(this.webhook).subscribe(result => {
console.log(result);
this.webhook = result;
});
}
}
<div style="display: flex; align-items: center; margin-top:20px">
<div style="margin-right:20px">
<div >
<button class="btn btn-primary" (click)="openModal()">{{'WEBHOOKS.NEW' | translate}}</button>
</div>
</div>
<div class="flex" style="margin-right:20px">
</div>
</div>
<h4 class="header">{{ 'WEBHOOKS.TITLE' | translate }}</h4>
<div class="background-section">
<p-table
[value]="webkooks"
[paginator]="true"
[rows]="maxItemsOnPage"
[rowsPerPageOptions]="[15, 20, 25, 30, 50]"
[responsiveLayout]="'scroll'">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="id" id="id"> {{ 'WEBHOOKS.ID' | translate }}
<p-sortIcon field="id"></p-sortIcon>
</th>
<th pSortableColumn="name" id="name"> {{ 'WEBHOOKS.NAME' | translate }}
<p-sortIcon field="name"></p-sortIcon>
</th>
<th pSortableColumn="url" id="url"> {{ 'WEBHOOKS.TARGET_URL' | translate }}
<p-sortIcon field="url"></p-sortIcon>
</th>
<th pSortableColumn="type" id="type"> {{ 'WEBHOOKS.TYPE' | translate }}
<p-sortIcon field="type"></p-sortIcon>
</th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-webhook>
<tr>
<td [routerLink]="[webhook.id]">{{webhook.id}}</td>
<td>{{webhook.name}}</td>
<td>{{('WEBHOOKS.' + webhook.eventType.toString().toUpperCase() ) | translate}}</td>
<td>{{webhook.targetUrl}}</td>
<td class="text-right">
<span class="dropdown">
<a style="display: inline-block" class="dropdown-toggle" aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button">
<em class="pi pi-cog" style="font-size: 1.8rem; color: var(--l-text-color)"></em>
</a>
<ul class="dropdown-menu pull-right-drop" >
<li><a [routerLink]="[ webhook.id]" class="">
{{ 'WEBHOOKS.DETAILS' | translate }}</a>
</li>
</ul>
</span>
</td>
</tr>
</ng-template>
</p-table>
</div>
<nmaas-modal >
<div class="nmaas-modal-header">{{'WEBHOOKS.TITLE_SHORT' | translate}}</div>
<div class="nmaas-modal-body">
<div class="flex flex-column">
<div class="mt-4">
<label for="name">{{'WEBHOOKS.NAME' | translate}}</label>
<input id="name" type="text" class="form-control" [(ngModel)]="addedWebhook.name" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<label for="desc">{{'WEBHOOKS.TARGET_URL' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.targetUrl" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<label for="contactEmail">{{'WEBHOOKS.TYPE' | translate}}</label>
<select id="domain" #typeSelect class="form-control" (change)="onTypeSelect(typeSelect.value)" >
<option *ngFor="let t of type" [value]="t.name"
>{{t.name | translate}}
</option>
</select>
</div>
<div class="mt-4">
<label for="assignDomain">Auth required</label>
<input class="ml-2" type="checkbox" [(ngModel)]="authRequired" id="authRequired"/>
</div>
<div *ngIf="authRequired" class="mt-4">
<label for="desc">{{'WEBHOOKS.TOKEN' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.tokenValue" [ngModelOptions]="{standalone: true}">
</div>
<div *ngIf="authRequired" class="mt-4">
<label for="desc">{{'WEBHOOKS.AUTH' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.authorizationHeader" [ngModelOptions]="{standalone: true}">
</div>
</div>
</div>
<div class="nmaas-modal-footer">
<button type="button" class="btn btn-primary" [disabled]=" addedWebhook?.name === null "(click)="closeModalAndSaveWebhook()"
pTooltip="Upload file is required before save" showDelay="2000" >{{'CLUSTERS.SAVE' | translate}}</button>
<button type="button" class="btn btn-secondary"
(click)="this.modal.hide()">{{'UNDEPLOY_MODAL.CANCEL_BUTTON' | translate}}</button>
</div>
</nmaas-modal>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WebhookListComponent } from './webhook-list.component';
describe('WebhookListComponent', () => {
let component: WebhookListComponent;
let fixture: ComponentFixture<WebhookListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [WebhookListComponent]
})
.compileComponents();
fixture = TestBed.createComponent(WebhookListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, ViewChild } from '@angular/core';
import { Webhook, WebhookType } from '../../../../model/webhook';
import { ModalComponent } from '../../../../shared';
import { WebhookService } from '../../../../service/webhook.service';
@Component({
selector: 'app-webhook-list',
templateUrl: './webhook-list.component.html',
styleUrl: './webhook-list.component.css'
})
export class WebhookListComponent implements OnInit {
public webkooks: Webhook[] = [];
public addedWebhook: Webhook = new Webhook();
public maxItemsOnPage = 15;
public authRequired: boolean = false;
public type =[
{ name: "DOMAIN_CREATION", value: "DOMAIN_CREATION" },
{ name: "APPLICATION_DEPLOYMENT", value: "APPLICATION_DEPLOYMENT" },
{ name: "USER_ASSIGNMENT", value: "USER_ASSIGNMENT" },
{ name: "DOMAIN_GROUP_CHANGE", value: "DOMAIN_GROUP_CHANGE" }
]
@ViewChild(ModalComponent, { static: true })
public modal: ModalComponent;
constructor(private service: WebhookService) {
}
ngOnInit() {
this.refreshList();
}
public refreshList() {
this.service.getAll().subscribe(result => {
this.webkooks = result;
})
}
onTypeSelect(event: any) {
console.log(event);
this.addedWebhook.eventType = event;
}
public openModal() {
this.addedWebhook.eventType = WebhookType.DOMAIN_CREATION
this.modal.show();
}
public closeModalAndSaveWebhook() {
this.service.create(this.addedWebhook).subscribe(result => {
this.modal.hide();
this.refreshList();
});
}
}
...@@ -51,6 +51,9 @@ import { InputSwitchModule } from 'primeng/inputswitch'; ...@@ -51,6 +51,9 @@ import { InputSwitchModule } from 'primeng/inputswitch';
import { OverlayPanelModule } from 'primeng/overlaypanel'; import { OverlayPanelModule } from 'primeng/overlaypanel';
import { SidebarModule } from 'primeng/sidebar'; import { SidebarModule } from 'primeng/sidebar';
import { ProgressBarModule } from 'primeng/progressbar'; import { ProgressBarModule } from 'primeng/progressbar';
import { WebhookDetailsComponent } from './admin/webhook/webhook-details/webhook-details.component';
import { WebhookListComponent } from './admin/webhook/webhook-list/webhook-list.component';
import { WebhookService } from '../service/webhook.service';
...@@ -67,7 +70,9 @@ import { ProgressBarModule } from 'primeng/progressbar'; ...@@ -67,7 +70,9 @@ import { ProgressBarModule } from 'primeng/progressbar';
BulkViewComponent, BulkViewComponent,
BulkAppListComponent, BulkAppListComponent,
BulkListComponent, BulkListComponent,
BulkSearchPipe BulkSearchPipe,
WebhookDetailsComponent,
WebhookListComponent
], ],
imports: [ imports: [
FormsModule, FormsModule,
...@@ -101,7 +106,7 @@ import { ProgressBarModule } from 'primeng/progressbar'; ...@@ -101,7 +106,7 @@ import { ProgressBarModule } from 'primeng/progressbar';
InputSwitchModule, InputSwitchModule,
OverlayPanelModule, OverlayPanelModule,
SidebarModule, SidebarModule,
ProgressBarModule ProgressBarModule,
], ],
exports: [ exports: [
AppMarketComponent, AppMarketComponent,
...@@ -116,6 +121,7 @@ import { ProgressBarModule } from 'primeng/progressbar'; ...@@ -116,6 +121,7 @@ import { ProgressBarModule } from 'primeng/progressbar';
ClusterService, ClusterService,
SortService, SortService,
SessionService, SessionService,
WebhookService
], ],
schemas: [ schemas: [
NO_ERRORS_SCHEMA, NO_ERRORS_SCHEMA,
......
export class Webhook {
public id: number = undefined;
public name: string = undefined;
public targetUrl: string = undefined;
public tokenValue: string = undefined;
public authorizationHeader: string = undefined;
public eventType: WebhookType = undefined;
}
export enum WebhookType {
DOMAIN_CREATION = "DOMAIN_CREATION",
APPLICATION_DEPLOYMENT = "APPLICATION_DEPLOYMENT",
USER_ASSIGNMENT = "USER_ASSIGNMENT",
DOMAIN_GROUP_CHANGE = "DOMAIN_GROUP_CHANGE",
}
\ No newline at end of file
import { HttpClient } from '@angular/common/http';
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import { AppConfigService } from './appconfig.service';
import { GenericDataService } from './genericdata.service';
import { Webhook } from '../model/webhook';
import { Id } from '../model';
@Injectable()
export class WebhookService extends GenericDataService {
protected url: string;
constructor(http: HttpClient, appConfig: AppConfigService) {
super(http, appConfig);
this.url = this.appConfig.getApiUrl() + '/webhooks';
}
public getAll() : Observable<Webhook[]> {
return this.get<Webhook[]>(this.url);
}
public create(webhook: Webhook) {
return this.post<Webhook, Id>(this.url, webhook);
}
public getOne(id: number) {
return this.get<Webhook>(this.url + '/' + id);
}
public update(webhook: Webhook) {
return this.put<Webhook, Webhook>(this.url + '/' + webhook.id, webhook);
}
}
...@@ -88,12 +88,20 @@ ...@@ -88,12 +88,20 @@
<div class="mt-4"> <div class="mt-4">
<div>
<label for="assignDomain">Assign to domain? </label>
<input type="checkbox" [(ngModel)]="assignedDomain" (change)="onDomainChange($event)" id="assignDomain" />
</div>
<div class="mt-4" *ngIf="assignedDomain">
<label for="name">{{'CLUSTERS.DOMAIN' | translate}}</label> <label for="name">{{'CLUSTERS.DOMAIN' | translate}}</label>
<select id="domain" #domainSelect class="form-control" (change)="onDomainSelection(domainSelect.value)"> <select id="domain" #domainSelect class="form-control" (change)="onDomainSelection(domainSelect.value)" plaaceholder="testtesttest" >
<option *ngFor="let domain of domains" [value]="domain.name" <option *ngFor="let domain of domains" [value]="domain.name"
>{{domain.name}} >{{domain.name}}
</option> </option>
</select> </select>
</div>
</div> </div>
......
...@@ -16,6 +16,7 @@ export class ClusterManagerComponent { ...@@ -16,6 +16,7 @@ export class ClusterManagerComponent {
public addedCluster: ClusterManager = new ClusterManager(); public addedCluster: ClusterManager = new ClusterManager();
public updatedFile : File = null; public updatedFile : File = null;
public maxItemsOnPage = 15; public maxItemsOnPage = 15;
public assignedDomain: boolean = false;
public domains = []; public domains = [];
...@@ -72,6 +73,8 @@ public openModal() { ...@@ -72,6 +73,8 @@ public openModal() {
this.modal.show(); this.modal.show();
} }
public onDomainChange(event: any) {
console.log(event);
}
} }
...@@ -119,6 +119,14 @@ ...@@ -119,6 +119,14 @@
</span> </span>
</a> </a>
</li> </li>
<li *roles="['ROLE_SYSTEM_ADMIN']" [routerLinkActiveOptions]="{exact:true}" [routerLinkActive]="['active']" [ngClass]="{'collapsed': isCollapsed}">
<a style="display: flex; align-items: center;" [routerLink]="['/admin/webhooks']">
<i class="pi pi-cog" style="margin-right:10px; font-size: 18px" title="Settings"></i>
<span *ngIf="!isCollapsed">
{{ 'WEBHOOKS.TITLE_SHORT' | translate }}
</span>
</a>
</li>
<li *roles="['ROLE_SYSTEM_ADMIN']" [routerLinkActiveOptions]="{exact:true}" [routerLinkActive]="['active']" [ngClass]="{'collapsed': isCollapsed}"> <li *roles="['ROLE_SYSTEM_ADMIN']" [routerLinkActiveOptions]="{exact:true}" [routerLinkActive]="['active']" [ngClass]="{'collapsed': isCollapsed}">
<a style="display: flex; align-items: center;" [routerLink]="['/admin/manage/clusters']"> <a style="display: flex; align-items: center;" [routerLink]="['/admin/manage/clusters']">
<i class="pi pi-cog" style="margin-right:10px; font-size: 18px"></i> <i class="pi pi-cog" style="margin-right:10px; font-size: 18px"></i>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment