Browse Source

Connect screen

pull/342/head
Sebastian Stehle 7 years ago
parent
commit
c8318775fd
  1. 12
      src/Squidex.Domain.Apps.Entities/Apps/AppHistoryEventsCreator.cs
  2. 16
      src/Squidex/app/features/rules/pages/rules/triggers/asset-changed-trigger.component.scss
  3. 20
      src/Squidex/app/features/rules/pages/rules/triggers/content-changed-trigger.component.scss
  4. 2
      src/Squidex/app/features/settings/module.ts
  5. 68
      src/Squidex/app/features/settings/pages/clients/client.component.html
  6. 22
      src/Squidex/app/features/settings/pages/clients/client.component.scss
  7. 53
      src/Squidex/app/features/settings/pages/clients/client.component.ts
  8. 4
      src/Squidex/app/features/settings/pages/plans/plans-page.component.html
  9. 45
      src/Squidex/app/theme/_common.scss

12
src/Squidex.Domain.Apps.Entities/Apps/AppHistoryEventsCreator.cs

@ -43,6 +43,9 @@ namespace Squidex.Domain.Apps.Entities.Apps
AddEventMessage<AppClientRenamed>(
"renamed client {[Id]} to {[Name]}");
AddEventMessage<AppPlanChanged>(
"changed plan to {[Plan]}");
AddEventMessage<AppLanguageAdded>(
"added language {[Language]}");
@ -200,6 +203,15 @@ namespace Squidex.Domain.Apps.Entities.Apps
.AddParameter("Name", @event.Name));
}
protected Task<HistoryEvent> On(AppPlanChanged @event)
{
const string channel = "settings.plan";
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Plan", @event.PlanId));
}
protected Task<HistoryEvent> On(AppRoleDeleted @event)
{
const string channel = "settings.roles";

16
src/Squidex/app/features/rules/pages/rules/triggers/asset-changed-trigger.component.scss

@ -3,20 +3,4 @@
textarea {
height: 100px;
}
.help {
& {
font-size: .9rem;
}
&-example {
margin-top: .375rem;
}
&-examples {
margin-top: 0;
margin-bottom: 0;
padding-left: 1.5rem;
}
}

20
src/Squidex/app/features/rules/pages/rules/triggers/content-changed-trigger.component.scss

@ -9,24 +9,4 @@
.form-check {
margin-top: 1rem;
}
textarea {
height: 100px;
}
.help {
& {
font-size: .9rem;
}
&-example {
margin-top: .375rem;
}
&-examples {
margin-top: 0;
margin-bottom: 0;
padding-left: 1.5rem;
}
}

2
src/Squidex/app/features/settings/module.ts

@ -66,7 +66,7 @@ const routes: Routes = [
path: 'history',
component: HistoryComponent,
data: {
channel: 'settings.plans'
channel: 'settings.plan'
}
}
]

68
src/Squidex/app/features/settings/pages/clients/client.component.html

@ -24,11 +24,9 @@
<i class="client-edit icon-pencil" (click)="toggleRename()"></i>
</ng-container>
</div>
<div class="client-expires">Access tokens expire after 30 days</div>
</div>
<div class="col-auto">
<button class="btn btn-secondary" (click)="createToken(client)">Create Token</button>
<button class="btn btn-secondary" (click)="createToken(client)">Connect</button>
</div>
<div class="col-auto cell-actions">
<button type="button" class="btn btn-text-danger"
@ -47,7 +45,7 @@
<input readonly class="form-control" value="{{appsState.appName}}:{{client.id}}" #inputName />
</div>
<div class="col-auto cell-actions">
<button type="button" class="btn btn-primary btn-text" [sqxCopy]="inputName">
<button type="button" class="btn btn-text" [sqxCopy]="inputName">
<i class="icon-copy"></i>
</button>
</div>
@ -60,7 +58,7 @@
<input readonly class="form-control" [attr.value]="client.secret" #inputSecret />
</div>
<div class="col-auto cell-actions">
<button type="button" class="btn btn-primary btn-text" [sqxCopy]="inputSecret">
<button type="button" class="btn btn-text" [sqxCopy]="inputSecret">
<i class="icon-copy"></i>
</button>
</div>
@ -79,12 +77,66 @@
</div>
</div>
<sqx-modal-dialog *sqxModalView="tokenDialog;onRoot:true" (closed)="tokenDialog.hide()">
<sqx-modal-dialog *sqxModalView="connectDialog;onRoot:true" large="true" (closed)="connectDialog.hide()">
<ng-container title>
Access token
Connect
</ng-container>
<ng-container content>
<textarea readonly class="form-control access-token">{{token.tokenType}} {{token.accessToken}}</textarea>
<div class="help">
<h2>How to connect to this client</h2>
<h3>Using HTTP</h3>
<div class="help-section">
1. Make the following request to get an access token. It will be valid for 30 days.
<pre class="code code-block">{{connectHttpText}}</pre>
</div>
<div class="help-section">
2. Add the bearer token as authorization header to all requests:
<pre class="code code-block">Authorization: Bearer [YOUR_TOKEN]</pre>
</div>
<div class="help-section">
Use the following token for testing
<ng-container *ngIf="connectToken">
<textarea class="form-control access-token" readonly>{{connectToken.tokenType}} {{connectToken.accessToken}}</textarea>
</ng-container>
</div>
<h3>Using the command line interface (CLI)</h3>
<div class="help-section">
Download the CLI here: <a href="https://github.com/Squidex/squidex-samples/releases" target="_blank">CLI Releases (Linux, OS X, Windows)</a>
</div>
<div class="help-section">
Connect with windows:
<pre class="code code-block">{{connectCLIWinText}}</pre>
</div>
<div class="help-section">
Connect with Linux / OS X
<pre class="code code-block">{{connectCLINixText}}</pre>
</div>
<h3>Using the C# Client Library</h3>
<div class="help-section">
Get the nuget library from <a href="https://www.nuget.org/packages/Squidex.ClientLibrary/" target="_blank">nuget.org</a>
</div>
<div class="help-section">
Create a client manager
<pre class="code code-block">{{connectLibrary}}</pre>
</div>
</div>
</ng-container>
</sqx-modal-dialog>

22
src/Squidex/app/features/settings/pages/clients/client.component.scss

@ -12,12 +12,6 @@ $color-editor: #eceeef;
vertical-align: top;
}
&-expires {
font-size: .8rem;
font-weight: normal;
margin-bottom: .75rem;
}
&-edit {
color: $color-border-dark;
display: none;
@ -35,11 +29,17 @@ $color-editor: #eceeef;
font-size: 1.2rem;
font-weight: normal;
line-height: 1.5rem;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
display: inline-block;
margin: 0;
}
&-header {
& {
margin-bottom: .5rem;
}
&:hover {
.client-edit {
display: inline-block;
@ -48,13 +48,6 @@ $color-editor: #eceeef;
}
}
h3 {
&.client-name {
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
}
.col-form-label {
text-align: left;
}
@ -68,8 +61,9 @@ h3 {
}
.access-token {
height: 18rem;
height: 10rem;
font-size: 1rem;
font-weight: normal;
font-family: monospace;
resize: none;
}

53
src/Squidex/app/features/settings/pages/clients/client.component.ts

@ -11,6 +11,7 @@ import { onErrorResumeNext } from 'rxjs/operators';
import {
AccessTokenDto,
ApiUrlConfig,
AppClientDto,
AppClientsService,
AppRoleDto,
@ -24,6 +25,36 @@ import {
const ESCAPE_KEY = 27;
function connectHttpText(apiUrl: ApiUrlConfig, app: string, client: { id: string, secret: string }) {
const url = apiUrl.buildUrl('identity-server/connect/token');
return `$ curl
-X POST '${url}'
-H 'Content-Type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials&
client_id=${app}:${client.id}&
client_secret=${client.secret}&
scope=squidex-api`;
}
function connectLibrary(apiUrl: ApiUrlConfig, app: string, client: { id: string, secret: string }) {
const url = apiUrl.value;
return `var clientManager = new SquidexClientManager(
"${url}",
"${app}",
"${app}:${client.id}",
"${client.secret}")`;
}
function connectCLIWinText(app: string, client: { id: string, secret: string }) {
return `.\\sq.exe config add ${app} ${app}:${client.id} ${client.secret};.\\sq.exe config use ${app}`;
}
function connectCLINixText(app: string, client: { id: string, secret: string }) {
return `sq config add ${app} ${app}:${client.id} ${client.secret} && sq config use ${app}`;
}
@Component({
selector: 'sqx-client',
styleUrls: ['./client.component.scss'],
@ -38,13 +69,19 @@ export class ClientComponent implements OnChanges {
public isRenaming = false;
public token: AccessTokenDto;
public tokenDialog = new DialogModel();
public connectToken: AccessTokenDto;
public connectDialog = new DialogModel();
public renameForm = new RenameClientForm(this.formBuilder);
public connectHttpText: string;
public connectCLINixText: string;
public connectCLIWinText: string;
public connectLibrary: string;
constructor(
public readonly appsState: AppsState,
private readonly apiUrl: ApiUrlConfig,
private readonly appClientsService: AppClientsService,
private readonly clientsState: ClientsState,
private readonly dialogs: DialogService,
@ -54,6 +91,13 @@ export class ClientComponent implements OnChanges {
public ngOnChanges() {
this.renameForm.load(this.client);
const app = this.appsState.appName;
this.connectHttpText = connectHttpText(this.apiUrl, app, this.client);
this.connectCLINixText = connectCLINixText(app, this.client);
this.connectCLIWinText = connectCLIWinText(app, this.client);
this.connectLibrary = connectLibrary(this.apiUrl, app, this.client);
}
public revoke() {
@ -92,10 +136,11 @@ export class ClientComponent implements OnChanges {
}
public createToken(client: AppClientDto) {
this.connectDialog.show();
this.appClientsService.createToken(this.appsState.appName, client)
.subscribe(dto => {
this.token = dto;
this.tokenDialog.show();
this.connectToken = dto;
}, error => {
this.dialogs.notifyError(error);
});

4
src/Squidex/app/features/settings/pages/plans/plans-page.component.html

@ -79,8 +79,8 @@
</ng-container>
<ng-container sidebar>
<a class="panel-link" routerLink="help" routerLinkActive="active">
<i class="icon-help"></i>
<a class="panel-link" routerLink="history" routerLinkActive="active">
<i class="icon-time"></i>
</a>
</ng-container>
</sqx-panel>

45
src/Squidex/app/theme/_common.scss

@ -62,6 +62,51 @@ pre {
padding: .25rem .5rem;
margin: 0;
}
&.code-block {
display: block;
}
}
//
// Help texts
//
.help {
& {
font-size: .9rem;
}
pre {
font-size: 100%;
}
h2 {
margin-top: 1rem;
}
h3 {
margin-top: 2rem;
margin-bottom: .25rem;
font-size: 1.1rem;
}
.code-block {
margin: .25rem 0;
}
&-section {
padding-top: .5rem;
}
&-example {
margin-top: .375rem;
}
&-examples {
margin-top: 0;
margin-bottom: 0;
padding-left: 1.5rem;
}
}
//

Loading…
Cancel
Save