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

Feature/123 refactor sorting of report code column #331

Merged
merged 23 commits into from
Jun 10, 2022
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
7 changes: 5 additions & 2 deletions front-end/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { spinnerReducer } from './store/spinner.reducer';
import { CommitteeAccountEffects } from './store/committee-account.effects';
import { LoginEffects } from './store/login.effects';
import { AppState } from './store/app-state.model';
import { labelLookupReducer } from './store/label-lookup.reducer';
import { LabelLookupEffects } from './store/label-lookup.effects';

// PrimeNG
import { ConfirmationService, MessageService } from 'primeng/api';
Expand Down Expand Up @@ -45,7 +47,7 @@ import { HttpErrorInterceptor } from './shared/interceptors/http-error.intercept
// Save ngrx store to localStorage dynamically
function localStorageSyncReducer(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
return localStorageSync({
keys: ['committeeAccount', 'spinnerOn', 'userLoginData'],
keys: ['committeeAccount', 'spinnerOn', 'userLoginData', 'reportCodeLabelList'],
storageKeySerializer: (key) => `fecfile_online_${key}`,
rehydrate: true,
})(reducer);
Expand Down Expand Up @@ -77,10 +79,11 @@ const metaReducers: Array<MetaReducer<AppState, Action>> = [localStorageSyncRedu
committeeAccount: committeeAccountReducer,
spinnerOn: spinnerReducer,
userLoginData: loginReducer,
reportCodeLabelList: labelLookupReducer,
},
{ metaReducers }
),
EffectsModule.forRoot([CommitteeAccountEffects, LoginEffects]),
EffectsModule.forRoot([CommitteeAccountEffects, LoginEffects, LabelLookupEffects]),
MenubarModule,
MenuModule,
PanelModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ <h5 class="m-0">Recent reports</h5>
<th pSortableColumn="TBD" id="form-type-column" role="columnheader">
Form type <p-sortIcon field="TBD"></p-sortIcon>
</th>
<th pSortableColumn="report_code_label" id="report-code-column" role="columnheader">
Type of report <p-sortIcon field="report_code_label"></p-sortIcon>
<th pSortableColumn="report_code__label" id="report-code-column" role="columnheader">
Type of report <p-sortIcon field="report_code__label"></p-sortIcon>
</th>
<th pSortableColumn="coverage_through_date" id="coverage-dates-column" role="columnheader">
Coverage dates <p-sortIcon field="coverage_through_date"></p-sortIcon>
Expand All @@ -59,7 +59,7 @@ <h5 class="m-0">Recent reports</h5>
<ng-template pTemplate="body" let-item>
<tr role="row">
<td>{{ item.form_type | label: f3xFormTypeLabels }}</td>
<td>{{ item.report_code | label: f3xReportCodeLabels }}</td>
<td>{{ (this.reportCodeLabelList$ | async | findOnReportCodePipe: item.report_code)?.label }}</td>
<td>
<ng-container *ngIf="item.coverage_from_date || item.coverage_through_date"
>{{ item.coverage_from_date | fecDate }} - {{ item.coverage_through_date | fecDate }}</ng-container
Expand Down
26 changes: 17 additions & 9 deletions front-end/src/app/reports/report-list/report-list.component.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { Component, ElementRef } from '@angular/core';
import { Component, ElementRef, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { ConfirmationService, MessageService } from 'primeng/api';
import { TableListBaseComponent } from '../../shared/components/table-list-base/table-list-base.component';
import { Report } from '../../shared/interfaces/report.interface';
import { LabelList } from '../../shared/utils/label.utils';
import { ReportCodeLabelList } from '../../shared/utils/reportCodeLabels.utils';
import { ReportService } from '../../shared/services/report.service';
import {
F3xSummary,
F3xFormTypeLabels,
F3xReportCodeLabels,
F3xFormVersionLabels,
} from 'app/shared/models/f3x-summary.model';
import { F3xSummary, F3xFormTypeLabels, F3xFormVersionLabels } from 'app/shared/models/f3x-summary.model';
import { Router } from '@angular/router';
import { selectReportCodeLabelList } from 'app/store/label-lookup.selectors';
import { updateLabelLookupAction } from '../../store/label-lookup.actions';

@Component({
selector: 'app-report-list',
templateUrl: './report-list.component.html',
})
export class ReportListComponent extends TableListBaseComponent<Report> {
export class ReportListComponent extends TableListBaseComponent<Report> implements OnInit {
f3xFormTypeLabels: LabelList = F3xFormTypeLabels;
f3xReportCodeLabels: LabelList = F3xReportCodeLabels;
f3xFormVerionLabels: LabelList = F3xFormVersionLabels;
reportCodeLabelList$: Observable<ReportCodeLabelList> = new Observable<ReportCodeLabelList>();

constructor(
private store: Store,
protected override messageService: MessageService,
protected override confirmationService: ConfirmationService,
protected override elementRef: ElementRef,
Expand All @@ -31,6 +32,13 @@ export class ReportListComponent extends TableListBaseComponent<Report> {
super(messageService, confirmationService, elementRef);
}

override ngOnInit() {
this.loading = true;
this.loadItemService(this.itemService);
this.reportCodeLabelList$ = this.store.select<ReportCodeLabelList>(selectReportCodeLabelList);
this.store.dispatch(updateLabelLookupAction());
}

protected getEmptyItem(): F3xSummary {
return new F3xSummary();
}
Expand Down
37 changes: 37 additions & 0 deletions front-end/src/app/shared/pipes/report-code-label-list.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ReportCodeLabelList } from '../utils/reportCodeLabels.utils';
import { FindOnReportCodePipe } from './report-code-label-list.pipe';

describe('FindOnReportCodePipe', () => {
const labelList: ReportCodeLabelList = [
{
label: 'Quarter 1',
report_code: 'Q1',
},
{
label: 'Quarter 2',
report_code: 'Q2',
},
];
let pipe: FindOnReportCodePipe;

beforeEach(() => {
pipe = new FindOnReportCodePipe();
});

it('create an instance', () => {
expect(pipe).toBeTruthy();
});

it('transforms should return a ReportCodeLabel object', () => {
expect(pipe.transform(labelList, 'Q1')).toEqual({ label: 'Quarter 1', report_code: 'Q1' });
expect(pipe.transform(labelList, 'Q2')).toEqual({ label: 'Quarter 2', report_code: 'Q2' });
});

it('transforms should return empty ReportCodeLabel object if no label found', () => {
expect(pipe.transform(labelList, 'does-not-exist')).toBe(undefined);
});

it('transforms should return an empty ReportCodeLabel object if the labelList is null', () => {
expect(pipe.transform(null, 'Q1')).toBe(undefined);
});
});
14 changes: 14 additions & 0 deletions front-end/src/app/shared/pipes/report-code-label-list.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ReportCodeLabelList, ReportCodeLabel } from '../utils/reportCodeLabels.utils';

@Pipe({ name: 'findOnReportCodePipe' })
export class FindOnReportCodePipe implements PipeTransform {
toddlees marked this conversation as resolved.
Show resolved Hide resolved
transform(list: ReportCodeLabelList | null, reportCode: string): ReportCodeLabel | undefined {
let label: ReportCodeLabel | undefined = undefined;

if (list != undefined && list?.length > 0) {
label = list.find((item) => item.report_code == reportCode);
}
return label;
}
}
5 changes: 3 additions & 2 deletions front-end/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LabelPipe } from './pipes/label.pipe';
import { FindOnReportCodePipe } from './pipes/report-code-label-list.pipe';
import { ErrorMessagesComponent } from './components/error-messages/error-messages.component';
import { FecDatePipe } from './pipes/fec-date.pipe';

@NgModule({
imports: [CommonModule],
declarations: [LabelPipe, ErrorMessagesComponent, FecDatePipe],
exports: [FecDatePipe, LabelPipe, ErrorMessagesComponent],
declarations: [LabelPipe, ErrorMessagesComponent, FecDatePipe, FindOnReportCodePipe],
exports: [FecDatePipe, LabelPipe, ErrorMessagesComponent, FindOnReportCodePipe],
})
export class SharedModule {}
1 change: 0 additions & 1 deletion front-end/src/app/shared/utils/label.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type LabelList = string[][];

export type PrimeOptions = { name: string; code: string }[];

/**
Expand Down
2 changes: 2 additions & 0 deletions front-end/src/app/shared/utils/reportCodeLabels.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type ReportCodeLabel = { report_code: string; label: string };
export type ReportCodeLabelList = ReportCodeLabel[];
2 changes: 2 additions & 0 deletions front-end/src/app/store/app-state.model.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { CommitteeAccount } from 'app/shared/models/committee-account.model';
import { UserLoginData } from 'app/shared/models/user.model';
import { ReportCodeLabelList } from '../shared/utils/reportCodeLabels.utils';

export interface AppState {
committeeAccount: CommitteeAccount;
spinnerOn: boolean;
userLoginData: UserLoginData;
reportCodeLabelList: ReportCodeLabelList;
}
10 changes: 10 additions & 0 deletions front-end/src/app/store/label-lookup.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createAction, props } from '@ngrx/store';
import { ReportCodeLabelList } from '../shared/utils/reportCodeLabels.utils';

export const setLabelLookupAction = createAction(
'[Label Lookup] Report Code Labels Retrieved',
props<{ payload: ReportCodeLabelList }>()
);

export const errorRetrievingLabelLookupAction = createAction('[Label Lookup] Report Code Labels Retrieval Error');
export const updateLabelLookupAction = createAction('[Label List] Update Report Code Labels');
32 changes: 32 additions & 0 deletions front-end/src/app/store/label-lookup.effects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { first, of } from 'rxjs';
import { map, mergeMap, catchError } from 'rxjs/operators';
import {
setLabelLookupAction,
errorRetrievingLabelLookupAction,
updateLabelLookupAction,
} from './label-lookup.actions';
import { ApiService } from '../shared/services/api.service';
import { ReportCodeLabelList } from '../shared/utils/reportCodeLabels.utils';

@Injectable()
export class LabelLookupEffects {
constructor(private actions$: Actions, private apiService: ApiService) {}

loadLabelLookup$ = createEffect(() =>
this.actions$.pipe(
ofType(updateLabelLookupAction.type),
first(),
mergeMap(() =>
this.apiService.get<ReportCodeLabelList>('/report-code-labels').pipe(
map((reportCodeLabelList: ReportCodeLabelList) => ({
type: setLabelLookupAction.type,
payload: reportCodeLabelList,
})),
catchError(() => of({ type: errorRetrievingLabelLookupAction.type }))
)
)
)
);
}
14 changes: 14 additions & 0 deletions front-end/src/app/store/label-lookup.reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createReducer, on, Action } from '@ngrx/store';
import { setLabelLookupAction } from './label-lookup.actions';
import { ReportCodeLabelList } from '../shared/utils/reportCodeLabels.utils';

export const initialState: ReportCodeLabelList = [];

const _labelLookupReducer = createReducer(
initialState,
on(setLabelLookupAction, (_state, update) => update.payload)
);

export function labelLookupReducer(state: ReportCodeLabelList | undefined, action: Action) {
return _labelLookupReducer(state, action);
}
4 changes: 4 additions & 0 deletions front-end/src/app/store/label-lookup.selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createFeatureSelector } from '@ngrx/store';
import { ReportCodeLabelList } from '../shared/utils/reportCodeLabels.utils';

export const selectReportCodeLabelList = createFeatureSelector<ReportCodeLabelList>('reportCodeLabelList');