mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
6.5 KiB
233 lines
6.5 KiB
/*
|
|
* Squidex Headless CMS
|
|
*
|
|
* @license
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
|
|
*/
|
|
|
|
import { Injectable } from '@angular/core';
|
|
import { FormBuilder, Validators, FormGroup } from '@angular/forms';
|
|
import { Observable } from 'rxjs';
|
|
|
|
import '@app/framework/utils/rxjs-extensions';
|
|
|
|
import {
|
|
AuthService,
|
|
DialogService,
|
|
ImmutableArray,
|
|
Pager,
|
|
Form,
|
|
State,
|
|
ValidatorsEx
|
|
} from '@app/shared';
|
|
|
|
import {
|
|
CreateUserDto,
|
|
UserDto,
|
|
UsersService,
|
|
UpdateUserDto
|
|
} from './../services/users.service';
|
|
|
|
export class UserForm extends Form<FormGroup> {
|
|
constructor(
|
|
formBuilder: FormBuilder
|
|
) {
|
|
super(formBuilder.group({
|
|
email: ['',
|
|
[
|
|
Validators.email,
|
|
Validators.required,
|
|
Validators.maxLength(100)
|
|
]
|
|
],
|
|
displayName: ['',
|
|
[
|
|
Validators.required,
|
|
Validators.maxLength(100)
|
|
]
|
|
],
|
|
password: ['',
|
|
[
|
|
Validators.nullValidator
|
|
]
|
|
],
|
|
passwordConfirm: ['',
|
|
[
|
|
ValidatorsEx.match('password', 'Passwords must be the same.')
|
|
]
|
|
]
|
|
}));
|
|
}
|
|
|
|
public load(user?: UserDto) {
|
|
if (user) {
|
|
this.form.controls['password'].setValidators(null);
|
|
} else {
|
|
this.form.controls['password'].setValidators(Validators.required);
|
|
}
|
|
|
|
super.load(user);
|
|
}
|
|
}
|
|
|
|
interface SnapshotUser {
|
|
user: UserDto;
|
|
|
|
isCurrentUser: boolean;
|
|
}
|
|
|
|
interface Snapshot {
|
|
users: ImmutableArray<SnapshotUser>;
|
|
usersPager: Pager;
|
|
usersQuery?: string;
|
|
|
|
isLoaded?: boolean;
|
|
|
|
selectedUser?: SnapshotUser;
|
|
}
|
|
|
|
@Injectable()
|
|
export class UsersState extends State<Snapshot> {
|
|
public users =
|
|
this.changes.map(x => x.users)
|
|
.distinctUntilChanged();
|
|
|
|
public usersPager =
|
|
this.changes.map(x => x.usersPager)
|
|
.distinctUntilChanged();
|
|
|
|
public selectedUser =
|
|
this.changes.map(x => x.selectedUser)
|
|
.distinctUntilChanged();
|
|
|
|
public isLoaded =
|
|
this.changes.map(x => !!x.isLoaded)
|
|
.distinctUntilChanged();
|
|
|
|
constructor(
|
|
private readonly authState: AuthService,
|
|
private readonly dialogs: DialogService,
|
|
private readonly usersService: UsersService
|
|
) {
|
|
super({ users: ImmutableArray.empty(), usersPager: new Pager(0) });
|
|
}
|
|
|
|
public select(id: string | null): Observable<UserDto | null> {
|
|
return this.loadUser(id)
|
|
.do(selectedUser => {
|
|
this.next(s => ({ ...s, selectedUser }));
|
|
})
|
|
.map(x => x && x.user);
|
|
}
|
|
|
|
private loadUser(id: string | null) {
|
|
return !id ?
|
|
Observable.of(null) :
|
|
Observable.of(this.snapshot.users.find(x => x.user.id === id))
|
|
.switchMap(user => {
|
|
if (!user) {
|
|
return this.usersService.getUser(id).map(x => this.createUser(x)).catch(() => Observable.of(null));
|
|
} else {
|
|
return Observable.of(user);
|
|
}
|
|
});
|
|
}
|
|
|
|
public load(notifyLoad = false): Observable<any> {
|
|
return this.usersService.getUsers(this.snapshot.usersPager.pageSize, this.snapshot.usersPager.skip, this.snapshot.usersQuery)
|
|
.do(dtos => {
|
|
if (notifyLoad) {
|
|
this.dialogs.notifyInfo('Users reloaded.');
|
|
}
|
|
|
|
this.next(s => {
|
|
const users = ImmutableArray.of(dtos.items.map(x => this.createUser(x)));
|
|
const usersPager = s.usersPager.setCount(dtos.total);
|
|
|
|
let selectedUser = s.selectedUser;
|
|
|
|
if (selectedUser) {
|
|
selectedUser = users.find(x => x.user.id === selectedUser!.user.id) || selectedUser;
|
|
}
|
|
|
|
return { ...s, users, usersPager, selectedUser, isLoaded: true };
|
|
});
|
|
})
|
|
.notify(this.dialogs);
|
|
}
|
|
|
|
public create(request: CreateUserDto): Observable<UserDto> {
|
|
return this.usersService.postUser(request)
|
|
.do(dto => {
|
|
this.next(s => {
|
|
const users = s.users.pushFront(this.createUser(dto));
|
|
const usersPager = s.usersPager.incrementCount();
|
|
|
|
return { ...s, users, usersPager };
|
|
});
|
|
});
|
|
}
|
|
|
|
public update(user: UserDto, request: UpdateUserDto): Observable<any> {
|
|
return this.usersService.putUser(user.id, request)
|
|
.do(() => {
|
|
this.replaceUser(update(user, request));
|
|
});
|
|
}
|
|
|
|
public lock(user: UserDto): Observable<any> {
|
|
return this.usersService.lockUser(user.id)
|
|
.do(() => {
|
|
this.replaceUser(setLocked(user, true));
|
|
})
|
|
.notify(this.dialogs);
|
|
}
|
|
|
|
public unlock(user: UserDto): Observable<any> {
|
|
return this.usersService.unlockUser(user.id)
|
|
.do(() => {
|
|
this.replaceUser(setLocked(user, false));
|
|
})
|
|
.notify(this.dialogs);
|
|
}
|
|
|
|
public search(query: string): Observable<any> {
|
|
this.next(s => ({ ...s, usersPager: new Pager(0), usersQuery: query }));
|
|
|
|
return this.load();
|
|
}
|
|
|
|
public goNext(): Observable<any> {
|
|
this.next(s => ({ ...s, usersPager: s.usersPager.goNext() }));
|
|
|
|
return this.load();
|
|
}
|
|
|
|
public goPrev(): Observable<any> {
|
|
this.next(s => ({ ...s, usersPager: s.usersPager.goPrev() }));
|
|
|
|
return this.load();
|
|
}
|
|
|
|
private replaceUser(userDto: UserDto) {
|
|
return this.next(s => {
|
|
const user = this.createUser(userDto);
|
|
const users = s.users.map(u => u.user.id === userDto.id ? user : u);
|
|
|
|
const selectedUser = s.selectedUser && s.selectedUser.user.id === userDto.id ? user : s.selectedUser;
|
|
|
|
return { ...s, users, selectedUser };
|
|
});
|
|
}
|
|
|
|
private createUser(user: UserDto): SnapshotUser {
|
|
return user ? { user, isCurrentUser: user.id === this.authState.user!.id } : null!;
|
|
}
|
|
}
|
|
|
|
|
|
const update = (user: UserDto, request: UpdateUserDto) =>
|
|
new UserDto(user.id, request.email, request.displayName, user.isLocked);
|
|
|
|
const setLocked = (user: UserDto, locked: boolean) =>
|
|
new UserDto(user.id, user.email, user.displayName, locked);
|