diff --git a/alcs-frontend/src/app/features/board/board.component.ts b/alcs-frontend/src/app/features/board/board.component.ts index 2d6914a78..73d8a9e5d 100644 --- a/alcs-frontend/src/app/features/board/board.component.ts +++ b/alcs-frontend/src/app/features/board/board.component.ts @@ -314,14 +314,6 @@ export class BoardComponent implements OnInit, OnDestroy { ...mappedPlanningReferrals, ...mappedNotifications, ].sort(noiSort); - } else if (boardCode === BOARD_TYPE_CODES.APP_CON) { - const appConSort = (a: CardData, b: CardData) => { - if (a.highPriority !== b.highPriority) { - return b.highPriority ? 1 : -1; - } - return 0; - }; - this.cards = mappedAppDecisionConditions.sort(appConSort); } else { const sorted = []; sorted.push( @@ -336,6 +328,7 @@ export class BoardComponent implements OnInit, OnDestroy { ...mappedPlanningReferrals.filter((r) => r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), ...mappedInquiries.filter((r) => r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), ...mappedNotifications.filter((r) => r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), + ...mappedAppDecisionConditions.filter((r) => r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), // non-high priority ...mappedNoticeOfIntents .filter((a) => !a.highPriority) @@ -349,6 +342,7 @@ export class BoardComponent implements OnInit, OnDestroy { ...mappedPlanningReferrals.filter((r) => !r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), ...mappedInquiries.filter((r) => !r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), ...mappedNotifications.filter((r) => !r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), + ...mappedAppDecisionConditions.filter((r) => !r.highPriority).sort((a, b) => a.dateReceived - b.dateReceived), ); this.cards = sorted; } @@ -537,7 +531,10 @@ export class BoardComponent implements OnInit, OnDestroy { dateReceived: 0, isExpired, isPastDue, + isInConditionBoard: this.currentBoardCode === BOARD_TYPE_CODES.APP_CON, decisionIsFlagged: applicationDecisionCondition.decisionIsFlagged, + isModification: applicationDecisionCondition.isModification, + isReconsideration: applicationDecisionCondition.isReconsideration, }; } diff --git a/alcs-frontend/src/app/features/board/dialogs/application-decision-condition-dialog/application-decision-condition-dialog.component.html b/alcs-frontend/src/app/features/board/dialogs/application-decision-condition-dialog/application-decision-condition-dialog.component.html index 0ddc0cb9a..025ded87f 100644 --- a/alcs-frontend/src/app/features/board/dialogs/application-decision-condition-dialog/application-decision-condition-dialog.component.html +++ b/alcs-frontend/src/app/features/board/dialogs/application-decision-condition-dialog/application-decision-condition-dialog.component.html @@ -44,6 +44,22 @@

+ + + +
-
- {{ cardData.typeLabel }} +
+
+ {{ cardData.typeLabel }} +
+
+
+ {{ cardData.title }} + !
- {{ cardData.title }} - ! -
- +
+
+ + + + + + +
-
-
- calendar_month - - {{ cardData.activeDays }} - - - {{ cardData.maxActiveDays }}+ - -
-
- pause - {{ cardData.pausedDays }} -
-
- Due: {{ cardData.dueDate | momentFormat }} -
-
- Due: {{ cardData.dueDate | momentFormat }} +
+
- Overduecalendar_month + + {{ cardData.activeDays }} + + + {{ cardData.maxActiveDays }}+ + +
+
+ pause + {{ cardData.pausedDays }} +
+
+ Due: {{ cardData.dueDate | momentFormat }} +
+
+ Due: {{ cardData.dueDate | momentFormat }} + Overdue +
-
-
- - +
+ + +
-
- +
+
+ - + +
diff --git a/alcs-frontend/src/app/shared/card/card.component.scss b/alcs-frontend/src/app/shared/card/card.component.scss index f910aff95..afdc09a72 100644 --- a/alcs-frontend/src/app/shared/card/card.component.scss +++ b/alcs-frontend/src/app/shared/card/card.component.scss @@ -74,7 +74,6 @@ $date-ht: 32px; font-size: 1.4em; font-weight: bold; color: colors.$error-color; - float: right; } .day-count { @@ -96,6 +95,8 @@ $date-ht: 32px; .labels { margin-top: 6px; + display: flex; + justify-items: flex-start; } .cdk-drag-placeholder { @@ -150,3 +151,21 @@ mat-card { .flag-icon { color: blue; } + +.left-card { + display: flex; + justify-content: flex-start; + flex: 1; +} + +.right-card { + display: flex; + justify-content: flex-end; + flex: 1; +} + +.row { + width: 100%; + display: flex; + justify-content: space-between; +} diff --git a/alcs-frontend/src/app/shared/card/card.component.ts b/alcs-frontend/src/app/shared/card/card.component.ts index cd5ecda1c..c69c5d455 100644 --- a/alcs-frontend/src/app/shared/card/card.component.ts +++ b/alcs-frontend/src/app/shared/card/card.component.ts @@ -3,8 +3,11 @@ import { ApplicationDecisionMeetingDto } from '../../services/application/applic import { AssigneeDto } from '../../services/user/user.dto'; import { ApplicationPill } from '../application-type-pill/application-type-pill.component'; import { + CONDITION_LABEL, DECISION_CONDITION_EXPIRED_LABEL, DECISION_CONDITION_PASTDUE_LABEL, + MODIFICATION_TYPE_LABEL, + RECON_TYPE_LABEL, } from '../application-type-pill/application-type-pill.constants'; export interface CardData { @@ -36,6 +39,9 @@ export interface CardData { export interface ConditionCardData extends CardData { isExpired: boolean; isPastDue: boolean; + isInConditionBoard: boolean; + isModification: boolean; + isReconsideration: boolean; } export interface CardSelectedEvent { @@ -68,9 +74,13 @@ export class CardComponent implements OnInit { @Input() cardData!: CardData | ConditionCardData; @Output() cardSelected = new EventEmitter(); + // Condition Card isConditionCard = false; + isInConditionBoard = true; isExpired = false; isPastDue = false; + isModification = false; + isReconsideration = false; constructor() {} @@ -99,8 +109,11 @@ export class CardComponent implements OnInit { } this.isConditionCard = this.cardData.cardType === CardType.APP_CON; + this.isInConditionBoard = this.isConditionCard ? (this.cardData as ConditionCardData).isInConditionBoard : true; this.isExpired = this.isConditionCard ? (this.cardData as ConditionCardData).isExpired : false; this.isPastDue = this.isConditionCard ? (this.cardData as ConditionCardData).isPastDue : false; + this.isModification = this.isConditionCard ? (this.cardData as ConditionCardData).isModification : false; + this.isReconsideration = this.isConditionCard ? (this.cardData as ConditionCardData).isReconsideration : false; } onMouseHover(e: any) { @@ -116,8 +129,14 @@ export class CardComponent implements OnInit { getStatusPill(status: string) { if (status === 'PASTDUE') { return DECISION_CONDITION_PASTDUE_LABEL; - } else { + } else if (status === 'EXPIRED') { return DECISION_CONDITION_EXPIRED_LABEL; + } else if (status === 'MODIFICATION') { + return MODIFICATION_TYPE_LABEL; + } else if (status === 'RECONSIDERATION') { + return RECON_TYPE_LABEL; + } else { + return CONDITION_LABEL; } } } diff --git a/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.spec.ts b/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.spec.ts index dc8f59a0d..ef6d6ff09 100644 --- a/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.spec.ts +++ b/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.spec.ts @@ -18,6 +18,8 @@ import { } from '../../../../../../../libs/common/src/exceptions/base.exception'; import { Card } from '../../../card/card.entity'; import { ApplicationProfile } from '../../../../common/automapper/application.automapper.profile'; +import { ApplicationModificationService } from '../../application-modification/application-modification.service'; +import { ApplicationReconsiderationService } from '../../application-reconsideration/application-reconsideration.service'; describe('ApplicationDecisionConditionCardService', () => { let service: ApplicationDecisionConditionCardService; @@ -26,6 +28,8 @@ describe('ApplicationDecisionConditionCardService', () => { let mockDecisionService: DeepMocked; let mockBoardService: DeepMocked; let mockCardService: DeepMocked; + let mockApplicationModificationService: DeepMocked; + let mockApplicationReconsiderationService: DeepMocked; let mockMapper: DeepMocked; const CARD_RELATIONS = { @@ -59,6 +63,8 @@ describe('ApplicationDecisionConditionCardService', () => { mockDecisionService = createMock(); mockBoardService = createMock(); mockCardService = createMock(); + mockApplicationModificationService = createMock(); + mockApplicationReconsiderationService = createMock(); mockMapper = createMock(); const module: TestingModule = await Test.createTestingModule({ @@ -89,6 +95,14 @@ describe('ApplicationDecisionConditionCardService', () => { provide: CardService, useValue: mockCardService, }, + { + provide: ApplicationModificationService, + useValue: mockApplicationModificationService, + }, + { + provide: ApplicationReconsiderationService, + useValue: mockApplicationReconsiderationService, + }, ApplicationDecisionProfile, ApplicationProfile, ], diff --git a/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.ts b/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.ts index dd54be5f9..def8acf83 100644 --- a/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.ts +++ b/services/apps/alcs/src/alcs/application-decision/application-decision-condition/application-decision-condition-card/application-decision-condition-card.service.ts @@ -25,6 +25,8 @@ import { ApplicationType } from '../../../code/application-code/application-type import { ApplicationTypeDto } from '../../../code/application-code/application-type/application-type.dto'; import { ApplicationDecision } from '../../application-decision.entity'; import { ApplicationDecisionCondition } from '../application-decision-condition.entity'; +import { ApplicationModificationService } from '../../application-modification/application-modification.service'; +import { ApplicationReconsiderationService } from '../../application-reconsideration/application-reconsideration.service'; @Injectable() export class ApplicationDecisionConditionCardService { @@ -62,6 +64,8 @@ export class ApplicationDecisionConditionCardService { private boardService: BoardService, @Inject(forwardRef(() => CardService)) private cardService: CardService, + private applicationModificationService: ApplicationModificationService, + private applicationReconsiderationService: ApplicationReconsiderationService, @InjectMapper() private mapper: Mapper, ) {} @@ -188,6 +192,14 @@ export class ApplicationDecisionConditionCardService { }); for (const dto of dtos) { + const appModifications = await this.applicationModificationService.getByApplicationDecisionUuid(dto.decisionUuid); + const appReconsiderations = await this.applicationReconsiderationService.getByApplicationDecisionUuid( + dto.decisionUuid, + ); + + dto.isModification = appModifications.length > 0; + dto.isReconsideration = appReconsiderations.length > 0; + for (const condition of dto.conditions) { const status = await this.applicationDecisionService.getDecisionConditionStatus(condition.uuid); condition.status = status !== '' ? status : undefined; diff --git a/services/apps/alcs/src/alcs/application-decision/application-modification/application-modification.service.ts b/services/apps/alcs/src/alcs/application-decision/application-modification/application-modification.service.ts index 9aae4e728..85d3afb04 100644 --- a/services/apps/alcs/src/alcs/application-decision/application-modification/application-modification.service.ts +++ b/services/apps/alcs/src/alcs/application-decision/application-modification/application-modification.service.ts @@ -1,5 +1,5 @@ import { ServiceNotFoundException } from '@app/common/exceptions/base.exception'; -import { Injectable } from '@nestjs/common'; +import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Mapper } from 'automapper-core'; import { InjectMapper } from 'automapper-nestjs'; @@ -26,6 +26,7 @@ export class ApplicationModificationService { @InjectMapper() private mapper: Mapper, private applicationService: ApplicationService, private applicationDecisionV2Service: ApplicationDecisionV2Service, + @Inject(forwardRef(() => CardService)) private cardService: CardService, ) {} diff --git a/services/apps/alcs/src/alcs/application-decision/application-reconsideration/application-reconsideration.service.ts b/services/apps/alcs/src/alcs/application-decision/application-reconsideration/application-reconsideration.service.ts index 10cc5baf7..aab1a51ed 100644 --- a/services/apps/alcs/src/alcs/application-decision/application-reconsideration/application-reconsideration.service.ts +++ b/services/apps/alcs/src/alcs/application-decision/application-reconsideration/application-reconsideration.service.ts @@ -1,5 +1,5 @@ import { ServiceNotFoundException } from '@app/common/exceptions/base.exception'; -import { Injectable } from '@nestjs/common'; +import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Mapper } from 'automapper-core'; import { InjectMapper } from 'automapper-nestjs'; @@ -32,6 +32,7 @@ export class ApplicationReconsiderationService { @InjectRepository(ApplicationReconsiderationType) private reconsiderationTypeRepository: Repository, private applicationService: ApplicationService, + @Inject(forwardRef(() => CardService)) private cardService: CardService, private applicationDecisionService: ApplicationDecisionV2Service, ) {} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1737750628423-add_application_condition_card_type_to_new_boards.ts b/services/apps/alcs/src/providers/typeorm/migrations/1737750628423-add_application_condition_card_type_to_new_boards.ts new file mode 100644 index 000000000..12423478d --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1737750628423-add_application_condition_card_type_to_new_boards.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddApplicationConditionCardTypeToNewBoards1737750628423 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + INSERT INTO alcs.board_allowed_card_types_card_type (board_uuid, card_type_code) + SELECT b.uuid, 'APPCON' + FROM alcs.board b + WHERE b.code IN ('ceo', 'exec', 'film', 'island', 'inte', 'soil', 'okan', 'koot', 'north', 'south'); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM alcs.board_allowed_card_types_card_type + WHERE card_type_code = 'APPCON' + AND alcs.board_uuid IN (SELECT uuid FROM alcs.board WHERE code IN ('ceo', 'exec', 'film', 'island', 'inte', 'soil', 'okan', 'koot', 'north', 'south')); + `); + } +}