Merge pull request #5500 from tsiegleauq/crate-users-svc

Add "create user" to more search value selectors
This commit is contained in:
Emanuel Schütze 2020-08-12 15:00:55 +02:00 committed by GitHub
commit b726801747
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 79 additions and 19 deletions

View File

@ -130,9 +130,9 @@ export class AssignmentRepositoryService extends BaseIsAgendaItemAndListOfSpeake
* of the candidate. Else, the candidate will be added if not on the list,
* and removed if on the list
*/
public async changeCandidate(user: ViewUser, assignment: ViewAssignment, adding?: boolean): Promise<void> {
const data = { user: user.id };
if (assignment.candidates.some(candidate => candidate.id === user.id) && adding !== true) {
public async changeCandidate(userId: number, assignment: ViewAssignment, adding?: boolean): Promise<void> {
const data = { user: userId };
if (assignment.candidates.some(candidate => candidate.id === userId) && adding !== true) {
await this.httpService.delete(this.restPath + assignment.id + this.candidatureOtherPath, data);
} else if (adding !== false) {
await this.httpService.post(this.restPath + assignment.id + this.candidatureOtherPath, data);

View File

@ -22,6 +22,11 @@ export interface MassImportResult {
errors: { [id: number]: string };
}
export interface NewUser {
id: number;
name: string;
}
/**
* type for determining the user name from a string during import.
* See {@link parseUserString} for implementations
@ -370,10 +375,10 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
* @param user: String to create the user from
* @returns Promise with a created user id and the raw name used as input
*/
public async createFromString(user: string): Promise<{ id: number; name: string }> {
public async createFromString(user: string): Promise<NewUser> {
const newUser = this.parseUserString(user);
const createdUser = await this.create(newUser);
return { id: createdUser.id, name: user };
return { id: createdUser.id, name: user } as NewUser;
}
/**

View File

@ -15,7 +15,7 @@
<div class="section-two">
<!-- {number}. {item.getTitle()} -->
<span *ngIf="count">{{ i + 1 }}.&nbsp;</span>
<span>{{ item.getTitle() }}</span>
<span>{{ item?.getTitle() }}</span>
</div>
<div class="section-three">
<!-- Extra controls slot using implicit template references -->

View File

@ -512,11 +512,11 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
*
* @param username The name of the new user.
*/
public onCreateUser(username: string): void {
this.userRepository.createFromString(username).then(result => {
this.addNewSpeaker(result.id);
});
public async onCreateUser(username: string): Promise<void> {
const newUser = await this.userRepository.createFromString(username);
this.addNewSpeaker(newUser.id);
}
/**
* Triggers an update of the filter for the list of available potential speakers
* (triggered on an update of users or config)

View File

@ -186,7 +186,14 @@
[multiple]="false"
placeholder="{{ 'Select a new candidate' | translate }}"
[inputListValues]="filteredCandidates"
></os-search-value-selector>
[showNotFoundButton]="true"
(clickNotFound)="createNewCandidate($event)"
>
<ng-container notFoundDescription>
<mat-icon>add</mat-icon>
{{ 'Create user' | translate }}
</ng-container>
</os-search-value-selector>
</mat-form-field>
</form>
</div>

View File

@ -338,9 +338,8 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn
* @param userId the id of a ViewUser
*/
public async addUser(userId: number): Promise<void> {
const user = this.userRepo.getViewModel(userId);
if (user) {
await this.repo.changeCandidate(user, this.assignment, true).catch(this.raiseError);
if (userId) {
await this.repo.changeCandidate(userId, this.assignment, true).catch(this.raiseError);
}
}
@ -350,7 +349,15 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn
* @param candidate A ViewAssignmentUser currently in the list of related users
*/
public async removeUser(candidate: ViewAssignmentRelatedUser): Promise<void> {
await this.repo.changeCandidate(candidate.user, this.assignment, false).catch(this.raiseError);
await this.repo.changeCandidate(candidate.user.id, this.assignment, false).catch(this.raiseError);
}
/**
* Creates unfound candidate on the fly and add the the list
*/
public async createNewCandidate(username: string): Promise<void> {
const newUserObj = await this.userRepo.createFromString(username);
await this.addUser(newUserObj.id);
}
/**

View File

@ -66,7 +66,9 @@
<mat-icon>picture_as_pdf</mat-icon>
<span>{{ 'PDF' | translate }}</span>
</button>
<mat-divider *osPerms="['core.can_manage_projector', 'agenda.can_manage', 'core.can_see_history']"></mat-divider>
<mat-divider
*osPerms="['core.can_manage_projector', 'agenda.can_manage', 'core.can_see_history']"
></mat-divider>
<!-- Project -->
<os-projector-button
[object]="motion"
@ -627,7 +629,14 @@
[multiple]="true"
placeholder="{{ 'Submitters' | translate }}"
[inputListValues]="submitterObserver"
></os-search-value-selector>
[showNotFoundButton]="true"
(clickNotFound)="createNewSubmitter($event)"
>
<ng-container notFoundDescription>
<mat-icon>add</mat-icon>
{{ 'Create user' | translate }}
</ng-container>
</os-search-value-selector>
</mat-form-field>
</ng-container>
</div>
@ -843,7 +852,14 @@
[multiple]="true"
placeholder="{{ 'Supporters' | translate }}"
[inputListValues]="supporterObserver"
></os-search-value-selector>
[showNotFoundButton]="true"
(clickNotFound)="createNewSupporter($event)"
>
<ng-container notFoundDescription>
<mat-icon>add</mat-icon>
{{ 'Create user' | translate }}
</ng-container>
</os-search-value-selector>
</mat-form-field>
</div>
</div>

View File

@ -29,7 +29,7 @@ import { MotionRepositoryService, ParagraphToChoose } from 'app/core/repositorie
import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions/statute-paragraph-repository.service';
import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service';
import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { NewUser, UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { DiffLinesInParagraph, LineRange } from 'app/core/ui-services/diff.service';
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
@ -1705,6 +1705,31 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
}
}
public async createNewSubmitter(username: string): Promise<void> {
const newUserObj = await this.createNewUser(username);
this.addNewUserToFormCtrl(newUserObj, 'submitters_id');
}
public async createNewSupporter(username: string): Promise<void> {
const newUserObj = await this.createNewUser(username);
this.addNewUserToFormCtrl(newUserObj, 'supporters_id');
}
private addNewUserToFormCtrl(newUserObj: NewUser, controlName: string): void {
const control = this.contentForm.get(controlName);
let currentSubmitters: number[] = control.value;
if (currentSubmitters?.length) {
currentSubmitters.push(newUserObj.id);
} else {
currentSubmitters = [newUserObj.id];
}
control.setValue(currentSubmitters);
}
private createNewUser(username: string): Promise<NewUser> {
return this.userRepo.createFromString(username);
}
public swipe(e: TouchEvent, when: string): void {
const coord: [number, number] = [e.changedTouches[0].pageX, e.changedTouches[0].pageY];
const time = new Date().getTime();