Force DataSource to refresh

Fixed a bug where data in MatTableDataStore was not updating.
Also:
Cleaned redundant list view sorting and filtering functions
This commit is contained in:
Sean Engelhardt 2019-02-18 13:31:15 +01:00
parent cc45525678
commit 57be0a5bea
12 changed files with 84 additions and 69 deletions

View File

@ -4,20 +4,20 @@ import { Router, ActivatedRoute } from '@angular/router';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { AgendaFilterListService } from '../../services/agenda-filter-list.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { ListViewBaseComponent } from 'app/site/base/list-view-base';
import { PromptService } from 'app/core/ui-services/prompt.service';
import { ViewItem } from '../../models/view-item';
import { AgendaCsvExportService } from '../../services/agenda-csv-export.service'; import { AgendaCsvExportService } from '../../services/agenda-csv-export.service';
import { AgendaFilterListService } from '../../services/agenda-filter-list.service';
import { AgendaPdfService } from '../../services/agenda-pdf.service'; import { AgendaPdfService } from '../../services/agenda-pdf.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { DurationService } from 'app/core/ui-services/duration.service'; import { DurationService } from 'app/core/ui-services/duration.service';
import { Item } from 'app/shared/models/agenda/item';
import { ItemInfoDialogComponent } from '../item-info-dialog/item-info-dialog.component'; import { ItemInfoDialogComponent } from '../item-info-dialog/item-info-dialog.component';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { ListViewBaseComponent } from 'app/site/base/list-view-base';
import { OperatorService } from 'app/core/core-services/operator.service';
import { PromptService } from 'app/core/ui-services/prompt.service';
import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service'; import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service';
import { ViewportService } from 'app/core/ui-services/viewport.service'; import { ViewportService } from 'app/core/ui-services/viewport.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { ViewItem } from '../../models/view-item';
/** /**
* List view for the agenda. * List view for the agenda.
@ -27,7 +27,7 @@ import { OperatorService } from 'app/core/core-services/operator.service';
templateUrl: './agenda-list.component.html', templateUrl: './agenda-list.component.html',
styleUrls: ['./agenda-list.component.scss'] styleUrls: ['./agenda-list.component.scss']
}) })
export class AgendaListComponent extends ListViewBaseComponent<ViewItem> implements OnInit { export class AgendaListComponent extends ListViewBaseComponent<ViewItem, Item> implements OnInit {
/** /**
* Determine the display columns in desktop view * Determine the display columns in desktop view
*/ */
@ -86,7 +86,7 @@ export class AgendaListComponent extends ListViewBaseComponent<ViewItem> impleme
private agendaPdfService: AgendaPdfService, private agendaPdfService: AgendaPdfService,
private pdfService: PdfDocumentService private pdfService: PdfDocumentService
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar, filterService);
// activate multiSelect mode for this listview // activate multiSelect mode for this listview
this.canMultiSelect = true; this.canMultiSelect = true;
@ -99,15 +99,18 @@ export class AgendaListComponent extends ListViewBaseComponent<ViewItem> impleme
public ngOnInit(): void { public ngOnInit(): void {
super.setTitle('Agenda'); super.setTitle('Agenda');
this.initTable(); this.initTable();
this.config
.get<boolean>('agenda_enable_numbering')
.subscribe(autoNumbering => (this.isNumberingAllowed = autoNumbering));
this.setFulltextFilter();
}
protected onFilter(): void {
this.filterService.filter().subscribe(newAgendaItems => { this.filterService.filter().subscribe(newAgendaItems => {
newAgendaItems.sort((a, b) => a.agendaListWeight - b.agendaListWeight); newAgendaItems.sort((a, b) => a.agendaListWeight - b.agendaListWeight);
this.dataSource.data = newAgendaItems; this.dataSource.data = newAgendaItems;
this.checkSelection(); this.checkSelection();
}); });
this.config
.get<boolean>('agenda_enable_numbering')
.subscribe(autoNumbering => (this.isNumberingAllowed = autoNumbering));
this.setFulltextFilter();
} }
/** /**

View File

@ -3,12 +3,13 @@ import { MatSnackBar } from '@angular/material';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { Assignment } from 'app/shared/models/assignments/assignment';
import { AssignmentFilterListService } from '../services/assignment-filter.service'; import { AssignmentFilterListService } from '../services/assignment-filter.service';
import { AssignmentSortListService } from '../services/assignment-sort-list.service';
import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service';
import { ListViewBaseComponent } from '../../base/list-view-base'; import { ListViewBaseComponent } from '../../base/list-view-base';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { ViewAssignment } from '../models/view-assignment'; import { ViewAssignment } from '../models/view-assignment';
import { AssignmentSortListService } from '../services/assignment-sort-list.service';
/** /**
* Listview for the assignments * Listview for the assignments
@ -19,7 +20,7 @@ import { AssignmentSortListService } from '../services/assignment-sort-list.serv
templateUrl: './assignment-list.component.html', templateUrl: './assignment-list.component.html',
styleUrls: ['./assignment-list.component.scss'] styleUrls: ['./assignment-list.component.scss']
}) })
export class AssignmentListComponent extends ListViewBaseComponent<ViewAssignment> implements OnInit { export class AssignmentListComponent extends ListViewBaseComponent<ViewAssignment, Assignment> implements OnInit {
/** /**
* Constructor. * Constructor.
* @param titleService * @param titleService
@ -39,7 +40,7 @@ export class AssignmentListComponent extends ListViewBaseComponent<ViewAssignmen
public filterService: AssignmentFilterListService, public filterService: AssignmentFilterListService,
public sortService: AssignmentSortListService public sortService: AssignmentSortListService
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar, filterService, sortService);
// activate multiSelect mode for this listview // activate multiSelect mode for this listview
this.canMultiSelect = true; this.canMultiSelect = true;
} }
@ -52,14 +53,6 @@ export class AssignmentListComponent extends ListViewBaseComponent<ViewAssignmen
public ngOnInit(): void { public ngOnInit(): void {
super.setTitle(this.translate.instant('Elections')); super.setTitle(this.translate.instant('Elections'));
this.initTable(); this.initTable();
this.filterService.filter().subscribe(filteredData => {
this.sortService.data = filteredData;
});
this.sortService.sort().subscribe(sortedData => {
this.dataSource.data = sortedData;
this.checkSelection();
});
} }
/** /**

View File

@ -5,8 +5,11 @@ import { ViewChild } from '@angular/core';
import { BaseViewComponent } from './base-view'; import { BaseViewComponent } from './base-view';
import { BaseViewModel } from './base-view-model'; import { BaseViewModel } from './base-view-model';
import { BaseSortListService } from 'app/core/ui-services/base-sort-list.service';
import { BaseFilterListService } from 'app/core/ui-services/base-filter-list.service';
import { BaseModel } from 'app/shared/models/base/base-model';
export abstract class ListViewBaseComponent<V extends BaseViewModel> extends BaseViewComponent { export abstract class ListViewBaseComponent<V extends BaseViewModel, M extends BaseModel> extends BaseViewComponent {
/** /**
* The data source for a table. Requires to be initialized with a BaseViewModel * The data source for a table. Requires to be initialized with a BaseViewModel
*/ */
@ -59,7 +62,13 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel> extends Bas
* @param translate the translate service * @param translate the translate service
* @param matSnackBar * @param matSnackBar
*/ */
public constructor(titleService: Title, translate: TranslateService, matSnackBar: MatSnackBar) { public constructor(
titleService: Title,
translate: TranslateService,
matSnackBar: MatSnackBar,
public filterService?: BaseFilterListService<M, V>,
public sortService?: BaseSortListService<V>
) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar);
this.selectedRows = []; this.selectedRows = [];
} }
@ -72,6 +81,32 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel> extends Bas
public initTable(): void { public initTable(): void {
this.dataSource = new MatTableDataSource(); this.dataSource = new MatTableDataSource();
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
if (this.filterService) {
this.onFilter();
}
if (this.sortService) {
this.onSort();
}
}
/**
* Standard filtering function. Sufficient for most list views but can be overwritten
*/
protected onFilter(): void {
this.filterService.filter().subscribe(filteredData => (this.sortService.data = filteredData));
}
/**
* Standard sorting function. Siffucient for most list views but can be overwritten
*/
protected onSort(): void {
this.sortService.sort().subscribe(sortedData => {
// the dataArray needs to be cleared (since angular 7)
// changes are not detected properly anymore
this.dataSource.data = [];
this.dataSource.data = sortedData;
this.checkSelection();
});
} }
public onSortButton(itemProperty: string): void { public onSortButton(itemProperty: string): void {

View File

@ -1,14 +1,15 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { MatSnackBar } from '@angular/material'; import { MatSnackBar } from '@angular/material';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ListViewBaseComponent } from 'app/site/base/list-view-base'; import { History } from 'app/shared/models/core/history';
import { HistoryRepositoryService } from 'app/core/repositories/history/history-repository.service'; import { HistoryRepositoryService } from 'app/core/repositories/history/history-repository.service';
import { isDetailNavigable } from 'app/shared/models/base/detail-navigable'; import { isDetailNavigable } from 'app/shared/models/base/detail-navigable';
import { ListViewBaseComponent } from 'app/site/base/list-view-base';
import { ViewHistory } from '../../models/view-history'; import { ViewHistory } from '../../models/view-history';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -22,7 +23,7 @@ import { ViewModelStoreService } from 'app/core/core-services/view-model-store.s
templateUrl: './history-list.component.html', templateUrl: './history-list.component.html',
styleUrls: ['./history-list.component.scss'] styleUrls: ['./history-list.component.scss']
}) })
export class HistoryListComponent extends ListViewBaseComponent<ViewHistory> implements OnInit { export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, History> implements OnInit {
/** /**
* Subject determine when the custom timestamp subject changes * Subject determine when the custom timestamp subject changes
*/ */

View File

@ -25,7 +25,7 @@ import { OperatorService } from 'app/core/core-services/operator.service';
templateUrl: './mediafile-list.component.html', templateUrl: './mediafile-list.component.html',
styleUrls: ['./mediafile-list.component.scss'] styleUrls: ['./mediafile-list.component.scss']
}) })
export class MediafileListComponent extends ListViewBaseComponent<ViewMediafile> implements OnInit { export class MediafileListComponent extends ListViewBaseComponent<ViewMediafile, Mediafile> implements OnInit {
/** /**
* Holds the actions for logos. Updated via an observable * Holds the actions for logos. Updated via an observable
*/ */
@ -99,9 +99,9 @@ export class MediafileListComponent extends ListViewBaseComponent<ViewMediafile>
public sortService: MediafilesSortListService, public sortService: MediafilesSortListService,
private operator: OperatorService private operator: OperatorService
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar, filterService, sortService);
// embles multiSelection for this listView // enables multiSelection for this listView
this.canMultiSelect = true; this.canMultiSelect = true;
} }
@ -118,14 +118,6 @@ export class MediafileListComponent extends ListViewBaseComponent<ViewMediafile>
hidden: new FormControl() hidden: new FormControl()
}); });
this.filterService.filter().subscribe(filteredData => {
this.sortService.data = filteredData;
});
this.sortService.sort().subscribe(sortedData => {
this.dataSource.data = sortedData;
});
// Observe the logo actions // Observe the logo actions
this.mediaManage.getLogoActions().subscribe(action => { this.mediaManage.getLogoActions().subscribe(action => {
this.logoActions = action; this.logoActions = action;

View File

@ -23,7 +23,7 @@ import { OperatorService } from '../../../../core/core-services/operator.service
templateUrl: './motion-block-detail.component.html', templateUrl: './motion-block-detail.component.html',
styleUrls: ['./motion-block-detail.component.scss'] styleUrls: ['./motion-block-detail.component.scss']
}) })
export class MotionBlockDetailComponent extends ListViewBaseComponent<ViewMotion> implements OnInit { export class MotionBlockDetailComponent extends ListViewBaseComponent<ViewMotion, MotionBlock> implements OnInit {
/** /**
* Determines the block id from the given URL * Determines the block id from the given URL
*/ */

View File

@ -25,7 +25,7 @@ import { ViewMotionBlock } from '../../models/view-motion-block';
templateUrl: './motion-block-list.component.html', templateUrl: './motion-block-list.component.html',
styleUrls: ['./motion-block-list.component.scss'] styleUrls: ['./motion-block-list.component.scss']
}) })
export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBlock> implements OnInit { export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBlock, MotionBlock> implements OnInit {
/** /**
* Holds the create form * Holds the create form
*/ */

View File

@ -92,7 +92,8 @@
</mat-basic-chip> </mat-basic-chip>
</div> </div>
<!-- recommendation line --> <!-- recommendation line -->
<div *ngIf="motion.recommendation && motion.state.next_states_id.length > 0" <div
*ngIf="motion.recommendation && motion.state.next_states_id.length > 0"
class="ellipsis-overflow white" class="ellipsis-overflow white"
> >
<mat-basic-chip class="bluegrey" [disabled]="true"> <mat-basic-chip class="bluegrey" [disabled]="true">

View File

@ -27,6 +27,7 @@ import { MotionPdfExportService } from '../../services/motion-pdf-export.service
import { MotionExportDialogComponent } from '../motion-export-dialog/motion-export-dialog.component'; import { MotionExportDialogComponent } from '../motion-export-dialog/motion-export-dialog.component';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService } from 'app/core/core-services/operator.service';
import { ViewportService } from 'app/core/ui-services/viewport.service'; import { ViewportService } from 'app/core/ui-services/viewport.service';
import { Motion } from 'app/shared/models/motions/motion';
/** /**
* Component that displays all the motions in a Table using DataSource. * Component that displays all the motions in a Table using DataSource.
@ -36,7 +37,7 @@ import { ViewportService } from 'app/core/ui-services/viewport.service';
templateUrl: './motion-list.component.html', templateUrl: './motion-list.component.html',
styleUrls: ['./motion-list.component.scss'] styleUrls: ['./motion-list.component.scss']
}) })
export class MotionListComponent extends ListViewBaseComponent<ViewMotion> implements OnInit { export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motion> implements OnInit {
/** /**
* Columns to display in table when desktop view is available * Columns to display in table when desktop view is available
*/ */
@ -64,7 +65,9 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
* *
* @param titleService Title * @param titleService Title
* @param translate Translation * @param translate Translation
* @param matSnackBar * @param matSnackBar showing errors
* @param sortService sorting
* @param filterService filtering
* @param router Router * @param router Router
* @param route Current route * @param route Current route
* @param configService The configuration provider * @param configService The configuration provider
@ -78,8 +81,6 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
* @param pdfExport To export motions as PDF * @param pdfExport To export motions as PDF
* @param multiselectService Service for the multiSelect actions * @param multiselectService Service for the multiSelect actions
* @param userRepo * @param userRepo
* @param sortService
* @param filterService
* @param vp * @param vp
* @param perms LocalPermissionService * @param perms LocalPermissionService
*/ */
@ -87,6 +88,8 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
titleService: Title, titleService: Title,
translate: TranslateService, translate: TranslateService,
matSnackBar: MatSnackBar, matSnackBar: MatSnackBar,
sortService: MotionSortListService,
filterService: MotionFilterListService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute,
private configService: ConfigService, private configService: ConfigService,
@ -101,11 +104,9 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
private dialog: MatDialog, private dialog: MatDialog,
private vp: ViewportService, private vp: ViewportService,
public multiselectService: MotionMultiselectService, public multiselectService: MotionMultiselectService,
public sortService: MotionSortListService,
public filterService: MotionFilterListService,
public perms: LocalPermissionsService public perms: LocalPermissionsService
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar, filterService, sortService);
// enable multiSelect for this listView // enable multiSelect for this listView
this.canMultiSelect = true; this.canMultiSelect = true;
@ -130,11 +131,6 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
this.categoryRepo.getSortedViewModelListObservable().subscribe(cats => (this.categories = cats)); this.categoryRepo.getSortedViewModelListObservable().subscribe(cats => (this.categories = cats));
this.tagRepo.getViewModelListObservable().subscribe(tags => (this.tags = tags)); this.tagRepo.getViewModelListObservable().subscribe(tags => (this.tags = tags));
this.workflowRepo.getViewModelListObservable().subscribe(wfs => (this.workflows = wfs)); this.workflowRepo.getViewModelListObservable().subscribe(wfs => (this.workflows = wfs));
this.filterService.filter().subscribe(filteredData => (this.sortService.data = filteredData));
this.sortService.sort().subscribe(sortedData => {
this.dataSource.data = sortedData;
this.checkSelection();
});
this.setFulltextFilter(); this.setFulltextFilter();
} }

View File

@ -19,7 +19,7 @@ import { Workflow } from 'app/shared/models/motions/workflow';
templateUrl: './workflow-list.component.html', templateUrl: './workflow-list.component.html',
styleUrls: ['./workflow-list.component.scss'] styleUrls: ['./workflow-list.component.scss']
}) })
export class WorkflowListComponent extends ListViewBaseComponent<ViewWorkflow> implements OnInit { export class WorkflowListComponent extends ListViewBaseComponent<ViewWorkflow, Workflow> implements OnInit {
/** /**
* Holds the new workflow title * Holds the new workflow title
*/ */

View File

@ -21,7 +21,7 @@ import { MatSnackBar } from '@angular/material';
templateUrl: './tag-list.component.html', templateUrl: './tag-list.component.html',
styleUrls: ['./tag-list.component.css'] styleUrls: ['./tag-list.component.css']
}) })
export class TagListComponent extends ListViewBaseComponent<ViewTag> implements OnInit { export class TagListComponent extends ListViewBaseComponent<ViewTag, Tag> implements OnInit {
public editTag = false; public editTag = false;
public newTag = false; public newTag = false;
public selectedTag: ViewTag; public selectedTag: ViewTag;
@ -55,7 +55,9 @@ export class TagListComponent extends ListViewBaseComponent<ViewTag> implements
super.setTitle('Tags'); super.setTitle('Tags');
this.initTable(); this.initTable();
this.tagForm = new FormGroup({ name: new FormControl('', Validators.required) }); this.tagForm = new FormGroup({ name: new FormControl('', Validators.required) });
// TODO Tag has not yet sort or filtering functions
this.repo.getViewModelListObservable().subscribe(newTags => { this.repo.getViewModelListObservable().subscribe(newTags => {
this.dataSource.data = [];
this.dataSource.data = newTags; this.dataSource.data = newTags;
}); });
} }

View File

@ -18,7 +18,7 @@ import { ViewportService } from 'app/core/ui-services/viewport.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService } from 'app/core/core-services/operator.service';
import { ViewUser } from '../../models/view-user'; import { ViewUser } from '../../models/view-user';
import { ViewGroup } from '../../models/view-group'; import { ViewGroup } from '../../models/view-group';
import { genders } from 'app/shared/models/users/user'; import { genders, User } from 'app/shared/models/users/user';
/** /**
* Interface for the short editing dialog. * Interface for the short editing dialog.
@ -55,7 +55,7 @@ interface InfoDialog {
templateUrl: './user-list.component.html', templateUrl: './user-list.component.html',
styleUrls: ['./user-list.component.scss'] styleUrls: ['./user-list.component.scss']
}) })
export class UserListComponent extends ListViewBaseComponent<ViewUser> implements OnInit { export class UserListComponent extends ListViewBaseComponent<ViewUser, User> implements OnInit {
/** /**
* The reference to the template. * The reference to the template.
*/ */
@ -147,7 +147,7 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
private userPdf: UserPdfExportService, private userPdf: UserPdfExportService,
private dialog: MatDialog private dialog: MatDialog
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar, filterService, sortService);
// enable multiSelect for this listView // enable multiSelect for this listView
this.canMultiSelect = true; this.canMultiSelect = true;
@ -163,14 +163,6 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
public ngOnInit(): void { public ngOnInit(): void {
super.setTitle(this.translate.instant('Participants')); super.setTitle(this.translate.instant('Participants'));
this.initTable(); this.initTable();
this.filterService.filter().subscribe(filteredData => {
this.sortService.data = filteredData;
});
this.sortService.sort().subscribe(sortedData => {
this.dataSource.data = sortedData;
this.checkSelection();
});
this.setFulltextFilter(); this.setFulltextFilter();
// Initialize the groups // Initialize the groups