Skip to content

Commit 7bd3b47

Browse files
authored
feat: SRS 1051 - CATS Application Search Enhancements (#1220)
* changes for implementing column preferences * changes for implementing column preferences * changes for CATS application search enhancements * changes to search config * uploading SearchApplications.generated file * running prettier format on frontend * fixed css issue in ColumnSelect.css * Fixed ColumnSelect.css
1 parent 727ad2e commit 7bd3b47

File tree

54 files changed

+2999
-238
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2999
-238
lines changed

backend/applications/src/app/constants/applicationType.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ enum ApplicationType {
55
SRCR = 'SRCR',
66
NIR = 'NIR',
77
SoSC = 'SOSC',
8+
CSSA = 'CSR',
89
}
910

1011
export default ApplicationType;

backend/applications/src/app/services/cats.service.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ApplicationType from '../constants/applicationType';
77

88
@Injectable()
99
export class CatsService {
10-
constructor() { }
10+
constructor() {}
1111

1212
getSiteIdsFromFormData = (formData: any) => {
1313
switch (formData.hdnAppType) {
@@ -68,7 +68,8 @@ export class CatsService {
6868

6969
case ApplicationType.SoSC:
7070
const soscSiteIds: number[] =
71-
formData.dataGrid?.map((item: any) => Number(item.siteId))
71+
formData.dataGrid
72+
?.map((item: any) => Number(item.siteId))
7273
.filter((id: number) => !isNaN(id)) || [];
7374

7475
return soscSiteIds;
@@ -87,6 +88,41 @@ export class CatsService {
8788
}
8889
};
8990

91+
getApplicationSpecificData = (formData: any): Record<string, any> | null => {
92+
switch (formData.hdnAppType) {
93+
case ApplicationType.CSSA:
94+
return {
95+
serviceType: formData.Servicetype,
96+
siteRiskClassification:
97+
formData.siteRiskClassificationAtTimeOfApplication,
98+
};
99+
case ApplicationType.DERA:
100+
return {
101+
siteIdNumber: formData.siteRiskClassificationAtTimeOfApplication,
102+
};
103+
104+
case ApplicationType.NOM:
105+
return {
106+
siteRiskClassification:
107+
formData.siteRiskClassificationAtTimeOfApplication,
108+
};
109+
110+
case ApplicationType.NIR:
111+
return {
112+
siteRiskClassification:
113+
formData.siteRiskClassificationAtTimeOfApplication,
114+
};
115+
116+
case ApplicationType.SRCR:
117+
return {
118+
siteRiskClassification: formData.siteRiskClassification,
119+
};
120+
121+
default:
122+
return null;
123+
}
124+
};
125+
90126
/**
91127
* To create a new application in CATS once a submission is received
92128
* @param formData
@@ -100,6 +136,9 @@ export class CatsService {
100136
// Parse and split comma-separated site IDs
101137
const siteIds = this.getSiteIdsFromFormData(formData);
102138

139+
// Get application-specific data
140+
const applicationSpecificData = this.getApplicationSpecificData(formData);
141+
103142
const createApplicationMutation = {
104143
query: `
105144
mutation CreateNewApplication($application: CreateApplication!) {
@@ -119,6 +158,9 @@ export class CatsService {
119158
siteIds: siteIds, // array of site id's
120159
appTypeAbbrev: formData.hdnAppType, // String!
121160
receivedDate: new Date(),
161+
applicationSpecificData: applicationSpecificData
162+
? JSON.stringify(applicationSpecificData)
163+
: null, // JSON string
122164
applicationStatus: [
123165
{
124166
statusTypeAbbrev: 'New',

backend/cats/src/app/cats.module.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import { DashboardService } from './services/dashboard/dashboard.service';
9191
import { DashboardResolver } from './resolvers/dashboard/dashboard.resolver';
9292
import { RecentViewedApplication } from './entities/recentViewedApplication.entity';
9393
import { StatusTypeService } from './services/statusType/statusType.service';
94+
import { StatusTypeResolver } from './resolvers/statusType/statusType.resolver';
9495
import { ServiceAssignmentFactor } from './entities/serviceAssignmentFactor';
9596
import { PermissionServiceType } from './entities/permissionServiceType';
9697
import { ApplicationSite } from './entities/applicationSite.entity';
@@ -99,6 +100,9 @@ import { EmailController } from './controllers/email.controller';
99100
import { ComsService } from './services/coms/coms.service';
100101
import { ComsResolver } from './resolvers/coms/coms.resolver';
101102
import { UploadController } from './controllers/upload.controller';
103+
import { ColumnPreferencesResolver } from './resolvers/application/columnPreferences.resolver';
104+
import { ColumnPreferencesService } from './services/application/columnPreferences.service';
105+
import { UserColumnPreferences } from './entities/userColumnPreferences.entity';
102106

103107
/**
104108
* Module for wrapping all functionalities in user microserivce
@@ -164,6 +168,7 @@ import { UploadController } from './controllers/upload.controller';
164168
ServiceAssignmentFactor,
165169
PermissionServiceType,
166170
ApplicationSite,
171+
UserColumnPreferences,
167172
]),
168173
HttpModule,
169174
],
@@ -186,6 +191,7 @@ import { UploadController } from './controllers/upload.controller';
186191
ApplicationDetailsResolver,
187192
AppTypeService,
188193
StatusTypeService,
194+
StatusTypeResolver,
189195
SiteResolver,
190196
SiteService,
191197
InvoiceResolver,
@@ -204,8 +210,10 @@ import { UploadController } from './controllers/upload.controller';
204210
DashboardService,
205211
DashboardResolver,
206212
ComsService,
207-
ComsResolver
213+
ComsResolver,
214+
ColumnPreferencesResolver,
215+
ColumnPreferencesService,
208216
],
209217
controllers: [UserController, EmailController, UploadController],
210218
})
211-
export class CatsModule { }
219+
export class CatsModule {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { validate } from 'class-validator';
2+
import { ColumnConfigDto } from './columnConfig.dto';
3+
4+
describe('ColumnConfigDto', () => {
5+
it('should pass validation with valid data', async () => {
6+
const dto = new ColumnConfigDto();
7+
dto.id = 1;
8+
dto.displayName = 'Application ID';
9+
dto.active = true;
10+
dto.sortOrder = 1;
11+
12+
const errors = await validate(dto);
13+
expect(errors).toHaveLength(0);
14+
});
15+
16+
it('should fail validation when required fields are missing', async () => {
17+
const dto = new ColumnConfigDto();
18+
19+
const errors = await validate(dto);
20+
expect(errors.length).toBeGreaterThan(0);
21+
});
22+
23+
it('should pass validation without optional sortOrder', async () => {
24+
const dto = new ColumnConfigDto();
25+
dto.id = 1;
26+
dto.displayName = 'Application ID';
27+
dto.active = true;
28+
29+
const errors = await validate(dto);
30+
expect(errors).toHaveLength(0);
31+
});
32+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { InputType, ObjectType, Field, Int } from '@nestjs/graphql';
2+
import { IsNumber, IsString, IsBoolean, IsOptional } from 'class-validator';
3+
4+
@InputType('ColumnConfigInput')
5+
@ObjectType('ColumnConfig')
6+
export class ColumnConfigDto {
7+
@Field(() => Int)
8+
@IsNumber()
9+
id: number;
10+
11+
@Field()
12+
@IsString()
13+
displayName: string;
14+
15+
@Field()
16+
@IsBoolean()
17+
active: boolean;
18+
19+
@Field(() => Int, { nullable: true })
20+
@IsOptional()
21+
@IsNumber()
22+
sortOrder?: number;
23+
24+
@Field(() => Int, { nullable: true })
25+
@IsOptional()
26+
@IsNumber()
27+
selectionOrder?: number;
28+
}
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import { Field, InputType } from '@nestjs/graphql';
22
import { ApplicationStatusDto } from './applicationStatus.dto';
3+
import { IsOptional } from 'class-validator';
34

45
// DTO for creating a person
56
@InputType()
67
export class CreateApplication {
7-
@Field(() => [Number])
8-
siteIds: number[]; // multiple sites for which the application is created
8+
@Field(() => [Number])
9+
siteIds: number[]; // multiple sites for which the application is created
910

10-
@Field()
11-
appTypeAbbrev: string; // the application type eg: SDS, SoSC etc
11+
@Field()
12+
appTypeAbbrev: string; // the application type eg: SDS, SoSC etc
1213

13-
@Field()
14-
receivedDate: Date; // date when application was submitted in SRS
14+
@Field()
15+
receivedDate: Date; // date when application was submitted in SRS
1516

16-
@Field(() => [ApplicationStatusDto])
17-
applicationStatus: ApplicationStatusDto[];
17+
@Field(() => [ApplicationStatusDto])
18+
applicationStatus: ApplicationStatusDto[];
1819

20+
@Field(() => String, { nullable: true })
21+
@IsOptional()
22+
applicationSpecificData?: string; // JSON string for application-specific fields
1923
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { validate } from 'class-validator';
2+
import { SaveColumnPreferencesDto } from './saveColumnPreferences.dto';
3+
import { ColumnConfigDto } from './columnConfig.dto';
4+
5+
describe('SaveColumnPreferencesDto', () => {
6+
it('should pass validation with valid data', async () => {
7+
const columnConfig = new ColumnConfigDto();
8+
columnConfig.id = 1;
9+
columnConfig.displayName = 'Application ID';
10+
columnConfig.active = true;
11+
columnConfig.sortOrder = 1;
12+
13+
const dto = new SaveColumnPreferencesDto();
14+
dto.page = 'applications';
15+
dto.columns = [columnConfig];
16+
17+
const errors = await validate(dto);
18+
expect(errors).toHaveLength(0);
19+
});
20+
21+
it('should fail validation when required fields are missing', async () => {
22+
const dto = new SaveColumnPreferencesDto();
23+
24+
const errors = await validate(dto);
25+
expect(errors.length).toBeGreaterThan(0);
26+
});
27+
28+
it('should pass validation with empty columns array', async () => {
29+
const dto = new SaveColumnPreferencesDto();
30+
dto.page = 'applications';
31+
dto.columns = [];
32+
33+
const errors = await validate(dto);
34+
expect(errors).toHaveLength(0);
35+
});
36+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { InputType, Field } from '@nestjs/graphql';
2+
import { IsString, IsArray, ValidateNested } from 'class-validator';
3+
import { Type } from 'class-transformer';
4+
import { ColumnConfigDto } from './columnConfig.dto';
5+
6+
@InputType()
7+
export class SaveColumnPreferencesDto {
8+
@Field()
9+
@IsString()
10+
page: string;
11+
12+
@Field(() => [ColumnConfigDto])
13+
@IsArray()
14+
@ValidateNested({ each: true })
15+
@Type(() => ColumnConfigDto)
16+
columns: ColumnConfigDto[];
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ObjectType, Field } from '@nestjs/graphql';
2+
import { ColumnConfigDto } from './columnConfig.dto';
3+
4+
@ObjectType()
5+
export class ViewColumnPreferences {
6+
@Field()
7+
userId: string;
8+
9+
@Field()
10+
page: string;
11+
12+
@Field(() => [ColumnConfigDto])
13+
columns: ColumnConfigDto[];
14+
15+
@Field()
16+
createdAt: Date;
17+
18+
@Field()
19+
updatedAt: Date;
20+
}

backend/cats/src/app/dto/applicationResultDto.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,16 @@ export class ApplicationResultDto {
4242

4343
@Field()
4444
url: string;
45+
46+
@Field()
47+
siteRiskClassification: string;
48+
49+
@Field()
50+
csapReference: string;
51+
52+
@Field()
53+
serviceType: string;
54+
55+
@Field()
56+
commonName: string;
4557
}

0 commit comments

Comments
 (0)