mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-28 02:21:24 +01:00
Refactor webhook policy page (#14758)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
c54e690f69
commit
afa3f6d3e4
@ -134,7 +134,7 @@
|
||||
<span>
|
||||
<button (click)="cancel()" id="system-robot-cancel" type="button" class="btn btn-outline">{{'BUTTON.CANCEL'
|
||||
| translate}}</button>
|
||||
<button [disabled]="disabled() || checkNameOnGoing" [clrLoading]="saveBtnState" (click)="save()" id="system-robot-save" type="button"
|
||||
<button [disabled]="disabled() || checkNameOnGoing || isNameExisting" [clrLoading]="saveBtnState" (click)="save()" id="system-robot-save" type="button"
|
||||
class="btn btn-primary">
|
||||
<span *ngIf="isEditMode">{{'BUTTON.SAVE'| translate}}</span>
|
||||
<span *ngIf="!isEditMode">{{'BUTTON.ADD'| translate}}</span>
|
||||
|
@ -233,6 +233,7 @@ export class NewRobotComponent implements OnInit, OnDestroy {
|
||||
this.isEditMode = isEditMode;
|
||||
this.addRobotOpened = true;
|
||||
this.inlineAlertComponent.close();
|
||||
this._nameSubject.next('');
|
||||
}
|
||||
disabled(): boolean {
|
||||
if (!this.isEditMode) {
|
||||
|
@ -111,7 +111,7 @@
|
||||
<span>
|
||||
<button (click)="cancel()" id="system-robot-cancel" type="button" class="btn btn-outline">{{'BUTTON.CANCEL'
|
||||
| translate}}</button>
|
||||
<button [disabled]="disabled()|| checkNameOnGoing" [clrLoading]="saveBtnState" (click)="save()" id="system-robot-save" type="button"
|
||||
<button [disabled]="disabled()|| checkNameOnGoing || isNameExisting" [clrLoading]="saveBtnState" (click)="save()" id="system-robot-save" type="button"
|
||||
class="btn btn-primary">
|
||||
<span *ngIf="isEditMode">{{'BUTTON.SAVE'| translate}}</span>
|
||||
<span *ngIf="!isEditMode">{{'BUTTON.ADD'| translate}}</span>
|
||||
|
@ -161,6 +161,8 @@ export class AddRobotComponent implements OnInit, OnDestroy {
|
||||
this.isEditMode = isEditMode;
|
||||
this.addRobotOpened = true;
|
||||
this.inlineAlertComponent.close();
|
||||
this.isNameExisting = false;
|
||||
this._nameSubject.next('');
|
||||
}
|
||||
disabled(): boolean {
|
||||
if (!this.isEditMode) {
|
||||
|
@ -156,5 +156,5 @@ export class RuleMetadate {
|
||||
}
|
||||
|
||||
export const RUNNING: string = "Running";
|
||||
export const PENDING: string = "pending";
|
||||
export const PENDING: string = "Pending";
|
||||
export const TIMEOUT: number = 5000;
|
||||
|
@ -5,14 +5,16 @@
|
||||
<!-- name -->
|
||||
<div class="clr-form-control">
|
||||
<label for="edit_endpoint_url" class="clr-control-label required">{{'WEBHOOK.NAME' | translate}}</label>
|
||||
<div class="clr-control-container" [class.clr-error]="name.errors && name.errors.required && (name.dirty || name.touched)">
|
||||
<div class="clr-control-container" [class.clr-error]="(name.errors && name.errors.required && (name.dirty || name.touched)) || isNameExisting">
|
||||
<div class="clr-input-wrapper">
|
||||
<input autocomplete="off" class="clr-input" type="text" id="name" [disabled]="checking" [(ngModel)]="webhook.name"
|
||||
<input (input)="inputName()" autocomplete="off" class="clr-input" type="text" id="name" [disabled]="checking" [(ngModel)]="webhook.name"
|
||||
size="30" name="notify-type" #name="ngModel" required>
|
||||
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
|
||||
<span class="spinner spinner-inline" [hidden]="!checkNameOnGoing"></span>
|
||||
</div>
|
||||
<clr-control-error *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)" class="tooltip-content">
|
||||
{{'WEBHOOK.NAME_REQUIRED' | translate}}
|
||||
<clr-control-error *ngIf="(name.errors && name.errors.required && (name.dirty || name.touched)) || isNameExisting" class="tooltip-content">
|
||||
<span *ngIf="!(name.errors && name.errors.required && (name.dirty || name.touched)) && isNameExisting">{{'SCANNER.NAME_EXISTS' | translate}}</span>
|
||||
<span *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)">{{'WEBHOOK.NAME_REQUIRED' | translate}}</span>
|
||||
</clr-control-error>
|
||||
</div>
|
||||
</div>
|
||||
@ -92,10 +94,10 @@
|
||||
</form>
|
||||
<div class="mt-1 bottom-btn" *ngIf="!isModify">
|
||||
<button type="button" class="btn btn-outline" id="add-webhook-cancel" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
||||
<button type="button" id="new-webhook-continue" class="btn btn-primary" [disabled]="!isValid" (click)="add()">{{'BUTTON.ADD' | translate}}</button>
|
||||
<button type="button" id="new-webhook-continue" class="btn btn-primary" [disabled]="!isValid || checkNameOnGoing || isNameExisting" (click)="add()">{{'BUTTON.ADD' | translate}}</button>
|
||||
</div>
|
||||
<div class="mt-1 bottom-btn" *ngIf="isModify">
|
||||
<button type="button" class="btn btn-outline" id="edit-webhook-cancel" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
||||
<button type="button" class="btn btn-primary" id="edit-webhook-save" [disabled]="!isValid || !hasChange()" (click)="save()">{{'BUTTON.SAVE' | translate}}</button>
|
||||
<button type="button" class="btn btn-primary" id="edit-webhook-save" [disabled]="!isValid || !hasChange() || checkNameOnGoing || isNameExisting" (click)="save()">{{'BUTTON.SAVE' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,42 +1,52 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { AddWebhookFormComponent } from './add-webhook-form.component';
|
||||
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { WebhookService } from "../webhook.service";
|
||||
import { ProjectWebhookService } from "../webhook.service";
|
||||
import { MessageHandlerService } from "../../../../shared/services/message-handler.service";
|
||||
import { of } from 'rxjs';
|
||||
import { Webhook } from "../webhook";
|
||||
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
||||
import { InlineAlertComponent } from "../../../../shared/components/inline-alert/inline-alert.component";
|
||||
import { WebhookPolicy } from "../../../../../../ng-swagger-gen/models/webhook-policy";
|
||||
import { delay } from "rxjs/operators";
|
||||
import { HttpHeaders, HttpResponse } from "@angular/common/http";
|
||||
import { Registry } from "../../../../../../ng-swagger-gen/models/registry";
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
import { WebhookService } from "../../../../../../ng-swagger-gen/services/webhook.service";
|
||||
|
||||
describe('AddWebhookFormComponent', () => {
|
||||
let component: AddWebhookFormComponent;
|
||||
let fixture: ComponentFixture<AddWebhookFormComponent>;
|
||||
const mockWebhookService = {
|
||||
getCurrentUser: () => {
|
||||
return of(null);
|
||||
},
|
||||
createWebhook() {
|
||||
return of(null);
|
||||
},
|
||||
editWebhook() {
|
||||
return of(null);
|
||||
},
|
||||
testEndpoint() {
|
||||
return of(null);
|
||||
},
|
||||
const mockProjectWebhookService = {
|
||||
eventTypeToText(eventType: string) {
|
||||
return eventType;
|
||||
}
|
||||
};
|
||||
const mockedWebhookService = {
|
||||
GetSupportedEventTypes() {
|
||||
return of(mockedMetadata).pipe(delay(0));
|
||||
},
|
||||
LastTrigger() {
|
||||
return of([]).pipe(delay(0));
|
||||
},
|
||||
ListWebhookPoliciesOfProjectResponse() {
|
||||
const response: HttpResponse<Array<Registry>> = new HttpResponse<Array<Registry>>({
|
||||
headers: new HttpHeaders({'x-total-count': [mockedWehook].length.toString()}),
|
||||
body: [mockedWehook]
|
||||
});
|
||||
return of(response).pipe(delay(0));
|
||||
},
|
||||
ListWebhookPoliciesOfProject: () => {
|
||||
return of(null);
|
||||
},
|
||||
UpdateWebhookPolicyOfProject() {
|
||||
return of(true);
|
||||
},
|
||||
CreateWebhookPolicyOfProject() {
|
||||
return of(true);
|
||||
}
|
||||
};
|
||||
const mockMessageHandlerService = {
|
||||
handleError: () => { }
|
||||
};
|
||||
const mockedWehook: Webhook = {
|
||||
const mockedWehook: WebhookPolicy = {
|
||||
id: 1,
|
||||
project_id: 1,
|
||||
name: 'test',
|
||||
@ -44,7 +54,6 @@ describe('AddWebhookFormComponent', () => {
|
||||
targets: [{
|
||||
address: 'https://test.com',
|
||||
type: 'http',
|
||||
attachment: null,
|
||||
auth_header: null,
|
||||
skip_cert_verify: true,
|
||||
}],
|
||||
@ -77,24 +86,15 @@ describe('AddWebhookFormComponent', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
TranslateModule.forRoot(),
|
||||
FormsModule,
|
||||
RouterTestingModule,
|
||||
NoopAnimationsModule,
|
||||
HttpClientTestingModule
|
||||
SharedTestingModule
|
||||
],
|
||||
declarations: [AddWebhookFormComponent,
|
||||
InlineAlertComponent,
|
||||
],
|
||||
providers: [
|
||||
TranslateService,
|
||||
{ provide: WebhookService, useValue: mockWebhookService },
|
||||
{ provide: ProjectWebhookService, useValue: mockProjectWebhookService },
|
||||
{ provide: WebhookService, useValue: mockedWebhookService },
|
||||
{ provide: MessageHandlerService, useValue: mockMessageHandlerService },
|
||||
ErrorHandler
|
||||
|
||||
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
|
@ -4,30 +4,37 @@ import {
|
||||
Input,
|
||||
ViewChild,
|
||||
Output,
|
||||
EventEmitter,
|
||||
EventEmitter, OnDestroy,
|
||||
} from "@angular/core";
|
||||
import { Webhook } from "../webhook";
|
||||
import { NgForm } from "@angular/forms";
|
||||
import { ClrLoadingState } from "@clr/angular";
|
||||
import { finalize } from "rxjs/operators";
|
||||
import { WebhookService } from "../webhook.service";
|
||||
import { debounceTime, distinctUntilChanged, filter, finalize, switchMap } from "rxjs/operators";
|
||||
import { ProjectWebhookService } from "../webhook.service";
|
||||
import { compareValue } from '../../../../shared/units/utils';
|
||||
import { InlineAlertComponent } from "../../../../shared/components/inline-alert/inline-alert.component";
|
||||
import { WebhookService } from "../../../../../../ng-swagger-gen/services/webhook.service";
|
||||
import { WebhookPolicy } from "../../../../../../ng-swagger-gen/models/webhook-policy";
|
||||
import { Subject, Subscription } from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: 'add-webhook-form',
|
||||
templateUrl: './add-webhook-form.component.html',
|
||||
styleUrls: ['./add-webhook-form.component.scss']
|
||||
})
|
||||
export class AddWebhookFormComponent implements OnInit {
|
||||
export class AddWebhookFormComponent implements OnInit, OnDestroy {
|
||||
closable: boolean = true;
|
||||
checking: boolean = false;
|
||||
checkBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
webhookForm: NgForm;
|
||||
submitting: boolean = false;
|
||||
@Input() projectId: number;
|
||||
webhook: Webhook = new Webhook();
|
||||
originValue: Webhook;
|
||||
webhook: WebhookPolicy = {
|
||||
enabled: true,
|
||||
event_types: [],
|
||||
targets: [{
|
||||
type: 'http',
|
||||
address: '',
|
||||
skip_cert_verify: true
|
||||
}]
|
||||
};
|
||||
originValue: WebhookPolicy;
|
||||
isModify: boolean;
|
||||
@Input() isOpen: boolean;
|
||||
@Output() close = new EventEmitter<boolean>();
|
||||
@ -35,14 +42,62 @@ export class AddWebhookFormComponent implements OnInit {
|
||||
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
|
||||
@Input()
|
||||
metadata: any;
|
||||
@Output() notify = new EventEmitter<Webhook>();
|
||||
@Output() notify = new EventEmitter<WebhookPolicy>();
|
||||
checkNameOnGoing: boolean = false;
|
||||
isNameExisting: boolean = false;
|
||||
private _nameSubject = new Subject<string>();
|
||||
_nameSubscription: Subscription;
|
||||
constructor(
|
||||
private webhookService: WebhookService,
|
||||
private projectWebhookService: ProjectWebhookService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.subscribeName();
|
||||
}
|
||||
ngOnDestroy() {
|
||||
if (this._nameSubscription) {
|
||||
this._nameSubscription.unsubscribe();
|
||||
this._nameSubscription = null;
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
this.isNameExisting = false;
|
||||
this._nameSubject.next('');
|
||||
}
|
||||
subscribeName() {
|
||||
if (!this._nameSubscription) {
|
||||
this._nameSubscription = this._nameSubject
|
||||
.pipe(
|
||||
debounceTime(500),
|
||||
distinctUntilChanged(),
|
||||
filter(name => {
|
||||
if (this.isModify && this.originValue && this.originValue.name === name) {
|
||||
return false;
|
||||
}
|
||||
return name.length > 0;
|
||||
}),
|
||||
switchMap((name) => {
|
||||
this.isNameExisting = false;
|
||||
this.checkNameOnGoing = true;
|
||||
return this.webhookService.ListWebhookPoliciesOfProject({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
q: encodeURIComponent(
|
||||
`name=${name}`)
|
||||
}).pipe(finalize(() => this.checkNameOnGoing = false));
|
||||
}))
|
||||
.subscribe(res => {
|
||||
if (res && res.length > 0) {
|
||||
this.isNameExisting = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
inputName() {
|
||||
this._nameSubject.next(this.webhook.name);
|
||||
}
|
||||
onCancel() {
|
||||
this.reset();
|
||||
this.close.emit(false);
|
||||
this.currentForm.reset();
|
||||
this.inlineAlert.close();
|
||||
@ -50,10 +105,14 @@ export class AddWebhookFormComponent implements OnInit {
|
||||
|
||||
add() {
|
||||
this.submitting = true;
|
||||
this.webhookService.createWebhook(this.projectId, this.webhook)
|
||||
this.webhookService.CreateWebhookPolicyOfProject({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
policy: this.webhook
|
||||
})
|
||||
.pipe(finalize(() => (this.submitting = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
this.reset();
|
||||
this.notify.emit();
|
||||
this.inlineAlert.close();
|
||||
},
|
||||
@ -65,10 +124,15 @@ export class AddWebhookFormComponent implements OnInit {
|
||||
|
||||
save() {
|
||||
this.submitting = true;
|
||||
this.webhookService.editWebhook(this.projectId, this.webhook.id, this.webhook)
|
||||
this.webhookService.UpdateWebhookPolicyOfProject({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
webhookPolicyId: this.webhook.id,
|
||||
policy: this.webhook
|
||||
})
|
||||
.pipe(finalize(() => (this.submitting = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
this.reset();
|
||||
this.inlineAlert.close();
|
||||
this.notify.emit();
|
||||
},
|
||||
@ -113,6 +177,6 @@ export class AddWebhookFormComponent implements OnInit {
|
||||
&& this.webhook.event_types.length > 0;
|
||||
}
|
||||
eventTypeToText(eventType: string): string {
|
||||
return this.webhookService.eventTypeToText(eventType);
|
||||
return this.projectWebhookService.eventTypeToText(eventType);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { AddWebhookComponent } from './add-webhook.component';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
describe('AddWebhookComponent', () => {
|
||||
let component: AddWebhookComponent;
|
||||
let fixture: ComponentFixture<AddWebhookComponent>;
|
||||
@ -18,18 +13,9 @@ describe('AddWebhookComponent', () => {
|
||||
NO_ERRORS_SCHEMA
|
||||
],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
TranslateModule.forRoot(),
|
||||
FormsModule,
|
||||
RouterTestingModule,
|
||||
NoopAnimationsModule,
|
||||
HttpClientTestingModule
|
||||
SharedTestingModule
|
||||
],
|
||||
declarations: [AddWebhookComponent],
|
||||
providers: [
|
||||
TranslateService
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
@ -6,8 +6,8 @@ import {
|
||||
Output,
|
||||
EventEmitter,
|
||||
} from "@angular/core";
|
||||
import { Webhook } from "../webhook";
|
||||
import { AddWebhookFormComponent } from "../add-webhook-form/add-webhook-form.component";
|
||||
import { WebhookPolicy } from "../../../../../../ng-swagger-gen/models/webhook-policy";
|
||||
|
||||
@Component({
|
||||
selector: 'add-webhook',
|
||||
@ -21,12 +21,12 @@ export class AddWebhookComponent implements OnInit {
|
||||
staticBackdrop: boolean = true;
|
||||
|
||||
@Input() projectId: number;
|
||||
webhook: Webhook;
|
||||
webhook: WebhookPolicy;
|
||||
@Input()
|
||||
metadata: any;
|
||||
@ViewChild(AddWebhookFormComponent)
|
||||
addWebhookFormComponent: AddWebhookFormComponent;
|
||||
@Output() notify = new EventEmitter<Webhook>();
|
||||
@Output() notify = new EventEmitter<WebhookPolicy>();
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { ClarityModule } from "@clr/angular";
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
import { LastTriggerComponent } from "./last-trigger.component";
|
||||
import { LastTrigger } from "../webhook";
|
||||
import { SimpleChange } from "@angular/core";
|
||||
import { WebhookService } from "../webhook.service";
|
||||
import { ProjectWebhookService } from "../webhook.service";
|
||||
import { WebhookLastTrigger } from "../../../../../../ng-swagger-gen/models/webhook-last-trigger";
|
||||
|
||||
describe('LastTriggerComponent', () => {
|
||||
const mokedTriggers: LastTrigger[] = [
|
||||
const mokedTriggers: WebhookLastTrigger[] = [
|
||||
{
|
||||
policy_name: 'http',
|
||||
enabled: true,
|
||||
@ -35,13 +33,11 @@ describe('LastTriggerComponent', () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SharedTestingModule,
|
||||
BrowserAnimationsModule,
|
||||
ClarityModule,
|
||||
],
|
||||
declarations: [
|
||||
LastTriggerComponent
|
||||
],
|
||||
providers: [{ provide: WebhookService, useValue: mockWebhookService }]
|
||||
providers: [{ provide: ProjectWebhookService, useValue: mockWebhookService }]
|
||||
});
|
||||
});
|
||||
beforeEach(() => {
|
||||
|
@ -2,8 +2,8 @@ import {
|
||||
Component, Input, OnChanges,
|
||||
OnInit, SimpleChanges
|
||||
} from "@angular/core";
|
||||
import { LastTrigger } from "../webhook";
|
||||
import { WebhookService } from "../webhook.service";
|
||||
import { ProjectWebhookService } from "../webhook.service";
|
||||
import { WebhookLastTrigger } from "../../../../../../ng-swagger-gen/models/webhook-last-trigger";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -12,10 +12,10 @@ import { WebhookService } from "../webhook.service";
|
||||
styleUrls: ['./last-trigger.component.scss']
|
||||
})
|
||||
export class LastTriggerComponent implements OnInit , OnChanges {
|
||||
@Input() inputLastTriggers: LastTrigger[];
|
||||
@Input() inputLastTriggers: WebhookLastTrigger[];
|
||||
@Input() webhookName: string;
|
||||
lastTriggers: LastTrigger[] = [];
|
||||
constructor(private webhookService: WebhookService) {
|
||||
lastTriggers: WebhookLastTrigger[] = [];
|
||||
constructor(private webhookService: ProjectWebhookService) {
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes && changes['inputLastTriggers']) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
<div class="row">
|
||||
<h4 class="mt-1">{{'WEBHOOK.WEBHOOKS' | translate}}</h4>
|
||||
<clr-datagrid [clrDgLoading]="loadingWebhookList || loadingMetadata" [(clrDgSelected)]="selectedRow">
|
||||
<clr-datagrid (clrDgRefresh)="getWebhooks($event)" [clrDgLoading]="loadingWebhookList" [(clrDgSelected)]="selectedRow">
|
||||
<clr-dg-action-bar>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-7">
|
||||
<button [disabled]="!hasCreatPermission" [clrLoading]="addBtnState" id="new-webhook" type="button" class="btn btn-secondary" (click)="newWebhook()">
|
||||
<button [disabled]="loadingMetadata||!hasCreatPermission" [clrLoading]="loadingMetadata||addBtnState" id="new-webhook" type="button" class="btn btn-secondary" (click)="newWebhook()">
|
||||
<clr-icon shape="plus" size="16"></clr-icon>
|
||||
{{'WEBHOOK.NEW_WEBHOOK' | translate}}
|
||||
</button>
|
||||
@ -43,7 +43,7 @@
|
||||
<div class="clr-col-5">
|
||||
<div class="action-head-pos">
|
||||
<span class="refresh-btn">
|
||||
<clr-icon shape="refresh" (click)="success()" [hidden]="loadingWebhookList || loadingMetadata"></clr-icon>
|
||||
<clr-icon shape="refresh" (click)="refresh()" [hidden]="loadingWebhookList || loadingMetadata"></clr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -54,12 +54,12 @@
|
||||
<clr-dg-column>{{'WEBHOOK.NOTIFY_TYPE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="min-width-340">{{'WEBHOOK.TARGET' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'WEBHOOK.EVENT_TYPES' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'WEBHOOK.CREATED' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'creation_time'">{{'WEBHOOK.CREATED' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'WEBHOOK.DESCRIPTION' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>
|
||||
{{'WEBHOOK.NO_WEBHOOK' | translate}}
|
||||
</clr-dg-placeholder>
|
||||
<clr-dg-row *clrDgItems="let w of webhookList" [clrDgItem]="w">
|
||||
<clr-dg-row *ngFor="let w of webhookList" [clrDgItem]="w">
|
||||
<clr-dg-cell>{{w.name}}</clr-dg-cell>
|
||||
<clr-dg-cell [ngSwitch]="w.enabled">
|
||||
<div *ngSwitchCase="true" class="icon-wrap">
|
||||
@ -101,9 +101,10 @@
|
||||
</clr-dg-row-detail>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
<clr-dg-pagination [clrDgPageSize]="15">
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="pageSize" [(clrDgPage)]="page" [clrDgTotalItems]="total">
|
||||
<clr-dg-page-size [clrPageSizeOptions]="[15,25,50]">{{"PAGINATION.PAGE_SIZE" | translate}}</clr-dg-page-size>
|
||||
<span *ngIf="webhookList?.length > 0">1 - {{webhookList?.length}} {{'WEBHOOK.OF' | translate}} </span> {{webhookList?.length}} {{'WEBHOOK.ITEMS' | translate}}
|
||||
<span *ngIf="total">{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'WEBHOOK.OF' | translate}}</span>
|
||||
{{total}} {{'WEBHOOK.ITEMS' | translate}}
|
||||
</clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
|
@ -1,18 +1,21 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { WebhookComponent } from './webhook.component';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { WebhookService } from './webhook.service';
|
||||
import { ProjectWebhookService } from './webhook.service';
|
||||
import { MessageHandlerService } from "../../../shared/services/message-handler.service";
|
||||
import { of } from 'rxjs';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { delay } from "rxjs/operators";
|
||||
import { Webhook } from "./webhook";
|
||||
import { AddWebhookFormComponent } from "./add-webhook-form/add-webhook-form.component";
|
||||
import { AddWebhookComponent } from "./add-webhook/add-webhook.component";
|
||||
import { ConfirmationDialogComponent } from "../../../shared/components/confirmation-dialog";
|
||||
import { UserPermissionService } from '../../../shared/services';
|
||||
import { InlineAlertComponent } from "../../../shared/components/inline-alert/inline-alert.component";
|
||||
import { SharedTestingModule } from "../../../shared/shared.module";
|
||||
import { WebhookPolicy } from "../../../../../ng-swagger-gen/models/webhook-policy";
|
||||
import { WebhookService } from "../../../../../ng-swagger-gen/services/webhook.service";
|
||||
import { HttpHeaders, HttpResponse } from "@angular/common/http";
|
||||
import { Registry } from "../../../../../ng-swagger-gen/models/registry";
|
||||
|
||||
describe('WebhookComponent', () => {
|
||||
let component: WebhookComponent;
|
||||
@ -37,7 +40,7 @@ describe('WebhookComponent', () => {
|
||||
"slack"
|
||||
]
|
||||
};
|
||||
const mockedWehook: Webhook = {
|
||||
const mockedWehook: WebhookPolicy = {
|
||||
id: 1,
|
||||
project_id: 1,
|
||||
name: 'test',
|
||||
@ -45,7 +48,6 @@ describe('WebhookComponent', () => {
|
||||
targets: [{
|
||||
address: 'https://test.com',
|
||||
type: 'http',
|
||||
attachment: null,
|
||||
auth_header: null,
|
||||
skip_cert_verify: true,
|
||||
}],
|
||||
@ -57,24 +59,29 @@ describe('WebhookComponent', () => {
|
||||
update_time: null,
|
||||
enabled: true,
|
||||
};
|
||||
const mockWebhookService = {
|
||||
listLastTrigger: () => {
|
||||
return of([]).pipe(delay(0));
|
||||
},
|
||||
listWebhook: () => {
|
||||
return of([mockedWehook
|
||||
]).pipe(delay(0));
|
||||
},
|
||||
getWebhookMetadata() {
|
||||
return of(mockedMetadata).pipe(delay(0));
|
||||
},
|
||||
editWebhook() {
|
||||
return of(true);
|
||||
},
|
||||
const mockProjectWebhookService = {
|
||||
eventTypeToText(eventType: string) {
|
||||
return eventType;
|
||||
}
|
||||
};
|
||||
const mockedWebhookService = {
|
||||
GetSupportedEventTypes() {
|
||||
return of(mockedMetadata).pipe(delay(0));
|
||||
},
|
||||
LastTrigger() {
|
||||
return of([]).pipe(delay(0));
|
||||
},
|
||||
ListWebhookPoliciesOfProjectResponse() {
|
||||
const response: HttpResponse<Array<Registry>> = new HttpResponse<Array<Registry>>({
|
||||
headers: new HttpHeaders({'x-total-count': [mockedWehook].length.toString()}),
|
||||
body: [mockedWehook]
|
||||
});
|
||||
return of(response).pipe(delay(0));
|
||||
},
|
||||
UpdateWebhookPolicyOfProject() {
|
||||
return of(true);
|
||||
}
|
||||
};
|
||||
const mockActivatedRoute = {
|
||||
RouterparamMap: of({ get: (key) => 'value' }),
|
||||
snapshot: {
|
||||
@ -113,7 +120,8 @@ describe('WebhookComponent', () => {
|
||||
ConfirmationDialogComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: WebhookService, useValue: mockWebhookService },
|
||||
{ provide: ProjectWebhookService, useValue: mockProjectWebhookService },
|
||||
{ provide: WebhookService, useValue: mockedWebhookService },
|
||||
{ provide: MessageHandlerService, useValue: mockMessageHandlerService },
|
||||
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
|
||||
{ provide: UserPermissionService, useValue: mockUserPermissionService },
|
||||
|
@ -17,17 +17,19 @@ import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { AddWebhookComponent } from './add-webhook/add-webhook.component';
|
||||
import { AddWebhookFormComponent } from './add-webhook-form/add-webhook-form.component';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { LastTrigger, Webhook } from './webhook';
|
||||
import { WebhookService } from './webhook.service';
|
||||
import { MessageHandlerService } from '../../../shared/services/message-handler.service';
|
||||
import { Project } from '../project';
|
||||
import { clone } from '../../../shared/units/utils';
|
||||
import { clone, DEFAULT_PAGE_SIZE, getSortingString } from '../../../shared/units/utils';
|
||||
import { forkJoin, Observable } from 'rxjs';
|
||||
import { UserPermissionService, USERSTATICPERMISSION } from '../../../shared/services';
|
||||
import { ClrLoadingState } from '@clr/angular';
|
||||
import { ClrDatagridStateInterface, ClrLoadingState } from '@clr/angular';
|
||||
import { ConfirmationDialogComponent } from "../../../shared/components/confirmation-dialog";
|
||||
import { ConfirmationButtons, ConfirmationState, ConfirmationTargets } from "../../../shared/entities/shared.const";
|
||||
import { ConfirmationMessage } from "../../global-confirmation-dialog/confirmation-message";
|
||||
import { WebhookService } from "../../../../../ng-swagger-gen/services/webhook.service";
|
||||
import { WebhookLastTrigger } from "../../../../../ng-swagger-gen/models/webhook-last-trigger";
|
||||
import { WebhookPolicy } from "../../../../../ng-swagger-gen/models/webhook-policy";
|
||||
import { ProjectWebhookService } from "./webhook.service";
|
||||
|
||||
@Component({
|
||||
templateUrl: './webhook.component.html',
|
||||
@ -40,23 +42,27 @@ export class WebhookComponent implements OnInit {
|
||||
addWebhookFormComponent: AddWebhookFormComponent;
|
||||
@ViewChild("confirmationDialogComponent")
|
||||
confirmationDialogComponent: ConfirmationDialogComponent;
|
||||
lastTriggers: LastTrigger[] = [];
|
||||
lastTriggerCount: number = 0;
|
||||
lastTriggers: WebhookLastTrigger[] = [];
|
||||
projectId: number;
|
||||
projectName: string;
|
||||
selectedRow: Webhook[] = [];
|
||||
webhookList: Webhook[] = [];
|
||||
selectedRow: WebhookPolicy[] = [];
|
||||
webhookList: WebhookPolicy[] = [];
|
||||
metadata: any;
|
||||
loadingMetadata: boolean = false;
|
||||
loadingWebhookList: boolean = false;
|
||||
loadingMetadata: boolean = true;
|
||||
loadingWebhookList: boolean = true;
|
||||
loadingTriggers: boolean = false;
|
||||
hasCreatPermission: boolean = false;
|
||||
hasUpdatePermission: boolean = false;
|
||||
addBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
page: number = 1;
|
||||
pageSize: number = DEFAULT_PAGE_SIZE;
|
||||
total: number = 0;
|
||||
state: ClrDatagridStateInterface;
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private translate: TranslateService,
|
||||
private webhookService: WebhookService,
|
||||
private projectWebhookService: ProjectWebhookService,
|
||||
private messageHandlerService: MessageHandlerService,
|
||||
private userPermissionService: UserPermissionService) { }
|
||||
|
||||
@ -85,16 +91,23 @@ export class WebhookComponent implements OnInit {
|
||||
this.addBtnState = ClrLoadingState.ERROR;
|
||||
});
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.page = 1;
|
||||
this.total = 0;
|
||||
this.selectedRow = [];
|
||||
this.getWebhooks(this.state);
|
||||
this.getData();
|
||||
}
|
||||
getData() {
|
||||
this.getMetadata();
|
||||
this.getLastTriggers();
|
||||
this.getWebhooks();
|
||||
this.selectedRow = [];
|
||||
}
|
||||
getMetadata() {
|
||||
this.loadingMetadata = true;
|
||||
this.webhookService.getWebhookMetadata(this.projectId)
|
||||
this.webhookService.GetSupportedEventTypes({
|
||||
projectNameOrId: this.projectId.toString()
|
||||
})
|
||||
.pipe(finalize(() => (this.loadingMetadata = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
@ -118,12 +131,13 @@ export class WebhookComponent implements OnInit {
|
||||
getLastTriggers() {
|
||||
this.loadingTriggers = true;
|
||||
this.webhookService
|
||||
.listLastTrigger(this.projectId)
|
||||
.LastTrigger({
|
||||
projectNameOrId: this.projectId.toString()
|
||||
})
|
||||
.pipe(finalize(() => (this.loadingTriggers = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
this.lastTriggers = response;
|
||||
this.lastTriggerCount = response.length;
|
||||
},
|
||||
error => {
|
||||
this.messageHandlerService.handleError(error);
|
||||
@ -131,14 +145,43 @@ export class WebhookComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
getWebhooks() {
|
||||
getWebhooks(state?: ClrDatagridStateInterface) {
|
||||
if (state) {
|
||||
this.state = state;
|
||||
}
|
||||
if (state && state.page) {
|
||||
this.pageSize = state.page.size;
|
||||
}
|
||||
let q: string;
|
||||
if (state && state.filters && state.filters.length) {
|
||||
q = encodeURIComponent(`${state.filters[0].property}=~${state.filters[0].value}`);
|
||||
}
|
||||
let sort: string;
|
||||
if (state && state.sort && state.sort.by) {
|
||||
sort = getSortingString(state);
|
||||
} else { // sort by creation_time desc by default
|
||||
sort = `-creation_time`;
|
||||
}
|
||||
this.loadingWebhookList = true;
|
||||
this.webhookService
|
||||
.listWebhook(this.projectId)
|
||||
.ListWebhookPoliciesOfProjectResponse({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
page: this.page,
|
||||
pageSize: this.pageSize,
|
||||
sort: sort,
|
||||
q: q
|
||||
})
|
||||
.pipe(finalize(() => (this.loadingWebhookList = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
this.webhookList = response;
|
||||
// Get total count
|
||||
if (response.headers) {
|
||||
let xHeader: string = response.headers.get("X-Total-Count");
|
||||
if (xHeader) {
|
||||
this.total = parseInt(xHeader, 0);
|
||||
}
|
||||
}
|
||||
this.webhookList = response.body || [];
|
||||
},
|
||||
error => {
|
||||
this.messageHandlerService.handleError(error);
|
||||
@ -172,11 +215,14 @@ export class WebhookComponent implements OnInit {
|
||||
message.state === ConfirmationState.CONFIRMED) {
|
||||
if (JSON.stringify(message.data) === '{}') {
|
||||
this.webhookService
|
||||
.editWebhook(this.projectId, this.selectedRow[0].id,
|
||||
Object.assign({}, this.selectedRow[0], { enabled: !this.selectedRow[0].enabled }))
|
||||
.UpdateWebhookPolicyOfProject({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
webhookPolicyId: this.selectedRow[0].id,
|
||||
policy: Object.assign({}, this.selectedRow[0], { enabled: !this.selectedRow[0].enabled })
|
||||
})
|
||||
.subscribe(
|
||||
response => {
|
||||
this.getData();
|
||||
this.refresh();
|
||||
},
|
||||
error => {
|
||||
this.messageHandlerService.handleError(error);
|
||||
@ -185,11 +231,14 @@ export class WebhookComponent implements OnInit {
|
||||
} else {
|
||||
const observableLists: Observable<any>[] = [];
|
||||
message.data.forEach(item => {
|
||||
observableLists.push(this.webhookService.deleteWebhook(this.projectId, item.id));
|
||||
observableLists.push(this.webhookService.DeleteWebhookPolicyOfProject({
|
||||
projectNameOrId: this.projectId.toString(),
|
||||
webhookPolicyId: item.id
|
||||
}));
|
||||
});
|
||||
forkJoin(...observableLists).subscribe(
|
||||
response => {
|
||||
this.getData();
|
||||
this.refresh();
|
||||
},
|
||||
error => {
|
||||
this.messageHandlerService.handleError(error);
|
||||
@ -219,12 +268,20 @@ export class WebhookComponent implements OnInit {
|
||||
this.addWebhookComponent.isEdit = false;
|
||||
this.addWebhookComponent.addWebhookFormComponent.isModify = false;
|
||||
this.addWebhookComponent.addWebhookFormComponent.currentForm.reset({notifyType: this.metadata.notify_type[0]});
|
||||
this.addWebhookComponent.addWebhookFormComponent.webhook = new Webhook();
|
||||
this.addWebhookComponent.addWebhookFormComponent.webhook = {
|
||||
enabled: true,
|
||||
event_types: [],
|
||||
targets: [{
|
||||
type: 'http',
|
||||
address: '',
|
||||
skip_cert_verify: true
|
||||
}]
|
||||
};
|
||||
this.addWebhookComponent.addWebhookFormComponent.webhook.event_types = clone(this.metadata.event_type);
|
||||
}
|
||||
}
|
||||
success() {
|
||||
this.getData();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
deleteWebhook() {
|
||||
@ -247,6 +304,6 @@ export class WebhookComponent implements OnInit {
|
||||
this.confirmationDialogComponent.open(msg);
|
||||
}
|
||||
eventTypeToText(eventType: string): string {
|
||||
return this.webhookService.eventTypeToText(eventType);
|
||||
return this.projectWebhookService.eventTypeToText(eventType);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { WebhookComponent } from "./webhook.component";
|
||||
import { LastTriggerComponent } from "./last-trigger/last-trigger.component";
|
||||
import { AddWebhookFormComponent } from "./add-webhook-form/add-webhook-form.component";
|
||||
import { AddWebhookComponent } from "./add-webhook/add-webhook.component";
|
||||
import { WebhookService } from "./webhook.service";
|
||||
import { ProjectWebhookService } from "./webhook.service";
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
@ -26,7 +26,7 @@ const routes: Routes = [
|
||||
SharedModule
|
||||
],
|
||||
providers: [
|
||||
WebhookService
|
||||
ProjectWebhookService
|
||||
]
|
||||
})
|
||||
export class WebhookModule { }
|
||||
|
@ -1,21 +1,17 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { WebhookService } from './webhook.service';
|
||||
import { ProjectWebhookService } from './webhook.service';
|
||||
|
||||
describe('WebhookService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
HttpClientTestingModule
|
||||
],
|
||||
providers: [WebhookService]
|
||||
providers: [ProjectWebhookService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([WebhookService], (service: WebhookService) => {
|
||||
it('should be created', inject([ProjectWebhookService], (service: ProjectWebhookService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
it('function eventTypeToText should work', inject([WebhookService], (service: WebhookService) => {
|
||||
it('function eventTypeToText should work', inject([ProjectWebhookService], (service: ProjectWebhookService) => {
|
||||
expect(service).toBeTruthy();
|
||||
const eventType: string = 'REPLICATION';
|
||||
expect(service.eventTypeToText(eventType)).toEqual('Replication finished');
|
||||
|
@ -11,12 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import { throwError as observableThrowError, Observable, of } from "rxjs";
|
||||
import { map, catchError, delay } from "rxjs/operators";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Webhook, LastTrigger } from "./webhook";
|
||||
import { CURRENT_BASE_HREF } from "../../../shared/units/utils";
|
||||
|
||||
const EVENT_TYPES_TEXT_MAP = {
|
||||
'REPLICATION': 'Replication finished',
|
||||
@ -34,54 +29,8 @@ const EVENT_TYPES_TEXT_MAP = {
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class WebhookService {
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
public listWebhook(projectId: number): Observable<Webhook[]> {
|
||||
return this.http
|
||||
.get(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/policies`)
|
||||
.pipe(map(response => response as Webhook[]))
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public listLastTrigger(projectId: number): Observable<LastTrigger[]> {
|
||||
return this.http
|
||||
.get(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/lasttrigger`)
|
||||
.pipe(map(response => response as LastTrigger[]))
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public editWebhook(projectId: number, policyId: number, data: any): Observable<any> {
|
||||
return this.http
|
||||
.put(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/policies/${policyId}`, data)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public deleteWebhook(projectId: number, policyId: number): Observable<any> {
|
||||
return this.http
|
||||
.delete(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/policies/${policyId}`)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public createWebhook(projectId: number, data: any): Observable<any> {
|
||||
return this.http
|
||||
.post(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/policies`, data)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
|
||||
public testEndpoint(projectId: number, param): Observable<any> {
|
||||
return this.http
|
||||
.post(`${ CURRENT_BASE_HREF }/projects/${projectId}/webhook/policies/test`, param)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public getWebhookMetadata(projectId: number): Observable<any> {
|
||||
return this.http
|
||||
.get(`${CURRENT_BASE_HREF}/projects/${projectId}/webhook/events`)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
export class ProjectWebhookService {
|
||||
constructor() { }
|
||||
public eventTypeToText(eventType: string): string {
|
||||
if (EVENT_TYPES_TEXT_MAP[eventType]) {
|
||||
return EVENT_TYPES_TEXT_MAP[eventType];
|
||||
|
@ -1,40 +0,0 @@
|
||||
export class Webhook {
|
||||
id: number;
|
||||
name: string;
|
||||
project_id: number;
|
||||
description: string;
|
||||
targets: Target[];
|
||||
event_types: string[];
|
||||
creator: string;
|
||||
creation_time: Date;
|
||||
update_time: Date;
|
||||
enabled: boolean;
|
||||
constructor () {
|
||||
this.targets = [];
|
||||
this.targets.push(new Target());
|
||||
this.event_types = [];
|
||||
this.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
export class Target {
|
||||
type: string;
|
||||
address: string;
|
||||
attachment: string;
|
||||
auth_header: string;
|
||||
skip_cert_verify: boolean;
|
||||
|
||||
constructor () {
|
||||
this.type = 'http';
|
||||
this.address = '';
|
||||
this.skip_cert_verify = true;
|
||||
}
|
||||
}
|
||||
|
||||
export class LastTrigger {
|
||||
policy_name: string;
|
||||
enabled: boolean;
|
||||
event_type: string;
|
||||
creation_time: Date;
|
||||
last_trigger_time: Date;
|
||||
}
|
Loading…
Reference in New Issue
Block a user