diff --git a/backend/typescript/graphql/index.ts b/backend/typescript/graphql/index.ts index a924a62..b01f5c7 100644 --- a/backend/typescript/graphql/index.ts +++ b/backend/typescript/graphql/index.ts @@ -63,8 +63,10 @@ const graphQLMiddlewares = { simpleEntities: authorizedByAllRoles(), dashboardById: authorizedByAllRoles(), applicationsByRole: authorizedByAllRoles(), + applicationsBySecondChoiceRole: authorizedByAllRoles(), applicationsById: authorizedByAllRoles(), applicationTable: authorizedByAllRoles(), + secondChoiceRoleApplicationTable: authorizedByAllRoles(), userById: authorizedByAdmin(), userByEmail: authorizedByAdmin(), login: authorizedByAdmin(), diff --git a/backend/typescript/graphql/resolvers/dashboardResolvers.ts b/backend/typescript/graphql/resolvers/dashboardResolvers.ts index cdaf3b9..d6ec50f 100644 --- a/backend/typescript/graphql/resolvers/dashboardResolvers.ts +++ b/backend/typescript/graphql/resolvers/dashboardResolvers.ts @@ -5,6 +5,7 @@ import { ApplicationDTO, ApplicationDashboardInput, ApplicationDashboardRowDTO, + ApplicantRole, } from "../../types"; const dashboardService: IAppDashboardService = new AppDashboardService(); @@ -20,7 +21,7 @@ const dashboardResolvers = { }, applicationsByRole: async ( _parent: undefined, - { firstChoice }: { firstChoice: string }, + { firstChoice }: { firstChoice: ApplicantRole }, ): Promise> => { const applications = await dashboardService.getApplicationsByRole( firstChoice, @@ -34,6 +35,15 @@ const dashboardResolvers = { const application = await dashboardService.getApplicationsById(id); return application; }, + applicationsBySecondChoiceRole: async ( + _parent: undefined, + { secondChoice }: { secondChoice: ApplicantRole }, + ): Promise> => { + const applications = await dashboardService.getApplicationsBySecondChoiceRole( + secondChoice, + ); + return applications; + }, dashboardsByApplicationId: async ( _parent: undefined, { applicationId }: { applicationId: number }, @@ -45,10 +55,18 @@ const dashboardResolvers = { }, applicationTable: async ( _parent: undefined, - { role }: { role: string }, + { role }: { role: ApplicantRole }, ): Promise => { return dashboardService.getApplicationDashboardTable(role); }, + secondChoiceRoleApplicationTable: async ( + _parent: undefined, + { role }: { role: ApplicantRole }, + ): Promise => { + return dashboardService.getApplicationBySecondChoiceRoleDashboardTable( + role, + ); + }, }, Mutation: { createApplicationDashboard: async ( diff --git a/backend/typescript/graphql/types/dashboardType.ts b/backend/typescript/graphql/types/dashboardType.ts index 05749bd..73ad49b 100644 --- a/backend/typescript/graphql/types/dashboardType.ts +++ b/backend/typescript/graphql/types/dashboardType.ts @@ -59,9 +59,13 @@ const dashboardType = gql` extend type Query { dashboardById(id: Int!): ApplicationDashboardDTO! applicationsByRole(firstChoice: String!): [ApplicationDTO]! + applicationsBySecondChoiceRole(secondChoice: String!): [ApplicationDTO]! applicationsById(id: Int!): ApplicationDTO! dashboardsByApplicationId(applicationId: Int!): [ApplicationDashboardDTO]! applicationTable(role: String!): [ApplicationDashboardRowDTO]! + secondChoiceRoleApplicationTable( + role: String! + ): [ApplicationDashboardRowDTO]! } extend type Mutation { diff --git a/backend/typescript/services/implementations/appDashboardService.ts b/backend/typescript/services/implementations/appDashboardService.ts index 6d41672..b8b80b9 100644 --- a/backend/typescript/services/implementations/appDashboardService.ts +++ b/backend/typescript/services/implementations/appDashboardService.ts @@ -3,6 +3,7 @@ import { ApplicationDTO, ApplicationDashboardRowDTO, UserDTO, + ApplicantRole, } from "../../types"; import { getErrorMessage } from "../../utilities/errorUtils"; import logger from "../../utilities/logger"; @@ -54,7 +55,58 @@ class AppDashboardService implements IAppDashboardService { }; } - async getApplicationsByRole(role: string): Promise> { + async getApplicationsById(id: number): Promise { + let applications: Array | null; + let applicationById: Application | undefined; + let applicationByIdDTO: ApplicationDTO; + try { + applications = await Application.findAll(); + applicationById = applications.find( + (application) => application.id === id, + ); + + if (applicationById === undefined) { + // Handle the case when no application is found + throw new Error(`Application with id ${id} not found`); + } + + applicationByIdDTO = { + id: applicationById.id, + academicOrCoop: applicationById.academicOrCoop, + academicYear: applicationById.academicYear, + email: applicationById.email, + firstChoiceRole: applicationById.firstChoiceRole, + firstName: applicationById.firstName, + heardFrom: applicationById.heardFrom, + lastName: applicationById.lastName, + locationPreference: applicationById.locationPreference, + program: applicationById.program, + pronouns: applicationById.pronouns, + pronounsSpecified: applicationById.pronounsSpecified, + resumeUrl: applicationById.resumeUrl, + roleSpecificQuestions: applicationById.roleSpecificQuestions, + secondChoiceRole: applicationById.secondChoiceRole, + shortAnswerQuestions: applicationById.shortAnswerQuestions, + secondChoiceStatus: applicationById.secondChoiceStatus, + status: applicationById.status, + term: applicationById.term, + timesApplied: applicationById.timesApplied, + timestamp: applicationById.timestamp, + }; + } catch (error: unknown) { + Logger.error( + `Failed to get applications by id = ${id}. Reason = ${getErrorMessage( + error, + )}`, + ); + throw error; + } + return applicationByIdDTO; + } + + async getApplicationsByRole( + role: ApplicantRole, + ): Promise> { let applications: Array | null; let applicationsByRole: Array | null; let applicationsByRoleDTO: Array = []; @@ -99,54 +151,57 @@ class AppDashboardService implements IAppDashboardService { return applicationsByRoleDTO; } - // Takes in an application id and returns an array of applicants with same id - async getApplicationsById(id: number): Promise { + async getApplicationsBySecondChoiceRole( + role: ApplicantRole, + ): Promise> { let applications: Array | null; - let applicationById: Application | undefined; - let applicationByIdDTO: ApplicationDTO; + let applicationsBySecondChoiceRole: Array | null; + let applicationsBySecondChoiceRoleDTO: Array = []; try { applications = await Application.findAll(); - applicationById = applications.find( - (application) => application.id === id, + applicationsBySecondChoiceRole = await applications.filter( + (application) => { + return ( + application.secondChoiceRole.toLowerCase() === role.toLowerCase() + ); + }, + ); + applicationsBySecondChoiceRoleDTO = await applicationsBySecondChoiceRole.map( + (application) => { + return { + id: application.id, + academicOrCoop: application.academicOrCoop, + academicYear: application.academicYear, + email: application.email, + firstChoiceRole: application.firstChoiceRole, + firstName: application.firstName, + heardFrom: application.heardFrom, + lastName: application.lastName, + locationPreference: application.locationPreference, + program: application.program, + pronouns: application.pronouns, + pronounsSpecified: application.pronounsSpecified, + resumeUrl: application.resumeUrl, + roleSpecificQuestions: application.roleSpecificQuestions, + secondChoiceRole: application.secondChoiceRole, + shortAnswerQuestions: application.shortAnswerQuestions, + status: application.status, + secondChoiceStatus: application.secondChoiceStatus, + term: application.term, + timesApplied: application.timesApplied, + timestamp: application.timestamp, + }; + }, ); - - if (applicationById === undefined) { - // Handle the case when no application is found - throw new Error(`Application with id ${id} not found`); - } - - applicationByIdDTO = { - id: applicationById.id, - academicOrCoop: applicationById.academicOrCoop, - academicYear: applicationById.academicYear, - email: applicationById.email, - firstChoiceRole: applicationById.firstChoiceRole, - firstName: applicationById.firstName, - heardFrom: applicationById.heardFrom, - lastName: applicationById.lastName, - locationPreference: applicationById.locationPreference, - program: applicationById.program, - pronouns: applicationById.pronouns, - pronounsSpecified: applicationById.pronounsSpecified, - resumeUrl: applicationById.resumeUrl, - roleSpecificQuestions: applicationById.roleSpecificQuestions, - secondChoiceRole: applicationById.secondChoiceRole, - shortAnswerQuestions: applicationById.shortAnswerQuestions, - secondChoiceStatus: applicationById.secondChoiceStatus, - status: applicationById.status, - term: applicationById.term, - timesApplied: applicationById.timesApplied, - timestamp: applicationById.timestamp, - }; } catch (error: unknown) { Logger.error( - `Failed to get applications by id = ${id}. Reason = ${getErrorMessage( + `Failed to get applications by this second choice role = ${role}. Reason = ${getErrorMessage( error, )}`, ); throw error; } - return applicationByIdDTO; + return applicationsBySecondChoiceRoleDTO; } async getDashboardsByApplicationId( @@ -185,7 +240,7 @@ class AppDashboardService implements IAppDashboardService { } async getApplicationDashboardTable( - role: string, + role: ApplicantRole, ): Promise { // get all the applications for the role const applications: Array = await this.getApplicationsByRole( @@ -212,6 +267,34 @@ class AppDashboardService implements IAppDashboardService { return appDashRows; } + async getApplicationBySecondChoiceRoleDashboardTable( + role: ApplicantRole, + ): Promise { + // get all the applications for the role + const applications: Array = await this.getApplicationsBySecondChoiceRole( + role, + ); + // get the dashboards associated with the applications + const appDashRows: Array = await Promise.all( + applications.map(async (application) => { + const reviewDashboards: Array = await this.getDashboardsByApplicationId( + application.id, + ); + const reviewers: Array = await Promise.all( + reviewDashboards.map(async (dash) => { + return userService.getUserByEmail(dash.reviewerEmail); + }), + ); + return { + application, + reviewDashboards, + reviewers, + }; + }), + ); + return appDashRows; + } + async mutateRating( id: number, ratingToBeChanged: string, diff --git a/backend/typescript/services/interfaces/appDashboardService.ts b/backend/typescript/services/interfaces/appDashboardService.ts index 74444bd..3c34515 100644 --- a/backend/typescript/services/interfaces/appDashboardService.ts +++ b/backend/typescript/services/interfaces/appDashboardService.ts @@ -2,17 +2,24 @@ import { ApplicationDashboardDTO, ApplicationDTO, ApplicationDashboardRowDTO, + ApplicantRole, } from "../../types"; interface IAppDashboardService { getDashboardById(id: number): Promise; - getApplicationsByRole(role: string): Promise; + getApplicationsByRole(role: ApplicantRole): Promise; + getApplicationsBySecondChoiceRole( + role: ApplicantRole, + ): Promise; getApplicationsById(id: number): Promise; getDashboardsByApplicationId( applicationId: number, ): Promise; getApplicationDashboardTable( - role: string, + role: ApplicantRole, + ): Promise; + getApplicationBySecondChoiceRoleDashboardTable( + role: ApplicantRole, ): Promise; mutateRating( id: number, diff --git a/backend/typescript/types.ts b/backend/typescript/types.ts index 362088c..d1299dd 100644 --- a/backend/typescript/types.ts +++ b/backend/typescript/types.ts @@ -103,3 +103,25 @@ export type NodemailerConfig = { }; export type SignUpMethod = "PASSWORD" | "GOOGLE"; + +export enum ApplicantRole { + pres = "president", // community tab + int_dir = "internal director", + ext_dir = "external director", + vpe = "vp engineering", // eng tab + vpd = "vp design", // design tab + vpp = "vp product", // prod tab + vpt = "vp talent", // community tab + vp_ext = "vp external", // community tab + vp_int = "vp internal", // community tab + vp_comms = "vp communications", // community tab + vp_scoping = "vp scoping", // community tab + vp_finance = "vp finance & operations", // community tab + pm = "project manager", // prod tab + pl = "project lead", // eng tab + design_mentor = "design mentor", // design tab + graphic_design = "graphic designer", // design tab + product_design = "product designer", // design tab + uxr = "user researcher", // design tab + dev = "project developer", // eng tab +}