From 59ed906a367b2b81defbab92841ada3b7db3a316 Mon Sep 17 00:00:00 2001 From: Maximilian Krambach Date: Wed, 13 Feb 2019 17:43:28 +0100 Subject: [PATCH] user sorting by config --- .../users/user-repository.service.ts | 39 +++++++++++++++++++ .../speaker-list/speaker-list.component.ts | 2 +- .../manage-submitters.component.ts | 6 ++- .../motion-detail/motion-detail.component.ts | 32 ++++++++------- .../users/services/user-sort-list.service.ts | 15 +++++++ openslides/users/config_variables.py | 1 + 6 files changed, 79 insertions(+), 16 deletions(-) diff --git a/client/src/app/core/repositories/users/user-repository.service.ts b/client/src/app/core/repositories/users/user-repository.service.ts index e7e29d7b6..1bff35684 100644 --- a/client/src/app/core/repositories/users/user-repository.service.ts +++ b/client/src/app/core/repositories/users/user-repository.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { Observable, BehaviorSubject } from 'rxjs'; import { BaseRepository } from '../base-repository'; import { ViewUser } from 'app/site/users/models/view-user'; @@ -305,4 +306,42 @@ export class UserRepositoryService extends BaseRepository { public getUserDuplicates(user: ViewUser): ViewUser[] { return this.getViewModelList().filter(existingUser => existingUser.full_name === user.full_name); } + + /** + * @returns the observable for users sorted according to configuration + */ + public getSortedViewModelListObservable(): Observable { + const subject = new BehaviorSubject([]); + this.getViewModelListObservable().subscribe(users => { + subject.next(this.sortViewUsersByConfig(users)); + }); + return subject.asObservable(); + } + + /** + * Sort viewUsers by the configured settings + * + * @param users + * @returns the users sorted by first name, last name or number, according + * to the config setting. Fallthrough and identical cases will be sorted by + * 'short_name' + */ + public sortViewUsersByConfig(users: ViewUser[]): ViewUser[] { + const sort = this.configService.instant<'first_name' | 'last_name' | 'number'>('users_sort_by') || 'last_name'; + return users.sort((a, b) => { + if (a[sort] && b[sort]) { + if (a[sort] === b[sort]) { + return a.short_name.localeCompare(b.short_name, this.translate.currentLang); + } else { + return a[sort].localeCompare(b[sort], this.translate.currentLang); + } + } else if (a[sort] && !b[sort]) { + return -1; + } else if (b[sort]) { + return 1; + } else { + return a.short_name.localeCompare(b.short_name); + } + }); + } } diff --git a/client/src/app/site/agenda/components/speaker-list/speaker-list.component.ts b/client/src/app/site/agenda/components/speaker-list/speaker-list.component.ts index 85317d4aa..1afc41321 100644 --- a/client/src/app/site/agenda/components/speaker-list/speaker-list.component.ts +++ b/client/src/app/site/agenda/components/speaker-list/speaker-list.component.ts @@ -144,7 +144,7 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit { public ngOnInit(): void { // load and observe users this.users = new BehaviorSubject(this.userRepository.getViewModelList()); - this.userRepository.getViewModelListObservable().subscribe(users => this.users.next(users)); + this.userRepository.getSortedViewModelListObservable().subscribe(users => this.users.next(users)); // detect changes in the form this.addSpeakerForm.valueChanges.subscribe(formResult => { diff --git a/client/src/app/site/motions/components/manage-submitters/manage-submitters.component.ts b/client/src/app/site/motions/components/manage-submitters/manage-submitters.component.ts index 68832fafb..968022f73 100644 --- a/client/src/app/site/motions/components/manage-submitters/manage-submitters.component.ts +++ b/client/src/app/site/motions/components/manage-submitters/manage-submitters.component.ts @@ -81,8 +81,10 @@ export class ManageSubmittersComponent extends BaseViewComponent { this.editSubmitterObservable = this.editSubmitterSubject.asObservable(); // get all users for the submitter add form - this.users = new BehaviorSubject(this.userRepository.getViewModelList()); - this.userRepository.getViewModelListObservable().subscribe(users => this.users.next(users)); + this.users = new BehaviorSubject( + this.userRepository.sortViewUsersByConfig(this.userRepository.getViewModelList()) + ); + this.userRepository.getSortedViewModelListObservable().subscribe(users => this.users.next(users)); // detect changes in the form this.addSubmitterForm.valueChanges.subscribe(formResult => { diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts index 297fa0065..0f736c9a4 100644 --- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts +++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts @@ -9,7 +9,6 @@ import { TranslateService } from '@ngx-translate/core'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { BaseViewComponent } from '../../../base/base-view'; -import { Category } from 'app/shared/models/motions/category'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service'; import { ChangeRecoMode, LineNumberingMode, ViewMotion } from '../../models/view-motion'; @@ -32,7 +31,6 @@ import { PersonalNoteContent } from 'app/shared/models/users/personal-note'; import { PersonalNoteService } from 'app/core/ui-services/personal-note.service'; import { PromptService } from 'app/core/ui-services/prompt.service'; import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions/statute-paragraph-repository.service'; -import { User } from 'app/shared/models/users/user'; import { ViewMotionChangeRecommendation } from '../../models/view-change-recommendation'; import { ViewCreateMotion } from '../../models/view-create-motion'; import { ViewportService } from 'app/core/ui-services/viewport.service'; @@ -41,6 +39,7 @@ import { ViewStatuteParagraph } from '../../models/view-statute-paragraph'; import { Workflow } from 'app/shared/models/motions/workflow'; import { LinenumberingService } from 'app/core/ui-services/linenumbering.service'; import { Tag } from 'app/shared/models/core/tag'; +import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { ViewMotionBlock } from '../../models/view-motion-block'; import { ViewWorkflow } from '../../models/view-workflow'; import { ViewUser } from 'app/site/users/models/view-user'; @@ -340,6 +339,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { * @param pdfExport export the motion to pdf * @param personalNoteService: personal comments and favorite marker * @param categoryRepo + * @param userRepo */ public constructor( title: Title, @@ -364,13 +364,18 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { private personalNoteService: PersonalNoteService, private linenumberingService: LinenumberingService, private viewModelStore: ViewModelStoreService, - private categoryRepo: CategoryRepositoryService + private categoryRepo: CategoryRepositoryService, + private userRepo: UserRepositoryService ) { super(title, translate, matSnackBar); // Initial Filling of the Subjects - this.submitterObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewUser)); - this.supporterObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewUser)); + this.submitterObserver = new BehaviorSubject( + this.userRepo.sortViewUsersByConfig(this.userRepo.getViewModelList()) + ); + this.supporterObserver = new BehaviorSubject( + this.userRepo.sortViewUsersByConfig(this.userRepo.getViewModelList()) + ); this.categoryObserver = new BehaviorSubject( this.categoryRepo.sortViewCategoriesByConfig(this.viewModelStore.getAll(ViewCategory)) ); @@ -381,16 +386,17 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { this.tagObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewTag)); this.motionObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotion)); + this.userRepo.getSortedViewModelListObservable().subscribe(sortedUsers => { + this.submitterObserver.next(sortedUsers); + this.supporterObserver.next(sortedUsers); + }); + this.categoryRepo.getSortedViewModelListObservable().subscribe(sortedCategories => { + this.categoryObserver.next(sortedCategories); + }); // Make sure the subjects are updated, when a new Model for the type arrives + // TODO get rid of DS here this.DS.changeObservable.subscribe(newModel => { - if (newModel instanceof User) { - this.submitterObserver.next(this.viewModelStore.getAll(ViewUser)); - this.supporterObserver.next(this.viewModelStore.getAll(ViewUser)); - } else if (newModel instanceof Category) { - this.categoryObserver.next( - this.categoryRepo.sortViewCategoriesByConfig(this.viewModelStore.getAll(ViewCategory)) - ); - } else if (newModel instanceof Workflow) { + if (newModel instanceof Workflow) { this.workflowObserver.next(this.viewModelStore.getAll(ViewWorkflow)); } else if (newModel instanceof MotionBlock) { this.blockObserver.next(this.viewModelStore.getAll(ViewMotionBlock)); diff --git a/client/src/app/site/users/services/user-sort-list.service.ts b/client/src/app/site/users/services/user-sort-list.service.ts index af9adee7c..b86c55110 100644 --- a/client/src/app/site/users/services/user-sort-list.service.ts +++ b/client/src/app/site/users/services/user-sort-list.service.ts @@ -1,6 +1,9 @@ import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; import { BaseSortListService, OsSortingDefinition } from 'app/core/ui-services/base-sort-list.service'; +import { ConfigService } from 'app/core/ui-services/config.service'; +import { StorageService } from 'app/core/core-services/storage.service'; import { ViewUser } from '../models/view-user'; @Injectable({ @@ -23,4 +26,16 @@ export class UserSortListService extends BaseSortListService { ] }; protected name = 'User'; + + /** + * Constructor. Sets the default sorting if none is set locally + * + * @param translate + * @param store + * @param config + */ + public constructor(translate: TranslateService, store: StorageService, config: ConfigService) { + super(translate, store); + this.sortOptions.sortProperty = config.instant('motions_motions_sorting'); + } } diff --git a/openslides/users/config_variables.py b/openslides/users/config_variables.py index 3e3ecd053..772e1b4ed 100644 --- a/openslides/users/config_variables.py +++ b/openslides/users/config_variables.py @@ -19,6 +19,7 @@ def get_config_variables(): choices=( {"value": "first_name", "display_name": "Given name"}, {"value": "last_name", "display_name": "Surname"}, + {"value": "number", "display_name": "Participant number"}, ), weight=510, group="Participants",