Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[INTF23] Second choice tab queries and fixes #45

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/typescript/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
22 changes: 20 additions & 2 deletions backend/typescript/graphql/resolvers/dashboardResolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ApplicationDTO,
ApplicationDashboardInput,
ApplicationDashboardRowDTO,
ApplicantRole,
} from "../../types";

const dashboardService: IAppDashboardService = new AppDashboardService();
Expand All @@ -20,7 +21,7 @@ const dashboardResolvers = {
},
applicationsByRole: async (
_parent: undefined,
{ firstChoice }: { firstChoice: string },
{ firstChoice }: { firstChoice: ApplicantRole },
): Promise<Array<ApplicationDTO>> => {
const applications = await dashboardService.getApplicationsByRole(
firstChoice,
Expand All @@ -34,6 +35,15 @@ const dashboardResolvers = {
const application = await dashboardService.getApplicationsById(id);
return application;
},
applicationsBySecondChoiceRole: async (
_parent: undefined,
{ secondChoice }: { secondChoice: ApplicantRole },
): Promise<Array<ApplicationDTO>> => {
const applications = await dashboardService.getApplicationsBySecondChoiceRole(
secondChoice,
);
return applications;
},
dashboardsByApplicationId: async (
_parent: undefined,
{ applicationId }: { applicationId: number },
Expand All @@ -45,10 +55,18 @@ const dashboardResolvers = {
},
applicationTable: async (
_parent: undefined,
{ role }: { role: string },
{ role }: { role: ApplicantRole },
): Promise<ApplicationDashboardRowDTO[]> => {
return dashboardService.getApplicationDashboardTable(role);
},
secondChoiceRoleApplicationTable: async (
_parent: undefined,
{ role }: { role: ApplicantRole },
): Promise<ApplicationDashboardRowDTO[]> => {
return dashboardService.getApplicationBySecondChoiceRoleDashboardTable(
role,
);
},
},
Mutation: {
createApplicationDashboard: async (
Expand Down
4 changes: 4 additions & 0 deletions backend/typescript/graphql/types/dashboardType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
161 changes: 122 additions & 39 deletions backend/typescript/services/implementations/appDashboardService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ApplicationDTO,
ApplicationDashboardRowDTO,
UserDTO,
ApplicantRole,
} from "../../types";
import { getErrorMessage } from "../../utilities/errorUtils";
import logger from "../../utilities/logger";
Expand Down Expand Up @@ -54,7 +55,58 @@ class AppDashboardService implements IAppDashboardService {
};
}

async getApplicationsByRole(role: string): Promise<Array<ApplicationDTO>> {
async getApplicationsById(id: number): Promise<ApplicationDTO> {
let applications: Array<Application> | 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<Array<ApplicationDTO>> {
let applications: Array<Application> | null;
let applicationsByRole: Array<Application> | null;
let applicationsByRoleDTO: Array<ApplicationDTO> = [];
Expand Down Expand Up @@ -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<ApplicationDTO> {
async getApplicationsBySecondChoiceRole(
role: ApplicantRole,
): Promise<Array<ApplicationDTO>> {
let applications: Array<Application> | null;
let applicationById: Application | undefined;
let applicationByIdDTO: ApplicationDTO;
let applicationsBySecondChoiceRole: Array<Application> | null;
let applicationsBySecondChoiceRoleDTO: Array<ApplicationDTO> = [];
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(
Expand Down Expand Up @@ -185,7 +240,7 @@ class AppDashboardService implements IAppDashboardService {
}

async getApplicationDashboardTable(
role: string,
role: ApplicantRole,
): Promise<ApplicationDashboardRowDTO[]> {
// get all the applications for the role
const applications: Array<ApplicationDTO> = await this.getApplicationsByRole(
Expand All @@ -212,6 +267,34 @@ class AppDashboardService implements IAppDashboardService {
return appDashRows;
}

async getApplicationBySecondChoiceRoleDashboardTable(
role: ApplicantRole,
): Promise<ApplicationDashboardRowDTO[]> {
// get all the applications for the role
const applications: Array<ApplicationDTO> = await this.getApplicationsBySecondChoiceRole(
role,
);
// get the dashboards associated with the applications
const appDashRows: Array<ApplicationDashboardRowDTO> = await Promise.all(
applications.map(async (application) => {
const reviewDashboards: Array<ApplicationDashboardDTO> = await this.getDashboardsByApplicationId(
application.id,
);
const reviewers: Array<UserDTO> = await Promise.all(
reviewDashboards.map(async (dash) => {
return userService.getUserByEmail(dash.reviewerEmail);
}),
);
return {
application,
reviewDashboards,
reviewers,
};
}),
);
return appDashRows;
}

async mutateRating(
id: number,
ratingToBeChanged: string,
Expand Down
11 changes: 9 additions & 2 deletions backend/typescript/services/interfaces/appDashboardService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@ import {
ApplicationDashboardDTO,
ApplicationDTO,
ApplicationDashboardRowDTO,
ApplicantRole,
} from "../../types";

interface IAppDashboardService {
getDashboardById(id: number): Promise<ApplicationDashboardDTO>;
getApplicationsByRole(role: string): Promise<ApplicationDTO[]>;
getApplicationsByRole(role: ApplicantRole): Promise<ApplicationDTO[]>;
getApplicationsBySecondChoiceRole(
role: ApplicantRole,
): Promise<ApplicationDTO[]>;
getApplicationsById(id: number): Promise<ApplicationDTO>;
getDashboardsByApplicationId(
applicationId: number,
): Promise<ApplicationDashboardDTO[]>;
getApplicationDashboardTable(
role: string,
role: ApplicantRole,
): Promise<ApplicationDashboardRowDTO[]>;
getApplicationBySecondChoiceRoleDashboardTable(
role: ApplicantRole,
): Promise<ApplicationDashboardRowDTO[]>;
mutateRating(
id: number,
Expand Down
22 changes: 22 additions & 0 deletions backend/typescript/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading