Browse Source

Move business logic from service to states.

pull/356/head
Sebastian 7 years ago
parent
commit
2493ca400f
  1. 14
      src/Squidex/app/shared/services/apps.service.spec.ts
  2. 27
      src/Squidex/app/shared/services/apps.service.ts
  3. 34
      src/Squidex/app/shared/services/rules.service.spec.ts
  4. 38
      src/Squidex/app/shared/services/rules.service.ts
  5. 27
      src/Squidex/app/shared/services/schemas.service.spec.ts
  6. 49
      src/Squidex/app/shared/services/schemas.service.ts
  7. 3
      src/Squidex/app/shared/state/_test-helpers.ts
  8. 12
      src/Squidex/app/shared/state/apps.state.spec.ts
  9. 22
      src/Squidex/app/shared/state/apps.state.ts
  10. 26
      src/Squidex/app/shared/state/asset-uploader.state.spec.ts
  11. 30
      src/Squidex/app/shared/state/comments.state.spec.ts
  12. 6
      src/Squidex/app/shared/state/contributors.state.spec.ts
  13. 10
      src/Squidex/app/shared/state/rules.state.spec.ts
  14. 39
      src/Squidex/app/shared/state/rules.state.ts
  15. 17
      src/Squidex/app/shared/state/schemas.state.spec.ts
  16. 29
      src/Squidex/app/shared/state/schemas.state.ts
  17. 24
      src/Squidex/package-lock.json
  18. 8
      src/Squidex/package.json
  19. 4
      src/Squidex/tslint.json

14
src/Squidex/app/shared/services/apps.service.spec.ts

@ -11,6 +11,7 @@ import { inject, TestBed } from '@angular/core/testing';
import {
AnalyticsService,
ApiUrlConfig,
AppCreatedDto,
AppDto,
AppsService,
DateTime,
@ -18,8 +19,6 @@ import {
} from '@app/shared/internal';
describe('AppsService', () => {
const now = DateTime.now();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
@ -84,9 +83,9 @@ describe('AppsService', () => {
const dto = { name: 'new-app' };
let app: AppDto;
let app: AppCreatedDto;
appsService.postApp(dto, now).subscribe(result => {
appsService.postApp(dto).subscribe(result => {
app = result;
});
@ -102,7 +101,12 @@ describe('AppsService', () => {
planUpgrade: 'Enterprise'
});
expect(app!).toEqual(new AppDto('123', dto.name, [new Permission('Reader')], now, now, 'Basic', 'Enterprise'));
expect(app!).toEqual({
id: '123',
permissions: ['Reader'],
planName: 'Basic',
planUpgrade: 'Enterprise'
});
}));
it('should make delete request to archive app',

27
src/Squidex/app/shared/services/apps.service.ts

@ -38,6 +38,13 @@ export interface CreateAppDto {
readonly template?: string;
}
export interface AppCreatedDto {
readonly id: string;
readonly permissions: string[];
readonly planName?: string;
readonly planUpgrade?: string;
}
@Injectable()
export class AppsService {
constructor(
@ -70,26 +77,10 @@ export class AppsService {
pretifyError('Failed to load apps. Please reload.'));
}
public postApp(dto: CreateAppDto, now?: DateTime): Observable<AppDto> {
public postApp(dto: CreateAppDto): Observable<AppCreatedDto> {
const url = this.apiUrl.buildUrl('api/apps');
return this.http.post<any>(url, dto).pipe(
map(body => {
now = now || DateTime.now();
const permissions = (<string[]>body.permissions).map(x => new Permission(x));
const app = new AppDto(
body.id,
dto.name,
permissions,
now,
now,
body.planName,
body.planUpgrade);
return app;
}),
return this.http.post<AppCreatedDto>(url, dto).pipe(
tap(() => {
this.analytics.trackEvent('App', 'Created', dto.name);
}),

34
src/Squidex/app/shared/services/rules.service.spec.ts

@ -19,12 +19,12 @@ import {
RuleEventDto,
RuleEventsDto,
RulesService,
Version
Version,
Versioned
} from '@app/shared/internal';
import { RuleCreatedDto } from './rules.service';
describe('RulesService', () => {
const now = DateTime.now();
const user = 'me';
const version = new Version('1');
beforeEach(() => {
@ -179,9 +179,9 @@ describe('RulesService', () => {
}
};
let rule: RuleDto;
let rule: Versioned<RuleCreatedDto>;
rulesService.postRule('my-app', dto, user, now).subscribe(result => {
rulesService.postRule('my-app', dto).subscribe(result => {
rule = result;
});
@ -190,28 +190,18 @@ describe('RulesService', () => {
expect(req.request.method).toEqual('POST');
expect(req.request.headers.get('If-Match')).toBeNull();
req.flush({ id: 'id1', sharedSecret: 'token1', schemaId: 'schema1' }, {
req.flush({ id: 'id1' }, {
headers: {
etag: '1'
}
});
expect(rule!).toEqual(
new RuleDto('id1', user, user, now, now,
version,
true,
{
param1: 1,
param2: 2,
triggerType: 'ContentChanged'
},
'ContentChanged',
{
param3: 3,
param4: 4,
actionType: 'Webhook'
},
'Webhook'));
expect(rule!).toEqual({
payload: {
id: 'id1'
},
version
});
}));
it('should make put request to update rule',

38
src/Squidex/app/shared/services/rules.service.ts

@ -15,6 +15,7 @@ import {
ApiUrlConfig,
DateTime,
HTTP,
mapVersioned,
Model,
pretifyError,
ResultSet,
@ -109,16 +110,18 @@ export class RuleEventDto extends Model<RuleEventDto> {
}
}
export interface CreateRuleDto {
readonly trigger: any;
readonly action: any;
export interface UpsertRuleDto {
readonly trigger: RuleAction;
readonly action: RuleAction;
}
export interface UpdateRuleDto {
readonly trigger?: any;
readonly action?: any;
export interface RuleCreatedDto {
readonly id: string;
}
export type RuleAction = { actionType: string } & any;
export type RuleTrigger = { triggerType: string } & any;
@Injectable()
export class RulesService {
constructor(
@ -190,33 +193,18 @@ export class RulesService {
pretifyError('Failed to load Rules. Please reload.'));
}
public postRule(appName: string, dto: CreateRuleDto, user: string, now: DateTime): Observable<RuleDto> {
public postRule(appName: string, dto: UpsertRuleDto): Observable<Versioned<RuleCreatedDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/rules`);
return HTTP.postVersioned<any>(this.http, url, dto).pipe(
map(({ version, payload }) => {
const body = payload.body;
return new RuleDto(
body.id,
user,
user,
now,
now,
version,
true,
dto.trigger,
dto.trigger.triggerType,
dto.action,
dto.action.actionType);
}),
return HTTP.postVersioned<RuleCreatedDto>(this.http, url, dto).pipe(
mapVersioned(({ body }) => body!),
tap(() => {
this.analytics.trackEvent('Rule', 'Created', appName);
}),
pretifyError('Failed to create rule. Please reload.'));
}
public putRule(appName: string, id: string, dto: UpdateRuleDto, version: Version): Observable<Versioned<any>> {
public putRule(appName: string, id: string, dto: Partial<UpsertRuleDto>, version: Version): Observable<Versioned<any>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/rules/${id}`);
return HTTP.putVersioned(this.http, url, dto, version).pipe(

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

@ -9,11 +9,9 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
import { inject, TestBed } from '@angular/core/testing';
import {
AddFieldDto,
AnalyticsService,
ApiUrlConfig,
createProperties,
CreateSchemaDto,
DateTime,
FieldDto,
NestedFieldDto,
@ -22,12 +20,12 @@ import {
SchemaDto,
SchemaPropertiesDto,
SchemasService,
Version
Version,
Versioned
} from '@app/shared/internal';
import { SchemaCreatedDto } from './schemas.service';
describe('SchemasService', () => {
const now = DateTime.now();
const user = 'me';
const version = new Version('1');
beforeEach(() => {
@ -330,11 +328,11 @@ describe('SchemasService', () => {
it('should make post request to create schema',
inject([SchemasService, HttpTestingController], (schemasService: SchemasService, httpMock: HttpTestingController) => {
const dto = new CreateSchemaDto('name', undefined, undefined, true);
const dto = { name: 'name' };
let schema: SchemaDetailsDto;
let schema: Versioned<SchemaCreatedDto>;
schemasService.postSchema('my-app', dto, user, now).subscribe(result => {
schemasService.postSchema('my-app', dto).subscribe(result => {
schema = result;
});
@ -347,11 +345,16 @@ describe('SchemasService', () => {
id: '1'
}, {
headers: {
etag: '2'
etag: '1'
}
});
expect(schema!).toEqual(new SchemaDetailsDto('1', dto.name, '', new SchemaPropertiesDto(), true, false, now, user, now, user, new Version('2'), [], {}, {}));
expect(schema!).toEqual({
payload: {
id: '1'
},
version
});
}));
it('should make put request to update schema',
@ -417,7 +420,7 @@ describe('SchemasService', () => {
it('should make post request to add field',
inject([SchemasService, HttpTestingController], (schemasService: SchemasService, httpMock: HttpTestingController) => {
const dto = new AddFieldDto('name', 'invariant', createProperties('Number'));
const dto = { name: 'name', partitioning: 'invariant', properties: createProperties('Number') };
let field: FieldDto;
@ -464,7 +467,7 @@ describe('SchemasService', () => {
it('should make post request to add nested field',
inject([SchemasService, HttpTestingController], (schemasService: SchemasService, httpMock: HttpTestingController) => {
const dto = new AddFieldDto('name', 'invariant', createProperties('Number'));
const dto = { name: 'name', partitioning: 'invariant', properties: createProperties('Number') };
let field: FieldDto;

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

@ -171,23 +171,21 @@ export class SchemaPropertiesDto {
}
}
export class AddFieldDto {
constructor(
public readonly name: string,
public readonly partitioning: string,
public readonly properties: FieldPropertiesDto
) {
}
export interface AddFieldDto {
readonly name: string;
readonly partitioning: string;
readonly properties: FieldPropertiesDto;
}
export class CreateSchemaDto {
constructor(
public readonly name: string,
public readonly fields?: RootFieldDto[],
public readonly properties?: SchemaPropertiesDto,
public readonly isSingleton?: boolean
) {
}
export interface CreateSchemaDto {
readonly name: string;
readonly fields?: RootFieldDto[];
readonly properties?: SchemaPropertiesDto;
readonly isSingleton?: boolean;
}
export interface SchemaCreatedDto {
readonly id: string;
}
export interface UpdateSchemaCategoryDto {
@ -303,28 +301,11 @@ export class SchemasService {
pretifyError('Failed to load schema. Please reload.'));
}
public postSchema(appName: string, dto: CreateSchemaDto, user: string, now: DateTime): Observable<SchemaDetailsDto> {
public postSchema(appName: string, dto: CreateSchemaDto): Observable<Versioned<SchemaCreatedDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/schemas`);
return HTTP.postVersioned<any>(this.http, url, dto).pipe(
map(({ version, payload }) => {
const body = payload.body;
now = now || DateTime.now();
const schema = new SchemaDetailsDto(
body.id,
dto.name, '',
dto.properties || new SchemaPropertiesDto(),
dto.isSingleton === true,
false,
now, user,
now, user,
version,
dto.fields || []);
return schema;
}),
mapVersioned(({ body }) => body!),
tap(() => {
this.analytics.trackEvent('Schema', 'Created', appName);
}),

3
src/Squidex/app/shared/state/_test-helpers.ts

@ -20,7 +20,6 @@ const creation = DateTime.today().addDays(-2);
const creator = 'me';
const modified = DateTime.now().addDays(-1);
const modifier = 'now-me';
const now = DateTime.now();
const version = new Version('1');
const newVersion = new Version('2');
@ -45,8 +44,6 @@ export const TestValues = {
creator,
modified,
modifier,
now,
newVersion,
userId: modifier,
version
};

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

@ -88,9 +88,9 @@ describe('AppsState', () => {
const request = { ...newApp };
appsService.setup(x => x.postApp(request))
.returns(() => of(newApp)).verifiable();
.returns(() => of({ ...newApp, permissions: ['Owner'] })).verifiable();
appsState.create(request).subscribe();
appsState.create(request, now).subscribe();
expect(appsState.snapshot.apps.values).toEqual([newApp, ...oldApps]);
});
@ -99,12 +99,12 @@ describe('AppsState', () => {
const request = { ...newApp };
appsService.setup(x => x.postApp(request))
.returns(() => of(newApp)).verifiable();
.returns(() => of({ ...newApp, permissions: ['Owner'] })).verifiable();
appsService.setup(x => x.deleteApp(newApp.name))
.returns(() => of({})).verifiable();
appsState.create(request).subscribe();
appsState.create(request, now).subscribe();
const appsAfterCreate = appsState.snapshot.apps.values;
@ -120,12 +120,12 @@ describe('AppsState', () => {
const request = { ...newApp };
appsService.setup(x => x.postApp(request))
.returns(() => of(newApp)).verifiable();
.returns(() => of({ ...newApp, permissions: ['Owner'] })).verifiable();
appsService.setup(x => x.deleteApp(newApp.name))
.returns(() => of({})).verifiable();
appsState.create(request).subscribe();
appsState.create(request, now).subscribe();
appsState.select(newApp.name).subscribe();
appsState.delete(newApp.name).subscribe();

22
src/Squidex/app/shared/state/apps.state.ts

@ -10,13 +10,16 @@ import { Observable, of } from 'rxjs';
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
import {
DateTime,
DialogService,
ImmutableArray,
Permission,
shareSubscribed,
State
} from '@app/framework';
import {
AppCreatedDto,
AppDto,
AppsService,
CreateAppDto
@ -79,11 +82,11 @@ export class AppsState extends State<Snapshot> {
shareSubscribed(this.dialogs));
}
public create(request: CreateAppDto): Observable<AppDto> {
public create(request: CreateAppDto, now?: DateTime): Observable<AppDto> {
return this.appsService.postApp(request).pipe(
tap(payload => {
this.next(s => {
const apps = s.apps.push(payload).sortByStringAsc(x => x.name);
const apps = s.apps.push(createApp(request, payload, now)).sortByStringAsc(x => x.name);
return { ...s, apps };
});
@ -104,4 +107,19 @@ export class AppsState extends State<Snapshot> {
}),
shareSubscribed(this.dialogs));
}
}
function createApp(request: CreateAppDto, response: AppCreatedDto, now?: DateTime) {
now = now || DateTime.now();
const app = new AppDto(
response.id,
request.name,
response.permissions.map(x => new Permission(x)),
now,
now,
response.planName,
response.planUpgrade);
return app;
}

26
src/Squidex/app/shared/state/asset-uploader.state.spec.ts

@ -31,9 +31,7 @@ describe('AssetsState', () => {
creator,
creation,
modified,
modifier,
now,
userId
modifier
} = TestValues;
let assetsService: IMock<AssetsService>;
@ -74,10 +72,10 @@ describe('AssetsState', () => {
it('should create initial state when uploading file', () => {
const file: File = <any>{ name: 'my-file' };
assetsService.setup(x => x.uploadFile(app, file, userId, now))
assetsService.setup(x => x.uploadFile(app, file, modifier, modified))
.returns(() => never()).verifiable();
assetUploader.uploadFile(file, undefined, now).subscribe();
assetUploader.uploadFile(file, undefined, modified).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);
@ -88,10 +86,10 @@ describe('AssetsState', () => {
it('should update progress when uploading file makes progress', () => {
const file: File = <any>{ name: 'my-file' };
assetsService.setup(x => x.uploadFile(app, file, userId, now))
assetsService.setup(x => x.uploadFile(app, file, modifier, modified))
.returns(() => ofForever(10, 20)).verifiable();
assetUploader.uploadFile(file, undefined, now).subscribe();
assetUploader.uploadFile(file, undefined, modified).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);
@ -102,10 +100,10 @@ describe('AssetsState', () => {
it('should update status when uploading file failed', () => {
const file: File = <any>{ name: 'my-file' };
assetsService.setup(x => x.uploadFile(app, file, userId, now))
assetsService.setup(x => x.uploadFile(app, file, modifier, modified))
.returns(() => throwError('Error')).verifiable();
assetUploader.uploadFile(file, undefined, now).pipe(onErrorResumeNext()).subscribe();
assetUploader.uploadFile(file, undefined, modified).pipe(onErrorResumeNext()).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);
@ -116,12 +114,12 @@ describe('AssetsState', () => {
it('should update status when uploading file completes', (cb) => {
const file: File = <any>{ name: 'my-file' };
assetsService.setup(x => x.uploadFile(app, file, userId, now))
assetsService.setup(x => x.uploadFile(app, file, modifier, modified))
.returns(() => of(10, 20, asset)).verifiable();
let uploadedAsset: AssetDto;
assetUploader.uploadFile(file, undefined, now).subscribe(dto => {
assetUploader.uploadFile(file, undefined, modified).subscribe(dto => {
if (Types.is(dto, AssetDto)) {
uploadedAsset = dto;
}
@ -142,7 +140,7 @@ describe('AssetsState', () => {
assetsService.setup(x => x.replaceFile(app, asset.id, file, asset.version))
.returns(() => never()).verifiable();
assetUploader.uploadAsset(asset, file, now).subscribe();
assetUploader.uploadAsset(asset, file, modified).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);
@ -156,7 +154,7 @@ describe('AssetsState', () => {
assetsService.setup(x => x.replaceFile(app, asset.id, file, asset.version))
.returns(() => ofForever(10, 20)).verifiable();
assetUploader.uploadAsset(asset, file, now).subscribe();
assetUploader.uploadAsset(asset, file, modified).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);
@ -170,7 +168,7 @@ describe('AssetsState', () => {
assetsService.setup(x => x.replaceFile(app, asset.id, file, asset.version))
.returns(() => throwError('Error')).verifiable();
assetUploader.uploadAsset(asset, file, now).pipe(onErrorResumeNext()).subscribe();
assetUploader.uploadAsset(asset, file, modified).pipe(onErrorResumeNext()).subscribe();
const upload = assetUploader.snapshot.uploads.at(0);

30
src/Squidex/app/shared/state/comments.state.spec.ts

@ -25,14 +25,14 @@ describe('CommentsState', () => {
app,
appsState,
creator,
now
modified
} = TestValues;
const commentsId = 'my-comments';
const oldComments = new CommentsDto([
new CommentDto('1', now, 'text1', creator),
new CommentDto('2', now, 'text2', creator)
new CommentDto('1', modified, 'text1', creator),
new CommentDto('2', modified, 'text2', creator)
], [], [], new Version('1'));
let dialogs: IMock<DialogService>;
@ -53,9 +53,9 @@ describe('CommentsState', () => {
describe('Loading', () => {
it('should load and merge comments', () => {
const newComments = new CommentsDto([
new CommentDto('3', now, 'text3', creator)
new CommentDto('3', modified, 'text3', creator)
], [
new CommentDto('2', now, 'text2_2', creator)
new CommentDto('2', modified, 'text2_2', creator)
], ['1'], new Version('2'));
commentsService.setup(x => x.getComments(app, commentsId, new Version('-1')))
@ -69,8 +69,8 @@ describe('CommentsState', () => {
expect(commentsState.snapshot.isLoaded).toBeTruthy();
expect(commentsState.snapshot.comments).toEqual(ImmutableArray.of([
new CommentDto('2', now, 'text2_2', creator),
new CommentDto('3', now, 'text3', creator)
new CommentDto('2', modified, 'text2_2', creator),
new CommentDto('3', modified, 'text3', creator)
]));
});
});
@ -84,7 +84,7 @@ describe('CommentsState', () => {
});
it('should add comment to snapshot when created', () => {
const newComment = new CommentDto('3', now, 'text3', creator);
const newComment = new CommentDto('3', modified, 'text3', creator);
const request = { text: 'text3' };
@ -94,9 +94,9 @@ describe('CommentsState', () => {
commentsState.create('text3').subscribe();
expect(commentsState.snapshot.comments).toEqual(ImmutableArray.of([
new CommentDto('1', now, 'text1', creator),
new CommentDto('2', now, 'text2', creator),
new CommentDto('3', now, 'text3', creator)
new CommentDto('1', modified, 'text1', creator),
new CommentDto('2', modified, 'text2', creator),
new CommentDto('3', modified, 'text3', creator)
]));
});
@ -106,11 +106,11 @@ describe('CommentsState', () => {
commentsService.setup(x => x.putComment(app, commentsId, '2', request))
.returns(() => of({})).verifiable();
commentsState.update(oldComments.createdComments[1], 'text2_2', now).subscribe();
commentsState.update(oldComments.createdComments[1], 'text2_2', modified).subscribe();
expect(commentsState.snapshot.comments).toEqual(ImmutableArray.of([
new CommentDto('1', now, 'text1', creator),
new CommentDto('2', now, 'text2_2', creator)
new CommentDto('1', modified, 'text1', creator),
new CommentDto('2', modified, 'text2_2', creator)
]));
});
@ -121,7 +121,7 @@ describe('CommentsState', () => {
commentsState.delete(oldComments.createdComments[1]).subscribe();
expect(commentsState.snapshot.comments).toEqual(ImmutableArray.of([
new CommentDto('1', now, 'text1', creator)
new CommentDto('1', modified, 'text1', creator)
]));
});
});

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

@ -23,14 +23,14 @@ describe('ContributorsState', () => {
app,
appsState,
authService,
modifier,
newVersion,
userId,
version
} = TestValues;
const oldContributors = [
new ContributorDto('id1', 'Developer'),
new ContributorDto(userId, 'Developer')
new ContributorDto(modifier, 'Developer')
];
let dialogs: IMock<DialogService>;
@ -109,7 +109,7 @@ describe('ContributorsState', () => {
});
it('should update contributor in snapshot when assigned and already added', () => {
const newContributor = new ContributorDto(userId, 'Owner');
const newContributor = new ContributorDto(modifier, 'Owner');
const request = { ...newContributor };
const response = { contributorId: newContributor.contributorId, isCreated: true };

10
src/Squidex/app/shared/state/rules.state.spec.ts

@ -87,14 +87,14 @@ describe('RulesState', () => {
});
it('should add rule to snapshot when created', () => {
const newRule = new RuleDto('id3', creator, creator, creation, creation, version, false, {}, 'trigger3', {}, 'action3');
const newRule = new RuleDto('id3', modifier, modifier, modified, modified, version, true, { value: 3 }, 'trigger3', { value: 1 }, 'action3');
const request = { action: {}, trigger: {} };
const request = { trigger: { triggerType: 'trigger3', value: 3 }, action: { actionType: 'action3', value: 1 } };
rulesService.setup(x => x.postRule(app, request, modifier, creation))
.returns(() => of(newRule));
rulesService.setup(x => x.postRule(app, request))
.returns(() => of(versioned(version, { id: 'id3' })));
rulesState.create(request, creation).subscribe();
rulesState.create(request, modified).subscribe();
expect(rulesState.snapshot.rules.values).toEqual([...oldRules, newRule]);
});

39
src/Squidex/app/shared/state/rules.state.ts

@ -15,16 +15,18 @@ import {
ImmutableArray,
shareSubscribed,
State,
Version
Version,
Versioned
} from '@app/framework';
import { AuthService} from './../services/auth.service';
import { AppsState } from './apps.state';
import {
CreateRuleDto,
RuleCreatedDto,
RuleDto,
RulesService
RulesService,
UpsertRuleDto
} from './../services/rules.service';
interface Snapshot {
@ -76,11 +78,11 @@ export class RulesState extends State<Snapshot> {
shareSubscribed(this.dialogs));
}
public create(request: CreateRuleDto, now?: DateTime): Observable<RuleDto> {
return this.rulesService.postRule(this.appName, request, this.user, now || DateTime.now()).pipe(
tap(rule => {
public create(request: UpsertRuleDto, now?: DateTime): Observable<RuleDto> {
return this.rulesService.postRule(this.appName, request).pipe(
tap(response => {
this.next(s => {
const rules = s.rules.push(rule);
const rules = s.rules.push(createRule(request, response, this.user, now));
return { ...s, rules };
});
@ -178,3 +180,26 @@ const setEnabled = (rule: RuleDto, isEnabled: boolean, user: string, version: Ve
lastModifiedBy: user,
version
});
function createRule(request: UpsertRuleDto, { payload, version }: Versioned<RuleCreatedDto>, user: string, now?: DateTime) {
now = now || DateTime.now();
const { triggerType, ...trigger } = request.trigger;
const { actionType, ...action } = request.action;
const rule = new RuleDto(
payload.id,
user,
user,
now,
now,
version,
true,
trigger,
triggerType,
action,
actionType);
return rule;
}

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

@ -11,14 +11,13 @@ import { IMock, It, Mock, Times } from 'typemoq';
import { SchemasState } from './schemas.state';
import {
AddFieldDto,
createProperties,
CreateSchemaDto,
DialogService,
NestedFieldDto,
RootFieldDto,
SchemaDetailsDto,
SchemaDto,
SchemaPropertiesDto,
SchemasService,
UpdateSchemaCategoryDto,
versioned
@ -298,17 +297,17 @@ describe('SchemasState', () => {
});
it('should add schema to snapshot when created', () => {
const request = new CreateSchemaDto('newName');
const request = { name: 'newName' };
const result = new SchemaDetailsDto('id4', 'newName', '', {}, false, false, modified, modifier, modified, modifier, version);
const result = new SchemaDetailsDto('id4', 'newName', '', new SchemaPropertiesDto(), false, false, modified, modifier, modified, modifier, version);
schemasService.setup(x => x.postSchema(app, request, modifier, modified))
.returns(() => of(result)).verifiable();
schemasService.setup(x => x.postSchema(app, request))
.returns(() => of(versioned(version, { id: 'id4' }))).verifiable();
schemasState.create(request, modified).subscribe();
expect(schemasState.snapshot.schemas.values.length).toBe(3);
expect(schemasState.snapshot.schemas.at(2)).toBe(result);
expect(schemasState.snapshot.schemas.at(2)).toEqual(result);
});
it('should remove schema from snapshot when deleted', () => {
@ -322,7 +321,7 @@ describe('SchemasState', () => {
});
it('should add field and update user info when field added', () => {
const request = new AddFieldDto(field1.name, field1.partitioning, field1.properties);
const request = { ...field1 };
const newField = new RootFieldDto(3, '3', createProperties('String'), 'invariant');
@ -338,7 +337,7 @@ describe('SchemasState', () => {
});
it('should add field and update user info when nested field added', () => {
const request = new AddFieldDto(field1.name, field1.partitioning, field1.properties);
const request = { ...field1 };
const newField = new NestedFieldDto(3, '3', createProperties('String'), 2);

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

@ -17,7 +17,8 @@ import {
shareSubscribed,
State,
Types,
Version
Version,
Versioned
} from '@app/framework';
import { AuthService } from './../services/auth.service';
@ -29,6 +30,7 @@ import {
FieldDto,
NestedFieldDto,
RootFieldDto,
SchemaCreatedDto,
SchemaDetailsDto,
SchemaDto,
SchemaPropertiesDto,
@ -136,10 +138,10 @@ export class SchemasState extends State<Snapshot> {
}
public create(request: CreateSchemaDto, now?: DateTime): Observable<SchemaDetailsDto> {
return this.schemasService.postSchema(this.appName, request, this.user, now || DateTime.now()).pipe(
tap(payload => {
return this.schemasService.postSchema(this.appName, request).pipe(
tap(response => {
this.next(s => {
const schemas = s.schemas.push(payload).sortByStringAsc(x => x.displayName);
const schemas = s.schemas.push(createSchema(request, response, this.user, now)).sortByStringAsc(x => x.displayName);
return { ...s, schemas };
});
@ -513,4 +515,21 @@ const pidof = <T extends FieldDto>(field: T) =>
Types.is(field, NestedFieldDto) ? field.parentId : undefined;
const pid = (field?: RootFieldDto) =>
field ? field.fieldId : undefined;
field ? field.fieldId : undefined;
function createSchema(request: CreateSchemaDto, { payload, version }: Versioned<SchemaCreatedDto>, user: string, now?: DateTime) {
now = now || DateTime.now();
const schema = new SchemaDetailsDto(
payload.id,
request.name, '',
request.properties || new SchemaPropertiesDto(),
request.isSingleton === true,
false,
now, user,
now, user,
version,
request.fields || []);
return schema;
}

24
src/Squidex/package-lock.json

@ -1670,9 +1670,9 @@
"dev": true
},
"@types/node": {
"version": "11.13.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.8.tgz",
"integrity": "sha512-szA3x/3miL90ZJxUCzx9haNbK5/zmPieGraZEe4WI+3srN0eGLiT22NXeMHmyhNEopn+IrxqMc7wdVwvPl8meg==",
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.0.tgz",
"integrity": "sha512-Jrb/x3HT4PTJp6a4avhmJCDEVrPdqLfl3e8GGMbpkGGdwAV5UGlIs4vVEfsHHfylZVOKZWpOqmqFH8CbfOZ6kg==",
"dev": true
},
"@types/prop-types": {
@ -1688,9 +1688,9 @@
"dev": true
},
"@types/react": {
"version": "16.8.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.14.tgz",
"integrity": "sha512-26tFVJ1omGmzIdFTFmnC5zhz1GTaqCjxgUxV4KzWvsybF42P7/j4RBn6UeO3KbHPXqKWZszMXMoI65xIWm954A==",
"version": "16.8.16",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.16.tgz",
"integrity": "sha512-A0+6kS6zwPtvubOLiCJmZ8li5bm3wKIkoKV0h3RdMDOnCj9cYkUnj3bWbE03/lcICdQmwBmUfoFiHeNhbFiyHQ==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@ -15023,9 +15023,9 @@
}
},
"ts-loader": {
"version": "5.4.4",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.4.tgz",
"integrity": "sha512-haLwWMts/tCruBFbLUWOR9hZezZ89TMW3EntrAEtYARDnPZSQt6dPA5tN3fvlsmUIYXVWDHO5SUhw8ndAomVlw==",
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz",
"integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
@ -18772,9 +18772,9 @@
"dev": true
},
"zone.js": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.9.0.tgz",
"integrity": "sha512-EfygvVnLxPSCMSgJ4h7SoY+XNr7ybdwvvwEQ70lvMFl9coNnciXSyWi8Kg6znK1ubyUSffkCKvleSQpLuUKw0Q=="
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.9.1.tgz",
"integrity": "sha512-GkPiJL8jifSrKReKaTZ5jkhrMEgXbXYC+IPo1iquBjayRa0q86w3Dipjn8b415jpitMExe9lV8iTsv8tk3DGag=="
}
}
}

8
src/Squidex/package.json

@ -44,7 +44,7 @@
"slugify": "1.3.4",
"sortablejs": "1.9.0",
"tslib": "1.9.3",
"zone.js": "0.9.0"
"zone.js": "0.9.1"
},
"devDependencies": {
"@angular/compiler": "7.2.14",
@ -54,8 +54,8 @@
"@types/jasmine": "3.3.12",
"@types/marked": "0.6.5",
"@types/mousetrap": "1.6",
"@types/node": "11.13.8",
"@types/react": "16.8.14",
"@types/node": "12.0.0",
"@types/react": "16.8.16",
"@types/react-dom": "16.8.4",
"@types/sortablejs": "1.7.2",
"angular-router-loader": "0.8.5",
@ -91,7 +91,7 @@
"sass-lint": "1.13.1",
"sass-loader": "7.1.0",
"style-loader": "0.23.1",
"ts-loader": "^5.4.4",
"ts-loader": "5.4.5",
"tsconfig-paths-webpack-plugin": "3.2.0",
"tslint": "5.16.0",
"tslint-webpack-plugin": "2.0.4",

4
src/Squidex/tslint.json

@ -65,6 +65,7 @@
],
"no-input-rename": false,
"no-output-rename": false,
"no-pipe-impure": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-switch-case-fall-through": true,
@ -103,7 +104,8 @@
true,
"always"
],
"templates-no-negated-async": true,
"template-no-negated-async": true,
"template-use-track-by-function": true,
"trailing-comma": [
true,
{

Loading…
Cancel
Save