Skip to content

Commit

Permalink
Feature/alcs 940 (#755)
Browse files Browse the repository at this point in the history
add noi modification subtasks to board
show nois in Peer review only to Soil officer
  • Loading branch information
mhuseinov authored Jul 6, 2023
1 parent 3373204 commit 5929eb5
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<div class="assignee">
<h4>{{ subtaskLabel }} Subtasks: {{ totalSubtaskCount }}</h4>

<section *ngIf="noticeOfIntentSubtasks.length">
<section *ngIf="noticeOfIntentSubtasks.length && showNoi">
<div class="subheading2">Notice of Intent</div>
<app-subtask-table [subtasks]="noticeOfIntentSubtasks" [users]="users"></app-subtask-table>
</section>
<section *ngIf="applicationSubtasks.length">
<section *ngIf="applicationSubtasks.length && showAppAndNonApp">
<div class="subheading2">Applications</div>
<app-subtask-table [subtasks]="applicationSubtasks" [users]="users"></app-subtask-table>
</section>
<section *ngIf="nonApplicationSubtasks.length">
<section *ngIf="nonApplicationSubtasks.length && showAppAndNonApp">
<div class="subheading2">Non-Applications</div>
<app-subtask-table [subtasks]="nonApplicationSubtasks" [users]="users"></app-subtask-table>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { BehaviorSubject } from 'rxjs';
import { AuthenticationService, ICurrentUser } from '../../../services/authentication/authentication.service';
import { CardSubtaskService } from '../../../services/card/card-subtask/card-subtask.service';
import { HomeService } from '../../../services/home/home.service';
import { AssigneeDto } from '../../../services/user/user.dto';
Expand All @@ -14,18 +15,26 @@ describe('AuditComponent', () => {
let component: SubtaskComponent;
let fixture: ComponentFixture<SubtaskComponent>;
let mockUserService: DeepMocked<UserService>;
let mockAuthenticationService: DeepMocked<AuthenticationService>;

beforeEach(async () => {
mockUserService = createMock();
mockUserService.$assignableUsers = new BehaviorSubject<AssigneeDto[]>([]);

mockAuthenticationService = createMock();
mockAuthenticationService.$currentUser = new BehaviorSubject<ICurrentUser | undefined>(undefined);

await TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [
{
provide: CardSubtaskService,
useValue: {},
},
{
provide: AuthenticationService,
useValue: mockAuthenticationService,
},
{
provide: UserService,
useValue: mockUserService,
Expand Down
49 changes: 42 additions & 7 deletions alcs-frontend/src/app/features/home/subtask/subtask.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { ROLES } from '../../../services/authentication/authentication.service';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { AuthenticationService, ROLES } from '../../../services/authentication/authentication.service';
import { CARD_SUBTASK_TYPE, HomepageSubtaskDto } from '../../../services/card/card-subtask/card-subtask.dto';
import { HomeService } from '../../../services/home/home.service';
import { AssigneeDto } from '../../../services/user/user.dto';
Expand All @@ -11,7 +12,9 @@ import { CardType } from '../../../shared/card/card.component';
templateUrl: './subtask.component.html',
styleUrls: ['./subtask.component.scss'],
})
export class SubtaskComponent implements OnInit {
export class SubtaskComponent implements OnInit, OnDestroy {
destroy = new Subject<void>();

@Input() subtaskType: CARD_SUBTASK_TYPE = CARD_SUBTASK_TYPE.AUDIT;
@Input() subtaskLabel = 'Set Please';
@Input() assignableRoles = [ROLES.LUP, ROLES.APP_SPECIALIST];
Expand All @@ -22,14 +25,28 @@ export class SubtaskComponent implements OnInit {
noticeOfIntentSubtasks: HomepageSubtaskDto[] = [];
nonApplicationSubtasks: HomepageSubtaskDto[] = [];

constructor(private homeService: HomeService, private userService: UserService) {}
showNoi = true;
showAppAndNonApp = true;

constructor(
private homeService: HomeService,
private userService: UserService,
private authService: AuthenticationService
) {}

ngOnInit(): void {
this.userService.$assignableUsers.subscribe((users) => {
this.userService.$assignableUsers.pipe(takeUntil(this.destroy)).subscribe((users) => {
this.users = users.filter((user) => user.clientRoles.some((role) => this.assignableRoles.includes(role)));
});
this.userService.fetchAssignableUsers();

this.authService.$currentUser.pipe(takeUntil(this.destroy)).subscribe((currentUser) => {
if (currentUser && this.subtaskType === CARD_SUBTASK_TYPE.PEER_REVIEW) {
this.showNoi = !!currentUser.client_roles && currentUser.client_roles.includes(ROLES.SOIL_OFFICER);
this.showAppAndNonApp = !!currentUser.client_roles && currentUser.client_roles.includes(ROLES.LUP);
}
});

this.loadSubtasks();
}

Expand All @@ -41,6 +58,7 @@ export class SubtaskComponent implements OnInit {
const modifications = allSubtasks.filter((s) => s.card.type === CardType.MODI);
const covenants = allSubtasks.filter((s) => s.card.type === CardType.COV);
const nois = allSubtasks.filter((s) => s.card.type === CardType.NOI);
const noiModifications = allSubtasks.filter((s) => s.card.type === CardType.NOI_MODI);

this.applicationSubtasks = [
...applications.filter((a) => a.card.highPriority).sort((a, b) => b.activeDays! - a.activeDays!),
Expand All @@ -53,7 +71,9 @@ export class SubtaskComponent implements OnInit {

this.noticeOfIntentSubtasks = [
...nois.filter((a) => a.card.highPriority).sort((a, b) => b.activeDays! - a.activeDays!),
...noiModifications.filter((r) => r.card.highPriority).sort((a, b) => a.createdAt! - b.createdAt!),
...nois.filter((a) => !a.card.highPriority).sort((a, b) => b.activeDays! - a.activeDays!),
...noiModifications.filter((r) => !r.card.highPriority).sort((a, b) => a.createdAt! - b.createdAt!),
];

this.nonApplicationSubtasks = [
Expand All @@ -63,7 +83,22 @@ export class SubtaskComponent implements OnInit {
...covenants.filter((r) => !r.card.highPriority).sort((a, b) => a.createdAt! - b.createdAt!),
];

this.totalSubtaskCount =
this.applicationSubtasks.length + this.noticeOfIntentSubtasks.length + this.nonApplicationSubtasks.length;
if (this.showNoi) {
this.totalSubtaskCount = this.noticeOfIntentSubtasks.length;
}

if (this.showAppAndNonApp) {
this.totalSubtaskCount = this.applicationSubtasks.length + this.nonApplicationSubtasks.length;
}

if (this.showAppAndNonApp && this.showNoi) {
this.totalSubtaskCount =
this.applicationSubtasks.length + this.noticeOfIntentSubtasks.length + this.nonApplicationSubtasks.length;
}
}

ngOnDestroy(): void {
this.destroy.next();
this.destroy.complete();
}
}
30 changes: 30 additions & 0 deletions services/apps/alcs/src/alcs/home/home.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { CardSubtaskService } from '../card/card-subtask/card-subtask.service';
import { CodeService } from '../code/code.service';
import { Covenant } from '../covenant/covenant.entity';
import { CovenantService } from '../covenant/covenant.service';
import { NoticeOfIntentModification } from '../notice-of-intent-decision/notice-of-intent-modification/notice-of-intent-modification.entity';
import { NoticeOfIntentModificationService } from '../notice-of-intent-decision/notice-of-intent-modification/notice-of-intent-modification.service';
import { NoticeOfIntent } from '../notice-of-intent/notice-of-intent.entity';
import { NoticeOfIntentService } from '../notice-of-intent/notice-of-intent.service';
Expand Down Expand Up @@ -352,5 +353,34 @@ describe('HomeController', () => {
expect(res[0].title).toContain(mockNoi.fileNumber);
expect(res[0].title).toContain(mockNoi.applicant);
});

it('should call NOI Modification Service and map it', async () => {
const mockNoiModification = new NoticeOfIntentModification({
noticeOfIntent: new NoticeOfIntent({
applicant: 'fake-applicant',
fileNumber: 'fileNumber',
}),
card: initCardMockEntity('222'),
});
mockNoticeOfIntentModificationService.getWithIncompleteSubtaskByType.mockResolvedValue(
[mockNoiModification],
);

const res = await controller.getIncompleteSubtasksByType(
CARD_SUBTASK_TYPE.PEER_REVIEW,
);

expect(res.length).toEqual(1);
expect(
mockNoticeOfIntentModificationService.getWithIncompleteSubtaskByType,
).toHaveBeenCalledTimes(1);

expect(res[0].title).toContain(
mockNoiModification.noticeOfIntent.fileNumber,
);
expect(res[0].title).toContain(
mockNoiModification.noticeOfIntent.applicant,
);
});
});
});
35 changes: 35 additions & 0 deletions services/apps/alcs/src/alcs/home/home.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { CovenantDto } from '../covenant/covenant.dto';
import { Covenant } from '../covenant/covenant.entity';
import { CovenantService } from '../covenant/covenant.service';
import { NoticeOfIntentModificationDto } from '../notice-of-intent-decision/notice-of-intent-modification/notice-of-intent-modification.dto';
import { NoticeOfIntentModification } from '../notice-of-intent-decision/notice-of-intent-modification/notice-of-intent-modification.entity';
import { NoticeOfIntentModificationService } from '../notice-of-intent-decision/notice-of-intent-modification/notice-of-intent-modification.service';
import { NoticeOfIntentDto } from '../notice-of-intent/notice-of-intent.dto';
import { NoticeOfIntent } from '../notice-of-intent/notice-of-intent.entity';
Expand Down Expand Up @@ -181,13 +182,22 @@ export class HomeController {
);
const noticeOfIntentSubtasks = this.mapNoticeOfIntentToDtos(noiSubtasks);

const noiModificationsWithSubtasks =
await this.noticeOfIntentModificationService.getWithIncompleteSubtaskByType(
subtaskType,
);
const noiModificationsSubtasks = this.mapNoiModificationsToDtos(
noiModificationsWithSubtasks,
);

return [
...noticeOfIntentSubtasks,
...applicationSubtasks,
...reconSubtasks,
...modificationSubtasks,
...planningReviewSubtasks,
...covenantReviewSubtasks,
...noiModificationsSubtasks,
];
}

Expand Down Expand Up @@ -333,4 +343,29 @@ export class HomeController {
}
return result;
}

private mapNoiModificationsToDtos(
modifications: NoticeOfIntentModification[],
) {
const result: HomepageSubtaskDTO[] = [];
for (const modification of modifications) {
if (!modification.card) {
continue;
}
for (const subtask of modification.card.subtasks) {
result.push({
type: subtask.type,
createdAt: subtask.createdAt.getTime(),
assignee: this.mapper.map(subtask.assignee, User, AssigneeDto),
uuid: subtask.uuid,
card: this.mapper.map(modification.card, Card, CardDto),
completedAt: subtask.completedAt?.getTime(),
paused: false,
title: `${modification.noticeOfIntent.fileNumber} (${modification.noticeOfIntent.applicant})`,
parentType: 'modification',
});
}
}
return result;
}
}

0 comments on commit 5929eb5

Please sign in to comment.