mirror of https://github.com/Squidex/squidex.git
5 changed files with 318 additions and 1 deletions
@ -0,0 +1,32 @@ |
|||
// ==========================================================================
|
|||
// WebhookCreatedDto.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Squidex.Controllers.Api.Webhooks.Models |
|||
{ |
|||
public class WebhookCreatedDto |
|||
{ |
|||
/// <summary>
|
|||
/// The id of the webhook.
|
|||
/// </summary>
|
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// The shared secret that is used to calculate the signature.
|
|||
/// </summary>
|
|||
[Required] |
|||
public string SharedSecret { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// The version of the schema.
|
|||
/// </summary>
|
|||
public long Version { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,143 @@ |
|||
<div class="table-items-row"> |
|||
<table class="table table-middle table-sm table-borderless table-fixed"> |
|||
<colgroup> |
|||
<col style="width: 120px; text-align: right;" /> |
|||
<col style="width: 100%" /> |
|||
<col style="width: 40px" /> |
|||
</colgroup> |
|||
|
|||
<tr> |
|||
<td class="text-right" colspan="2"> |
|||
<button class="btn btn-primary" [disabled]="!hasUrl">Save</button> |
|||
</td> |
|||
<td class="client-delete"> |
|||
<button type="button" class="btn btn-link btn-danger" |
|||
(sqxConfirmClick)="deleting.emit()" |
|||
confirmTitle="Delete webhook" |
|||
confirmText="Do you really want to delete the webhook?"> |
|||
<i class="icon-bin2"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
<tr> |
|||
<td>Url:</td> |
|||
<td> |
|||
<input class="form-control" [attr.value]="webhook.url" #inputUrl /> |
|||
</td> |
|||
<td> |
|||
<button type="button" class="btn btn-primary btn-link" [sqxCopy]="inputUrl"> |
|||
<i class="icon-copy"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
<tr> |
|||
<td>Secret:</td> |
|||
<td> |
|||
<input readonly class="form-control" [attr.value]="webhook.sharedSecret" #inputSecret /> |
|||
</td> |
|||
<td> |
|||
<button type="button" class="btn btn-primary btn-link" [sqxCopy]="inputSecret"> |
|||
<i class="icon-copy"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
</table> |
|||
|
|||
<div class="webhook-section"> |
|||
<table *ngIf="schemas.length > 0" class="table table-middle table-sm table-fixed table-borderless"> |
|||
<colgroup> |
|||
<col style="width: 100%" /> |
|||
<col style="width: 40px" /> |
|||
<col style="width: 40px" /> |
|||
<col style="width: 40px" /> |
|||
<col style="width: 40px" /> |
|||
<col style="width: 40px" /> |
|||
<col style="width: 40px" /> |
|||
</colgroup> |
|||
|
|||
<tr> |
|||
<th>Schema</th> |
|||
<th title="Created"> |
|||
C |
|||
</th> |
|||
<th title="Updated"> |
|||
U |
|||
</th> |
|||
<th title="Deleted"> |
|||
D |
|||
</th> |
|||
<th title="Published"> |
|||
P |
|||
</th> |
|||
<th title="Unpublished"> |
|||
U |
|||
</th> |
|||
<th></th> |
|||
</tr> |
|||
|
|||
<tr *ngFor="let schema of schemas"> |
|||
<td> |
|||
<span class="truncate">{{schema.schema.name}}</span> |
|||
</td> |
|||
<td title="Created"> |
|||
<input type="checkbox" [(ngModel)]="schema.sendCreate" /> |
|||
</td> |
|||
<td title="Updated"> |
|||
<input type="checkbox" [(ngModel)]="schema.sendUpdate" /> |
|||
</td> |
|||
<td title="Deleted"> |
|||
<input type="checkbox" [(ngModel)]="schema.sendDelete" /> |
|||
</td> |
|||
<td title="Published"> |
|||
<input type="checkbox" [(ngModel)]="schema.sendPublish" /> |
|||
</td> |
|||
<td title="Unpublished"> |
|||
<input type="checkbox" [(ngModel)]="schema.sendUnpublish" /> |
|||
</td> |
|||
<td class="text-center"> |
|||
<button type="button" class="btn btn-link btn-danger" |
|||
(sqxConfirmClick)="removeSchema(schema)" |
|||
confirmTitle="Remove schema" |
|||
confirmText="Do you really want to remove the schema?"> |
|||
<i class="icon-bin2"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
</table> |
|||
|
|||
<form class="form-inline" [formGroup]="addSchemaForm" (ngSubmit)="addSchema()"> |
|||
<div class="form-group mr-1"> |
|||
<select class="form-control schemas-control" formControlName="schema"> |
|||
<option *ngFor="let schema of schemasToAdd" [ngValue]="schema">{{schema.name}}</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<button type="submit" class="btn btn-success" [disabled]="!hasSchema">Add Schema</button> |
|||
</form> |
|||
</div> |
|||
|
|||
<div class="webhook-section" *ngIf="webhook.averageRequestTimeMs > 0"> |
|||
<div class="row"> |
|||
<div class="col-3"> |
|||
<span title="Succeeded Requests" [class.success]="webhook.totalSucceeded > 0"> |
|||
<i class="icon-checkmark"></i> {{webhook.totalSucceeded}} |
|||
</span> |
|||
</div> |
|||
<div class="col-3"> |
|||
<span title="Failed Requests" [class.failed]="webhook.totalFailed > 0"> |
|||
<i class="icon-bug"></i> {{webhook.totalFailed}} |
|||
</span> |
|||
</div> |
|||
<div class="col-3"> |
|||
<span title="Timeout Requests" [class.failed]="webhook.totalTimedout > 0"> |
|||
<i class="icon-timeout"></i> {{webhook.totalTimedout}} |
|||
</span> |
|||
</div> |
|||
<div class="col-3"> |
|||
<span title="Average Response Time"> |
|||
<i class="icon-elapsed"></i> {{webhook.averageRequestTimeMs}} ms |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,13 @@ |
|||
@import '_vars'; |
|||
@import '_mixins'; |
|||
|
|||
.schemas-control { |
|||
width: 18rem; |
|||
} |
|||
|
|||
.webhook-section { |
|||
border-top: 1px solid $color-border; |
|||
margin-left: -1.25rem; |
|||
margin-right: -1.25rem; |
|||
padding: 1rem 1.25rem 0; |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Sebastian Stehle. All rights reserved |
|||
*/ |
|||
|
|||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; |
|||
import { FormBuilder, Validators } from '@angular/forms'; |
|||
|
|||
import { |
|||
ImmutableArray, |
|||
SchemaDto, |
|||
UpdateWebhookDto, |
|||
WebhookDto |
|||
} from 'shared'; |
|||
|
|||
interface WebhookSchemaForm { |
|||
schema: SchemaDto; |
|||
sendCreate: boolean; |
|||
sendUpdate: boolean; |
|||
sendDelete: boolean; |
|||
sendPublish: boolean; |
|||
sendUnpublish: boolean; |
|||
} |
|||
|
|||
@Component({ |
|||
selector: 'sqx-webhook', |
|||
styleUrls: ['./webhook.component.scss'], |
|||
templateUrl: './webhook.component.html' |
|||
}) |
|||
export class WebhookComponent implements OnInit { |
|||
@Output() |
|||
public deleting = new EventEmitter(); |
|||
|
|||
@Output() |
|||
public updating = new EventEmitter<UpdateWebhookDto>(); |
|||
|
|||
@Input() |
|||
public allSchemas: SchemaDto[]; |
|||
|
|||
@Input() |
|||
public webhook: WebhookDto; |
|||
|
|||
public schemas: ImmutableArray<WebhookSchemaForm>; |
|||
|
|||
public schemasToAdd: ImmutableArray<SchemaDto>; |
|||
|
|||
public webhookFormSubmitted = false; |
|||
public webhookForm = |
|||
this.formBuilder.group({ |
|||
url: ['', |
|||
[ |
|||
Validators.required |
|||
]] |
|||
}); |
|||
|
|||
public addSchemaForm = |
|||
this.formBuilder.group({ |
|||
schema: [null] |
|||
}); |
|||
|
|||
public get hasUrl() { |
|||
return this.webhookForm.controls['url'].value && this.webhookForm.controls['url'].value.length > 0; |
|||
} |
|||
|
|||
public get hasSchema() { |
|||
return this.addSchemaForm.controls['schema'].value; |
|||
} |
|||
|
|||
constructor( |
|||
private readonly formBuilder: FormBuilder |
|||
) { |
|||
} |
|||
|
|||
public ngOnInit() { |
|||
this.webhookForm.controls['url'].setValue(this.webhook.url); |
|||
|
|||
this.schemasToAdd = |
|||
ImmutableArray.of( |
|||
this.allSchemas.filter(schema => |
|||
!this.webhook.schemas.find(w => w.schemaId === schema.id))) |
|||
.sortByStringAsc(x => x.name); |
|||
|
|||
this.schemas = |
|||
ImmutableArray.of( |
|||
this.webhook.schemas.map(webhookSchema => { |
|||
const schema = this.allSchemas.find(s => s.id === webhookSchema.schemaId); |
|||
|
|||
if (schema) { |
|||
return { |
|||
schema: schema, |
|||
sendCreate: webhookSchema.sendCreate, |
|||
sendUpdate: webhookSchema.sendUpdate, |
|||
sendDelete: webhookSchema.sendDelete, |
|||
sendPublish: webhookSchema.sendPublish, |
|||
sendUnpublish: webhookSchema.sendUnpublish |
|||
}; |
|||
} else { |
|||
return null; |
|||
} |
|||
}).filter(w => !!w)).sortByStringAsc(x => x.schema.name); |
|||
|
|||
this.addSchemaForm.controls['schema'].setValue(this.schemasToAdd.find(x => true)); |
|||
} |
|||
|
|||
public removeSchema(webhookSchema: WebhookSchemaForm) { |
|||
this.schemasToAdd = this.schemasToAdd.push(webhookSchema.schema).sortByStringAsc(x => x.name); |
|||
this.schemas = this.schemas.remove(webhookSchema); |
|||
|
|||
this.addSchemaForm.controls['schema'].setValue(this.schemasToAdd.find(x => true)); |
|||
} |
|||
|
|||
public addSchema() { |
|||
const schema: SchemaDto = this.addSchemaForm.controls['schema'].value; |
|||
|
|||
this.schemasToAdd = this.schemasToAdd.remove(schema).sortByStringAsc(x => x.name); |
|||
this.schemas = this.schemas.push({ |
|||
schema: schema, |
|||
sendCreate: false, |
|||
sendUpdate: false, |
|||
sendDelete: false, |
|||
sendPublish: false, |
|||
sendUnpublish: false |
|||
}).sortByStringAsc(x => x.schema.name); |
|||
|
|||
this.addSchemaForm.controls['schema'].setValue(this.schemasToAdd.find(x => true)); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue