From 337ee0e4fa6063415d68ebced63f9ac42cbd4c78 Mon Sep 17 00:00:00 2001 From: Craig Yu Date: Wed, 11 Sep 2024 12:20:57 -0700 Subject: [PATCH 1/7] fix: add isCommentingOpen state --- .../fom-add-edit/fom-add-edit.component.ts | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts index 1887fa54..f2a6d5e2 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts @@ -38,11 +38,11 @@ type ApplicationPageType = 'create' | 'edit'; @Component({ standalone: true, imports: [ - NgIf, - FormsModule, - ReactiveFormsModule, - BsDatepickerModule, - NgClass, + NgIf, + FormsModule, + ReactiveFormsModule, + BsDatepickerModule, + NgClass, NgFor, AppFormControlDirective, NewlinesPipe, @@ -69,6 +69,7 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { public districtIdSelect: any = null; public forestClientSelect: any = null; public isPublishState: boolean = false; + public isCommentingOpen: boolean = false; files: any[] = []; maxFileSize: number = MAX_FILEUPLOAD_SIZE.DOCUMENT; publicNoticeContent: any; @@ -97,12 +98,12 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { private scrollToFragment: string = null; private snackBarRef: MatSnackBarRef = null; private ngUnsubscribe: Subject = new Subject(); - + // bsDatepicker config object readonly bsConfig = { - dateInputFormat: 'YYYY', - minMode: 'year', - minDate: moment().toDate(), + dateInputFormat: 'YYYY', + minMode: 'year', + minDate: moment().toDate(), maxDate: moment().add(7, 'years').toDate(), // current + 7 years containerClass: 'theme-dark-blue' } as Partial @@ -127,7 +128,7 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { get isCreate() { return this.state === 'create'; } - + get isLoading() { return this.stateSvc.loading; } @@ -172,6 +173,8 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { this.isPublishState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.Published; + this.isCommentingOpen = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.CommentOpen; + this.attachmentResolverSvc.getAttachments(this.originalProjectResponse.id) .then( (result) => { for(const attachmentResponse of result ) { @@ -335,11 +338,11 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { this.fg.get('forestClient').setValue(forestClientField.value); this.forestClientSelect = parseInt(forestClientField.value.id); - // 'TIMBER SALES MANAGER' name field is required (to be validated) based on forestClient name - // conditionally. Due to it's validation is annotation-based in fom-add-edit.form.ts + // 'TIMBER SALES MANAGER' name field is required (to be validated) based on forestClient name + // conditionally. Due to it's validation is annotation-based in fom-add-edit.form.ts // (using @rxweb/reactive-form-validators), when forestClient is changed, bctsMgrName does not get // rerenderred (no ngIf, ngFor etc on this field). - // Just trigger the dynamic form field (with enable()) is probably easier than using 'ChangeDetectorRef'. + // Just trigger the dynamic form field (with enable()) is probably easier than using 'ChangeDetectorRef'. this.fg.get('bctsMgrName').enable(); } @@ -356,7 +359,7 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { } /* - * Closed Date cannot be before (30 days after Comment Opening Date) + * Closed Date cannot be before (30 days after Comment Opening Date) * if FOM status is in 'Commenting Open". */ validateClosedDate(closedDate: Date): void { @@ -457,7 +460,7 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { const commentingClosedDateField = fg.get('commentingClosedDate'); const closeDatePipe = this.datePipe.transform(fg.value.commentingClosedDate,'yyyy-MM-dd'); commentingClosedDateField.setValue(closeDatePipe); - if ((user.isMinistry && !user.isForestClient) || + if ((user.isMinistry && !user.isForestClient) || commentingOpenDateField.value == null) { commentingClosedDateField.disable(); } @@ -479,4 +482,4 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { return control?.touched || control?.dirty; } -} \ No newline at end of file +} From 5691e85c61f50bf3a99766f18222978cdf71d17e Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Wed, 11 Sep 2024 14:50:05 -0700 Subject: [PATCH 2/7] adjust admin add/edit form condition for some fields so that it should not be editable during commenting open --- .../fom-add-edit/fom-add-edit.component.html | 220 +++++++++++++----- .../fom-add-edit/fom-add-edit.component.ts | 17 +- 2 files changed, 177 insertions(+), 60 deletions(-) diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html index ea683bfd..12f14686 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html @@ -37,7 +37,7 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
-
+
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' [value]="originalProjectResponse.id" />
+
-
+
+
+ +
+ +
+
-
- -
+
-
+
+
+ +
+ +
+
-
- -
@@ -109,8 +136,9 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
- + {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' [bsConfig]="bsConfig" [appFormControl]="fg.get('opStartDate')" /> +
@@ -130,8 +168,9 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '

- + {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' [bsConfig]="bsConfig" [appFormControl]="fg.get('opEndDate')" /> +
@@ -159,8 +208,8 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
- - {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' [selected]="option.code === fg.get('projectPlanCode').value" [innerHTML]="option.description"> - {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
- {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' formControlName="fspId" [appFormControl]="fg.get('fspId')" /> +
{{getErrorMessage('fspId', 'required')}}
@@ -207,9 +264,10 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
- {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' formControlName="woodlotLicenseNumber" [appFormControl]="fg.get('woodlotLicenseNumber')" /> + +
@@ -232,10 +298,18 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
- + +
@@ -247,6 +321,7 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' formControlName="name" [appFormControl]="fg.get('name')" /> +
@@ -265,21 +349,22 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' {{getErrorMessage('name', 'minLength')}}

+
- - {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '

+
-
+
- + {{descriptionLimit-fg.get('description').value?.length}} characters remaining.
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
-
+ +
Newspaper Public Notice diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts index f2a6d5e2..f1c3f633 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts @@ -68,8 +68,8 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { public initialPublicDocument: any[] = []; public districtIdSelect: any = null; public forestClientSelect: any = null; + public isInitialState: boolean = true; public isPublishState: boolean = false; - public isCommentingOpen: boolean = false; files: any[] = []; maxFileSize: number = MAX_FILEUPLOAD_SIZE.DOCUMENT; publicNoticeContent: any; @@ -170,11 +170,9 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { } this.forestClientSelect = this.originalProjectResponse.forestClient.id; - + this.isInitialState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.Initial; this.isPublishState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.Published; - this.isCommentingOpen = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.CommentOpen; - this.attachmentResolverSvc.getAttachments(this.originalProjectResponse.id) .then( (result) => { for(const attachmentResponse of result ) { @@ -440,6 +438,17 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { return item; } + getDistrictDesc(districtId) { + const desc = this.districts.filter((item) => { + return item.id == districtId + })[0]["name"]; + return desc; + } + + getformatedDate(yearField, format = 'YYYY') { + return moment(this.fg.get(yearField).value).format(format); + } + /** * Additional setup for form control. */ From fea33ae78f287806a023c2c053ba3099dae53943 Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Wed, 11 Sep 2024 14:50:44 -0700 Subject: [PATCH 3/7] Add Timber Sales Manager clientId for fake user access for testing. --- admin/src/core/services/mock-user.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/admin/src/core/services/mock-user.ts b/admin/src/core/services/mock-user.ts index 87e9ce0d..524e5032 100644 --- a/admin/src/core/services/mock-user.ts +++ b/admin/src/core/services/mock-user.ts @@ -53,5 +53,6 @@ export function getFakeAllAccessUser(): User { user.isForestClient = true; user.clientIds.push('00001011') user.clientIds.push('00001012'); + user.clientIds.push('00132188'); return user; } From d10f4ca92bccb0e2341f6abe95d694f422a611dc Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Wed, 11 Sep 2024 15:02:33 -0700 Subject: [PATCH 4/7] Dummy touch for api for deployment. --- api/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main.ts b/api/src/main.ts index 787f2e5e..da907958 100644 --- a/api/src/main.ts +++ b/api/src/main.ts @@ -189,4 +189,4 @@ if (process.argv.length > 2 && standaloneRunTestDataMigrations(); } else { startApi(); -} \ No newline at end of file +} \ No newline at end of file From 676f7b78e612e17e8561f76890fccdad1531e9b9 Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Wed, 11 Sep 2024 15:10:42 -0700 Subject: [PATCH 5/7] rename variable --- admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts index f1c3f633..016fc615 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts @@ -445,8 +445,8 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { return desc; } - getformatedDate(yearField, format = 'YYYY') { - return moment(this.fg.get(yearField).value).format(format); + getformatedDate(field, format = 'YYYY') { + return moment(this.fg.get(field).value).format(format); } /** From 1266c886cc777ac62f1279b1a162820a9d84e84e Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Wed, 11 Sep 2024 23:44:49 -0700 Subject: [PATCH 6/7] Adjust disabled condition based on further clearification. --- .../fom-add-edit/fom-add-edit.component.html | 455 +++++++++--------- .../fom-add-edit/fom-add-edit.component.ts | 4 + 2 files changed, 241 insertions(+), 218 deletions(-) diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html index 12f14686..7b779984 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.html @@ -38,6 +38,7 @@

{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
+ {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' />
+
-
-
+
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : '
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' placeholder="YYYY" [value]="getformatedDate('commentingOpenDate', 'YYYY-MM-DD')" /> -
+
-
-
- -
- -
-
+
+
+ +
+
- +
- - + +
+ +
+ {{getErrorMessage('opStartDate', 'required')}} +
+
+ {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' placeholder="YYYY" [value]="getformatedDate('opStartDate')" /> -
- {{getErrorMessage('opStartDate', 'required')}} -
+ +
- - + +
+ +
+ {{getErrorMessage('opEndDate', 'required')}} +
+
+ {{getErrorMessage('opEndDate', 'minDate')}} +
+
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' placeholder="YYYY" [value]="getformatedDate('opEndDate')" /> -
- {{getErrorMessage('opEndDate', 'required')}} -
-
- {{getErrorMessage('opEndDate', 'minDate')}} -
+ - +
+ +
+ {{getErrorMessage('projectPlanCode', 'required')}} +
+
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' disabled [value]="getProjectPlanDesc()" /> -
- {{getErrorMessage('projectPlanCode', 'required')}} -
- + +
- - - + -
-
{{getErrorMessage('fspId', 'required')}}
-
{{getErrorMessage('fspId', 'numeric')}}
+ formControlName="fspId" + [appFormControl]="fg.get('fspId')" + /> +
+
{{getErrorMessage('fspId', 'required')}}
+
{{getErrorMessage('fspId', 'numeric')}}
+
+
- +
- - - - + -
-
- {{getErrorMessage('woodlotLicenseNumber', 'required')}} -
-
- {{getErrorMessage('woodlotLicenseNumber', 'woodlotFormat')}} + formControlName="woodlotLicenseNumber" + [appFormControl]="fg.get('woodlotLicenseNumber')" + /> +
+
+ {{getErrorMessage('woodlotLicenseNumber', 'required')}} +
+
+ {{getErrorMessage('woodlotLicenseNumber', 'woodlotFormat')}} +
+
+
- +
+ +
+ {{getErrorMessage('district', 'required')}} +
+
{{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' disabled [value]="getDistrictDesc(fg.get('district').value)" /> -
- {{getErrorMessage('district', 'required')}} -
+ +
+
+ +
+ {{getErrorMessage('name', 'required')}} +
+
+ {{getErrorMessage('name', 'minLength')}} +
+
- {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' disabled [value]="fg.get('name').value" /> -
- {{getErrorMessage('name', 'required')}} -
-
- {{getErrorMessage('name', 'minLength')}} -
+
+
+ {{getErrorMessage('bctsMgrName', 'required')}} +
+
+ {{getErrorMessage('bctsMgrName', 'minLength')}} +
+
+ {{getErrorMessage('bctsMgrName', 'maxLength')}} +
+
- {{isCreate ? 'Add New' : 'Edit'}} FOM {{isCreate ? '' : ' name="bctsMgrName" [value]="fg.get('bctsMgrName').value" /> -
- {{getErrorMessage('bctsMgrName', 'required')}} -
-
- {{getErrorMessage('bctsMgrName', 'minLength')}} -
-
- {{getErrorMessage('bctsMgrName', 'maxLength')}} -
+
- +
+ + {{descriptionLimit-fg.get('description').value?.length}} characters remaining. +
+ {{getErrorMessage('description', 'required')}} +
+
- {{descriptionLimit-fg.get('description').value?.length}} characters remaining. -
- {{getErrorMessage('description', 'required')}} -
diff --git a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts index 016fc615..87c38d96 100644 --- a/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts +++ b/admin/src/app/foms/fom-add-edit/fom-add-edit.component.ts @@ -69,6 +69,8 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { public districtIdSelect: any = null; public forestClientSelect: any = null; public isInitialState: boolean = true; + public isCommentingOpenState: boolean = false; + public isCommentingClosedState: boolean = false; public isPublishState: boolean = false; files: any[] = []; maxFileSize: number = MAX_FILEUPLOAD_SIZE.DOCUMENT; @@ -171,6 +173,8 @@ export class FomAddEditComponent implements OnInit, AfterViewInit, OnDestroy { this.forestClientSelect = this.originalProjectResponse.forestClient.id; this.isInitialState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.Initial; + this.isCommentingOpenState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.CommentOpen; + this.isCommentingClosedState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.CommentClosed; this.isPublishState = this.originalProjectResponse.workflowState.code === WorkflowStateEnum.Published; this.attachmentResolverSvc.getAttachments(this.originalProjectResponse.id) From 7571733acccae19796b9269f921d2d3f0db34ae4 Mon Sep 17 00:00:00 2001 From: Ian Liu Date: Thu, 12 Sep 2024 00:09:41 -0700 Subject: [PATCH 7/7] Add business rules for update --- .../app/modules/project/project.service.ts | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/api/src/app/modules/project/project.service.ts b/api/src/app/modules/project/project.service.ts index 570e0993..d2c97ce4 100644 --- a/api/src/app/modules/project/project.service.ts +++ b/api/src/app/modules/project/project.service.ts @@ -131,9 +131,29 @@ export class ProjectService extends DataService, Pr } } - // Cannot change commenting closed date when state is COMMENT_CLOSED. + // When COMMENT_CLOSED, cannot change: "Start of Operation", "End of Operation", "FSP ID", "District", + // "FOM Name", "Timber Sales Manager Name", "Description" + if (WorkflowStateEnum.COMMENT_OPEN == entity.workflowStateCode) { + if (entity.operationStartYear !== dto.operationStartYear || + entity.operationEndYear !== dto.operationEndYear || + entity.fspId !== dto.fspId || + entity.districtId !== dto.districtId || + entity.name !== dto.name || + entity.bctsMgrName !== dto.bctsMgrName || + entity.description !== dto.description + ) { + this.logger.debug(`Cannot change "Start of Operation", "End of Operation", "FSP ID", "District", + "FOM Name", "Timber Sales Manager Name", "Description" for state ${entity.workflowStateCode}.`); + return false; + } + } + + // When COMMENT_CLOSED, cannot change "commenting open date" "commenting closed date", "district". if (WorkflowStateEnum.COMMENT_CLOSED == entity.workflowStateCode) { - if (entity.commentingClosedDate !== dto.commentingClosedDate) { + if (entity.commentingOpenDate !== dto.commentingOpenDate || + entity.commentingClosedDate !== dto.commentingClosedDate || + entity.districtId !== dto.districtId + ) { this.logger.debug(`Cannot change commenting closed date for state ${entity.workflowStateCode}.`); return false; }