Browse Source

Temp

pull/355/head
Sebastian Stehle 8 years ago
parent
commit
b47deb8ab4
  1. 3
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  2. 7
      src/Squidex/app/features/administration/pages/users/user-page.component.ts
  3. 3
      src/Squidex/app/features/administration/pages/users/users-page.component.ts
  4. 6
      src/Squidex/app/features/administration/services/users.service.spec.ts
  5. 3
      src/Squidex/app/features/content/pages/content/content-field.component.ts
  6. 3
      src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts
  7. 5
      src/Squidex/app/features/schemas/pages/schema/field-wizard.component.ts
  8. 9
      src/Squidex/app/features/schemas/pages/schema/field.component.ts
  9. 6
      src/Squidex/app/features/schemas/pages/schema/forms/field-form-validation.component.ts
  10. 6
      src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts
  11. 21
      src/Squidex/app/features/settings/pages/clients/client.component.ts
  12. 9
      src/Squidex/app/features/settings/pages/clients/clients-page.component.ts
  13. 13
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts
  14. 5
      src/Squidex/app/features/settings/pages/languages/language.component.ts
  15. 4
      src/Squidex/app/features/settings/pages/patterns/pattern.component.ts
  16. 4
      src/Squidex/app/features/settings/pages/patterns/patterns-page.component.ts
  17. 9
      src/Squidex/app/features/settings/pages/roles/role.component.ts
  18. 10
      src/Squidex/app/features/settings/pages/roles/roles-page.component.ts
  19. 16
      src/Squidex/app/framework/state.ts
  20. 3
      src/Squidex/app/shared/components/app-form.component.ts
  21. 8
      src/Squidex/app/shared/internal.ts
  22. 16
      src/Squidex/app/shared/module.ts
  23. 8
      src/Squidex/app/shared/services/app-languages.service.ts
  24. 42
      src/Squidex/app/shared/services/assets.service.spec.ts
  25. 4
      src/Squidex/app/shared/services/assets.service.ts
  26. 42
      src/Squidex/app/shared/services/clients.service.spec.ts
  27. 26
      src/Squidex/app/shared/services/clients.service.ts
  28. 30
      src/Squidex/app/shared/services/contributors.service.spec.ts
  29. 14
      src/Squidex/app/shared/services/contributors.service.ts
  30. 2
      src/Squidex/app/shared/services/help.service.spec.ts
  31. 30
      src/Squidex/app/shared/services/patterns.service.spec.ts
  32. 22
      src/Squidex/app/shared/services/patterns.service.ts
  33. 32
      src/Squidex/app/shared/services/roles.service.spec.ts
  34. 24
      src/Squidex/app/shared/services/roles.service.ts
  35. 8
      src/Squidex/app/shared/services/schemas.service.spec.ts
  36. 12
      src/Squidex/app/shared/services/schemas.service.ts
  37. 20
      src/Squidex/app/shared/state/clients.state.spec.ts
  38. 30
      src/Squidex/app/shared/state/clients.state.ts
  39. 26
      src/Squidex/app/shared/state/contributors.state.spec.ts
  40. 26
      src/Squidex/app/shared/state/contributors.state.ts
  41. 20
      src/Squidex/app/shared/state/patterns.state.spec.ts
  42. 28
      src/Squidex/app/shared/state/patterns.state.ts
  43. 20
      src/Squidex/app/shared/state/roles.state.spec.ts
  44. 30
      src/Squidex/app/shared/state/roles.state.ts
  45. 12
      src/Squidex/app/shared/state/schemas.state.spec.ts
  46. 11
      src/Squidex/app/shared/state/schemas.state.ts

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

@ -11,8 +11,7 @@ import { onErrorResumeNext, switchMap } from 'rxjs/operators';
import { DialogModel, ResourceOwner } from '@app/shared'; import { DialogModel, ResourceOwner } from '@app/shared';
import { EventConsumerDto } from './../../services/event-consumers.service'; import { EventConsumerDto, EventConsumersState } from '../../declarations';
import { EventConsumersState } from './../../state/event-consumers.state';
@Component({ @Component({
selector: 'sqx-event-consumers-page', selector: 'sqx-event-consumers-page',

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

@ -11,8 +11,11 @@ import { ActivatedRoute, Router } from '@angular/router';
import { ResourceOwner } from '@app/shared'; import { ResourceOwner } from '@app/shared';
import { UserDto } from './../../services/users.service'; import {
import { UserForm, UsersState } from './../../state/users.state'; UserDto,
UserForm,
UsersState
} from '../../declarations';
@Component({ @Component({
selector: 'sqx-user-page', selector: 'sqx-user-page',

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

@ -9,8 +9,7 @@ import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { onErrorResumeNext } from 'rxjs/operators'; import { onErrorResumeNext } from 'rxjs/operators';
import { UserDto } from './../../services/users.service'; import { UserDto, UsersState } from '../../declarations';
import { UsersState } from './../../state/users.state';
@Component({ @Component({
selector: 'sqx-users-page', selector: 'sqx-users-page',

6
src/Squidex/app/features/administration/services/users.service.spec.ts

@ -11,8 +11,6 @@ import { inject, TestBed } from '@angular/core/testing';
import { ApiUrlConfig } from '@app/framework'; import { ApiUrlConfig } from '@app/framework';
import { import {
CreateUserDto,
UpdateUserDto,
UserDto, UserDto,
UsersDto, UsersDto,
UsersService UsersService
@ -145,7 +143,7 @@ describe('UsersService', () => {
it('should make post request to create user', it('should make post request to create user',
inject([UsersService, HttpTestingController], (userManagementService: UsersService, httpMock: HttpTestingController) => { inject([UsersService, HttpTestingController], (userManagementService: UsersService, httpMock: HttpTestingController) => {
const dto = new CreateUserDto('mail@squidex.io', 'Squidex User', ['Permission1'], 'password'); const dto = { email: 'mail@squidex.io', displayName: 'Squidex User', permissions: ['Permission1'], password: 'password' };
let user: UserDto; let user: UserDto;
@ -166,7 +164,7 @@ describe('UsersService', () => {
it('should make put request to update user', it('should make put request to update user',
inject([UsersService, HttpTestingController], (userManagementService: UsersService, httpMock: HttpTestingController) => { inject([UsersService, HttpTestingController], (userManagementService: UsersService, httpMock: HttpTestingController) => {
const dto = new UpdateUserDto('mail@squidex.io', 'Squidex User', ['Permission1'], 'password'); const dto = { email: 'mail@squidex.io', displayName: 'Squidex User', permissions: ['Permission1'], password: 'password' };
userManagementService.putUser('123', dto).subscribe(); userManagementService.putUser('123', dto).subscribe();

3
src/Squidex/app/features/content/pages/content/content-field.component.ts

@ -19,7 +19,6 @@ import {
LocalStoreService, LocalStoreService,
RootFieldDto, RootFieldDto,
SchemaDto, SchemaDto,
TranslateDto,
TranslationsService, TranslationsService,
Types, Types,
value$ value$
@ -158,7 +157,7 @@ export class ContentFieldComponent implements OnChanges {
const value = control.value; const value = control.value;
if (!value) { if (!value) {
const request = new TranslateDto(text, sourceLanguage, targetLanguage); const request = { text, sourceLanguage, targetLanguage };
this.translations.translate(this.appsState.appName, request) this.translations.translate(this.appsState.appName, request)
.subscribe(result => { .subscribe(result => {

3
src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts

@ -9,7 +9,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { import {
CreateRuleDto,
Form, Form,
ImmutableArray, ImmutableArray,
RuleDto, RuleDto,
@ -118,7 +117,7 @@ export class RuleWizardComponent implements OnInit {
} }
private createRule() { private createRule() {
const requestDto = new CreateRuleDto(this.trigger, this.action); const requestDto = { trigger: this.trigger, action: this.action };
this.rulesState.create(requestDto) this.rulesState.create(requestDto)
.subscribe(() => { .subscribe(() => {

5
src/Squidex/app/features/schemas/pages/schema/field-wizard.component.ts

@ -18,8 +18,7 @@ import {
RootFieldDto, RootFieldDto,
SchemaDetailsDto, SchemaDetailsDto,
SchemasState, SchemasState,
Types, Types
UpdateFieldDto
} from '@app/shared'; } from '@app/shared';
@Component({ @Component({
@ -103,7 +102,7 @@ export class FieldWizardComponent implements OnInit {
if (value) { if (value) {
const properties = createProperties(this.field.properties['fieldType'], value); const properties = createProperties(this.field.properties['fieldType'], value);
this.schemasState.updateField(this.schema, this.field as RootFieldDto, new UpdateFieldDto(properties)) this.schemasState.updateField(this.schema, this.field as RootFieldDto, { properties })
.subscribe(() => { .subscribe(() => {
this.editForm.submitCompleted(); this.editForm.submitCompleted();

9
src/Squidex/app/features/schemas/pages/schema/field.component.ts

@ -10,7 +10,6 @@ import { FormBuilder } from '@angular/forms';
import { onErrorResumeNext } from 'rxjs/operators'; import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AppPatternDto,
createProperties, createProperties,
DialogModel, DialogModel,
EditFieldForm, EditFieldForm,
@ -18,10 +17,10 @@ import {
ImmutableArray, ImmutableArray,
ModalModel, ModalModel,
NestedFieldDto, NestedFieldDto,
PatternDto,
RootFieldDto, RootFieldDto,
SchemaDetailsDto, SchemaDetailsDto,
SchemasState, SchemasState
UpdateFieldDto
} from '@app/shared'; } from '@app/shared';
@Component({ @Component({
@ -43,7 +42,7 @@ export class FieldComponent implements OnChanges {
public parent: RootFieldDto; public parent: RootFieldDto;
@Input() @Input()
public patterns: ImmutableArray<AppPatternDto>; public patterns: ImmutableArray<PatternDto>;
public dropdown = new ModalModel(); public dropdown = new ModalModel();
@ -120,7 +119,7 @@ export class FieldComponent implements OnChanges {
if (value) { if (value) {
const properties = createProperties(this.field.properties['fieldType'], value); const properties = createProperties(this.field.properties['fieldType'], value);
this.schemasState.updateField(this.schema, this.field, new UpdateFieldDto(properties)) this.schemasState.updateField(this.schema, this.field, { properties })
.subscribe(() => { .subscribe(() => {
this.editForm.submitCompleted(); this.editForm.submitCompleted();
}, error => { }, error => {

6
src/Squidex/app/features/schemas/pages/schema/forms/field-form-validation.component.ts

@ -9,9 +9,9 @@ import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { import {
AppPatternDto,
FieldDto, FieldDto,
ImmutableArray ImmutableArray,
PatternDto
} from '@app/shared'; } from '@app/shared';
@Component({ @Component({
@ -27,5 +27,5 @@ export class FieldFormValidationComponent {
public field: FieldDto; public field: FieldDto;
@Input() @Input()
public patterns: ImmutableArray<AppPatternDto>; public patterns: ImmutableArray<PatternDto>;
} }

6
src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts

@ -10,11 +10,11 @@ import { FormControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { import {
AppPatternDto,
FieldDto, FieldDto,
hasNoValue$, hasNoValue$,
ImmutableArray, ImmutableArray,
ModalModel, ModalModel,
PatternDto,
ResourceOwner, ResourceOwner,
RootFieldDto, RootFieldDto,
StringFieldPropertiesDto, StringFieldPropertiesDto,
@ -37,7 +37,7 @@ export class StringValidationComponent extends ResourceOwner implements OnInit {
public properties: StringFieldPropertiesDto; public properties: StringFieldPropertiesDto;
@Input() @Input()
public patterns: ImmutableArray<AppPatternDto>; public patterns: ImmutableArray<PatternDto>;
public showDefaultValue: Observable<boolean>; public showDefaultValue: Observable<boolean>;
public showPatternMessage: boolean; public showPatternMessage: boolean;
@ -93,7 +93,7 @@ export class StringValidationComponent extends ResourceOwner implements OnInit {
this.setPatternName(); this.setPatternName();
} }
public setPattern(pattern: AppPatternDto) { public setPattern(pattern: PatternDto) {
this.patternName = pattern.name; this.patternName = pattern.name;
this.editForm.controls['pattern'].setValue(pattern.pattern); this.editForm.controls['pattern'].setValue(pattern.pattern);
this.editForm.controls['patternMessage'].setValue(pattern.message); this.editForm.controls['patternMessage'].setValue(pattern.message);

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

@ -12,15 +12,14 @@ import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AccessTokenDto, AccessTokenDto,
ApiUrlConfig, ApiUrlConfig,
AppClientDto,
AppClientsService,
AppRoleDto,
AppsState, AppsState,
ClientDto,
ClientsService,
ClientsState, ClientsState,
DialogModel, DialogModel,
DialogService, DialogService,
RenameClientForm, RenameClientForm,
UpdateAppClientDto RoleDto
} from '@app/shared'; } from '@app/shared';
const ESCAPE_KEY = 27; const ESCAPE_KEY = 27;
@ -62,10 +61,10 @@ function connectLibrary(apiUrl: ApiUrlConfig, app: string, client: { id: string,
}) })
export class ClientComponent implements OnChanges { export class ClientComponent implements OnChanges {
@Input() @Input()
public client: AppClientDto; public client: ClientDto;
@Input() @Input()
public clientRoles: AppRoleDto[]; public clientRoles: RoleDto[];
public isRenaming = false; public isRenaming = false;
@ -82,7 +81,7 @@ export class ClientComponent implements OnChanges {
constructor( constructor(
public readonly appsState: AppsState, public readonly appsState: AppsState,
private readonly apiUrl: ApiUrlConfig, private readonly apiUrl: ApiUrlConfig,
private readonly appClientsService: AppClientsService, private readonly clientsService: ClientsService,
private readonly clientsState: ClientsState, private readonly clientsState: ClientsState,
private readonly dialogs: DialogService, private readonly dialogs: DialogService,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
@ -105,7 +104,7 @@ export class ClientComponent implements OnChanges {
} }
public update(role: string) { public update(role: string) {
this.clientsState.update(this.client, new UpdateAppClientDto(undefined, role)).pipe(onErrorResumeNext()).subscribe(); this.clientsState.update(this.client, { role }).pipe(onErrorResumeNext()).subscribe();
} }
public toggleRename() { public toggleRename() {
@ -122,9 +121,7 @@ export class ClientComponent implements OnChanges {
const value = this.renameForm.submit(); const value = this.renameForm.submit();
if (value) { if (value) {
const requestDto = new UpdateAppClientDto(value.name); this.clientsState.update(this.client, value)
this.clientsState.update(this.client, requestDto)
.subscribe(() => { .subscribe(() => {
this.renameForm.submitCompleted(); this.renameForm.submitCompleted();
@ -138,7 +135,7 @@ export class ClientComponent implements OnChanges {
public connect() { public connect() {
this.connectDialog.show(); this.connectDialog.show();
this.appClientsService.createToken(this.appsState.appName, this.client) this.clientsService.createToken(this.appsState.appName, this.client)
.subscribe(dto => { .subscribe(dto => {
this.connectToken = dto; this.connectToken = dto;
}, error => { }, error => {

9
src/Squidex/app/features/settings/pages/clients/clients-page.component.ts

@ -10,11 +10,10 @@ import { FormBuilder } from '@angular/forms';
import { onErrorResumeNext } from 'rxjs/operators'; import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AppClientDto,
AppsState, AppsState,
AttachClientForm, AttachClientForm,
ClientDto,
ClientsState, ClientsState,
CreateAppClientDto,
RolesState RolesState
} from '@app/shared'; } from '@app/shared';
@ -48,9 +47,7 @@ export class ClientsPageComponent implements OnInit {
const value = this.addClientForm.submit(); const value = this.addClientForm.submit();
if (value) { if (value) {
const requestDto = new CreateAppClientDto(value.name); this.clientsState.attach(value)
this.clientsState.attach(requestDto)
.subscribe(() => { .subscribe(() => {
this.addClientForm.submitCompleted(); this.addClientForm.submitCompleted();
}, error => { }, error => {
@ -63,7 +60,7 @@ export class ClientsPageComponent implements OnInit {
this.addClientForm.submitCompleted(); this.addClientForm.submitCompleted();
} }
public trackByClient(index: number, item: AppClientDto) { public trackByClient(index: number, item: ClientDto) {
return item.id; return item.id;
} }
} }

13
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts

@ -11,11 +11,10 @@ import { Observable } from 'rxjs';
import { onErrorResumeNext, withLatestFrom } from 'rxjs/operators'; import { onErrorResumeNext, withLatestFrom } from 'rxjs/operators';
import { import {
AppContributorDto,
AppsState, AppsState,
AssignContributorDto,
AssignContributorForm, AssignContributorForm,
AutocompleteSource, AutocompleteSource,
ContributorDto,
ContributorsState, ContributorsState,
DialogService, DialogService,
RolesState, RolesState,
@ -78,12 +77,12 @@ export class ContributorsPageComponent implements OnInit {
this.contributorsState.load(true).pipe(onErrorResumeNext()).subscribe(); this.contributorsState.load(true).pipe(onErrorResumeNext()).subscribe();
} }
public remove(contributor: AppContributorDto) { public remove(contributor: ContributorDto) {
this.contributorsState.revoke(contributor).pipe(onErrorResumeNext()).subscribe(); this.contributorsState.revoke(contributor).pipe(onErrorResumeNext()).subscribe();
} }
public changeRole(contributor: AppContributorDto, role: string) { public changeRole(contributor: ContributorDto, role: string) {
this.contributorsState.assign(new AssignContributorDto(contributor.contributorId, role)).pipe(onErrorResumeNext()).subscribe(); this.contributorsState.assign({ contributorId: contributor.contributorId, role }).pipe(onErrorResumeNext()).subscribe();
} }
public assignContributor() { public assignContributor() {
@ -96,7 +95,7 @@ export class ContributorsPageComponent implements OnInit {
user = user.id; user = user.id;
} }
const requestDto = new AssignContributorDto(user, 'Editor', true); const requestDto = { contributorId: user, role: 'Editor', invite: true };
this.contributorsState.assign(requestDto) this.contributorsState.assign(requestDto)
.subscribe(isCreated => { .subscribe(isCreated => {
@ -111,7 +110,7 @@ export class ContributorsPageComponent implements OnInit {
} }
} }
public trackByContributor(index: number, contributorInfo: { contributor: AppContributorDto }) { public trackByContributor(index: number, contributorInfo: { contributor: ContributorDto }) {
return contributorInfo.contributor.contributorId; return contributorInfo.contributor.contributorId;
} }
} }

5
src/Squidex/app/features/settings/pages/languages/language.component.ts

@ -14,8 +14,7 @@ import {
EditLanguageForm, EditLanguageForm,
fadeAnimation, fadeAnimation,
ImmutableArray, ImmutableArray,
LanguagesState, LanguagesState
UpdateAppLanguageDto
} from '@app/shared'; } from '@app/shared';
@Component({ @Component({
@ -64,7 +63,7 @@ export class LanguageComponent implements OnChanges {
const value = this.editForm.submit(); const value = this.editForm.submit();
if (value) { if (value) {
const request = new UpdateAppLanguageDto(value.isMaster, value.isOptional, this.fallbackLanguages.map(x => x.iso2Code).values); const request = { ...value, fallbackLanguages: this.fallbackLanguages.map(x => x.iso2Code).values };
this.languagesState.update(this.language, request) this.languagesState.update(this.language, request)
.subscribe(() => { .subscribe(() => {

4
src/Squidex/app/features/settings/pages/patterns/pattern.component.ts

@ -10,8 +10,8 @@ import { FormBuilder } from '@angular/forms';
import { onErrorResumeNext } from 'rxjs/operators'; import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AppPatternDto,
EditPatternForm, EditPatternForm,
PatternDto,
PatternsState PatternsState
} from '@app/shared'; } from '@app/shared';
@ -22,7 +22,7 @@ import {
}) })
export class PatternComponent implements OnInit { export class PatternComponent implements OnInit {
@Input() @Input()
public pattern: AppPatternDto; public pattern: PatternDto;
public editForm = new EditPatternForm(this.formBuilder); public editForm = new EditPatternForm(this.formBuilder);

4
src/Squidex/app/features/settings/pages/patterns/patterns-page.component.ts

@ -9,8 +9,8 @@ import { Component, OnInit } from '@angular/core';
import { onErrorResumeNext } from 'rxjs/operators'; import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AppPatternDto,
AppsState, AppsState,
PatternDto,
PatternsState PatternsState
} from '@app/shared'; } from '@app/shared';
@ -34,7 +34,7 @@ export class PatternsPageComponent implements OnInit {
this.patternsState.load(true).pipe(onErrorResumeNext()).subscribe(); this.patternsState.load(true).pipe(onErrorResumeNext()).subscribe();
} }
public trackByPattern(index: number, pattern: AppPatternDto) { public trackByPattern(index: number, pattern: PatternDto) {
return pattern.id; return pattern.id;
} }
} }

9
src/Squidex/app/features/settings/pages/roles/role.component.ts

@ -11,13 +11,12 @@ import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AddPermissionForm, AddPermissionForm,
AppRoleDto,
AutocompleteComponent, AutocompleteComponent,
AutocompleteSource, AutocompleteSource,
EditPermissionsForm, EditPermissionsForm,
fadeAnimation, fadeAnimation,
RolesState, RoleDto,
UpdateAppRoleDto RolesState
} from '@app/shared'; } from '@app/shared';
const DEFAULT_ROLES = [ const DEFAULT_ROLES = [
@ -37,7 +36,7 @@ const DEFAULT_ROLES = [
}) })
export class RoleComponent implements OnChanges { export class RoleComponent implements OnChanges {
@Input() @Input()
public role: AppRoleDto; public role: RoleDto;
@Input() @Input()
public allPermissions: AutocompleteSource; public allPermissions: AutocompleteSource;
@ -95,7 +94,7 @@ export class RoleComponent implements OnChanges {
const value = this.editForm.submit(); const value = this.editForm.submit();
if (value) { if (value) {
const request = new UpdateAppRoleDto(value); const request = { permissions: value };
this.rolesState.update(this.role, request) this.rolesState.update(this.role, request)
.subscribe(() => { .subscribe(() => {

10
src/Squidex/app/features/settings/pages/roles/roles-page.component.ts

@ -12,17 +12,17 @@ import { onErrorResumeNext } from 'rxjs/operators';
import { import {
AddRoleForm, AddRoleForm,
AppRoleDto,
AppRolesService,
AppsState, AppsState,
AutocompleteSource, AutocompleteSource,
RoleDto,
RolesService,
RolesState RolesState
} from '@app/shared'; } from '@app/shared';
class PermissionsAutocomplete implements AutocompleteSource { class PermissionsAutocomplete implements AutocompleteSource {
private permissions: string[] = []; private permissions: string[] = [];
constructor(appsState: AppsState, rolesService: AppRolesService) { constructor(appsState: AppsState, rolesService: RolesService) {
rolesService.getPermissions(appsState.appName).subscribe(x => this.permissions = x); rolesService.getPermissions(appsState.appName).subscribe(x => this.permissions = x);
} }
@ -43,7 +43,7 @@ export class RolesPageComponent implements OnInit {
constructor( constructor(
public readonly appsState: AppsState, public readonly appsState: AppsState,
public readonly rolesService: AppRolesService, public readonly rolesService: RolesService,
public readonly rolesState: RolesState, public readonly rolesState: RolesState,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
@ -74,7 +74,7 @@ export class RolesPageComponent implements OnInit {
} }
} }
public trackByRole(index: number, role: AppRoleDto) { public trackByRole(index: number, role: RoleDto) {
return role.name; return role.name;
} }
} }

16
src/Squidex/app/framework/state.ts

@ -20,7 +20,7 @@ export interface FormState {
error?: string | null; error?: string | null;
} }
export class Form<T extends AbstractControl> { export class Form<T extends AbstractControl, V = any> {
private readonly state = new State<FormState>({ submitted: false }); private readonly state = new State<FormState>({ submitted: false });
public submitted = public submitted =
@ -42,21 +42,21 @@ export class Form<T extends AbstractControl> {
this.form.enable(); this.form.enable();
} }
protected reset(value: any) { protected reset(value: V | undefined) {
this.form.reset(value); this.form.reset(value);
} }
protected setValue(value: any) { protected setValue(value: V | undefined) {
this.form.reset(value, { emitEvent: true }); this.form.reset(value, { emitEvent: true });
} }
public load(value: any) { public load(value: V | undefined) {
this.state.next(_ => ({ submitted: false, error: null })); this.state.next(_ => ({ submitted: false, error: null }));
this.setValue(value); this.setValue(value);
} }
public submit(): any | null { public submit(): V | null {
this.state.next(_ => ({ submitted: true })); this.state.next(_ => ({ submitted: true }));
if (this.form.valid) { if (this.form.valid) {
@ -70,7 +70,7 @@ export class Form<T extends AbstractControl> {
} }
} }
public submitCompleted(newValue?: any) { public submitCompleted(newValue?: V) {
this.state.next(_ => ({ submitted: false, error: null })); this.state.next(_ => ({ submitted: false, error: null }));
this.enable(); this.enable();
@ -106,8 +106,8 @@ export class Model<T> {
return this.clone(value, validOnly); return this.clone(value, validOnly);
} }
protected clone(update: ((v: any) => T) | Partial<T>, validOnly = false): T { protected clone<V>(update: ((v: any) => V) | Partial<V>, validOnly = false): V {
let values: Partial<T>; let values: Partial<V>;
if (Types.isFunction(update)) { if (Types.isFunction(update)) {
values = update(<any>this); values = update(<any>this);
} else { } else {

3
src/Squidex/app/shared/components/app-form.component.ts

@ -11,7 +11,6 @@ import { FormBuilder } from '@angular/forms';
import { import {
ApiUrlConfig, ApiUrlConfig,
AppsState, AppsState,
CreateAppDto,
CreateAppForm CreateAppForm
} from '@app/shared/internal'; } from '@app/shared/internal';
@ -45,7 +44,7 @@ export class AppFormComponent {
const value = this.createForm.submit(); const value = this.createForm.submit();
if (value) { if (value) {
const request = new CreateAppDto(value.name, this.template); const request = { ...value, template: this.template };
this.appsStore.create(request) this.appsStore.create(request)
.subscribe(() => { .subscribe(() => {

8
src/Squidex/app/shared/internal.ts

@ -19,14 +19,12 @@ export * from './guards/unset-content.guard';
export * from './interceptors/auth.interceptor'; export * from './interceptors/auth.interceptor';
export * from './services/app-contributors.service';
export * from './services/app-clients.service';
export * from './services/app-languages.service'; export * from './services/app-languages.service';
export * from './services/app-patterns.service';
export * from './services/app-roles.service';
export * from './services/apps.service'; export * from './services/apps.service';
export * from './services/assets.service'; export * from './services/assets.service';
export * from './services/auth.service'; export * from './services/auth.service';
export * from './services/clients.service';
export * from './services/contributors.service';
export * from './services/backups.service'; export * from './services/backups.service';
export * from './services/comments.service'; export * from './services/comments.service';
export * from './services/contents.service'; export * from './services/contents.service';
@ -35,7 +33,9 @@ export * from './services/help.service';
export * from './services/history.service'; export * from './services/history.service';
export * from './services/languages.service'; export * from './services/languages.service';
export * from './services/news.service'; export * from './services/news.service';
export * from './services/patterns.service';
export * from './services/plans.service'; export * from './services/plans.service';
export * from './services/roles.service';
export * from './services/rules.service'; export * from './services/rules.service';
export * from './services/schemas.service'; export * from './services/schemas.service';
export * from './services/schemas.types'; export * from './services/schemas.types';

16
src/Squidex/app/shared/module.ts

@ -13,13 +13,9 @@ import { DndModule } from 'ng2-dnd';
import { SqxFrameworkModule } from '@app/framework'; import { SqxFrameworkModule } from '@app/framework';
import { import {
AppClientsService,
AppContributorsService,
AppFormComponent, AppFormComponent,
AppLanguagesService, AppLanguagesService,
AppMustExistGuard, AppMustExistGuard,
AppPatternsService,
AppRolesService,
AppsService, AppsService,
AppsState, AppsState,
AssetComponent, AssetComponent,
@ -35,6 +31,7 @@ import {
AuthService, AuthService,
BackupsService, BackupsService,
BackupsState, BackupsState,
ClientsService,
ClientsState, ClientsState,
CommentComponent, CommentComponent,
CommentsComponent, CommentsComponent,
@ -42,6 +39,7 @@ import {
ContentMustExistGuard, ContentMustExistGuard,
ContentsService, ContentsService,
ContentsState, ContentsState,
ContributorsService,
ContributorsState, ContributorsState,
FileIconPipe, FileIconPipe,
GeolocationEditorComponent, GeolocationEditorComponent,
@ -62,11 +60,13 @@ import {
MustBeAuthenticatedGuard, MustBeAuthenticatedGuard,
MustBeNotAuthenticatedGuard, MustBeNotAuthenticatedGuard,
NewsService, NewsService,
PatternsService,
PatternsState, PatternsState,
PermissionDirective, PermissionDirective,
PlansService, PlansService,
PlansState, PlansState,
RichEditorComponent, RichEditorComponent,
RolesService,
RolesState, RolesState,
RuleEventsState, RuleEventsState,
RulesService, RulesService,
@ -173,12 +173,12 @@ export class SqxSharedModule {
return { return {
ngModule: SqxSharedModule, ngModule: SqxSharedModule,
providers: [ providers: [
AppClientsService, ClientsService,
AppContributorsService, ContributorsService,
AppLanguagesService, AppLanguagesService,
AppMustExistGuard, AppMustExistGuard,
AppPatternsService, PatternsService,
AppRolesService, RolesService,
AppsService, AppsService,
AppsState, AppsState,
AssetsState, AssetsState,

8
src/Squidex/app/shared/services/app-languages.service.ts

@ -73,8 +73,8 @@ export class AppLanguagesService {
return new AppLanguageDto( return new AppLanguageDto(
item.iso2Code, item.iso2Code,
item.englishName, item.englishName,
item.isMaster === true, item.isMaster,
item.isOptional === true, item.isOptional,
item.fallback || []); item.fallback || []);
}); });
@ -93,8 +93,8 @@ export class AppLanguagesService {
const language = new AppLanguageDto( const language = new AppLanguageDto(
body.iso2Code, body.iso2Code,
body.englishName, body.englishName,
body.isMaster === true, body.isMaster,
body.isOptional === true, body.isOptional,
body.fallback || []); body.fallback || []);
return new Versioned(response.version, language); return new Versioned(response.version, language);

42
src/Squidex/app/shared/services/assets.service.spec.ts

@ -35,7 +35,7 @@ describe('AssetDto', () => {
const asset_1 = new AssetDto('1', creator, creator, creation, creation, 'Name.png', 'Hash', 'png', 1, 1, 'image/png', false, false, 1, 1, 'name.png', [], 'url', version); const asset_1 = new AssetDto('1', creator, creator, creation, creation, 'Name.png', 'Hash', 'png', 1, 1, 'image/png', false, false, 1, 1, 'name.png', [], 'url', version);
const asset_2 = asset_1.annnotate(update, modifier, newVersion, modified); const asset_2 = asset_1.annnotate(update, modifier, newVersion, modified);
expect(asset_2.fileName).toEqual('NewName.png'); expect(asset_2.fileName).toEqual(update.fileName);
expect(asset_2.tags).toEqual([]); expect(asset_2.tags).toEqual([]);
expect(asset_2.slug).toEqual(asset_1.slug); expect(asset_2.slug).toEqual(asset_1.slug);
expect(asset_2.lastModified).toEqual(modified); expect(asset_2.lastModified).toEqual(modified);
@ -44,18 +44,26 @@ describe('AssetDto', () => {
}); });
it('should update file properties when uploading', () => { it('should update file properties when uploading', () => {
const update = new AssetReplacedDto('Hash New', 2, 2, 'image/jpeg', true, 2, 2); const update = {
fileHash: 'Hash New',
fileSize: 1024,
fileVersion: 12,
mimeType: 'image/png',
isImage: true,
pixelWidth: 1024,
pixelHeight: 2048
};
const asset_1 = new AssetDto('1', creator, creator, creation, creation, 'Name.png', 'Hash', 'png', 1, 1, 'image/png', false, false, 1, 1, 'name.png', [], 'url', version); const asset_1 = new AssetDto('1', creator, creator, creation, creation, 'Name.png', 'Hash', 'png', 1, 1, 'image/png', false, false, 1, 1, 'name.png', [], 'url', version);
const asset_2 = asset_1.update(update, modifier, newVersion, modified); const asset_2 = asset_1.update(update, modifier, newVersion, modified);
expect(asset_2.fileHash).toEqual('Hash New'); expect(asset_2.fileHash).toEqual(update.fileHash);
expect(asset_2.fileSize).toEqual(2); expect(asset_2.fileSize).toEqual(update.fileSize);
expect(asset_2.fileVersion).toEqual(2); expect(asset_2.fileVersion).toEqual(update.fileVersion);
expect(asset_2.mimeType).toEqual('image/jpeg'); expect(asset_2.mimeType).toEqual(update.mimeType);
expect(asset_2.isImage).toBeTruthy(); expect(asset_2.isImage).toBeTruthy();
expect(asset_2.pixelWidth).toEqual(2); expect(asset_2.pixelWidth).toEqual(update.pixelWidth);
expect(asset_2.pixelHeight).toEqual(2); expect(asset_2.pixelHeight).toEqual(update.pixelHeight);
expect(asset_2.lastModified).toEqual(modified); expect(asset_2.lastModified).toEqual(modified);
expect(asset_2.lastModifiedBy).toEqual(modifier); expect(asset_2.lastModifiedBy).toEqual(modifier);
expect(asset_2.version).toEqual(newVersion); expect(asset_2.version).toEqual(newVersion);
@ -407,15 +415,15 @@ describe('AssetsService', () => {
pixelHeight: 2048 pixelHeight: 2048
}); });
expect(asset!).toEqual( expect(asset!).toEqual({
new AssetReplacedDto( fileHash: 'Hash New',
'Hash New', fileSize: 1024,
1024, fileVersion: 12,
12, mimeType: 'image/png',
'image/png', isImage: true,
true, pixelWidth: 1024,
1024, pixelHeight: 2048
2048)); });
})); }));
it('should return proper error when replace failed with 413', it('should return proper error when replace failed with 413',

4
src/Squidex/app/shared/services/assets.service.ts

@ -56,7 +56,7 @@ export class AssetDto extends Model<AssetDto> {
} }
public update(update: AssetReplacedDto, user: string, version: Version, now?: DateTime): AssetDto { public update(update: AssetReplacedDto, user: string, version: Version, now?: DateTime): AssetDto {
return this.clone({ return this.with({
...update, ...update,
lastModified: now || DateTime.now(), lastModified: now || DateTime.now(),
lastModifiedBy: user, lastModifiedBy: user,
@ -65,7 +65,7 @@ export class AssetDto extends Model<AssetDto> {
} }
public annnotate(update: AnnotateAssetDto, user: string, version: Version, now?: DateTime): AssetDto { public annnotate(update: AnnotateAssetDto, user: string, version: Version, now?: DateTime): AssetDto {
return this.clone({ return this.with({
...<any>update, ...<any>update,
lastModified: now || DateTime.now(), lastModified: now || DateTime.now(),
lastModifiedBy: user, lastModifiedBy: user,

42
src/Squidex/app/shared/services/app-clients.service.spec.ts → src/Squidex/app/shared/services/clients.service.spec.ts

@ -12,13 +12,13 @@ import {
AccessTokenDto, AccessTokenDto,
AnalyticsService, AnalyticsService,
ApiUrlConfig, ApiUrlConfig,
AppClientDto, ClientDto,
AppClientsDto, ClientsDto,
AppClientsService, ClientsService,
Version Version
} from './../'; } from './../';
describe('AppClientsService', () => { describe('ClientsService', () => {
const version = new Version('1'); const version = new Version('1');
beforeEach(() => { beforeEach(() => {
@ -27,7 +27,7 @@ describe('AppClientsService', () => {
HttpClientTestingModule HttpClientTestingModule
], ],
providers: [ providers: [
AppClientsService, ClientsService,
{ provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') }, { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') },
{ provide: AnalyticsService, useValue: new AnalyticsService() } { provide: AnalyticsService, useValue: new AnalyticsService() }
] ]
@ -39,11 +39,11 @@ describe('AppClientsService', () => {
})); }));
it('should make get request to get app clients', it('should make get request to get app clients',
inject([AppClientsService, HttpTestingController], (appClientsService: AppClientsService, httpMock: HttpTestingController) => { inject([ClientsService, HttpTestingController], (clientsService: ClientsService, httpMock: HttpTestingController) => {
let clients: AppClientsDto; let clients: ClientsDto;
appClientsService.getClients('my-app').subscribe(result => { clientsService.getClients('my-app').subscribe(result => {
clients = result; clients = result;
}); });
@ -72,20 +72,20 @@ describe('AppClientsService', () => {
}); });
expect(clients!).toEqual( expect(clients!).toEqual(
new AppClientsDto([ new ClientsDto([
new AppClientDto('client1', 'Client 1', 'secret1', 'Editor'), new ClientDto('client1', 'Client 1', 'secret1', 'Editor'),
new AppClientDto('client2', 'Client 2', 'secret2', 'Developer') new ClientDto('client2', 'Client 2', 'secret2', 'Developer')
], new Version('2'))); ], new Version('2')));
})); }));
it('should make post request to create client', it('should make post request to create client',
inject([AppClientsService, HttpTestingController], (appClientsService: AppClientsService, httpMock: HttpTestingController) => { inject([ClientsService, HttpTestingController], (clientsService: ClientsService, httpMock: HttpTestingController) => {
const dto = { id: 'client1' }; const dto = { id: 'client1' };
let client: AppClientDto; let client: ClientDto;
appClientsService.postClient('my-app', dto, version).subscribe(result => { clientsService.postClient('my-app', dto, version).subscribe(result => {
client = result.payload; client = result.payload;
}); });
@ -96,15 +96,15 @@ describe('AppClientsService', () => {
req.flush({ id: 'client1', name: 'Client 1', secret: 'secret1', role: 'Developer' }); req.flush({ id: 'client1', name: 'Client 1', secret: 'secret1', role: 'Developer' });
expect(client!).toEqual(new AppClientDto('client1', 'Client 1', 'secret1', 'Developer')); expect(client!).toEqual(new ClientDto('client1', 'Client 1', 'secret1', 'Developer'));
})); }));
it('should make put request to rename client', it('should make put request to rename client',
inject([AppClientsService, HttpTestingController], (appClientsService: AppClientsService, httpMock: HttpTestingController) => { inject([ClientsService, HttpTestingController], (clientsService: ClientsService, httpMock: HttpTestingController) => {
const dto = { name: 'New Name' }; const dto = { name: 'New Name' };
appClientsService.putClient('my-app', 'client1', dto, version).subscribe(); clientsService.putClient('my-app', 'client1', dto, version).subscribe();
const req = httpMock.expectOne('http://service/p/api/apps/my-app/clients/client1'); const req = httpMock.expectOne('http://service/p/api/apps/my-app/clients/client1');
@ -115,9 +115,9 @@ describe('AppClientsService', () => {
})); }));
it('should make delete request to remove client', it('should make delete request to remove client',
inject([AppClientsService, HttpTestingController], (appClientsService: AppClientsService, httpMock: HttpTestingController) => { inject([ClientsService, HttpTestingController], (clientsService: ClientsService, httpMock: HttpTestingController) => {
appClientsService.deleteClient('my-app', 'client1', version).subscribe(); clientsService.deleteClient('my-app', 'client1', version).subscribe();
const req = httpMock.expectOne('http://service/p/api/apps/my-app/clients/client1'); const req = httpMock.expectOne('http://service/p/api/apps/my-app/clients/client1');
@ -128,11 +128,11 @@ describe('AppClientsService', () => {
})); }));
it('should make form request to create token', it('should make form request to create token',
inject([AppClientsService, HttpTestingController], (appClientsService: AppClientsService, httpMock: HttpTestingController) => { inject([ClientsService, HttpTestingController], (clientsService: ClientsService, httpMock: HttpTestingController) => {
let accessTokenDto: AccessTokenDto; let accessTokenDto: AccessTokenDto;
appClientsService.createToken('my-app', new AppClientDto('myClientId', 'myClient', 'mySecret', 'Editor')).subscribe(result => { clientsService.createToken('my-app', new ClientDto('myClientId', 'myClient', 'mySecret', 'Editor')).subscribe(result => {
accessTokenDto = result; accessTokenDto = result;
}); });

26
src/Squidex/app/shared/services/app-clients.service.ts → src/Squidex/app/shared/services/clients.service.ts

@ -20,16 +20,16 @@ import {
Versioned Versioned
} from '@app/framework'; } from '@app/framework';
export class AppClientsDto extends Model<AppClientsDto> { export class ClientsDto extends Model<ClientsDto> {
constructor( constructor(
public readonly clients: AppClientDto[], public readonly clients: ClientDto[],
public readonly version: Version public readonly version: Version
) { ) {
super(); super();
} }
} }
export class AppClientDto extends Model<AppClientDto> { export class ClientDto extends Model<ClientDto> {
constructor( constructor(
public readonly id: string, public readonly id: string,
public readonly name: string, public readonly name: string,
@ -48,17 +48,17 @@ export class AccessTokenDto {
} }
} }
export interface CreateAppClientDto { export interface CreateClientDto {
readonly id: string; readonly id: string;
} }
export interface UpdateAppClientDto { export interface UpdateClientDto {
readonly name?: string; readonly name?: string;
readonly role?: string; readonly role?: string;
} }
@Injectable() @Injectable()
export class AppClientsService { export class ClientsService {
constructor( constructor(
private readonly http: HttpClient, private readonly http: HttpClient,
private readonly apiUrl: ApiUrlConfig, private readonly apiUrl: ApiUrlConfig,
@ -66,7 +66,7 @@ export class AppClientsService {
) { ) {
} }
public getClients(appName: string): Observable<AppClientsDto> { public getClients(appName: string): Observable<ClientsDto> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients`);
return HTTP.getVersioned<any>(this.http, url).pipe( return HTTP.getVersioned<any>(this.http, url).pipe(
@ -76,26 +76,26 @@ export class AppClientsService {
const items: any[] = body; const items: any[] = body;
const clients = items.map(item => { const clients = items.map(item => {
return new AppClientDto( return new ClientDto(
item.id, item.id,
item.name || body.id, item.name || body.id,
item.secret, item.secret,
item.role); item.role);
}); });
return new AppClientsDto(clients, response.version); return new ClientsDto(clients, response.version);
}), }),
pretifyError('Failed to load clients. Please reload.')); pretifyError('Failed to load clients. Please reload.'));
} }
public postClient(appName: string, dto: CreateAppClientDto, version: Version): Observable<Versioned<AppClientDto>> { public postClient(appName: string, dto: CreateClientDto, version: Version): Observable<Versioned<ClientDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients`);
return HTTP.postVersioned<any>(this.http, url, dto, version).pipe( return HTTP.postVersioned<any>(this.http, url, dto, version).pipe(
map(response => { map(response => {
const body = response.payload.body; const body = response.payload.body;
const client = new AppClientDto( const client = new ClientDto(
body.id, body.id,
body.name || body.id, body.name || body.id,
body.secret, body.secret,
@ -109,7 +109,7 @@ export class AppClientsService {
pretifyError('Failed to add client. Please reload.')); pretifyError('Failed to add client. Please reload.'));
} }
public putClient(appName: string, id: string, dto: UpdateAppClientDto, version: Version): Observable<Versioned<any>> { public putClient(appName: string, id: string, dto: UpdateClientDto, version: Version): Observable<Versioned<any>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients/${id}`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/clients/${id}`);
return HTTP.putVersioned(this.http, url, dto, version).pipe( return HTTP.putVersioned(this.http, url, dto, version).pipe(
@ -129,7 +129,7 @@ export class AppClientsService {
pretifyError('Failed to revoke client. Please reload.')); pretifyError('Failed to revoke client. Please reload.'));
} }
public createToken(appName: string, client: AppClientDto): Observable<AccessTokenDto> { public createToken(appName: string, client: ClientDto): Observable<AccessTokenDto> {
const options = { const options = {
headers: new HttpHeaders({ headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded', 'NoAuth': 'true' 'Content-Type': 'application/x-www-form-urlencoded', 'NoAuth': 'true'

30
src/Squidex/app/shared/services/app-contributors.service.spec.ts → src/Squidex/app/shared/services/contributors.service.spec.ts

@ -11,14 +11,14 @@ import { inject, TestBed } from '@angular/core/testing';
import { import {
AnalyticsService, AnalyticsService,
ApiUrlConfig, ApiUrlConfig,
AppContributorDto,
AppContributorsDto,
AppContributorsService,
ContributorAssignedDto, ContributorAssignedDto,
ContributorDto,
ContributorsDto,
ContributorsService,
Version Version
} from './../'; } from './../';
describe('AppContributorsService', () => { describe('ContributorsService', () => {
const version = new Version('1'); const version = new Version('1');
beforeEach(() => { beforeEach(() => {
@ -27,7 +27,7 @@ describe('AppContributorsService', () => {
HttpClientTestingModule HttpClientTestingModule
], ],
providers: [ providers: [
AppContributorsService, ContributorsService,
{ provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') }, { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') },
{ provide: AnalyticsService, useValue: new AnalyticsService() } { provide: AnalyticsService, useValue: new AnalyticsService() }
] ]
@ -39,11 +39,11 @@ describe('AppContributorsService', () => {
})); }));
it('should make get request to get app contributors', it('should make get request to get app contributors',
inject([AppContributorsService, HttpTestingController], (appContributorsService: AppContributorsService, httpMock: HttpTestingController) => { inject([ContributorsService, HttpTestingController], (contributorsService: ContributorsService, httpMock: HttpTestingController) => {
let contributors: AppContributorsDto; let contributors: ContributorsDto;
appContributorsService.getContributors('my-app').subscribe(result => { contributorsService.getContributors('my-app').subscribe(result => {
contributors = result; contributors = result;
}); });
@ -71,20 +71,20 @@ describe('AppContributorsService', () => {
}); });
expect(contributors!).toEqual( expect(contributors!).toEqual(
new AppContributorsDto([ new ContributorsDto([
new AppContributorDto('123', 'Owner'), new ContributorDto('123', 'Owner'),
new AppContributorDto('456', 'Owner') new ContributorDto('456', 'Owner')
], 100, new Version('2'))); ], 100, new Version('2')));
})); }));
it('should make post request to assign contributor', it('should make post request to assign contributor',
inject([AppContributorsService, HttpTestingController], (appContributorsService: AppContributorsService, httpMock: HttpTestingController) => { inject([ContributorsService, HttpTestingController], (contributorsService: ContributorsService, httpMock: HttpTestingController) => {
const dto = { contributorId: '123', role: 'Owner' }; const dto = { contributorId: '123', role: 'Owner' };
let contributorAssignedDto: ContributorAssignedDto; let contributorAssignedDto: ContributorAssignedDto;
appContributorsService.postContributor('my-app', dto, version).subscribe(result => { contributorsService.postContributor('my-app', dto, version).subscribe(result => {
contributorAssignedDto = result.payload; contributorAssignedDto = result.payload;
}); });
@ -99,9 +99,9 @@ describe('AppContributorsService', () => {
})); }));
it('should make delete request to remove contributor', it('should make delete request to remove contributor',
inject([AppContributorsService, HttpTestingController], (appContributorsService: AppContributorsService, httpMock: HttpTestingController) => { inject([ContributorsService, HttpTestingController], (contributorsService: ContributorsService, httpMock: HttpTestingController) => {
appContributorsService.deleteContributor('my-app', '123', version).subscribe(); contributorsService.deleteContributor('my-app', '123', version).subscribe();
const req = httpMock.expectOne('http://service/p/api/apps/my-app/contributors/123'); const req = httpMock.expectOne('http://service/p/api/apps/my-app/contributors/123');

14
src/Squidex/app/shared/services/app-contributors.service.ts → src/Squidex/app/shared/services/contributors.service.ts

@ -20,9 +20,9 @@ import {
Versioned Versioned
} from '@app/framework'; } from '@app/framework';
export class AppContributorsDto extends Model<AppContributorsDto> { export class ContributorsDto extends Model<ContributorsDto> {
constructor( constructor(
public readonly contributors: AppContributorDto[], public readonly contributors: ContributorDto[],
public readonly maxContributors: number, public readonly maxContributors: number,
public readonly version: Version public readonly version: Version
) { ) {
@ -30,7 +30,7 @@ export class AppContributorsDto extends Model<AppContributorsDto> {
} }
} }
export class AppContributorDto extends Model<AssignContributorDto> { export class ContributorDto extends Model<AssignContributorDto> {
constructor( constructor(
public readonly contributorId: string, public readonly contributorId: string,
public readonly role: string public readonly role: string
@ -51,7 +51,7 @@ export interface AssignContributorDto {
} }
@Injectable() @Injectable()
export class AppContributorsService { export class ContributorsService {
constructor( constructor(
private readonly http: HttpClient, private readonly http: HttpClient,
private readonly apiUrl: ApiUrlConfig, private readonly apiUrl: ApiUrlConfig,
@ -59,7 +59,7 @@ export class AppContributorsService {
) { ) {
} }
public getContributors(appName: string): Observable<AppContributorsDto> { public getContributors(appName: string): Observable<ContributorsDto> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/contributors`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/contributors`);
return HTTP.getVersioned<any>(this.http, url).pipe( return HTTP.getVersioned<any>(this.http, url).pipe(
@ -68,9 +68,9 @@ export class AppContributorsService {
const items: any[] = body.contributors; const items: any[] = body.contributors;
return new AppContributorsDto( return new ContributorsDto(
items.map(item => { items.map(item => {
return new AppContributorDto( return new ContributorDto(
item.contributorId, item.contributorId,
item.role); item.role);
}), }),

2
src/Squidex/app/shared/services/help.service.spec.ts

@ -10,7 +10,7 @@ import { inject, TestBed } from '@angular/core/testing';
import { HelpService } from './../'; import { HelpService } from './../';
describe('AppClientsService', () => { describe('ClientsService', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [

30
src/Squidex/app/shared/services/app-patterns.service.spec.ts → src/Squidex/app/shared/services/patterns.service.spec.ts

@ -11,13 +11,13 @@ import { inject, TestBed } from '@angular/core/testing';
import { import {
AnalyticsService, AnalyticsService,
ApiUrlConfig, ApiUrlConfig,
AppPatternDto, PatternDto,
AppPatternsDto, PatternsDto,
AppPatternsService, PatternsService,
Version Version
} from './../'; } from './../';
describe('AppPatternsService', () => { describe('PatternsService', () => {
const version = new Version('1'); const version = new Version('1');
beforeEach(() => { beforeEach(() => {
@ -26,7 +26,7 @@ describe('AppPatternsService', () => {
HttpClientTestingModule HttpClientTestingModule
], ],
providers: [ providers: [
AppPatternsService, PatternsService,
{ provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') }, { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') },
{ provide: AnalyticsService, useValue: new AnalyticsService() } { provide: AnalyticsService, useValue: new AnalyticsService() }
] ]
@ -38,9 +38,9 @@ describe('AppPatternsService', () => {
})); }));
it('should make get request to get patterns', it('should make get request to get patterns',
inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { inject([PatternsService, HttpTestingController], (patternService: PatternsService, httpMock: HttpTestingController) => {
let patterns: AppPatternsDto; let patterns: PatternsDto;
patternService.getPatterns('my-app').subscribe(result => { patternService.getPatterns('my-app').subscribe(result => {
patterns = result; patterns = result;
@ -70,18 +70,18 @@ describe('AppPatternsService', () => {
}); });
expect(patterns!).toEqual( expect(patterns!).toEqual(
new AppPatternsDto([ new PatternsDto([
new AppPatternDto('1', 'Number', '[0-9]', 'Message1'), new PatternDto('1', 'Number', '[0-9]', 'Message1'),
new AppPatternDto('2', 'Numbers', '[0-9]*', 'Message2') new PatternDto('2', 'Numbers', '[0-9]*', 'Message2')
], new Version('2'))); ], new Version('2')));
})); }));
it('should make post request to add pattern', it('should make post request to add pattern',
inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { inject([PatternsService, HttpTestingController], (patternService: PatternsService, httpMock: HttpTestingController) => {
const dto = { name: 'Number', pattern: '[0-9]' }; const dto = { name: 'Number', pattern: '[0-9]' };
let pattern: AppPatternDto; let pattern: PatternDto;
patternService.postPattern('my-app', dto, version).subscribe(result => { patternService.postPattern('my-app', dto, version).subscribe(result => {
pattern = result.payload; pattern = result.payload;
@ -99,11 +99,11 @@ describe('AppPatternsService', () => {
message: 'Message1' message: 'Message1'
}); });
expect(pattern!).toEqual(new AppPatternDto('1', 'Number', '[0-9]', 'Message1')); expect(pattern!).toEqual(new PatternDto('1', 'Number', '[0-9]', 'Message1'));
})); }));
it('should make put request to update pattern', it('should make put request to update pattern',
inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { inject([PatternsService, HttpTestingController], (patternService: PatternsService, httpMock: HttpTestingController) => {
const dto = { name: 'Number', pattern: '[0-9]' }; const dto = { name: 'Number', pattern: '[0-9]' };
@ -118,7 +118,7 @@ describe('AppPatternsService', () => {
})); }));
it('should make delete request to remove pattern', it('should make delete request to remove pattern',
inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { inject([PatternsService, HttpTestingController], (patternService: PatternsService, httpMock: HttpTestingController) => {
patternService.deletePattern('my-app', '1', version).subscribe(); patternService.deletePattern('my-app', '1', version).subscribe();

22
src/Squidex/app/shared/services/app-patterns.service.ts → src/Squidex/app/shared/services/patterns.service.ts

@ -20,16 +20,16 @@ import {
Versioned Versioned
} from '@app/framework'; } from '@app/framework';
export class AppPatternsDto extends Model<AppPatternsDto> { export class PatternsDto extends Model<PatternsDto> {
constructor( constructor(
public readonly patterns: AppPatternDto[], public readonly patterns: PatternDto[],
public readonly version: Version public readonly version: Version
) { ) {
super(); super();
} }
} }
export class AppPatternDto extends Model<AppPatternDto> { export class PatternDto extends Model<PatternDto> {
constructor( constructor(
public readonly id: string, public readonly id: string,
public readonly name: string, public readonly name: string,
@ -40,14 +40,14 @@ export class AppPatternDto extends Model<AppPatternDto> {
} }
} }
export interface EditAppPatternDto { export interface EditPatternDto {
readonly name: string; readonly name: string;
readonly pattern: string; readonly pattern: string;
readonly message?: string; readonly message?: string;
} }
@Injectable() @Injectable()
export class AppPatternsService { export class PatternsService {
constructor( constructor(
private readonly http: HttpClient, private readonly http: HttpClient,
private readonly apiUrl: ApiUrlConfig, private readonly apiUrl: ApiUrlConfig,
@ -55,7 +55,7 @@ export class AppPatternsService {
) { ) {
} }
public getPatterns(appName: string): Observable<AppPatternsDto> { public getPatterns(appName: string): Observable<PatternsDto> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`);
return HTTP.getVersioned<any>(this.http, url).pipe( return HTTP.getVersioned<any>(this.http, url).pipe(
@ -64,9 +64,9 @@ export class AppPatternsService {
const items: any[] = body; const items: any[] = body;
return new AppPatternsDto( return new PatternsDto(
items.map(item => { items.map(item => {
return new AppPatternDto( return new PatternDto(
item.patternId, item.patternId,
item.name, item.name,
item.pattern, item.pattern,
@ -77,14 +77,14 @@ export class AppPatternsService {
pretifyError('Failed to add pattern. Please reload.')); pretifyError('Failed to add pattern. Please reload.'));
} }
public postPattern(appName: string, dto: EditAppPatternDto, version: Version): Observable<Versioned<AppPatternDto>> { public postPattern(appName: string, dto: EditPatternDto, version: Version): Observable<Versioned<PatternDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`);
return HTTP.postVersioned<any>(this.http, url, dto, version).pipe( return HTTP.postVersioned<any>(this.http, url, dto, version).pipe(
map(response => { map(response => {
const body = response.payload.body; const body = response.payload.body;
const pattern = new AppPatternDto( const pattern = new PatternDto(
body.patternId, body.patternId,
body.name, body.name,
body.pattern, body.pattern,
@ -98,7 +98,7 @@ export class AppPatternsService {
pretifyError('Failed to add pattern. Please reload.')); pretifyError('Failed to add pattern. Please reload.'));
} }
public putPattern(appName: string, id: string, dto: EditAppPatternDto, version: Version): Observable<Versioned<any>> { public putPattern(appName: string, id: string, dto: EditPatternDto, version: Version): Observable<Versioned<any>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns/${id}`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns/${id}`);
return HTTP.putVersioned(this.http, url, dto, version).pipe( return HTTP.putVersioned(this.http, url, dto, version).pipe(

32
src/Squidex/app/shared/services/app-roles.service.spec.ts → src/Squidex/app/shared/services/roles.service.spec.ts

@ -11,13 +11,13 @@ import { inject, TestBed } from '@angular/core/testing';
import { import {
AnalyticsService, AnalyticsService,
ApiUrlConfig, ApiUrlConfig,
AppRoleDto, RoleDto,
AppRolesDto, RolesDto,
AppRolesService, RolesService,
Version Version
} from './../'; } from './../';
describe('AppRolesService', () => { describe('RolesService', () => {
const version = new Version('1'); const version = new Version('1');
beforeEach(() => { beforeEach(() => {
@ -26,7 +26,7 @@ describe('AppRolesService', () => {
HttpClientTestingModule HttpClientTestingModule
], ],
providers: [ providers: [
AppRolesService, RolesService,
{ provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') }, { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') },
{ provide: AnalyticsService, useValue: new AnalyticsService() } { provide: AnalyticsService, useValue: new AnalyticsService() }
] ]
@ -38,7 +38,7 @@ describe('AppRolesService', () => {
})); }));
it('should make get request to get all permissions', it('should make get request to get all permissions',
inject([AppRolesService, HttpTestingController], (roleService: AppRolesService, httpMock: HttpTestingController) => { inject([RolesService, HttpTestingController], (roleService: RolesService, httpMock: HttpTestingController) => {
let permissions: string[]; let permissions: string[];
@ -57,9 +57,9 @@ describe('AppRolesService', () => {
})); }));
it('should make get request to get roles', it('should make get request to get roles',
inject([AppRolesService, HttpTestingController], (roleService: AppRolesService, httpMock: HttpTestingController) => { inject([RolesService, HttpTestingController], (roleService: RolesService, httpMock: HttpTestingController) => {
let roles: AppRolesDto; let roles: RolesDto;
roleService.getRoles('my-app').subscribe(result => { roleService.getRoles('my-app').subscribe(result => {
roles = result; roles = result;
@ -89,19 +89,19 @@ describe('AppRolesService', () => {
}); });
expect(roles!).toEqual( expect(roles!).toEqual(
new AppRolesDto([ new RolesDto([
new AppRoleDto('Role1', 3, 5, ['P1']), new RoleDto('Role1', 3, 5, ['P1']),
new AppRoleDto('Role2', 7, 9, ['P2']) new RoleDto('Role2', 7, 9, ['P2'])
], ],
new Version('2'))); new Version('2')));
})); }));
it('should make post request to add role', it('should make post request to add role',
inject([AppRolesService, HttpTestingController], (roleService: AppRolesService, httpMock: HttpTestingController) => { inject([RolesService, HttpTestingController], (roleService: RolesService, httpMock: HttpTestingController) => {
const dto = { name: 'Role3' }; const dto = { name: 'Role3' };
let role: AppRoleDto; let role: RoleDto;
roleService.postRole('my-app', dto, version).subscribe(result => { roleService.postRole('my-app', dto, version).subscribe(result => {
role = result.payload; role = result.payload;
@ -114,11 +114,11 @@ describe('AppRolesService', () => {
req.flush({}); req.flush({});
expect(role!).toEqual(new AppRoleDto('Role3', 0, 0, [])); expect(role!).toEqual(new RoleDto('Role3', 0, 0, []));
})); }));
it('should make put request to update role', it('should make put request to update role',
inject([AppRolesService, HttpTestingController], (roleService: AppRolesService, httpMock: HttpTestingController) => { inject([RolesService, HttpTestingController], (roleService: RolesService, httpMock: HttpTestingController) => {
const dto = { permissions: ['P4', 'P5'] }; const dto = { permissions: ['P4', 'P5'] };
@ -133,7 +133,7 @@ describe('AppRolesService', () => {
})); }));
it('should make delete request to remove role', it('should make delete request to remove role',
inject([AppRolesService, HttpTestingController], (roleService: AppRolesService, httpMock: HttpTestingController) => { inject([RolesService, HttpTestingController], (roleService: RolesService, httpMock: HttpTestingController) => {
roleService.deleteRole('my-app', 'role1', version).subscribe(); roleService.deleteRole('my-app', 'role1', version).subscribe();

24
src/Squidex/app/shared/services/app-roles.service.ts → src/Squidex/app/shared/services/roles.service.ts

@ -20,16 +20,16 @@ import {
Versioned Versioned
} from '@app/framework'; } from '@app/framework';
export class AppRolesDto extends Model<AppRolesDto> { export class RolesDto extends Model<RolesDto> {
constructor( constructor(
public readonly roles: AppRoleDto[], public readonly roles: RoleDto[],
public readonly version: Version public readonly version: Version
) { ) {
super(); super();
} }
} }
export class AppRoleDto extends Model<AppRoleDto> { export class RoleDto extends Model<RoleDto> {
constructor( constructor(
public readonly name: string, public readonly name: string,
public readonly numClients: number, public readonly numClients: number,
@ -40,16 +40,16 @@ export class AppRoleDto extends Model<AppRoleDto> {
} }
} }
export interface CreateAppRoleDto { export interface CreateRoleDto {
readonly name: string; readonly name: string;
} }
export interface UpdateAppRoleDto { export interface UpdateRoleDto {
readonly permissions: string[]; readonly permissions: string[];
} }
@Injectable() @Injectable()
export class AppRolesService { export class RolesService {
constructor( constructor(
private readonly http: HttpClient, private readonly http: HttpClient,
private readonly apiUrl: ApiUrlConfig, private readonly apiUrl: ApiUrlConfig,
@ -57,7 +57,7 @@ export class AppRolesService {
) { ) {
} }
public getRoles(appName: string): Observable<AppRolesDto> { public getRoles(appName: string): Observable<RolesDto> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles`);
return HTTP.getVersioned<any>(this.http, url).pipe( return HTTP.getVersioned<any>(this.http, url).pipe(
@ -67,24 +67,24 @@ export class AppRolesService {
const items: any[] = body.roles; const items: any[] = body.roles;
const roles = items.map(item => { const roles = items.map(item => {
return new AppRoleDto( return new RoleDto(
item.name, item.name,
item.numClients, item.numClients,
item.numContributors, item.numContributors,
item.permissions); item.permissions);
}); });
return new AppRolesDto(roles, response.version); return new RolesDto(roles, response.version);
}), }),
pretifyError('Failed to load roles. Please reload.')); pretifyError('Failed to load roles. Please reload.'));
} }
public postRole(appName: string, dto: CreateAppRoleDto, version: Version): Observable<Versioned<AppRoleDto>> { public postRole(appName: string, dto: CreateRoleDto, version: Version): Observable<Versioned<RoleDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles`);
return HTTP.postVersioned<any>(this.http, url, dto, version).pipe( return HTTP.postVersioned<any>(this.http, url, dto, version).pipe(
map(response => { map(response => {
const role = new AppRoleDto(dto.name, 0, 0, []); const role = new RoleDto(dto.name, 0, 0, []);
return new Versioned(response.version, role); return new Versioned(response.version, role);
}), }),
@ -94,7 +94,7 @@ export class AppRolesService {
pretifyError('Failed to add role. Please reload.')); pretifyError('Failed to add role. Please reload.'));
} }
public putRole(appName: string, name: string, dto: UpdateAppRoleDto, version: Version): Observable<Versioned<any>> { public putRole(appName: string, name: string, dto: UpdateRoleDto, version: Version): Observable<Versioned<any>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles/${name}`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/roles/${name}`);
return HTTP.putVersioned(this.http, url, dto, version).pipe( return HTTP.putVersioned(this.http, url, dto, version).pipe(

8
src/Squidex/app/shared/services/schemas.service.spec.ts

@ -48,7 +48,9 @@ describe('SchemasService', () => {
})); }));
it('should throw if creating invalid property type', () => { it('should throw if creating invalid property type', () => {
expect(() => createProperties('invalid')).toThrow('Invalid properties type'); const type: any = 'invalid';
expect(() => createProperties(type)).toThrow('Invalid properties type');
}); });
it('should make get request to get schemas', it('should make get request to get schemas',
@ -417,7 +419,7 @@ describe('SchemasService', () => {
const dto = new AddFieldDto('name', 'invariant', createProperties('Number')); const dto = new AddFieldDto('name', 'invariant', createProperties('Number'));
let field: FieldDto; let field: FieldDto<any>;
schemasService.postField('my-app', 'my-schema', dto, undefined, version).subscribe(result => { schemasService.postField('my-app', 'my-schema', dto, undefined, version).subscribe(result => {
field = result.payload; field = result.payload;
@ -464,7 +466,7 @@ describe('SchemasService', () => {
const dto = new AddFieldDto('name', 'invariant', createProperties('Number')); const dto = new AddFieldDto('name', 'invariant', createProperties('Number'));
let field: FieldDto; let field: FieldDto<any>;
schemasService.postField('my-app', 'my-schema', dto, 13, version).subscribe(result => { schemasService.postField('my-app', 'my-schema', dto, 13, version).subscribe(result => {
field = result.payload; field = result.payload;

12
src/Squidex/app/shared/services/schemas.service.ts

@ -84,6 +84,10 @@ export class SchemaDetailsDto extends SchemaDto {
this.listFieldsEditable = fields.filter(x => x.isInlineEditable); this.listFieldsEditable = fields.filter(x => x.isInlineEditable);
} }
} }
public with(value: Partial<SchemaDetailsDto>): SchemaDetailsDto {
return this.clone(value);
}
} }
export class FieldDto extends Model<FieldDto> { export class FieldDto extends Model<FieldDto> {
@ -137,6 +141,10 @@ export class RootFieldDto extends FieldDto {
) { ) {
super(fieldId, name, properties, isLocked, isHidden, isDisabled); super(fieldId, name, properties, isLocked, isHidden, isDisabled);
} }
public with(value: Partial<RootFieldDto>): RootFieldDto {
return this.clone(value);
}
} }
export class NestedFieldDto extends FieldDto { export class NestedFieldDto extends FieldDto {
@ -148,6 +156,10 @@ export class NestedFieldDto extends FieldDto {
) { ) {
super(fieldId, name, properties, isLocked, isHidden, isDisabled); super(fieldId, name, properties, isLocked, isHidden, isDisabled);
} }
public with(value: Partial<NestedFieldDto>): NestedFieldDto {
return this.clone(value);
}
} }
export class SchemaPropertiesDto { export class SchemaPropertiesDto {

20
src/Squidex/app/shared/state/clients.state.spec.ts

@ -9,10 +9,10 @@ import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq'; import { IMock, It, Mock, Times } from 'typemoq';
import { import {
AppClientDto,
AppClientsDto,
AppClientsService,
AppsState, AppsState,
ClientDto,
ClientsDto,
ClientsService,
ClientsState, ClientsState,
DialogService, DialogService,
Version, Version,
@ -25,13 +25,13 @@ describe('ClientsState', () => {
const newVersion = new Version('2'); const newVersion = new Version('2');
const oldClients = [ const oldClients = [
new AppClientDto('id1', 'name1', 'secret1'), new ClientDto('id1', 'name1', 'secret1'),
new AppClientDto('id2', 'name2', 'secret2') new ClientDto('id2', 'name2', 'secret2')
]; ];
let dialogs: IMock<DialogService>; let dialogs: IMock<DialogService>;
let appsState: IMock<AppsState>; let appsState: IMock<AppsState>;
let clientsService: IMock<AppClientsService>; let clientsService: IMock<ClientsService>;
let clientsState: ClientsState; let clientsState: ClientsState;
beforeEach(() => { beforeEach(() => {
@ -42,10 +42,10 @@ describe('ClientsState', () => {
appsState.setup(x => x.appName) appsState.setup(x => x.appName)
.returns(() => app); .returns(() => app);
clientsService = Mock.ofType<AppClientsService>(); clientsService = Mock.ofType<ClientsService>();
clientsService.setup(x => x.getClients(app)) clientsService.setup(x => x.getClients(app))
.returns(() => of(new AppClientsDto(oldClients, version))); .returns(() => of(new ClientsDto(oldClients, version)));
clientsState = new ClientsState(clientsService.object, appsState.object, dialogs.object); clientsState = new ClientsState(clientsService.object, appsState.object, dialogs.object);
clientsState.load().subscribe(); clientsState.load().subscribe();
@ -68,12 +68,12 @@ describe('ClientsState', () => {
}); });
it('should add client to snapshot when created', () => { it('should add client to snapshot when created', () => {
const newClient = new AppClientDto('id3', 'name3', 'secret3'); const newClient = new ClientDto('id3', 'name3', 'secret3');
const request = { id: 'id3' }; const request = { id: 'id3' };
clientsService.setup(x => x.postClient(app, request, version)) clientsService.setup(x => x.postClient(app, request, version))
.returns(() => of(new Versioned<AppClientDto>(newVersion, newClient))); .returns(() => of(new Versioned<ClientDto>(newVersion, newClient)));
clientsState.attach(request).subscribe(); clientsState.attach(request).subscribe();

30
src/Squidex/app/shared/state/clients.state.ts

@ -20,15 +20,15 @@ import {
import { AppsState } from './apps.state'; import { AppsState } from './apps.state';
import { import {
AppClientDto, ClientDto,
AppClientsService, ClientsService,
CreateAppClientDto, CreateClientDto,
UpdateAppClientDto UpdateClientDto
} from './../services/app-clients.service'; } from './../services/clients.service';
interface Snapshot { interface Snapshot {
// The current clients. // The current clients.
clients: ImmutableArray<AppClientDto>; clients: ImmutableArray<ClientDto>;
// The app version. // The app version.
version: Version; version: Version;
@ -48,7 +48,7 @@ export class ClientsState extends State<Snapshot> {
distinctUntilChanged()); distinctUntilChanged());
constructor( constructor(
private readonly appClientsService: AppClientsService, private readonly clientsService: ClientsService,
private readonly appsState: AppsState, private readonly appsState: AppsState,
private readonly dialogs: DialogService private readonly dialogs: DialogService
) { ) {
@ -60,7 +60,7 @@ export class ClientsState extends State<Snapshot> {
this.resetState(); this.resetState();
} }
return this.appClientsService.getClients(this.appName).pipe( return this.clientsService.getClients(this.appName).pipe(
tap(dtos => { tap(dtos => {
if (isReload) { if (isReload) {
this.dialogs.notifyInfo('Clients reloaded.'); this.dialogs.notifyInfo('Clients reloaded.');
@ -75,8 +75,8 @@ export class ClientsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public attach(request: CreateAppClientDto): Observable<any> { public attach(request: CreateClientDto): Observable<any> {
return this.appClientsService.postClient(this.appName, request, this.version).pipe( return this.clientsService.postClient(this.appName, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const clients = s.clients.push(dto.payload); const clients = s.clients.push(dto.payload);
@ -87,8 +87,8 @@ export class ClientsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public revoke(client: AppClientDto): Observable<any> { public revoke(client: ClientDto): Observable<any> {
return this.appClientsService.deleteClient(this.appName, client.id, this.version).pipe( return this.clientsService.deleteClient(this.appName, client.id, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const clients = s.clients.filter(c => c.id !== client.id); const clients = s.clients.filter(c => c.id !== client.id);
@ -99,8 +99,8 @@ export class ClientsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public update(client: AppClientDto, request: UpdateAppClientDto): Observable<any> { public update(client: ClientDto, request: UpdateClientDto): Observable<any> {
return this.appClientsService.putClient(this.appName, client.id, request, this.version).pipe( return this.clientsService.putClient(this.appName, client.id, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const clients = s.clients.replaceBy('id', update(client, request)); const clients = s.clients.replaceBy('id', update(client, request));
@ -120,5 +120,5 @@ export class ClientsState extends State<Snapshot> {
} }
} }
const update = (client: AppClientDto, request: UpdateAppClientDto) => const update = (client: ClientDto, request: UpdateClientDto) =>
client.with({ name: request.name || client.name, role: request.role || client.role }); client.with({ name: request.name || client.name, role: request.role || client.role });

26
src/Squidex/app/shared/state/contributors.state.spec.ts

@ -9,12 +9,12 @@ import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq'; import { IMock, It, Mock, Times } from 'typemoq';
import { import {
AppContributorDto,
AppContributorsDto,
AppContributorsService,
AppsState, AppsState,
AuthService, AuthService,
ContributorAssignedDto, ContributorAssignedDto,
ContributorDto,
ContributorsDto,
ContributorsService,
ContributorsState, ContributorsState,
DialogService, DialogService,
Version, Version,
@ -27,14 +27,14 @@ describe('ContributorsState', () => {
const newVersion = new Version('2'); const newVersion = new Version('2');
const oldContributors = [ const oldContributors = [
new AppContributorDto('id1', 'Developer'), new ContributorDto('id1', 'Developer'),
new AppContributorDto('id2', 'Developer') new ContributorDto('id2', 'Developer')
]; ];
let dialogs: IMock<DialogService>; let dialogs: IMock<DialogService>;
let appsState: IMock<AppsState>; let appsState: IMock<AppsState>;
let authService: IMock<AuthService>; let authService: IMock<AuthService>;
let contributorsService: IMock<AppContributorsService>; let contributorsService: IMock<ContributorsService>;
let contributorsState: ContributorsState; let contributorsState: ContributorsState;
beforeEach(() => { beforeEach(() => {
@ -50,10 +50,10 @@ describe('ContributorsState', () => {
appsState.setup(x => x.appName) appsState.setup(x => x.appName)
.returns(() => app); .returns(() => app);
contributorsService = Mock.ofType<AppContributorsService>(); contributorsService = Mock.ofType<ContributorsService>();
contributorsService.setup(x => x.getContributors(app)) contributorsService.setup(x => x.getContributors(app))
.returns(() => of(new AppContributorsDto(oldContributors, 3, version))); .returns(() => of(new ContributorsDto(oldContributors, 3, version)));
contributorsState = new ContributorsState(contributorsService.object, appsState.object, authService.object, dialogs.object); contributorsState = new ContributorsState(contributorsService.object, appsState.object, authService.object, dialogs.object);
contributorsState.load().subscribe(); contributorsState.load().subscribe();
@ -81,12 +81,12 @@ describe('ContributorsState', () => {
}); });
it('should add contributor to snapshot when assigned', () => { it('should add contributor to snapshot when assigned', () => {
const newContributor = new AppContributorDto('id3', 'Developer'); const newContributor = new ContributorDto('id3', 'Developer');
const request = { contributorId: 'mail2stehle@gmail.com', role: 'Developer' }; const request = { contributorId: 'mail2stehle@gmail.com', role: 'Developer' };
contributorsService.setup(x => x.postContributor(app, request, version)) contributorsService.setup(x => x.postContributor(app, request, version))
.returns(() => of(new Versioned<ContributorAssignedDto>(newVersion, new ContributorAssignedDto('id3', true)))); .returns(() => of(new Versioned<ContributorAssignedDto>(newVersion, { contributorId: '123', isCreated: true })));
contributorsState.assign(request).subscribe(); contributorsState.assign(request).subscribe();
@ -101,12 +101,12 @@ describe('ContributorsState', () => {
}); });
it('should update contributor in snapshot when assigned and already added', () => { it('should update contributor in snapshot when assigned and already added', () => {
const newContributor = new AppContributorDto('id2', 'Owner'); const newContributor = new ContributorDto('id2', 'Owner');
const request = new AssignContributorDto('mail2stehle@gmail.com', 'Owner'); const request = { ...newContributor };
contributorsService.setup(x => x.postContributor(app, request, version)) contributorsService.setup(x => x.postContributor(app, request, version))
.returns(() => of(new Versioned<ContributorAssignedDto>(newVersion, new ContributorAssignedDto('id2', true)))); .returns(() => of(new Versioned<ContributorAssignedDto>(newVersion, { contributorId: '123', isCreated: true })));
contributorsState.assign(request).subscribe(); contributorsState.assign(request).subscribe();

26
src/Squidex/app/shared/state/contributors.state.ts

@ -20,17 +20,17 @@ import {
} from '@app/framework'; } from '@app/framework';
import { import {
AppContributorDto, AssignContributorDto,
AppContributorsService, ContributorDto,
AssignContributorDto ContributorsService
} from './../services/app-contributors.service'; } from './../services/contributors.service';
import { AuthService } from './../services/auth.service'; import { AuthService } from './../services/auth.service';
import { AppsState } from './apps.state'; import { AppsState } from './apps.state';
interface SnapshotContributor { interface SnapshotContributor {
// The contributor. // The contributor.
contributor: AppContributorDto; contributor: ContributorDto;
// Indicates if the contributor is the ucrrent user. // Indicates if the contributor is the ucrrent user.
isCurrentUser: boolean; isCurrentUser: boolean;
@ -72,7 +72,7 @@ export class ContributorsState extends State<Snapshot> {
distinctUntilChanged()); distinctUntilChanged());
constructor( constructor(
private readonly appContributorsService: AppContributorsService, private readonly contributorsService: ContributorsService,
private readonly appsState: AppsState, private readonly appsState: AppsState,
private readonly authState: AuthService, private readonly authState: AuthService,
private readonly dialogs: DialogService private readonly dialogs: DialogService
@ -85,7 +85,7 @@ export class ContributorsState extends State<Snapshot> {
this.resetState(); this.resetState();
} }
return this.appContributorsService.getContributors(this.appName).pipe( return this.contributorsService.getContributors(this.appName).pipe(
tap(dtos => { tap(dtos => {
if (isReload) { if (isReload) {
this.dialogs.notifyInfo('Contributors reloaded.'); this.dialogs.notifyInfo('Contributors reloaded.');
@ -98,8 +98,8 @@ export class ContributorsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public revoke(contributor: AppContributorDto): Observable<any> { public revoke(contributor: ContributorDto): Observable<any> {
return this.appContributorsService.deleteContributor(this.appName, contributor.contributorId, this.version).pipe( return this.contributorsService.deleteContributor(this.appName, contributor.contributorId, this.version).pipe(
tap(dto => { tap(dto => {
const contributors = this.snapshot.contributors.filter(x => x.contributor.contributorId !== contributor.contributorId); const contributors = this.snapshot.contributors.filter(x => x.contributor.contributorId !== contributor.contributorId);
@ -108,8 +108,8 @@ export class ContributorsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public assign(request: AssignContributorDto): Observable<boolean> { public assign(request: AssignContributorDto): Observable<boolean | undefined> {
return this.appContributorsService.postContributor(this.appName, request, this.version).pipe( return this.contributorsService.postContributor(this.appName, request, this.version).pipe(
map(dto => { map(dto => {
const contributors = this.updateContributors(dto.payload.contributorId, request.role, dto.version); const contributors = this.updateContributors(dto.payload.contributorId, request.role, dto.version);
@ -128,7 +128,7 @@ export class ContributorsState extends State<Snapshot> {
} }
private updateContributors(id: string, role: string, version: Version) { private updateContributors(id: string, role: string, version: Version) {
const contributor = new AppContributorDto(id, role); const contributor = new ContributorDto(id, role);
const contributors = this.snapshot.contributors; const contributors = this.snapshot.contributors;
if (contributors.find(x => x.contributor.contributorId === id)) { if (contributors.find(x => x.contributor.contributorId === id)) {
@ -161,7 +161,7 @@ export class ContributorsState extends State<Snapshot> {
return this.snapshot.version; return this.snapshot.version;
} }
private createContributor(contributor: AppContributorDto, current?: SnapshotContributor): SnapshotContributor { private createContributor(contributor: ContributorDto, current?: SnapshotContributor): SnapshotContributor {
if (!contributor) { if (!contributor) {
return null!; return null!;
} else if (current && current.contributor === contributor) { } else if (current && current.contributor === contributor) {

20
src/Squidex/app/shared/state/patterns.state.spec.ts

@ -9,11 +9,11 @@ import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq'; import { IMock, It, Mock, Times } from 'typemoq';
import { import {
AppPatternDto,
AppPatternsDto,
AppPatternsService,
AppsState, AppsState,
DialogService, DialogService,
PatternDto,
PatternsDto,
PatternsService,
PatternsState, PatternsState,
Version, Version,
Versioned Versioned
@ -25,13 +25,13 @@ describe('PatternsState', () => {
const newVersion = new Version('2'); const newVersion = new Version('2');
const oldPatterns = [ const oldPatterns = [
new AppPatternDto('id1', 'name1', 'pattern1', ''), new PatternDto('id1', 'name1', 'pattern1', ''),
new AppPatternDto('id2', 'name2', 'pattern2', '') new PatternDto('id2', 'name2', 'pattern2', '')
]; ];
let dialogs: IMock<DialogService>; let dialogs: IMock<DialogService>;
let appsState: IMock<AppsState>; let appsState: IMock<AppsState>;
let patternsService: IMock<AppPatternsService>; let patternsService: IMock<PatternsService>;
let patternsState: PatternsState; let patternsState: PatternsState;
beforeEach(() => { beforeEach(() => {
@ -42,10 +42,10 @@ describe('PatternsState', () => {
appsState.setup(x => x.appName) appsState.setup(x => x.appName)
.returns(() => app); .returns(() => app);
patternsService = Mock.ofType<AppPatternsService>(); patternsService = Mock.ofType<PatternsService>();
patternsService.setup(x => x.getPatterns(app)) patternsService.setup(x => x.getPatterns(app))
.returns(() => of(new AppPatternsDto(oldPatterns, version))); .returns(() => of(new PatternsDto(oldPatterns, version)));
patternsState = new PatternsState(patternsService.object, appsState.object, dialogs.object); patternsState = new PatternsState(patternsService.object, appsState.object, dialogs.object);
patternsState.load().subscribe(); patternsState.load().subscribe();
@ -67,12 +67,12 @@ describe('PatternsState', () => {
}); });
it('should add pattern to snapshot when created', () => { it('should add pattern to snapshot when created', () => {
const newPattern = new AppPatternDto('id3', 'name3', 'pattern3', ''); const newPattern = new PatternDto('id3', 'name3', 'pattern3', '');
const request = { ...newPattern }; const request = { ...newPattern };
patternsService.setup(x => x.postPattern(app, request, version)) patternsService.setup(x => x.postPattern(app, request, version))
.returns(() => of(new Versioned<AppPatternDto>(newVersion, newPattern))); .returns(() => of(new Versioned<PatternDto>(newVersion, newPattern)));
patternsState.create(request).subscribe(); patternsState.create(request).subscribe();

28
src/Squidex/app/shared/state/patterns.state.ts

@ -20,14 +20,14 @@ import {
import { AppsState } from './apps.state'; import { AppsState } from './apps.state';
import { import {
AppPatternDto, EditPatternDto,
AppPatternsService, PatternDto,
EditAppPatternDto PatternsService
} from './../services/app-patterns.service'; } from './../services/patterns.service';
interface Snapshot { interface Snapshot {
// The current patterns. // The current patterns.
patterns: ImmutableArray<AppPatternDto>; patterns: ImmutableArray<PatternDto>;
// The app version. // The app version.
version: Version; version: Version;
@ -47,7 +47,7 @@ export class PatternsState extends State<Snapshot> {
distinctUntilChanged()); distinctUntilChanged());
constructor( constructor(
private readonly appPatternsService: AppPatternsService, private readonly patternsService: PatternsService,
private readonly appsState: AppsState, private readonly appsState: AppsState,
private readonly dialogs: DialogService private readonly dialogs: DialogService
) { ) {
@ -59,7 +59,7 @@ export class PatternsState extends State<Snapshot> {
this.resetState(); this.resetState();
} }
return this.appPatternsService.getPatterns(this.appName).pipe( return this.patternsService.getPatterns(this.appName).pipe(
tap(dtos => { tap(dtos => {
if (isReload) { if (isReload) {
this.dialogs.notifyInfo('Patterns reloaded.'); this.dialogs.notifyInfo('Patterns reloaded.');
@ -74,8 +74,8 @@ export class PatternsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public create(request: EditAppPatternDto): Observable<any> { public create(request: EditPatternDto): Observable<any> {
return this.appPatternsService.postPattern(this.appName, request, this.version).pipe( return this.patternsService.postPattern(this.appName, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const patterns = s.patterns.push(dto.payload).sortByStringAsc(x => x.name); const patterns = s.patterns.push(dto.payload).sortByStringAsc(x => x.name);
@ -86,8 +86,8 @@ export class PatternsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public update(pattern: AppPatternDto, request: EditAppPatternDto): Observable<any> { public update(pattern: PatternDto, request: EditPatternDto): Observable<any> {
return this.appPatternsService.putPattern(this.appName, pattern.id, request, this.version).pipe( return this.patternsService.putPattern(this.appName, pattern.id, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const patterns = s.patterns.replaceBy('id', update(pattern, request)).sortByStringAsc(x => x.name); const patterns = s.patterns.replaceBy('id', update(pattern, request)).sortByStringAsc(x => x.name);
@ -98,8 +98,8 @@ export class PatternsState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public delete(pattern: AppPatternDto): Observable<any> { public delete(pattern: PatternDto): Observable<any> {
return this.appPatternsService.deletePattern(this.appName, pattern.id, this.version).pipe( return this.patternsService.deletePattern(this.appName, pattern.id, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const patterns = s.patterns.filter(c => c.id !== pattern.id); const patterns = s.patterns.filter(c => c.id !== pattern.id);
@ -119,5 +119,5 @@ export class PatternsState extends State<Snapshot> {
} }
} }
const update = (pattern: AppPatternDto, request: EditAppPatternDto) => const update = (pattern: PatternDto, request: EditPatternDto) =>
pattern.with(request); pattern.with(request);

20
src/Squidex/app/shared/state/roles.state.spec.ts

@ -9,11 +9,11 @@ import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq'; import { IMock, It, Mock, Times } from 'typemoq';
import { import {
AppRoleDto,
AppRolesDto,
AppRolesService,
AppsState, AppsState,
DialogService, DialogService,
RoleDto,
RolesDto,
RolesService,
RolesState, RolesState,
Version, Version,
Versioned Versioned
@ -25,13 +25,13 @@ describe('RolesState', () => {
const newVersion = new Version('2'); const newVersion = new Version('2');
const oldRoles = [ const oldRoles = [
new AppRoleDto('Role1', 3, 5, ['P1']), new RoleDto('Role1', 3, 5, ['P1']),
new AppRoleDto('Role2', 7, 9, ['P2']) new RoleDto('Role2', 7, 9, ['P2'])
]; ];
let dialogs: IMock<DialogService>; let dialogs: IMock<DialogService>;
let appsState: IMock<AppsState>; let appsState: IMock<AppsState>;
let rolesService: IMock<AppRolesService>; let rolesService: IMock<RolesService>;
let rolesState: RolesState; let rolesState: RolesState;
beforeEach(() => { beforeEach(() => {
@ -42,10 +42,10 @@ describe('RolesState', () => {
appsState.setup(x => x.appName) appsState.setup(x => x.appName)
.returns(() => app); .returns(() => app);
rolesService = Mock.ofType<AppRolesService>(); rolesService = Mock.ofType<RolesService>();
rolesService.setup(x => x.getRoles(app)) rolesService.setup(x => x.getRoles(app))
.returns(() => of(new AppRolesDto(oldRoles, version))); .returns(() => of(new RolesDto(oldRoles, version)));
rolesState = new RolesState(rolesService.object, appsState.object, dialogs.object); rolesState = new RolesState(rolesService.object, appsState.object, dialogs.object);
rolesState.load().subscribe(); rolesState.load().subscribe();
@ -68,12 +68,12 @@ describe('RolesState', () => {
}); });
it('should add role to snapshot when added', () => { it('should add role to snapshot when added', () => {
const newRole = new AppRoleDto('Role3', 0, 0, ['P3']); const newRole = new RoleDto('Role3', 0, 0, ['P3']);
const request = { name: newRole.name }; const request = { name: newRole.name };
rolesService.setup(x => x.postRole(app, request, version)) rolesService.setup(x => x.postRole(app, request, version))
.returns(() => of(new Versioned<AppRoleDto>(newVersion, newRole))); .returns(() => of(new Versioned<RoleDto>(newVersion, newRole)));
rolesState.add(request).subscribe(); rolesState.add(request).subscribe();

30
src/Squidex/app/shared/state/roles.state.ts

@ -20,15 +20,15 @@ import {
import { AppsState } from './apps.state'; import { AppsState } from './apps.state';
import { import {
AppRoleDto, CreateRoleDto,
AppRolesService, RoleDto,
CreateAppRoleDto, RolesService,
UpdateAppRoleDto UpdateRoleDto
} from './../services/app-roles.service'; } from './../services/roles.service';
interface Snapshot { interface Snapshot {
// The current roles. // The current roles.
roles: ImmutableArray<AppRoleDto>; roles: ImmutableArray<RoleDto>;
// The app version. // The app version.
version: Version; version: Version;
@ -48,7 +48,7 @@ export class RolesState extends State<Snapshot> {
distinctUntilChanged()); distinctUntilChanged());
constructor( constructor(
private readonly appRolesService: AppRolesService, private readonly rolesService: RolesService,
private readonly appsState: AppsState, private readonly appsState: AppsState,
private readonly dialogs: DialogService private readonly dialogs: DialogService
) { ) {
@ -60,7 +60,7 @@ export class RolesState extends State<Snapshot> {
this.resetState(); this.resetState();
} }
return this.appRolesService.getRoles(this.appName).pipe( return this.rolesService.getRoles(this.appName).pipe(
tap(dtos => { tap(dtos => {
if (isReload) { if (isReload) {
this.dialogs.notifyInfo('Roles reloaded.'); this.dialogs.notifyInfo('Roles reloaded.');
@ -75,8 +75,8 @@ export class RolesState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public add(request: CreateAppRoleDto): Observable<any> { public add(request: CreateRoleDto): Observable<any> {
return this.appRolesService.postRole(this.appName, request, this.version).pipe( return this.rolesService.postRole(this.appName, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const roles = s.roles.push(dto.payload).sortByStringAsc(x => x.name); const roles = s.roles.push(dto.payload).sortByStringAsc(x => x.name);
@ -87,8 +87,8 @@ export class RolesState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public delete(role: AppRoleDto): Observable<any> { public delete(role: RoleDto): Observable<any> {
return this.appRolesService.deleteRole(this.appName, role.name, this.version).pipe( return this.rolesService.deleteRole(this.appName, role.name, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const roles = s.roles.filter(c => c.name !== role.name); const roles = s.roles.filter(c => c.name !== role.name);
@ -99,8 +99,8 @@ export class RolesState extends State<Snapshot> {
notify(this.dialogs)); notify(this.dialogs));
} }
public update(role: AppRoleDto, request: UpdateAppRoleDto): Observable<any> { public update(role: RoleDto, request: UpdateRoleDto): Observable<any> {
return this.appRolesService.putRole(this.appName, role.name, request, this.version).pipe( return this.rolesService.putRole(this.appName, role.name, request, this.version).pipe(
tap(dto => { tap(dto => {
this.next(s => { this.next(s => {
const roles = s.roles.replaceBy('name', update(role, request)); const roles = s.roles.replaceBy('name', update(role, request));
@ -120,5 +120,5 @@ export class RolesState extends State<Snapshot> {
} }
} }
const update = (role: AppRoleDto, request: UpdateAppRoleDto) => const update = (role: RoleDto, request: UpdateRoleDto) =>
role.with({ permissions: request.permissions }); role.with({ permissions: request.permissions });

12
src/Squidex/app/shared/state/schemas.state.spec.ts

@ -23,9 +23,7 @@ import {
SchemaDetailsDto, SchemaDetailsDto,
SchemaDto, SchemaDto,
SchemasService, SchemasService,
UpdateFieldDto,
UpdateSchemaCategoryDto, UpdateSchemaCategoryDto,
UpdateSchemaDto,
Version, Version,
Versioned Versioned
} from './../'; } from './../';
@ -248,7 +246,7 @@ describe('SchemasState', () => {
}); });
it('should update properties and update user info when updated', () => { it('should update properties and update user info when updated', () => {
const request = new UpdateSchemaDto('name2_label', 'name2_hints'); const request = { label: 'name2_label', hints: 'name2_hints' };
schemasService.setup(x => x.putSchema(app, schema.name, It.isAny(), version)) schemasService.setup(x => x.putSchema(app, schema.name, It.isAny(), version))
.returns(() => of(new Versioned<any>(newVersion, {}))); .returns(() => of(new Versioned<any>(newVersion, {})));
@ -257,8 +255,8 @@ describe('SchemasState', () => {
const schema_1 = <SchemaDetailsDto>schemasState.snapshot.schemas.at(1); const schema_1 = <SchemaDetailsDto>schemasState.snapshot.schemas.at(1);
expect(schema_1.properties.label).toEqual('name2_label'); expect(schema_1.properties.label).toEqual(request.label);
expect(schema_1.properties.hints).toEqual('name2_hints'); expect(schema_1.properties.hints).toEqual(request.hints);
expectToBeModified(schema_1); expectToBeModified(schema_1);
}); });
@ -395,7 +393,7 @@ describe('SchemasState', () => {
}); });
it('should update field properties and update user info when field updated', () => { it('should update field properties and update user info when field updated', () => {
const request = new UpdateFieldDto(createProperties('String')); const request = { properties: createProperties('String') };
schemasService.setup(x => x.putField(app, schema.name, field1.fieldId, request, undefined, version)) schemasService.setup(x => x.putField(app, schema.name, field1.fieldId, request, undefined, version))
.returns(() => of(new Versioned<any>(newVersion, {}))); .returns(() => of(new Versioned<any>(newVersion, {})));
@ -409,7 +407,7 @@ describe('SchemasState', () => {
}); });
it('should update field properties and update user info when nested field updated', () => { it('should update field properties and update user info when nested field updated', () => {
const request = new UpdateFieldDto(createProperties('String')); const request = { properties: createProperties('String') };
schemasService.setup(x => x.putField(app, schema.name, nested1.fieldId, request, 2, version)) schemasService.setup(x => x.putField(app, schema.name, nested1.fieldId, request, 2, version))
.returns(() => of(new Versioned<any>(newVersion, {}))); .returns(() => of(new Versioned<any>(newVersion, {})));

11
src/Squidex/app/shared/state/schemas.state.ts

@ -33,7 +33,6 @@ import {
SchemaPropertiesDto, SchemaPropertiesDto,
SchemasService, SchemasService,
UpdateFieldDto, UpdateFieldDto,
UpdateSchemaCategoryDto,
UpdateSchemaDto UpdateSchemaDto
} from './../services/schemas.service'; } from './../services/schemas.service';
@ -190,7 +189,7 @@ export class SchemasState extends State<Snapshot> {
} }
public changeCategory(schema: SchemaDto, name: string, now?: DateTime): Observable<any> { public changeCategory(schema: SchemaDto, name: string, now?: DateTime): Observable<any> {
return this.schemasService.putCategory(this.appName, schema.name, new UpdateSchemaCategoryDto(name), schema.version).pipe( return this.schemasService.putCategory(this.appName, schema.name, { name }, schema.version).pipe(
tap(dto => { tap(dto => {
this.replaceSchema(changeCategory(schema, name, this.user, dto.version, now)); this.replaceSchema(changeCategory(schema, name, this.user, dto.version, now));
}), }),
@ -474,8 +473,8 @@ const setDisabled = <T extends FieldDto>(field: T, isDisabled: boolean) =>
const update = <T extends FieldDto>(field: T, properties: FieldPropertiesDto) => const update = <T extends FieldDto>(field: T, properties: FieldPropertiesDto) =>
<T>field.with({ properties }); <T>field.with({ properties });
const pid = (field?: RootFieldDto) => const pidof = <T extends FieldDto>(field: T) =>
field ? field.fieldId : undefined; Types.is(field, NestedFieldDto) ? field.parentId : undefined;
const pidof = (field: FieldDto) => const pid = (field?: RootFieldDto) =>
Types.is(field, NestedFieldDto) ? field.parentId : undefined; field ? field.fieldId : undefined;
Loading…
Cancel
Save