Skip to content

Commit

Permalink
feat: #572 public search by fom (#615)
Browse files Browse the repository at this point in the history
* Initial add new search field (fom  #) projectId

* Add new projectId for ProjectFindCriteria.

* Update swagger spec for projectId search field addition.

* Add fomNumberFilter to public

* Add api-cliebnt for new 'projectId' search field for findPublicSummary.

* Add 'fomNumberParam' filter to public Find component and api call.

* Try removing inline javascript.

* Using type="text" instead of "number" type and add listener verifyFomNumberInput to restrict value.

* minor wording.
  • Loading branch information
ianliuwk1019 authored Apr 10, 2024
1 parent f98e1d5 commit 6cd10bb
Show file tree
Hide file tree
Showing 8 changed files with 2,660 additions and 2,607 deletions.
5,212 changes: 2,610 additions & 2,602 deletions api/openapi/swagger-spec.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions api/src/app/modules/project/project.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ export class ProjectController {
// Anonymous access allowed
@Get('/publicSummary')
@AuthGuardMeta(GUARD_OPTIONS.PUBLIC)
@ApiQuery({ name: 'projectId', required: false})
@ApiQuery({ name: 'includeCommentOpen', required: false})
@ApiQuery({ name: 'includePostCommentOpen', required: false})
@ApiQuery({ name: 'forestClientName', required: false})
@ApiQuery({ name: 'openedOnOrAfter', required: false})
@ApiResponse({ status: HttpStatus.OK, type: [ProjectPublicSummaryResponse] })
async findPublicSummary(
@Query('projectId') projectId?: string,
@Query('includeCommentOpen') includeCommentOpen: string = 'true',
@Query('includePostCommentOpen') includePostCommentOpen: string = 'true',
@Query('forestClientName') forestClientName?: string,
Expand All @@ -36,6 +38,10 @@ export class ProjectController {

const findCriteria: ProjectFindCriteria = new ProjectFindCriteria();

if (projectId) {
findCriteria.projectId = await new ParseIntPipe().transform(projectId, null);
}

if (forestClientName) {
findCriteria.likeForestClientName = forestClientName;
}
Expand Down
4 changes: 4 additions & 0 deletions api/src/app/modules/project/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ export class ProjectFindCriteria {
fspId?: number;
districtId?: number;
includeForestClientNumbers: string[] = [];
projectId?: number;

applyFindCriteria(query: SelectQueryBuilder<Project>) {
if (this.projectId) {
query.andWhere("p.id = :projectId", {projectId: this.projectId})
}
if (this.fspId) {
query.andWhere("p.fsp_id = :fspId", {fspId: `${this.fspId}`});
}
Expand Down
13 changes: 9 additions & 4 deletions libs/client/typescript-ng/api/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,19 +455,24 @@ export class ProjectService {
}

/**
* @param projectId
* @param includeCommentOpen
* @param includePostCommentOpen
* @param forestClientName
* @param openedOnOrAfter
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public projectControllerFindPublicSummary(includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<Array<ProjectPublicSummaryResponse>>;
public projectControllerFindPublicSummary(includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<Array<ProjectPublicSummaryResponse>>>;
public projectControllerFindPublicSummary(includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<Array<ProjectPublicSummaryResponse>>>;
public projectControllerFindPublicSummary(includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {
public projectControllerFindPublicSummary(projectId?: string, includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<Array<ProjectPublicSummaryResponse>>;
public projectControllerFindPublicSummary(projectId?: string, includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<Array<ProjectPublicSummaryResponse>>>;
public projectControllerFindPublicSummary(projectId?: string, includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<Array<ProjectPublicSummaryResponse>>>;
public projectControllerFindPublicSummary(projectId?: string, includeCommentOpen?: string, includePostCommentOpen?: string, forestClientName?: string, openedOnOrAfter?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> {

let queryParameters = new HttpParams({encoder: this.encoder});
if (projectId !== undefined && projectId !== null) {
queryParameters = this.addToHttpParams(queryParameters,
<any>projectId, 'projectId');
}
if (includeCommentOpen !== undefined && includeCommentOpen !== null) {
queryParameters = this.addToHttpParams(queryParameters,
<any>includeCommentOpen, 'includeCommentOpen');
Expand Down
13 changes: 12 additions & 1 deletion public/src/app/applications/find-panel/find-panel.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ <h3 class="title">Find FOM</h3>

<div class="flex-panel__scroll">
<div class="find-form">
<div class="form-group">
<label class="control-label">FOM #</label>
<input id="fomNumberInput" type="text"
class="form-control limit-width-1"
[maxlength]="maxInputLength"
(keyup)="verifyFomNumberInput($event)"
(keyup.enter)="applyAllFilters()"
(mousewheel)="$event.preventDefault()"
[(ngModel)]="fomNumberFilter.filter.value" />
</div>

<div class="form-group">
<label class="control-label">FOM Holder Name (or portion)</label>
<input id="forestClientNameInput" type="text"
Expand Down Expand Up @@ -81,4 +92,4 @@ <h3>What is a FOM Holder Name?</h3>
</section>

</div>
</div>
</div>
13 changes: 13 additions & 0 deletions public/src/app/applications/find-panel/find-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ export class FindPanelComponent implements OnDestroy, OnInit {
private ngUnsubscribe: Subject<void> = new Subject<void>();
public workflowState: _.Dictionary<WorkflowStateCode>;
private fomFilters: Map<string, IFilter | IMultiFilter>;
public fomNumberFilter = new Filter<number>({ filter: { queryParam: 'fomNumber', value: null }});
public forestClientNameFilter = new Filter<string>({ filter: { queryParam: 'fcName', value: null }});
public commentStatusFilters: MultiFilter<boolean>; // For 'Commenting Open' or 'Commenting Closed'.
public postedOnAfterFilter = new Filter<Date>({ filter: { queryParam: 'pdOnAfter', value: null } });
readonly minDate = moment('2018-03-23').toDate(); // first app created
readonly maxDate = moment().toDate(); // today
readonly maxInputLength = 9;

constructor(public urlSvc: UrlService,
private fomFiltersSvc: FOMFiltersService) {
Expand All @@ -52,6 +54,7 @@ export class FindPanelComponent implements OnDestroy, OnInit {
ngOnInit(): void {
this.fomFiltersSvc.filters$.pipe(takeUntil(this.ngUnsubscribe)).subscribe((filters) => {
this.fomFilters = filters;
this.fomNumberFilter = this.fomFilters.get(FOM_FILTER_NAME.FOM_NUMBER) as Filter<number>;
this.forestClientNameFilter = this.fomFilters.get(FOM_FILTER_NAME.FOREST_CLIENT_NAME) as Filter<string>;
this.commentStatusFilters = this.fomFilters.get(FOM_FILTER_NAME.COMMENT_STATUS) as MultiFilter<boolean>;
this.postedOnAfterFilter = this.fomFilters.get(FOM_FILTER_NAME.POSTED_ON_AFTER) as Filter<Date>;
Expand All @@ -67,6 +70,7 @@ export class FindPanelComponent implements OnDestroy, OnInit {
*/
public checkAndSetFiltersHash(): boolean {
const newFilterHash = FilterUtils.hashFilters(
this.fomNumberFilter,
this.forestClientNameFilter,
this.commentStatusFilters,
this.postedOnAfterFilter);
Expand Down Expand Up @@ -98,6 +102,15 @@ export class FindPanelComponent implements OnDestroy, OnInit {
}
}

public verifyFomNumberInput(event) {
let parsed = parseInt(event.target.value.toString().replace(/^0+(?=\d)/, ''), 10);
// fomNumber search field is a positive integer excluding 0;
if (isNaN(parsed) || parsed == 0) {
parsed = null;
}
this.fomNumberFilter.filter.value = parsed;
}

/**
* Emit the current selected filters to the parent, if the filters have changed since the last time emit was called.
*
Expand Down
2 changes: 2 additions & 0 deletions public/src/app/applications/projects.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export class ProjectsComponent implements OnInit, OnDestroy {
}

fetchFOMs(fomFilters: Map<string, IFilter | IMultiFilter>) {
const fomNumberParam = (fomFilters.get(FOM_FILTER_NAME.FOM_NUMBER) as Filter<number>).filter.value;
const forestClientNameParam = (fomFilters.get(FOM_FILTER_NAME.FOREST_CLIENT_NAME) as Filter<string>).filter.value;
const commentStatusFilters = fomFilters.get(FOM_FILTER_NAME.COMMENT_STATUS)['filters'] as Array<IMultiFilterFields<boolean>>;
const commentOpenParam = commentStatusFilters.filter(filter => filter.queryParam == COMMENT_STATUS_FILTER_PARAMS.COMMENT_OPEN)[0].value;
Expand All @@ -173,6 +174,7 @@ export class ProjectsComponent implements OnInit, OnDestroy {
this.loading = true;
this.projectService
.projectControllerFindPublicSummary(
fomNumberParam?.toString(),
commentOpenParam.toString(),
commentClosedParam.toString(),
forestClientNameParam,
Expand Down
4 changes: 4 additions & 0 deletions public/src/core/services/fomFilters.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
import { Filter, IFilter, IMultiFilter, IMultiFilterFields, MultiFilter } from '../../app/applications/utils/filter';

export enum FOM_FILTER_NAME {
FOM_NUMBER = 'fomNumber',
FOREST_CLIENT_NAME = 'fcName',
POSTED_ON_AFTER = 'pdOnAfter',
COMMENT_STATUS = 'cmtStatus'
Expand All @@ -22,6 +23,7 @@ export const COMMENT_STATUS_FILTER_PARAMS = {
(However, that inteface definition is kind of strange, may need to review/refactor later.)
*/
export const DEFAULT_FOM_FILTERS = {
fomNumberFilter: { filter: {queryParam: FOM_FILTER_NAME.FOM_NUMBER, value: null }},
fcNameFilter: { filter: {queryParam: FOM_FILTER_NAME.FOREST_CLIENT_NAME, value: null }},
postedOnAfterFilter: { filter: {queryParam: FOM_FILTER_NAME.POSTED_ON_AFTER, value: null }},
commentStatusFilters: {
Expand Down Expand Up @@ -89,9 +91,11 @@ export class FOMFiltersService {

_getDefaultFilters(): Map<string, IFilter|IMultiFilter> {
let defaultFilters = new Map();
const fomNumberFilter = new Filter<string>(AppUtils.copy(DEFAULT_FOM_FILTERS.fomNumberFilter));
const forestClientNameFilter = new Filter<string>(AppUtils.copy(DEFAULT_FOM_FILTERS.fcNameFilter));
const postedOnAfterFilter = new Filter<Date>(AppUtils.copy(DEFAULT_FOM_FILTERS.postedOnAfterFilter));
const commentStatusFilters = new MultiFilter<boolean>(AppUtils.copy(DEFAULT_FOM_FILTERS.commentStatusFilters));
defaultFilters.set(FOM_FILTER_NAME.FOM_NUMBER, fomNumberFilter);
defaultFilters.set(FOM_FILTER_NAME.FOREST_CLIENT_NAME, forestClientNameFilter);
defaultFilters.set(FOM_FILTER_NAME.POSTED_ON_AFTER, postedOnAfterFilter);
defaultFilters.set(FOM_FILTER_NAME.COMMENT_STATUS, commentStatusFilters);
Expand Down

0 comments on commit 6cd10bb

Please sign in to comment.