Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faulty list view when back navigating #1243

Merged
merged 9 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/app/core/models/table-settings.model.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest the member fields to have proper type annotation, so that the compiler can detect errors if the fields are not assigned the correct value. Also, the fields should have proper initial values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linter prevents me from adding type annotations to member fields that are initialized. Error: no-inferrable-types.
The initial values used are also what I deem proper as initially the tables are not sorted at all, internally matsort is initialised with an empty string which is what I am emulating here.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class TableSettings {
public sortActiveId = ''; // The ID of the column the table is sorted by
public sortDirection = '';
public pageSize = 20;
public pageIndex = 0;
}
25 changes: 25 additions & 0 deletions src/app/core/services/issue-table-settings.service.ts
cheehongw marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { TableSettings } from '../models/table-settings.model';
@Injectable({
providedIn: 'root'
})

/**
* Responsible for storing and retrieving the table settings for issue tables created
* Map is required since there can be multiple tables within the same page
*/
export class IssueTableSettingsService {
private _tableSettingsMap: { [index: string]: TableSettings } = {};

public getTableSettings(tableName: string): TableSettings {
return this._tableSettingsMap[tableName] || new TableSettings();
}

public setTableSettings(tableName: string, tableSettings: TableSettings): void {
this._tableSettingsMap[tableName] = tableSettings;
}

public clearTableSettings(): void {
this._tableSettingsMap = {};
}
}
17 changes: 15 additions & 2 deletions src/app/shared/issue-tables/issue-tables.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<mat-table [dataSource]="this.issues" matSort class="mat-elevation-z8">
<mat-table
[dataSource]="this.issues"
matSort
[matSortActive]="this.tableSettings.sortActiveId"
[matSortDirection]="this.tableSettings.sortDirection"
(matSortChange)="this.sortChange($event)"
class="mat-elevation-z8"
>
<!-- ID Column -->
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
Expand Down Expand Up @@ -262,4 +269,10 @@
<mat-card *ngIf="this.issues.isLoading$ | async" style="display: flex; justify-content: center; align-items: center">
<mat-progress-spinner color="primary" mode="indeterminate" diameter="50" strokeWidth="5"></mat-progress-spinner>
</mat-card>
<mat-paginator [paginatorLocalStorage]="this.table_name" [pageSize]="20" [pageSizeOptions]="[10, 20, 50]"></mat-paginator>
<mat-paginator
[paginatorLocalStorage]="this.table_name"
[pageSize]="this.tableSettings.pageSize"
[pageSizeOptions]="[10, 20, 50]"
[pageIndex]="this.tableSettings.pageIndex"
(page)="this.pageChange($event)"
></mat-paginator>
22 changes: 20 additions & 2 deletions src/app/shared/issue-tables/issue-tables.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatSort } from '@angular/material/sort';
import { MatSort, Sort } from '@angular/material/sort';
import { finalize } from 'rxjs/operators';
import { Issue, STATUS } from '../../core/models/issue.model';
import { TableSettings } from '../../core/models/table-settings.model';
import { DialogService } from '../../core/services/dialog.service';
import { ErrorHandlingService } from '../../core/services/error-handling.service';
import { GithubService } from '../../core/services/github.service';
import { IssueTableSettingsService } from '../../core/services/issue-table-settings.service';
import { IssueService } from '../../core/services/issue.service';
import { LabelService } from '../../core/services/label.service';
import { LoggingService } from '../../core/services/logging.service';
Expand Down Expand Up @@ -44,6 +46,8 @@ export class IssueTablesComponent implements OnInit, AfterViewInit {
issues: IssuesDataTable;
issuesPendingDeletion: { [id: number]: boolean };

public tableSettings: TableSettings;

public readonly action_buttons = ACTION_BUTTONS;

// Messages for the modal popup window upon deleting an issue
Expand All @@ -57,6 +61,7 @@ export class IssueTablesComponent implements OnInit, AfterViewInit {
public labelService: LabelService,
private githubService: GithubService,
public issueService: IssueService,
public issueTableSettingsService: IssueTableSettingsService,
private phaseService: PhaseService,
private errorHandlingService: ErrorHandlingService,
private logger: LoggingService,
Expand All @@ -67,6 +72,7 @@ export class IssueTablesComponent implements OnInit, AfterViewInit {
ngOnInit() {
this.issues = new IssuesDataTable(this.issueService, this.sort, this.paginator, this.headers, this.filters);
this.issuesPendingDeletion = {};
this.tableSettings = this.issueTableSettingsService.getTableSettings(this.table_name);
}

ngAfterViewInit(): void {
Expand All @@ -75,6 +81,18 @@ export class IssueTablesComponent implements OnInit, AfterViewInit {
});
}

sortChange(newSort: Sort) {
this.tableSettings.sortActiveId = newSort.active;
this.tableSettings.sortDirection = newSort.direction;
this.issueTableSettingsService.setTableSettings(this.table_name, this.tableSettings);
}

pageChange(pageEvent: PageEvent) {
this.tableSettings.pageSize = pageEvent.pageSize;
this.tableSettings.pageIndex = pageEvent.pageIndex;
this.issueTableSettingsService.setTableSettings(this.table_name, this.tableSettings);
}

Comment on lines +84 to +95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the best practice to sync settings of a table component with the service. I would suggest the following:

  • Service's settings values to be of type Observable<TableSettings>
  • Table component settings to sync with service's settings value using Observable::subscribe
  • In these methods, only call issueTableSettingsService::setTableSettings

@CATcher-org/2324s2 What do yall think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case wouldn't I still need these two functions to update the TableSettings in the service.
I am not sure of the benefit of the observable implementation since the only things listening and emitting these changes is from the tables component.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't see the benefit for observables too. I think an observable implementation is beneficial if we have more than 1 table listening to the same set of settings but so far we are saving the settings for each table (or to be more precise table_name, but currently each table has a unique table_name).

isActionVisible(action: ACTION_BUTTONS): boolean {
return this.actions.includes(action);
}
Expand Down
7 changes: 6 additions & 1 deletion src/app/shared/layout/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DialogService } from '../../core/services/dialog.service';
import { ErrorHandlingService } from '../../core/services/error-handling.service';
import { GithubService } from '../../core/services/github.service';
import { GithubEventService } from '../../core/services/githubevent.service';
import { IssueTableSettingsService } from '../../core/services/issue-table-settings.service';
import { IssueService } from '../../core/services/issue.service';
import { LoggingService } from '../../core/services/logging.service';
import { PhaseDescription, PhaseService } from '../../core/services/phase.service';
Expand Down Expand Up @@ -45,7 +46,8 @@ export class HeaderComponent implements OnInit {
private issueService: IssueService,
private errorHandlingService: ErrorHandlingService,
private githubService: GithubService,
private dialogService: DialogService
private dialogService: DialogService,
private issueTableSettingsService: IssueTableSettingsService
) {
router.events
.pipe(
Expand Down Expand Up @@ -81,6 +83,9 @@ export class HeaderComponent implements OnInit {
this.issueService.reset(false);
this.reload();

// Reset Issue Table Settings
this.issueTableSettingsService.clearTableSettings();

// Route app to new phase.
this.router.navigateByUrl(this.phaseService.currentPhase);
}
Expand Down
Loading