Browse Source

State updated

pull/271/head
Sebastian Stehle 8 years ago
parent
commit
af97cb3831
  1. 13
      src/Squidex/app/features/administration/pages/users/user-page.component.ts
  2. 70
      src/Squidex/app/features/administration/state/users.state.ts
  3. 2
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts
  4. 8
      src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts
  5. 344
      src/Squidex/app/features/schemas/state/schemas.state.ts

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

@ -11,7 +11,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { UserDto } from './../../services/users.service';
import { UserForm, UsersState, getSelectedUser } from './../../state/users.state';
import { UserForm, UsersState } from './../../state/users.state';
@Component({
selector: 'sqx-user-page',
@ -25,7 +25,7 @@ export class UserPageComponent implements OnDestroy, OnInit {
public userForm: UserForm;
public selectedUser =
this.usersState.changes.map(getSelectedUser)
this.usersState.changes.map(x => x.selectedUser)
.distinctUntilChanged();
public isCurrentUser =
@ -46,10 +46,11 @@ export class UserPageComponent implements OnDestroy, OnInit {
public ngOnInit() {
this.selectedUserSubscription =
this.usersState.changes.map(getSelectedUser).subscribe(user => {
this.user = user;
this.userForm.load(user);
});
this.usersState.changes.map(x => x.selectedUser)
.subscribe(user => {
this.user = user;
this.userForm.load(user);
});
}
public save() {

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

@ -14,6 +14,7 @@ import '@app/framework/utils/rxjs-extensions';
import {
AuthService,
DialogService,
ImmutableArray,
Pager,
Form,
State,
@ -23,7 +24,8 @@ import {
import {
CreateUserDto,
UserDto,
UsersService
UsersService,
UpdateUserDto
} from './../services/users.service';
export class UserForm extends Form<FormGroup> {
@ -69,10 +71,10 @@ export class UserForm extends Form<FormGroup> {
}
interface Snapshot {
users: UserDto[];
users: ImmutableArray<UserDto>;
usersPager: Pager;
usersQuery?: string;
selectedUserId?: string | null;
selectedUser?: UserDto;
isCurrentUser?: boolean;
}
@ -83,15 +85,15 @@ export class UsersState extends State<Snapshot> {
private readonly dialogs: DialogService,
private readonly usersService: UsersService
) {
super({ users: [], usersPager: new Pager(10) });
super({ users: ImmutableArray.empty(), usersPager: new Pager(10) });
}
public selectUser(selectedUserId: string | null): Observable<UserDto | null> {
return this.loadUser(selectedUserId)
.do(user => {
const isCurrentUser = selectedUserId === this.authState.user!.id;
public selectUser(id: string | null): Observable<UserDto | null> {
return this.loadUser(id)
.do(selectedUser => {
const isCurrentUser = id === this.authState.user!.id;
this.next(s => ({...s, selectedUserId, isCurrentUser }));
this.next(s => ({...s, selectedUser, isCurrentUser }));
});
}
@ -111,26 +113,26 @@ export class UsersState extends State<Snapshot> {
public loadUsers(notify = false): Observable<any> {
return this.usersService.getUsers(this.snapshot.usersPager.pageSize, this.snapshot.usersPager.skip, this.snapshot.usersQuery)
.catch(error => this.dialogs.notifyError(error))
.do(dtos => {
if (notify) {
this.dialogs.notifyInfo('Users reloaded.');
}
this.next(s => {
const users = dtos.items;
const users = ImmutableArray.of(dtos.items);
const usersPager = s.usersPager.setCount(dtos.total);
return { ...s, users, usersPager, usersLoading: false };
});
});
})
.catch(error => this.dialogs.notifyError(error));
}
public createUser(request: CreateUserDto): Observable<UserDto> {
return this.usersService.postUser(request)
.do(dto => {
this.next(s => {
const users = [dto, ...s.users];
const users = s.users.pushFront(dto);
const usersPager = s.usersPager.incrementCount();
return { ...s, users, usersPager };
@ -143,36 +145,24 @@ export class UsersState extends State<Snapshot> {
.do(() => {
this.dialogs.notifyInfo('User saved successsfull');
this.next(s => {
const users = s.users.map(u => u.id === user.id ? u.update(request.email, request.displayName) : u);
return { ...s, users };
});
this.replaceUser(update(user, request));
});
}
public lockUser(user: UserDto): Observable<any> {
return this.usersService.lockUser(user.id)
.catch(error => this.dialogs.notifyError(error))
.do(() => {
this.next(s => {
const users = s.users.map(u => u.id === user.id ? u.lock() : u);
return { ...s, users };
});
});
this.replaceUser(setLocked(user, true));
})
.catch(error => this.dialogs.notifyError(error));
}
public unlockUser(user: UserDto): Observable<any> {
return this.usersService.unlockUser(user.id)
.catch(error => this.dialogs.notifyError(error))
.do(() => {
this.next(s => {
const users = s.users.map(u => u.id === user.id ? u.unlock() : u);
return { ...s, users };
});
});
this.replaceUser(setLocked(user, false));
})
.catch(error => this.dialogs.notifyError(error));
}
public search(query: string): Observable<any> {
@ -192,6 +182,20 @@ export class UsersState extends State<Snapshot> {
return this.loadUsers();
}
private replaceUser(user: UserDto) {
return this.next(s => {
const users = s.users.replaceBy('id', user);
const selectedUser = s.selectedUser && s.selectedUser.id === user.id ? user : s.selectedUser;
return { ...s, users, selectedUser };
});
}
}
export const getSelectedUser = (c: Snapshot) => c.users.find(x => x.id === c.selectedUserId);
const update = (user: UserDto, request: UpdateUserDto) =>
new UserDto(user.id, request.email, request.displayName, user.pictureUrl, user.isLocked);
const setLocked = (user: UserDto, locked: boolean) =>
new UserDto(user.id, user.email, user.displayName, user.pictureUrl, locked);

2
src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts

@ -65,7 +65,7 @@ export class SchemaPageComponent implements OnDestroy, OnInit {
public ngOnInit() {
this.selectedSchemaSubscription =
this.schemasState.selectedSchema
this.schemasState.changes.map(x => x.selectedSchema)
.subscribe(schema => {
this.schema = schema!;

8
src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts

@ -32,14 +32,14 @@ export class SchemasPageComponent implements OnDestroy, OnInit {
public schemasFilter = new FormControl();
public schemasFiltered =
this.schemasState.schemasItems
this.schemasState.changes.map(x => x.schemas)
.combineLatest(this.schemasFilter.valueChanges.startWith(''),
(schemas, query) => {
if (query && query.length > 0) {
schemas = schemas.filter(t => t.name.indexOf(query) >= 0);
return schemas.filter(t => t.name.indexOf(query) >= 0);
} else {
return schemas;
}
return schemas.sortByStringAsc(x => x.name);
});
public import: any;

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

@ -7,7 +7,7 @@
import { Injectable } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs';
import { Observable } from 'rxjs';
import '@app/framework/utils/rxjs-extensions';
@ -25,10 +25,14 @@ import {
SchemaDto,
SchemaDetailsDto,
SchemasService,
State,
UpdateFieldDto,
UpdateSchemaScriptsDto,
UpdateSchemaDto,
ValidatorsEx
ValidatorsEx,
Version,
SchemaPropertiesDto,
FieldPropertiesDto
} from '@app/shared';
const FALLBACK_NAME = 'my-schema';
@ -133,21 +137,13 @@ export class AddFieldForm extends Form<FormGroup> {
}
}
@Injectable()
export class SchemasState {
public schemasItems = new BehaviorSubject<ImmutableArray<SchemaDto>>(ImmutableArray.empty());
public selectedSchema = new BehaviorSubject<SchemaDetailsDto | null>(null);
public selectedReferencedSchema = new BehaviorSubject<SchemaDetailsDto | null>(null);
public get schemaName() {
return this.selectedSchema.value!.name;
}
public get referencedSchemaName() {
return this.selectedReferencedSchema.value!.name;
}
interface Snapshot {
schemas: ImmutableArray<SchemaDto>;
selectedSchema?: SchemaDetailsDto | null;
}
@Injectable()
export class SchemasState extends State<Snapshot> {
private get appName() {
return this.appsState.appName;
}
@ -157,31 +153,29 @@ export class SchemasState {
}
constructor(
private readonly schemasService: SchemasService,
private readonly dialogs: DialogService,
private readonly appsState: AppsState,
private readonly authState: AuthService,
private readonly appsState: AppsState
private readonly dialogs: DialogService,
private readonly schemasService: SchemasService
) {
super({ schemas: ImmutableArray.of() });
}
public selectSchema(id: string | null): Observable<SchemaDetailsDto | null> {
return this.loadSchema(id)
public selectSchema(selectedSchemaId: string | null): Observable<SchemaDetailsDto | null> {
return this.loadSchema(selectedSchemaId)
.do(schema => {
this.selectedSchema.next(schema);
});
}
this.next(s => {
const schemas = schema ? s.schemas.replaceBy('id', schema) : s.schemas;
public selectReferencedSchema(id: string | null): Observable<SchemaDetailsDto | null> {
return this.loadSchema(id)
.do(schema => {
this.selectedReferencedSchema.next(schema);
return { ...s, selectedSchemaId, schemas };
});
});
}
private loadSchema(id: string | null) {
return !id ?
Observable.of(null) :
Observable.of(<SchemaDetailsDto>this.schemasItems.value.find(x => x.id === id && x instanceof SchemaDetailsDto))
Observable.of(<SchemaDetailsDto>this.snapshot.schemas.find(x => x.id === id && x instanceof SchemaDetailsDto))
.switchMap(schema => {
if (!schema) {
return this.schemasService.getSchema(this.appName, id).catch(() => Observable.of(null));
@ -193,144 +187,312 @@ export class SchemasState {
public load(): Observable<any> {
return this.schemasService.getSchemas(this.appName)
.catch(error => this.dialogs.notifyError(error))
.do(dtos => {
this.schemasItems.nextBy(v => ImmutableArray.of(dtos));
});
return this.next(s => {
const schemas = ImmutableArray.of(dtos).sortByStringAsc(x => x.displayName);
return { ...s, schemas };
});
})
.catch(error => this.dialogs.notifyError(error));
}
public delete(schema: SchemaDto): Observable<any> {
return this.schemasService.deleteSchema(this.appName, schema.name, schema.version)
.do(dto => {
return this.next(s => {
const schemas = s.schemas.filter(x => x.id !== schema.id);
return { ...s, schemas };
});
})
.catch(error => this.dialogs.notifyError(error));
}
public create(request: CreateSchemaDto) {
return this.schemasService.postSchema(this.appName, request, this.user, DateTime.now())
.do(dto => {
this.schemasItems.nextBy(v => v.push(dto));
return this.next(s => {
const schemas = s.schemas.push(dto).sortByStringAsc(x => x.displayName);
return { ...s, schemas };
});
});
}
public addField(schema: SchemaDetailsDto, request: AddFieldDto): Observable<FieldDto> {
return this.schemasService.postField(this.appName, schema.name, request, schema.version)
.do(dto => {
this.replaceSchema(schema.addField(dto.payload, this.user, dto.version));
this.replaceSchema(addField(schema, dto.payload, this.user, dto.version));
}).map(d => d.payload);
}
public publish(schema: SchemaDto): Observable<any> {
return this.schemasService.publishSchema(this.appName, schema.name, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.publish(this.user, dto.version));
});
this.replaceSchema(setPublished(schema, true, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public unpublish(schema: SchemaDto): Observable<any> {
return this.schemasService.unpublishSchema(this.appName, schema.name, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.unpublish(this.user, dto.version));
});
this.replaceSchema(setPublished(schema, true, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public enableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.enableField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.enable(), this.user, dto.version));
});
this.replaceSchema(updateField(schema, setDisabled(field, false), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public disableField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.disableField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.disable(), this.user, dto.version));
});
this.replaceSchema(updateField(schema, setDisabled(field, true), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public lockField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.lockField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.lock(), this.user, dto.version));
});
this.replaceSchema(updateField(schema, setLocked(field, true), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public showField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.showField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.show(), this.user, dto.version));
});
this.replaceSchema(updateField(schema, setHidden(field, false), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public hideField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.hideField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.hide(), this.user, dto.version));
});
this.replaceSchema(updateField(schema, setHidden(field, true), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public deleteField(schema: SchemaDetailsDto, field: FieldDto): Observable<any> {
return this.schemasService.deleteField(this.appName, schema.name, field.fieldId, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.removeField(field, this.user, dto.version));
});
this.replaceSchema(removeField(schema, field, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public sortFields(schema: SchemaDetailsDto, fields: FieldDto[]): Observable<any> {
return this.schemasService.putFieldOrdering(this.appName, schema.name, fields.map(t => t.fieldId), schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.replaceFields(fields, this.user, dto.version));
});
this.replaceSchema(replaceFields(schema, fields, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public updateField(schema: SchemaDetailsDto, field: FieldDto, request: UpdateFieldDto): Observable<any> {
return this.schemasService.putField(this.appName, schema.name, field.fieldId, request, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.updateField(field.update(request.properties), this.user, dto.version));
});
this.replaceSchema(updateField(schema, update(field, request.properties), this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public configureScripts(schema: SchemaDetailsDto, request: UpdateSchemaScriptsDto): Observable<any> {
return this.schemasService.putSchemaScripts(this.appName, schema.name, request, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.configureScripts(request, this.user, dto.version));
});
this.replaceSchema(configureScripts(schema, request, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
public update(schema: SchemaDetailsDto, request: UpdateSchemaDto): Observable<any> {
return this.schemasService.putSchema(this.appName, schema.name, request, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.replaceSchema(schema.update(request, this.user, dto.version));
});
}
public delete(schema: SchemaDto): Observable<any> {
return this.schemasService.deleteSchema(this.appName, schema.name, schema.version)
.catch(error => this.dialogs.notifyError(error))
.do(dto => {
this.schemasItems.nextBy(v => v.filter(s => s.id !== schema.id));
});
this.replaceSchema(updateProperties(schema, request, this.user, dto.version));
})
.catch(error => this.dialogs.notifyError(error));
}
private replaceSchema(schema: SchemaDto) {
this.schemasItems.nextBy(v => v.replaceBy('id', schema));
if (schema instanceof SchemaDetailsDto) {
this.selectedSchema.nextBy(v => v !== null && v.id === schema.id ? schema : v);
this.selectedReferencedSchema.nextBy(v => v !== null && v.id === schema.id ? schema : v);
}
}
return this.next(s => {
const schemas = s.schemas.replaceBy('id', schema).sortByStringAsc(x => x.displayName);
const selectedSchema = s.selectedSchema && s.selectedSchema.id === schema.id ? schema : s.selectedSchema;
public trackBySchema(index: number, schema: SchemaDto): any {
return schema.id;
return { ...s, schemas, selectedSchema };
});
}
}
public trackByField(index: number, field: FieldDto): any {
return field.fieldId;
}
}
const setPublished = (schema: SchemaDto | SchemaDetailsDto, publish: boolean, user: string, version: Version, now?: DateTime) => {
if (schema instanceof SchemaDetailsDto) {
return new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
true,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
schema.fields,
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
} else {
return new SchemaDto(
schema.id,
schema.name,
schema.properties,
true,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version);
}
};
const configureScripts = (schema: SchemaDetailsDto, scripts: UpdateSchemaScriptsDto, user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
schema.fields,
scripts.scriptQuery,
scripts.scriptCreate,
scripts.scriptUpdate,
scripts.scriptDelete,
scripts.scriptChange);
const updateProperties = (schema: SchemaDetailsDto, properties: SchemaPropertiesDto, user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
schema.fields,
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
const addField = (schema: SchemaDetailsDto, field: FieldDto, user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
[...schema.fields, field],
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
const updateField = (schema: SchemaDetailsDto, field: FieldDto, user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
schema.fields.map(f => f.fieldId === field.fieldId ? field : f),
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
const replaceFields = (schema: SchemaDetailsDto, fields: FieldDto[], user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
fields,
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
const removeField = (schema: SchemaDetailsDto, field: FieldDto, user: string, version: Version, now?: DateTime) =>
new SchemaDetailsDto(
schema.id,
schema.name,
schema.properties,
schema.isPublished,
schema.createdBy, user,
schema.created, now || DateTime.now(),
version,
schema.fields.filter(f => f.fieldId !== field.fieldId),
schema.scriptQuery,
schema.scriptCreate,
schema.scriptUpdate,
schema.scriptDelete,
schema.scriptChange);
const setLocked = (field: FieldDto, isLocked: boolean) =>
new FieldDto(
field.fieldId,
field.name,
isLocked,
field.isHidden,
field.isDisabled,
field.partitioning,
field.properties);
const setHidden = (field: FieldDto, isHidden: boolean) =>
new FieldDto(
field.fieldId,
field.name,
field.isLocked,
isHidden,
field.isDisabled,
field.partitioning,
field.properties);
const setDisabled = (field: FieldDto, isDisabled: boolean) =>
new FieldDto(
field.fieldId,
field.name,
field.isLocked,
field.isDisabled,
isDisabled,
field.partitioning,
field.properties);
const update = (field: FieldDto, properties: FieldPropertiesDto) =>
new FieldDto(
field.fieldId,
field.name,
field.isLocked,
field.isHidden,
field.isDisabled,
field.partitioning,
properties);
Loading…
Cancel
Save