Disable various expensive sorting functions
Prevents the usage of: "sortViewUsersByConfig" of the userRepository since it's an incredibe heavy operation for ~500 (real) users. I would advice to sort the datastore rather than the lists in the view to prevent unnecessary sorting overhead
This commit is contained in:
parent
497a3ec71d
commit
3785545a35
@ -115,6 +115,8 @@ export class CategoryRepositoryService extends BaseRepository<ViewCategory, Cate
|
|||||||
*
|
*
|
||||||
* @param categories
|
* @param categories
|
||||||
* @returns the categories sorted by prefix or name, according to the config setting
|
* @returns the categories sorted by prefix or name, according to the config setting
|
||||||
|
*
|
||||||
|
* TODO: That operation is HEAVY
|
||||||
*/
|
*/
|
||||||
public sortViewCategoriesByConfig(categories: ViewCategory[]): ViewCategory[] {
|
public sortViewCategoriesByConfig(categories: ViewCategory[]): ViewCategory[] {
|
||||||
const sort = this.configService.instant<'prefix' | 'name'>('motions_category_sorting') || 'prefix';
|
const sort = this.configService.instant<'prefix' | 'name'>('motions_category_sorting') || 'prefix';
|
||||||
|
@ -305,6 +305,7 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all duplicates of an user (currently: full name matches)
|
* Returns all duplicates of an user (currently: full name matches)
|
||||||
|
*
|
||||||
* @param user
|
* @param user
|
||||||
*/
|
*/
|
||||||
public getUserDuplicates(user: ViewUser): ViewUser[] {
|
public getUserDuplicates(user: ViewUser): ViewUser[] {
|
||||||
@ -313,6 +314,8 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns the observable for users sorted according to configuration
|
* @returns the observable for users sorted according to configuration
|
||||||
|
*
|
||||||
|
* TODO: This is leading to heavy operations
|
||||||
*/
|
*/
|
||||||
public getSortedViewModelListObservable(): Observable<ViewUser[]> {
|
public getSortedViewModelListObservable(): Observable<ViewUser[]> {
|
||||||
const subject = new BehaviorSubject<ViewUser[]>([]);
|
const subject = new BehaviorSubject<ViewUser[]>([]);
|
||||||
@ -329,6 +332,8 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
|
|||||||
* @returns the users sorted by first name, last name or number, according
|
* @returns the users sorted by first name, last name or number, according
|
||||||
* to the config setting. Fallthrough and identical cases will be sorted by
|
* to the config setting. Fallthrough and identical cases will be sorted by
|
||||||
* 'short_name'
|
* 'short_name'
|
||||||
|
*
|
||||||
|
* TODO: That operation is HEAVY
|
||||||
*/
|
*/
|
||||||
public sortViewUsersByConfig(users: ViewUser[]): ViewUser[] {
|
public sortViewUsersByConfig(users: ViewUser[]): ViewUser[] {
|
||||||
const sort = this.configService.instant<'first_name' | 'last_name' | 'number'>('users_sort_by') || 'last_name';
|
const sort = this.configService.instant<'first_name' | 'last_name' | 'number'>('users_sort_by') || 'last_name';
|
||||||
|
@ -90,9 +90,12 @@
|
|||||||
<ng-container matColumnDef="menu">
|
<ng-container matColumnDef="menu">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Menu</mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Menu</mat-header-cell>
|
||||||
<mat-cell *matCellDef="let item">
|
<mat-cell *matCellDef="let item">
|
||||||
<button mat-icon-button
|
<button
|
||||||
|
mat-icon-button
|
||||||
*osPerms="'agenda.can_manage'"
|
*osPerms="'agenda.can_manage'"
|
||||||
[matMenuTriggerFor]="singleItemMenu" [matMenuTriggerData]="{ item: item }">
|
[matMenuTriggerFor]="singleItemMenu"
|
||||||
|
[matMenuTriggerData]="{ item: item }"
|
||||||
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -65,9 +65,7 @@ export class ViewAssignment extends BaseAgendaViewModel {
|
|||||||
this._tags = tags;
|
this._tags = tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateDependencies(update: BaseViewModel): void {
|
public updateDependencies(update: BaseViewModel): void {}
|
||||||
console.log('TODO: assignment updateDependencies');
|
|
||||||
}
|
|
||||||
|
|
||||||
public getAgendaItem(): ViewItem {
|
public getAgendaItem(): ViewItem {
|
||||||
return this.agendaItem;
|
return this.agendaItem;
|
||||||
|
@ -5,6 +5,7 @@ import { MatSnackBar, MatSnackBarRef, SimpleSnackBar } from '@angular/material';
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { BaseComponent } from '../../base.component';
|
import { BaseComponent } from '../../base.component';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for all views. Implements a generic error handling by raising a snack bar
|
* A base class for all views. Implements a generic error handling by raising a snack bar
|
||||||
@ -17,6 +18,11 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
|
|||||||
*/
|
*/
|
||||||
private messageSnackBar: MatSnackBarRef<SimpleSnackBar>;
|
private messageSnackBar: MatSnackBarRef<SimpleSnackBar>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscriptions added to this list will be cleared 'on destroy'
|
||||||
|
*/
|
||||||
|
protected subscriptions: Subscription[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for bas elist views
|
* Constructor for bas elist views
|
||||||
* @param titleService the title serivce, passed to the base component
|
* @param titleService the title serivce, passed to the base component
|
||||||
@ -25,6 +31,7 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
|
|||||||
*/
|
*/
|
||||||
public constructor(titleService: Title, translate: TranslateService, private matSnackBar: MatSnackBar) {
|
public constructor(titleService: Title, translate: TranslateService, private matSnackBar: MatSnackBar) {
|
||||||
super(titleService, translate);
|
super(titleService, translate);
|
||||||
|
this.subscriptions = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,11 +65,18 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* automatically dismisses the error snack bar, if the component is destroyed.
|
* automatically dismisses the error snack bar and clears subscriptions
|
||||||
|
* if the component is destroyed.
|
||||||
*/
|
*/
|
||||||
public ngOnDestroy(): void {
|
public ngOnDestroy(): void {
|
||||||
if (this.messageSnackBar) {
|
if (this.messageSnackBar) {
|
||||||
this.messageSnackBar.dismiss();
|
this.messageSnackBar.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.subscriptions.length > 0) {
|
||||||
|
for (const sub of this.subscriptions) {
|
||||||
|
sub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,20 +96,24 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel, M extends B
|
|||||||
* Standard filtering function. Sufficient for most list views but can be overwritten
|
* Standard filtering function. Sufficient for most list views but can be overwritten
|
||||||
*/
|
*/
|
||||||
protected onFilter(): void {
|
protected onFilter(): void {
|
||||||
this.filterService.filter().subscribe(filteredData => (this.sortService.data = filteredData));
|
this.subscriptions.push(
|
||||||
|
this.filterService.filter().subscribe(filteredData => (this.sortService.data = filteredData))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard sorting function. Siffucient for most list views but can be overwritten
|
* Standard sorting function. Siffucient for most list views but can be overwritten
|
||||||
*/
|
*/
|
||||||
protected onSort(): void {
|
protected onSort(): void {
|
||||||
|
this.subscriptions.push(
|
||||||
this.sortService.sort().subscribe(sortedData => {
|
this.sortService.sort().subscribe(sortedData => {
|
||||||
// the dataArray needs to be cleared (since angular 7)
|
// the dataArray needs to be cleared (since angular 7)
|
||||||
// changes are not detected properly anymore
|
// changes are not detected properly anymore
|
||||||
this.dataSource.data = [];
|
this.dataSource.data = [];
|
||||||
this.dataSource.data = sortedData;
|
this.dataSource.data = sortedData;
|
||||||
this.checkSelection();
|
this.checkSelection();
|
||||||
});
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSortButton(itemProperty: string): void {
|
public onSortButton(itemProperty: string): void {
|
||||||
|
@ -80,12 +80,6 @@ export class ManageSubmittersComponent extends BaseViewComponent {
|
|||||||
this.addSubmitterForm = new FormGroup({ userId: new FormControl([]) });
|
this.addSubmitterForm = new FormGroup({ userId: new FormControl([]) });
|
||||||
this.editSubmitterObservable = this.editSubmitterSubject.asObservable();
|
this.editSubmitterObservable = this.editSubmitterSubject.asObservable();
|
||||||
|
|
||||||
// get all users for the submitter add form
|
|
||||||
this.users = new BehaviorSubject<ViewUser[]>(
|
|
||||||
this.userRepository.sortViewUsersByConfig(this.userRepository.getViewModelList())
|
|
||||||
);
|
|
||||||
this.userRepository.getSortedViewModelListObservable().subscribe(users => this.users.next(users));
|
|
||||||
|
|
||||||
// detect changes in the form
|
// detect changes in the form
|
||||||
this.addSubmitterForm.valueChanges.subscribe(formResult => {
|
this.addSubmitterForm.valueChanges.subscribe(formResult => {
|
||||||
if (formResult && formResult.userId) {
|
if (formResult && formResult.userId) {
|
||||||
@ -101,6 +95,10 @@ export class ManageSubmittersComponent extends BaseViewComponent {
|
|||||||
this.isEditMode = true;
|
this.isEditMode = true;
|
||||||
this.editSubmitterSubject.next(this.motion.submitters.map(x => x));
|
this.editSubmitterSubject.next(this.motion.submitters.map(x => x));
|
||||||
this.addSubmitterForm.reset();
|
this.addSubmitterForm.reset();
|
||||||
|
|
||||||
|
// get all users for the submitter add form
|
||||||
|
this.users = new BehaviorSubject<ViewUser[]>(this.userRepository.getViewModelList());
|
||||||
|
this.userRepository.getViewModelListObservable().subscribe(users => this.users.next(users));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -402,16 +402,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
) {
|
) {
|
||||||
super(title, translate, matSnackBar);
|
super(title, translate, matSnackBar);
|
||||||
|
|
||||||
// Initial Filling of the Subjects
|
|
||||||
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))
|
|
||||||
);
|
|
||||||
this.workflowObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewWorkflow));
|
this.workflowObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewWorkflow));
|
||||||
this.blockObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotionBlock));
|
this.blockObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotionBlock));
|
||||||
this.mediafilesObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMediafile));
|
this.mediafilesObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMediafile));
|
||||||
@ -419,13 +409,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
this.tagObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewTag));
|
this.tagObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewTag));
|
||||||
this.motionObserver = new BehaviorSubject(this.viewModelStore.getAll(ViewMotion));
|
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
|
// Make sure the subjects are updated, when a new Model for the type arrives
|
||||||
// TODO get rid of DS here
|
// TODO get rid of DS here
|
||||||
this.DS.changeObservable.subscribe(newModel => {
|
this.DS.changeObservable.subscribe(newModel => {
|
||||||
@ -477,6 +460,23 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
this.getMotionByUrl();
|
this.getMotionByUrl();
|
||||||
this.setSurroundingMotions();
|
this.setSurroundingMotions();
|
||||||
|
|
||||||
|
// TODO: Changed to un-sort, since it's a really heavy operation
|
||||||
|
this.userRepo.getViewModelListObservable().subscribe(unsortedUsers => {
|
||||||
|
this.submitterObserver.next(unsortedUsers);
|
||||||
|
this.supporterObserver.next(unsortedUsers);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.categoryRepo.getViewModelListObservable().subscribe(unsortedCategories => {
|
||||||
|
this.categoryObserver.next(unsortedCategories);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial Filling of the Subjects
|
||||||
|
this.submitterObserver = new BehaviorSubject(this.userRepo.getViewModelList());
|
||||||
|
this.supporterObserver = new BehaviorSubject(this.userRepo.getViewModelList());
|
||||||
|
this.categoryObserver = new BehaviorSubject(
|
||||||
|
this.categoryRepo.sortViewCategoriesByConfig(this.viewModelStore.getAll(ViewCategory))
|
||||||
|
);
|
||||||
|
|
||||||
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
|
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
|
||||||
this.statuteParagraphs = newViewStatuteParagraphs;
|
this.statuteParagraphs = newViewStatuteParagraphs;
|
||||||
});
|
});
|
||||||
@ -501,6 +501,10 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called during view destruction.
|
||||||
|
* Sends a notification to user editors of the motion was edited
|
||||||
|
*/
|
||||||
public ngOnDestroy(): void {
|
public ngOnDestroy(): void {
|
||||||
this.unsubscribeEditNotifications(TypeOfNotificationViewMotion.TYPE_CLOSING_EDITING_MOTION);
|
this.unsubscribeEditNotifications(TypeOfNotificationViewMotion.TYPE_CLOSING_EDITING_MOTION);
|
||||||
}
|
}
|
||||||
@ -1086,6 +1090,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
* then appending motion without identifiers sorted by title
|
* then appending motion without identifiers sorted by title
|
||||||
*/
|
*/
|
||||||
public setSurroundingMotions(): void {
|
public setSurroundingMotions(): void {
|
||||||
|
// TODO: that operation is HEAVY
|
||||||
this.motionObserver.value.sort((a, b) => {
|
this.motionObserver.value.sort((a, b) => {
|
||||||
if (a.identifier && b.identifier) {
|
if (a.identifier && b.identifier) {
|
||||||
return a.identifier.localeCompare(b.identifier, this.translate.currentLang);
|
return a.identifier.localeCompare(b.identifier, this.translate.currentLang);
|
||||||
|
Loading…
Reference in New Issue
Block a user