Browse Source

Discourse Action.

pull/315/head
Sebastian Stehle 8 years ago
parent
commit
74e6745721
  1. 6
      extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs
  2. 51
      extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs
  3. 10
      src/Squidex/app/features/rules/declarations.ts
  4. 27
      src/Squidex/app/features/rules/module.ts
  5. 2
      src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html
  6. 2
      src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html
  7. 99
      src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.html
  8. 6
      src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.scss
  9. 56
      src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.ts
  10. 2
      src/Squidex/app/features/rules/pages/rules/actions/elastic-search-action.component.html
  11. 2
      src/Squidex/app/features/rules/pages/rules/actions/fastly-action.component.html
  12. 15
      src/Squidex/app/features/rules/pages/rules/actions/index.ts
  13. 2
      src/Squidex/app/features/rules/pages/rules/actions/medium-action.component.html
  14. 2
      src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html
  15. 2
      src/Squidex/app/features/rules/pages/rules/actions/tweet-action.component.html
  16. 2
      src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html
  17. 10
      src/Squidex/app/features/rules/pages/rules/rule-element.component.scss
  18. 11
      src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html
  19. 16
      src/Squidex/app/features/rules/pages/rules/rule-wizard.component.scss
  20. 2
      src/Squidex/app/features/rules/pages/rules/triggers/asset-changed-trigger.component.html
  21. 2
      src/Squidex/app/features/rules/pages/rules/triggers/content-changed-trigger.component.html

6
extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs

@ -27,9 +27,13 @@ namespace Squidex.Extensions.Actions.Discourse
public Uri Url { get; set; }
[Required]
[Display(Name = "Api Key", Description = "The api key.")]
[Display(Name = "Api Key", Description = "The api key to authenticate to your discourse server.")]
public string ApiKey { get; set; }
[Required]
[Display(Name = "Api Username", Description = "The api username to authenticate to your discourse server.")]
public string ApiUsername { get; set; }
[Required]
[Display(Name = "Text", Description = "The text as markdown.")]
public string Text { get; set; }

51
extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs

@ -7,14 +7,20 @@
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.HandleRules.Actions.Utils;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Discourse
{
public sealed class DiscourseActionHandler : RuleActionHandler<DiscourseAction, DiscourseJob>
{
private const string DescriptionCreatePost = "Create discourse Post";
private const string DescriptionCreateTopic = "Create discourse Topic";
private readonly IHttpClientFactory httpClientFactory;
public DiscourseActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
@ -23,19 +29,50 @@ namespace Squidex.Extensions.Actions.Discourse
this.httpClientFactory = httpClientFactory;
}
protected override Task<(string Description, DiscourseJob Data)> CreateJobAsync(EnrichedEvent @event, DiscourseAction action)
protected override (string Description, DiscourseJob Data) CreateJob(EnrichedEvent @event, DiscourseAction action)
{
return base.CreateJobAsync(@event, action);
var url = $"{action.Url.ToString().TrimEnd('/')}/posts.json?api_key={action.ApiKey}&api_username={action.ApiUsername}";
var json =
new JObject(
new JProperty("raw", Format(action.Text, @event)),
new JProperty("title", Format(action.Title, @event)));
if (action.Topic.HasValue)
{
json.Add(new JProperty("topic_id", action.Topic.Value));
}
if (action.Category.HasValue)
{
json.Add(new JProperty("category", action.Category.Value));
}
var ruleJob = new DiscourseJob
{
RequestUrl = url,
RequestBody = json.ToString()
};
var description =
action.Topic.HasValue ?
DescriptionCreateTopic :
DescriptionCreatePost;
return (description, ruleJob);
}
protected override Task<(string Dump, Exception Exception)> ExecuteJobAsync(DiscourseJob job)
protected override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(DiscourseJob job)
{
using (var client = httpClientFactory.CreateClient())
using (var httpClient = httpClientFactory.CreateClient())
{
// Foo
}
var request = new HttpRequestMessage(HttpMethod.Post, job.RequestUrl)
{
Content = new StringContent(job.RequestBody, Encoding.UTF8, "application/json")
};
return Task.FromResult<(string Dump, Exception Exception)>((string.Empty, null));
return await httpClient.OneWayRequestAsync(request, job.RequestBody);
}
}
}

10
src/Squidex/app/features/rules/declarations.ts

@ -5,6 +5,16 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
export * from './pages/rules/actions/algolia-action.component';
export * from './pages/rules/actions/azure-queue-action.component';
export * from './pages/rules/actions/discourse-action.component';
export * from './pages/rules/actions/elastic-search-action.component';
export * from './pages/rules/actions/fastly-action.component';
export * from './pages/rules/actions/medium-action.component';
export * from './pages/rules/actions/slack-action.component';
export * from './pages/rules/actions/tweet-action.component';
export * from './pages/rules/actions/webhook-action.component';
export * from './pages/rules/triggers/asset-changed-trigger.component';
export * from './pages/rules/triggers/content-changed-trigger.component';

27
src/Squidex/app/features/rules/module.ts

@ -14,18 +14,23 @@ import {
SqxSharedModule
} from '@app/shared';
import * as actions from './pages/rules/actions';
const actionTypes: any = Object.values(actions);
import {
AlgoliaActionComponent,
AssetChangedTriggerComponent,
AzureQueueActionComponent,
ContentChangedTriggerComponent,
DiscourseActionComponent,
ElasticSearchActionComponent,
FastlyActionComponent,
MediumActionComponent,
RuleElementComponent,
RuleEventBadgeClassPipe,
RuleEventsPageComponent,
RulesPageComponent,
RuleWizardComponent
RuleWizardComponent,
SlackActionComponent,
TweetActionComponent,
WebhookActionComponent
} from './declarations';
const routes: Routes = [
@ -55,14 +60,22 @@ const routes: Routes = [
RouterModule.forChild(routes)
],
declarations: [
...actionTypes,
AlgoliaActionComponent,
AssetChangedTriggerComponent,
AzureQueueActionComponent,
ContentChangedTriggerComponent,
DiscourseActionComponent,
ElasticSearchActionComponent,
FastlyActionComponent,
MediumActionComponent,
RuleElementComponent,
RuleEventBadgeClassPipe,
RuleEventsPageComponent,
RulesPageComponent,
RuleWizardComponent
RuleWizardComponent,
SlackActionComponent,
TweetActionComponent,
WebhookActionComponent
]
})
export class SqxFeatureRulesModule { }

2
src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Populate index in algolia with content</h3>
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="appId">App ID</label>

2
src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Send event payload to Azure Storage Queue</h3>
<form [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="connectionString">Connection String</label>

99
src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.html

@ -0,0 +1,99 @@
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="url">Url</label>
<div class="col col-9">
<sqx-control-errors for="url" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="url" class="form-control" id="url" formControlName="url" />
<small class="form-text text-muted">
The url where the events will be sent to.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="apiKey">Api Key</label>
<div class="col col-9">
<sqx-control-errors for="apiKey" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="apiKey" class="form-control" id="apiKey" formControlName="apiKey" />
<small class="form-text text-muted">
The api key to authenticate to your discourse server.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="apiUsername">Api Username</label>
<div class="col col-9">
<sqx-control-errors for="apiUsername" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="apiUsername" class="form-control" id="apiUsername" formControlName="apiUsername" />
<small class="form-text text-muted">
The api username to authenticate to your discourse server.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="text">Text</label>
<div class="col col-9">
<sqx-control-errors for="text" [submitted]="actionFormSubmitted"></sqx-control-errors>
<textarea class="form-control" id="text" formControlName="text"></textarea>
<small class="form-text text-muted">
The text for your topic or post. Read the <a routerLink="help">help</a> section for information about advanced formatting.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="title">Title</label>
<div class="col col-9">
<sqx-control-errors for="title" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="title" class="form-control" id="title" formControlName="title" />
<small class="form-text text-muted">
The optional title, when you want to create a topic. Read the <a routerLink="help">help</a> section for information about advanced formatting.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="topic">Topic</label>
<div class="col col-9">
<sqx-control-errors for="topic" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="number" class="form-control" id="topic" formControlName="topic" />
<small class="form-text text-muted">
The topic id when you want to create a post.
</small>
</div>
</div>
<div class="form-group row">
<label class="col col-3 col-form-label" for="category">Category</label>
<div class="col col-9">
<sqx-control-errors for="category" [submitted]="actionFormSubmitted"></sqx-control-errors>
<input type="number" class="form-control" id="category" formControlName="category" />
<small class="form-text text-muted">
The category id when you create a topic.
</small>
</div>
</div>
</div>

6
src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.scss

@ -0,0 +1,6 @@
@import '_vars';
@import '_mixins';
textarea {
height: 150px;
}

56
src/Squidex/app/features/rules/pages/rules/actions/discourse-action.component.ts

@ -0,0 +1,56 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'sqx-discourse-action',
styleUrls: ['./discourse-action.component.scss'],
templateUrl: './discourse-action.component.html'
})
export class DiscourseActionComponent implements OnInit {
@Input()
public action: any;
@Input()
public actionForm: FormGroup;
@Input()
public actionFormSubmitted = false;
public ngOnInit() {
this.actionForm.setControl('url',
new FormControl(this.action.url || '', [
Validators.required
]));
this.actionForm.setControl('apiKey',
new FormControl(this.action.apiKey || '', [
Validators.required
]));
this.actionForm.setControl('apiUsername',
new FormControl(this.action.apiUsername || '', [
Validators.required
]));
this.actionForm.setControl('text',
new FormControl(this.action.text || '', [
Validators.required
]));
this.actionForm.setControl('title',
new FormControl(this.action.title));
this.actionForm.setControl('topic',
new FormControl(this.action.topic));
this.actionForm.setControl('category',
new FormControl(this.action.category));
}
}

2
src/Squidex/app/features/rules/pages/rules/actions/elastic-search-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Populate index in ElasticSearch with content</h3>
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="host">Host</label>

2
src/Squidex/app/features/rules/pages/rules/actions/fastly-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Purge cache entries in Fastly</h3>
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="serviceId">Service ID</label>

15
src/Squidex/app/features/rules/pages/rules/actions/index.ts

@ -1,15 +0,0 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
export * from './algolia-action.component';
export * from './azure-queue-action.component';
export * from './elastic-search-action.component';
export * from './fastly-action.component';
export * from './medium-action.component';
export * from './slack-action.component';
export * from './tweet-action.component';
export * from './webhook-action.component';

2
src/Squidex/app/features/rules/pages/rules/actions/medium-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Post to Medium</h3>
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="accessToken">Access Token</label>

2
src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Send custom text to an incoming webhook in Slack</h3>
<form [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="webhookUrl">Webhook Url</label>

2
src/Squidex/app/features/rules/pages/rules/actions/tweet-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Tweet a status update to your twitter feed</h3>
<form [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<div class="col col-9 offset-3">

2
src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Send event payload to webhook</h3>
<div [formGroup]="actionForm" class="form-horizontal">
<div class="form-group row">
<label class="col col-3 col-form-label" for="url">Url</label>

10
src/Squidex/app/features/rules/pages/rules/rule-element.component.scss

@ -42,14 +42,16 @@
max-height: 100px;
}
&-title {
font-weight: bold;
}
&-link {
font-size: .8rem;
}
&-title {
font-weight: bold;
font-size: 1rem;
line-height: 1;
}
&-text {
font-size: .8rem;
margin-top: .25rem;

11
src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html

@ -31,6 +31,8 @@
<ng-container *ngIf="step === 2 && schemas">
<form [formGroup]="triggerForm.form" (submit)="saveTrigger()">
<h3 class="wizard-title">{{ruleTriggers[triggerType].display}}</h3>
<ng-container [ngSwitch]="triggerType">
<ng-container *ngSwitchCase="'AssetChanged'">
<sqx-asset-changed-trigger
@ -61,6 +63,8 @@
<ng-container *ngIf="step === 4">
<form [formGroup]="actionForm.form" (submit)="saveAction()">
<h3 class="wizard-title">{{ruleActions[actionType].display}}</h3>
<ng-container [ngSwitch]="actionType">
<ng-container *ngSwitchCase="'Algolia'">
<sqx-algolia-action
@ -76,6 +80,13 @@
[actionFormSubmitted]="actionForm.submitted | async">
</sqx-azure-queue-action>
</ng-container>
<ng-container *ngSwitchCase="'Discourse'">
<sqx-discourse-action
[action]="action"
[actionForm]="actionForm.form"
[actionFormSubmitted]="actionForm.submitted | async">
</sqx-discourse-action>
</ng-container>
<ng-container *ngSwitchCase="'ElasticSearch'">
<sqx-elastic-search-action
[action]="action"

16
src/Squidex/app/features/rules/pages/rules/rule-wizard.component.scss

@ -5,14 +5,12 @@
margin: .25rem;
}
:host /deep/ {
.wizard-title {
background: $color-border;
margin: -1rem;
margin-bottom: 1rem;
font-weight: 400;
font-size: 1.05rem;
padding: 1rem;
}
.wizard-title {
background: $color-border;
margin: -1rem;
margin-bottom: 1rem;
font-weight: 400;
font-size: 1.05rem;
padding: 1rem;
}

2
src/Squidex/app/features/rules/pages/rules/triggers/asset-changed-trigger.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Trigger rule when events happen for assets...</h3>
<div [formGroup]="triggerForm" class="form-horizontal">
<div class="form-group">
<div class="form-check">

2
src/Squidex/app/features/rules/pages/rules/triggers/content-changed-trigger.component.html

@ -1,5 +1,3 @@
<h3 class="wizard-title">Trigger rule when events happen for schemas...</h3>
<ng-container *ngIf="!triggerForm.controls.handleAll.value">
<table class="table table-middle table-sm table-fixed table-borderless">
<colgroup>

Loading…
Cancel
Save