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" class="center">
- {{ cardData.maxActiveDays }}+
-
-
-
- pause
- {{ cardData.pausedDays }}
-
-
- Due: {{ cardData.dueDate | momentFormat }}
-
-
-
Due: {{ cardData.dueDate | momentFormat }}
+
+
- = cardData.maxActiveDays" class="center red-text"
- >Overduecalendar_month
+
+ {{ cardData.activeDays }}
+
+ = cardData.maxActiveDays" class="center">
+ {{ cardData.maxActiveDays }}+
+
+
+
+ pause
+ {{ cardData.pausedDays }}
+
+
+ Due: {{ cardData.dueDate | momentFormat }}
+
+
+ Due: {{ cardData.dueDate | momentFormat }}
+ = cardData.maxActiveDays"
+ class="center red-text"
+ >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'));
+ `);
+ }
+}