Browse Source

App context removed.

pull/271/head
Sebastian Stehle 9 years ago
parent
commit
a3538bad26
  1. 18
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  2. 25
      src/Squidex/app/features/administration/pages/users/user-page.component.ts
  3. 4
      src/Squidex/app/features/administration/pages/users/users-page.component.html
  4. 25
      src/Squidex/app/features/administration/pages/users/users-page.component.ts
  5. 22
      src/Squidex/app/features/administration/state/users.state.ts
  6. 40
      src/Squidex/app/features/schemas/state/schemas.state.ts
  7. 60
      src/Squidex/app/framework/angular/http-extensions-impl.ts
  8. 1
      src/Squidex/app/framework/declarations.ts
  9. 16
      src/Squidex/app/framework/services/dialog.service.ts
  10. 40
      src/Squidex/app/framework/utils/error.spec.ts
  11. 57
      src/Squidex/app/framework/utils/error.ts
  12. 11
      src/Squidex/app/framework/utils/version.spec.ts
  13. 8
      src/Squidex/app/framework/utils/version.ts

18
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts

@ -9,8 +9,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { import {
AppContext,
fadeAnimation, fadeAnimation,
DialogService,
ImmutableArray, ImmutableArray,
ModalView ModalView
} from 'shared'; } from 'shared';
@ -21,9 +21,6 @@ import { EventConsumerDto, EventConsumersService } from './../../services/event-
selector: 'sqx-event-consumers-page', selector: 'sqx-event-consumers-page',
styleUrls: ['./event-consumers-page.component.scss'], styleUrls: ['./event-consumers-page.component.scss'],
templateUrl: './event-consumers-page.component.html', templateUrl: './event-consumers-page.component.html',
providers: [
AppContext
],
animations: [ animations: [
fadeAnimation fadeAnimation
] ]
@ -35,7 +32,8 @@ export class EventConsumersPageComponent implements OnDestroy, OnInit {
public eventConsumerError = ''; public eventConsumerError = '';
public eventConsumers = ImmutableArray.empty<EventConsumerDto>(); public eventConsumers = ImmutableArray.empty<EventConsumerDto>();
constructor(public readonly ctx: AppContext, constructor(
private readonly dialogs: DialogService,
private readonly eventConsumersService: EventConsumersService private readonly eventConsumersService: EventConsumersService
) { ) {
} }
@ -59,11 +57,11 @@ export class EventConsumersPageComponent implements OnDestroy, OnInit {
this.eventConsumers = ImmutableArray.of(dtos); this.eventConsumers = ImmutableArray.of(dtos);
if (showInfo) { if (showInfo) {
this.ctx.notifyInfo('Event Consumers reloaded.'); this.dialogs.notifyInfo('Event Consumers reloaded.');
} }
}, error => { }, error => {
if (showError) { if (showError) {
this.ctx.notifyError(error); this.dialogs.notifyError(error);
} }
}); });
} }
@ -73,7 +71,7 @@ export class EventConsumersPageComponent implements OnDestroy, OnInit {
.subscribe(() => { .subscribe(() => {
this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.start()); this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.start());
}, error => { }, error => {
this.ctx.notifyError(error); this.dialogs.notifyError(error);
}); });
} }
@ -82,7 +80,7 @@ export class EventConsumersPageComponent implements OnDestroy, OnInit {
.subscribe(() => { .subscribe(() => {
this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.stop()); this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.stop());
}, error => { }, error => {
this.ctx.notifyError(error); this.dialogs.notifyError(error);
}); });
} }
@ -91,7 +89,7 @@ export class EventConsumersPageComponent implements OnDestroy, OnInit {
.subscribe(() => { .subscribe(() => {
this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.reset()); this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.reset());
}, error => { }, error => {
this.ctx.notifyError(error); this.dialogs.notifyError(error);
}); });
} }

25
src/Squidex/app/features/administration/pages/users/user-page.component.ts

@ -7,10 +7,10 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms'; import { FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { AppContext, ValidatorsEx } from 'shared'; import { AuthService, ValidatorsEx } from 'shared';
import { UserDto } from './../../services/users.service'; import { UserDto } from './../../services/users.service';
import { UsersState } from './../../state/users.state'; import { UsersState } from './../../state/users.state';
@ -18,10 +18,7 @@ import { UsersState } from './../../state/users.state';
@Component({ @Component({
selector: 'sqx-user-page', selector: 'sqx-user-page',
styleUrls: ['./user-page.component.scss'], styleUrls: ['./user-page.component.scss'],
templateUrl: './user-page.component.html', templateUrl: './user-page.component.html'
providers: [
AppContext
]
}) })
export class UserPageComponent implements OnDestroy, OnInit { export class UserPageComponent implements OnDestroy, OnInit {
private selectedUserSubscription: Subscription; private selectedUserSubscription: Subscription;
@ -55,10 +52,12 @@ export class UserPageComponent implements OnDestroy, OnInit {
public isCurrentUser = false; public isCurrentUser = false;
constructor(public readonly ctx: AppContext, constructor(
private readonly authService: AuthService,
private readonly formBuilder: FormBuilder, private readonly formBuilder: FormBuilder,
private readonly route: ActivatedRoute,
private readonly router: Router, private readonly router: Router,
private readonly state: UsersState private readonly usersState: UsersState
) { ) {
} }
@ -68,7 +67,7 @@ export class UserPageComponent implements OnDestroy, OnInit {
public ngOnInit() { public ngOnInit() {
this.selectedUserSubscription = this.selectedUserSubscription =
this.state.selectedUser.subscribe(user => this.setupAndPopulateForm(user!)); this.usersState.selectedUser.subscribe(user => this.setupAndPopulateForm(user!));
} }
public save() { public save() {
@ -80,14 +79,14 @@ export class UserPageComponent implements OnDestroy, OnInit {
const requestDto = this.userForm.value; const requestDto = this.userForm.value;
if (!this.user) { if (!this.user) {
this.state.createUser(requestDto) this.usersState.createUser(requestDto)
.subscribe(user => { .subscribe(user => {
this.back(); this.back();
}, error => { }, error => {
this.resetFormState(error.displayMessage); this.resetFormState(error.displayMessage);
}); });
} else { } else {
this.state.updateUser(this.user!, requestDto) this.usersState.updateUser(this.user!, requestDto)
.subscribe(() => { .subscribe(() => {
this.resetFormState(); this.resetFormState();
}, error => { }, error => {
@ -98,13 +97,13 @@ export class UserPageComponent implements OnDestroy, OnInit {
} }
private back() { private back() {
this.router.navigate(['../'], { relativeTo: this.ctx.route, replaceUrl: true }); this.router.navigate(['../'], { relativeTo: this.route, replaceUrl: true });
} }
private setupAndPopulateForm(user: UserDto | null) { private setupAndPopulateForm(user: UserDto | null) {
this.user = user; this.user = user;
this.isCurrentUser = user !== null && user.id === this.ctx.userId; this.isCurrentUser = user !== null && user.id === this.authService.user!.id;
this.userForm.controls['password'].setValidators( this.userForm.controls['password'].setValidators(
user ? user ?

4
src/Squidex/app/features/administration/pages/users/users-page.component.html

@ -56,7 +56,7 @@
<div sqxIgnoreScrollbar> <div sqxIgnoreScrollbar>
<table class="table table-items table-fixed"> <table class="table table-items table-fixed">
<tbody> <tbody>
<ng-template ngFor let-user [ngForOf]="state.usersItems | async" [ngForTrackBy]="state.trackBy"> <ng-template ngFor let-user [ngForOf]="state.usersItems | async" [ngForTrackBy]="state.trackByUser">
<tr [routerLink]="user.id" routerLinkActive="active"> <tr [routerLink]="user.id" routerLinkActive="active">
<td class="cell-user"> <td class="cell-user">
<img class="user-picture" [attr.title]="user.name" [attr.src]="user | sqxUserDtoPicture" /> <img class="user-picture" [attr.title]="user.name" [attr.src]="user | sqxUserDtoPicture" />
@ -88,7 +88,7 @@
</div> </div>
</div> </div>
<ng-container *ngIf="state.usersPager | async as pager"> <ng-container *ngIf="usersState.usersPager | async as pager">
<div class="grid-footer clearfix" *ngIf="pager.numberOfItems > 0"> <div class="grid-footer clearfix" *ngIf="pager.numberOfItems > 0">
<div class="float-right pagination"> <div class="float-right pagination">
<span class="pagination-text">{{pager.itemFirst}}-{{pager.itemLast}} of {{pager.numberOfItems}}</span> <span class="pagination-text">{{pager.itemFirst}}-{{pager.itemLast}} of {{pager.numberOfItems}}</span>

25
src/Squidex/app/features/administration/pages/users/users-page.component.ts

@ -8,7 +8,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { AppContext } from 'shared'; import { DialogService } from 'shared';
import { UserDto } from './../../services/users.service'; import { UserDto } from './../../services/users.service';
import { UsersState } from './../../state/users.state'; import { UsersState } from './../../state/users.state';
@ -16,16 +16,13 @@ import { UsersState } from './../../state/users.state';
@Component({ @Component({
selector: 'sqx-users-page', selector: 'sqx-users-page',
styleUrls: ['./users-page.component.scss'], styleUrls: ['./users-page.component.scss'],
templateUrl: './users-page.component.html', templateUrl: './users-page.component.html'
providers: [
AppContext
]
}) })
export class UsersPageComponent implements OnInit { export class UsersPageComponent implements OnInit {
public usersFilter = new FormControl(); public usersFilter = new FormControl();
constructor(public readonly ctx: AppContext, constructor(public readonly usersState: UsersState,
public readonly state: UsersState private readonly dialogs: DialogService
) { ) {
} }
@ -34,32 +31,32 @@ export class UsersPageComponent implements OnInit {
} }
public search() { public search() {
this.state.search(this.usersFilter.value).subscribe(); this.usersState.search(this.usersFilter.value).subscribe();
} }
public load(showInfo = false) { public load(showInfo = false) {
this.state.loadUsers() this.usersState.loadUsers()
.subscribe(() => { .subscribe(() => {
if (showInfo) { if (showInfo) {
this.ctx.notifyInfo('Users reloaded.'); this.dialogs.notifyInfo('Users reloaded.');
} }
}); });
} }
public lock(user: UserDto) { public lock(user: UserDto) {
this.state.lockUser(user).subscribe(); this.usersState.lockUser(user).subscribe();
} }
public unlock(user: UserDto) { public unlock(user: UserDto) {
this.state.unlockUser(user).subscribe(); this.usersState.unlockUser(user).subscribe();
} }
public goPrev() { public goPrev() {
this.state.goPrev().subscribe(); this.usersState.goPrev().subscribe();
} }
public goNext() { public goNext() {
this.state.goNext().subscribe(); this.usersState.goNext().subscribe();
} }
} }

22
src/Squidex/app/features/administration/state/users.state.ts

@ -12,9 +12,7 @@ import 'framework/utils/rxjs-extensions';
import { import {
DialogService, DialogService,
ErrorDto,
ImmutableArray, ImmutableArray,
Notification,
Pager Pager
} from 'shared'; } from 'shared';
@ -59,7 +57,7 @@ export class UsersState {
public loadUsers(): Observable<any> { public loadUsers(): Observable<any> {
return this.usersService.getUsers(this.usersPager.value.pageSize, this.usersPager.value.skip, this.usersQuery.value) return this.usersService.getUsers(this.usersPager.value.pageSize, this.usersPager.value.skip, this.usersQuery.value)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dtos => { .do(dtos => {
this.users.nextBy(v => ImmutableArray.of(dtos.items)); this.users.nextBy(v => ImmutableArray.of(dtos.items));
this.usersPager.nextBy(v => v.setCount(dtos.total)); this.usersPager.nextBy(v => v.setCount(dtos.total));
@ -77,7 +75,7 @@ export class UsersState {
public updateUser(user: UserDto, request: CreateUserDto): Observable<any> { public updateUser(user: UserDto, request: CreateUserDto): Observable<any> {
return this.usersService.putUser(user.id, request) return this.usersService.putUser(user.id, request)
.do(() => { .do(() => {
this.dialogs.notify(Notification.info('User saved successsfull')); this.dialogs.notifyInfo('User saved successsfull');
this.replaceUser(user.update(request.email, request.displayName)); this.replaceUser(user.update(request.email, request.displayName));
}); });
@ -85,7 +83,7 @@ export class UsersState {
public lockUser(user: UserDto): Observable<any> { public lockUser(user: UserDto): Observable<any> {
return this.usersService.lockUser(user.id) return this.usersService.lockUser(user.id)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(() => { .do(() => {
this.replaceUser(user.lock()); this.replaceUser(user.lock());
}); });
@ -93,7 +91,7 @@ export class UsersState {
public unlockUser(user: UserDto): Observable<any> { public unlockUser(user: UserDto): Observable<any> {
return this.usersService.unlockUser(user.id) return this.usersService.unlockUser(user.id)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(() => { .do(() => {
this.replaceUser(user.unlock()); this.replaceUser(user.unlock());
}); });
@ -118,7 +116,7 @@ export class UsersState {
return this.loadUsers(); return this.loadUsers();
} }
public trackBy(index: number, user: UserDto): any { public trackByUser(index: number, user: UserDto): any {
return user.id; return user.id;
} }
@ -127,14 +125,4 @@ export class UsersState {
this.selectedUser.nextBy(v => v !== null && v.id === user.id ? user : v); this.selectedUser.nextBy(v => v !== null && v.id === user.id ? user : v);
} }
private notifyError(error: string | ErrorDto) {
if (error instanceof ErrorDto) {
this.dialogs.notify(Notification.error(error.displayMessage));
} else {
this.dialogs.notify(Notification.error(error));
}
return Observable.throw(error);
}
} }

40
src/Squidex/app/features/schemas/state/schemas.state.ts

@ -17,10 +17,8 @@ import {
CreateSchemaDto, CreateSchemaDto,
DateTime, DateTime,
DialogService, DialogService,
ErrorDto,
FieldDto, FieldDto,
ImmutableArray, ImmutableArray,
Notification,
SchemaDto, SchemaDto,
SchemaDetailsDto, SchemaDetailsDto,
SchemasService, SchemasService,
@ -73,7 +71,7 @@ export class SchemasState {
public load(): Observable<any> { public load(): Observable<any> {
return this.schemasService.getSchemas(this.app) return this.schemasService.getSchemas(this.app)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dtos => { .do(dtos => {
this.schemasItems.nextBy(v => ImmutableArray.of(dtos)); this.schemasItems.nextBy(v => ImmutableArray.of(dtos));
}); });
@ -95,7 +93,7 @@ export class SchemasState {
public publish(schema: SchemaDto): Observable<any> { public publish(schema: SchemaDto): Observable<any> {
return this.schemasService.publishSchema(this.app, schema.name, schema.version) return this.schemasService.publishSchema(this.app, schema.name, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.publish(this.user, dto.version)); this.replaceSchema(schema.publish(this.user, dto.version));
}); });
@ -103,7 +101,7 @@ export class SchemasState {
public unpublish(schema: SchemaDto): Observable<any> { public unpublish(schema: SchemaDto): Observable<any> {
return this.schemasService.unpublishSchema(this.app, schema.name, schema.version) return this.schemasService.unpublishSchema(this.app, schema.name, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.unpublish(this.user, dto.version)); this.replaceSchema(schema.unpublish(this.user, dto.version));
}); });
@ -111,7 +109,7 @@ export class SchemasState {
public enableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public enableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.enableField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.enableField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.enable(), this.user, dto.version)); this.replaceSchema(schema.updateField(field.enable(), this.user, dto.version));
}); });
@ -119,7 +117,7 @@ export class SchemasState {
public disableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public disableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.disableField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.disableField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.disable(), this.user, dto.version)); this.replaceSchema(schema.updateField(field.disable(), this.user, dto.version));
}); });
@ -127,7 +125,7 @@ export class SchemasState {
public lockField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public lockField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.lockField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.lockField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.lock(), this.user, dto.version)); this.replaceSchema(schema.updateField(field.lock(), this.user, dto.version));
}); });
@ -135,7 +133,7 @@ export class SchemasState {
public showField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public showField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.showField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.showField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.show(), this.user, dto.version)); this.replaceSchema(schema.updateField(field.show(), this.user, dto.version));
}); });
@ -143,7 +141,7 @@ export class SchemasState {
public hideField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public hideField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.hideField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.hideField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.hide(), this.user, dto.version)); this.replaceSchema(schema.updateField(field.hide(), this.user, dto.version));
}); });
@ -151,7 +149,7 @@ export class SchemasState {
public deleteField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> { public deleteField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.deleteField(this.app, schema.name, field.fieldId, schema.version) return this.schemasService.deleteField(this.app, schema.name, field.fieldId, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.removeField(field, this.user, dto.version)); this.replaceSchema(schema.removeField(field, this.user, dto.version));
}); });
@ -159,7 +157,7 @@ export class SchemasState {
public sortFields(schema: SchemaDetailsDto, fields: FieldDto[]): Observable<any> { public sortFields(schema: SchemaDetailsDto, fields: FieldDto[]): Observable<any> {
return this.schemasService.putFieldOrdering(this.app, schema.name, fields.map(t => t.fieldId), schema.version) return this.schemasService.putFieldOrdering(this.app, schema.name, fields.map(t => t.fieldId), schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.replaceFields(fields, this.user, dto.version)); this.replaceSchema(schema.replaceFields(fields, this.user, dto.version));
}); });
@ -167,7 +165,7 @@ export class SchemasState {
public updateField(schema: SchemaDetailsDto, field: FieldDto, request: UpdateFieldDto): Observable<any> { public updateField(schema: SchemaDetailsDto, field: FieldDto, request: UpdateFieldDto): Observable<any> {
return this.schemasService.putField(this.app, schema.name, field.fieldId, request, schema.version) return this.schemasService.putField(this.app, schema.name, field.fieldId, request, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.updateField(field.update(request.properties), this.user, dto.version)); this.replaceSchema(schema.updateField(field.update(request.properties), this.user, dto.version));
}); });
@ -175,7 +173,7 @@ export class SchemasState {
public configureScripts(schema: SchemaDetailsDto, request: UpdateSchemaScriptsDto): Observable<any> { public configureScripts(schema: SchemaDetailsDto, request: UpdateSchemaScriptsDto): Observable<any> {
return this.schemasService.putSchemaScripts(this.app, schema.name, request, schema.version) return this.schemasService.putSchemaScripts(this.app, schema.name, request, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.configureScripts(request, this.user, dto.version)); this.replaceSchema(schema.configureScripts(request, this.user, dto.version));
}); });
@ -183,7 +181,7 @@ export class SchemasState {
public update(schema: SchemaDetailsDto, request: UpdateSchemaDto): Observable<any> { public update(schema: SchemaDetailsDto, request: UpdateSchemaDto): Observable<any> {
return this.schemasService.putSchema(this.app, schema.name, request, schema.version) return this.schemasService.putSchema(this.app, schema.name, request, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.replaceSchema(schema.update(request, this.user, dto.version)); this.replaceSchema(schema.update(request, this.user, dto.version));
}); });
@ -191,7 +189,7 @@ export class SchemasState {
public delete(schema: SchemaDto): Observable<any> { public delete(schema: SchemaDto): Observable<any> {
return this.schemasService.deleteSchema(this.app, schema.name, schema.version) return this.schemasService.deleteSchema(this.app, schema.name, schema.version)
.catch(error => this.notifyError(error)) .catch(error => this.dialogs.notifyError(error))
.do(dto => { .do(dto => {
this.schemasItems.nextBy(v => v.filter(s => s.id !== schema.id)); this.schemasItems.nextBy(v => v.filter(s => s.id !== schema.id));
}); });
@ -210,14 +208,4 @@ export class SchemasState {
public trackByField(index: number, field: FieldDto): any { public trackByField(index: number, field: FieldDto): any {
return field.fieldId; return field.fieldId;
} }
private notifyError(error: string | ErrorDto) {
if (error instanceof ErrorDto) {
this.dialogs.notify(Notification.error(error.displayMessage));
} else {
this.dialogs.notify(Notification.error(error));
}
return Observable.throw(error);
}
} }

60
src/Squidex/app/framework/angular/http-extensions-impl.ts

@ -8,65 +8,9 @@
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http'; import { HttpClient, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { Version } from './../utils/version'; import { ErrorDto } from './../utils/error';
export class Versioned<T> { import { Version, Versioned } from './../utils/version';
constructor(
public readonly version: Version,
public readonly payload: T
) {
}
}
function formatMessage(message: string, details?: string[]) {
const appendLast = (row: string, char: string) => {
const last = row[row.length - 1];
if (last !== char) {
return row + char;
} else {
return row;
}
};
const removeLast = (row: string, char: string) => {
const last = row[row.length - 1];
if (last === char) {
return row.substr(0, row.length - 1);
} else {
return row;
}
};
if (details && details.length > 1) {
let result = appendLast(message, '.') + '<ul>';
for (let detail of details) {
result += `<li>${appendLast(detail, '.')}</li>`;
}
result = result + '</ul>';
return result;
} else if (details && details.length === 1) {
return `${appendLast(removeLast(message, '.'), ':')} ${appendLast(details[0], '.')}`;
} else {
return appendLast(message, '.');
}
}
export class ErrorDto {
public readonly displayMessage: string;
constructor(
public readonly statusCode: number,
public readonly message: string,
public readonly details: string[] = []
) {
this.displayMessage = formatMessage(message, details);
}
}
export module HTTP { export module HTTP {
export function getVersioned<T>(http: HttpClient, url: string, version?: Version): Observable<Versioned<HttpResponse<T>>> { export function getVersioned<T>(http: HttpClient, url: string, version?: Version): Observable<Versioned<HttpResponse<T>>> {

1
src/Squidex/app/framework/declarations.ts

@ -67,6 +67,7 @@ export * from './services/title.service';
export * from './utils/date-helper'; export * from './utils/date-helper';
export * from './utils/date-time'; export * from './utils/date-time';
export * from './utils/duration'; export * from './utils/duration';
export * from './utils/error';
export * from './utils/immutable-array'; export * from './utils/immutable-array';
export * from './utils/math-helper'; export * from './utils/math-helper';
export * from './utils/modal-view'; export * from './utils/modal-view';

16
src/Squidex/app/framework/services/dialog.service.ts

@ -8,6 +8,8 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { ErrorDto } from './../utils/error';
export const DialogServiceFactory = () => { export const DialogServiceFactory = () => {
return new DialogService(); return new DialogService();
}; };
@ -61,6 +63,20 @@ export class DialogService {
return this.notificationsStream$; return this.notificationsStream$;
} }
public notifyError(error: string | ErrorDto) {
if (error instanceof ErrorDto) {
this.notify(Notification.error(error.displayMessage));
} else {
this.notify(Notification.error(error));
}
return Observable.throw(error);
}
public notifyInfo(text: string) {
this.notificationsStream$.next(Notification.info(text));
}
public notify(notification: Notification) { public notify(notification: Notification) {
this.notificationsStream$.next(notification); this.notificationsStream$.next(notification);
} }

40
src/Squidex/app/framework/utils/error.spec.ts

@ -0,0 +1,40 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { ErrorDto } from './../';
describe('ErrorDto', () => {
it('Should create simple message when no details are specified.', () => {
const error = new ErrorDto(500, 'Error Message.');
expect(error.displayMessage).toBe('Error Message.');
});
it('Should append dot to message', () => {
const error = new ErrorDto(500, 'Error Message');
expect(error.displayMessage).toBe('Error Message.');
});
it('Should create simple message when detail has one item', () => {
const error = new ErrorDto(500, 'Error Message.', ['Detail Message.']);
expect(error.displayMessage).toBe('Error Message: Detail Message.');
});
it('Should create append do to simple message when detail has one item', () => {
const error = new ErrorDto(500, 'Error Message', ['Detail Message']);
expect(error.displayMessage).toBe('Error Message: Detail Message.');
});
it('Should create html list when error has more items.', () => {
const error = new ErrorDto(500, 'Error Message', ['Detail1.', 'Detail2.']);
expect(error.displayMessage).toBe('Error Message.<ul><li>Detail1.</li><li>Detail2.</li></ul>');
});
});

57
src/Squidex/app/framework/utils/error.ts

@ -0,0 +1,57 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
export class ErrorDto {
public readonly displayMessage: string;
constructor(
public readonly statusCode: number,
public readonly message: string,
public readonly details: string[] = []
) {
this.displayMessage = formatMessage(message, details);
}
}
function formatMessage(message: string, details?: string[]) {
const appendLast = (row: string, char: string) => {
const last = row[row.length - 1];
if (last !== char) {
return row + char;
} else {
return row;
}
};
const removeLast = (row: string, char: string) => {
const last = row[row.length - 1];
if (last === char) {
return row.substr(0, row.length - 1);
} else {
return row;
}
};
if (details && details.length > 1) {
let result = appendLast(message, '.') + '<ul>';
for (let detail of details) {
result += `<li>${appendLast(detail, '.')}</li>`;
}
result = result + '</ul>';
return result;
} else if (details && details.length === 1) {
return `${appendLast(removeLast(message, '.'), ':')} ${appendLast(details[0], '.')}`;
} else {
return appendLast(message, '.');
}
}

11
src/Squidex/app/framework/utils/version.spec.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { Version } from './../'; import { Version, Versioned } from './../';
describe('Version', () => { describe('Version', () => {
it('should initialize with init value', () => { it('should initialize with init value', () => {
@ -13,4 +13,13 @@ describe('Version', () => {
expect(version.value).toBe('1.0'); expect(version.value).toBe('1.0');
}); });
});
describe('Versioned', () => {
it('should initialize with version and payload', () => {
const versioned = new Versioned<number>(new Version('1.0'), 123);
expect(versioned.version.value).toBe('1.0');
expect(versioned.payload).toBe(123);
});
}); });

8
src/Squidex/app/framework/utils/version.ts

@ -10,4 +10,12 @@ export class Version {
public readonly value: string public readonly value: string
) { ) {
} }
}
export class Versioned<T> {
constructor(
public readonly version: Version,
public readonly payload: T
) {
}
} }
Loading…
Cancel
Save