Skip to content

Commit 45a3609

Browse files
authored
Merge pull request #4083 from Northeastern-Electric-Racing/#4025-guest-change-request-page
#4025 guest change requests page
2 parents 3e75d3e + f600696 commit 45a3609

13 files changed

Lines changed: 282 additions & 9 deletions

File tree

src/backend/src/controllers/change-requests.controllers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ export default class ChangeRequestsController {
2323
}
2424
}
2525

26+
static async getAllGuestChangeRequests(req: Request, res: Response, next: NextFunction) {
27+
try {
28+
const changeRequests = await ChangeRequestsService.getAllGuestChangeRequests(req.organization);
29+
res.status(200).json(changeRequests);
30+
} catch (error: unknown) {
31+
next(error);
32+
}
33+
}
34+
2635
static async getToReviewChangeRequests(req: Request, res: Response, next: NextFunction) {
2736
try {
2837
const changeRequests = await ChangeRequestsService.getToReviewChangeRequests(req.currentUser, req.organization);

src/backend/src/prisma-query-args/change-requests.query-args.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,51 @@ export const getManyChangeRequestQueryArgs = (organizationId: string) =>
6868
}
6969
});
7070

71+
export type ChangeRequestGuestQueryArgs = ReturnType<typeof getGuestChangeRequestQueryArgs>;
72+
73+
export const getGuestChangeRequestQueryArgs = (organizationId: string) =>
74+
Prisma.validator<Prisma.Change_RequestDefaultArgs>()({
75+
select: {
76+
crId: true,
77+
identifier: true,
78+
dateSubmitted: true,
79+
type: true,
80+
accepted: true,
81+
dateReviewed: true,
82+
submitter: getUserQueryArgs(organizationId),
83+
reviewer: getUserQueryArgs(organizationId),
84+
changes: { select: { changeId: true } },
85+
wbsElement: {
86+
select: {
87+
carNumber: true,
88+
projectNumber: true,
89+
workPackageNumber: true,
90+
name: true,
91+
project: {
92+
select: {
93+
wbsElement: { select: { name: true } },
94+
teams: {
95+
select: { teamType: { select: { name: true } } }
96+
}
97+
}
98+
},
99+
workPackage: {
100+
select: {
101+
project: {
102+
select: {
103+
wbsElement: { select: { name: true } },
104+
teams: {
105+
select: { teamType: { select: { name: true } } }
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}
112+
}
113+
}
114+
});
115+
71116
export const getChangeRequestWithProjectAndWorkPackageQueryArgs = (organizationId: string) =>
72117
Prisma.validator<Prisma.Change_RequestDefaultArgs>()({
73118
include: {

src/backend/src/prisma/schema.prisma

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,11 @@ model Receipt {
739739
model Reimbursement_Request {
740740
reimbursementRequestId String @id @default(uuid())
741741
identifier Int
742-
saboId String? @unique
742+
saboId String? @unique
743743
dateCreated DateTime @default(now())
744744
dateDeleted DateTime?
745745
dateOfExpense DateTime?
746-
description String @default("")
746+
description String @default("")
747747
reimbursementStatuses Reimbursement_Status[]
748748
recipientId String
749749
recipient User @relation(name: "reimbursementRequestRecipient", fields: [recipientId], references: [userId])

src/backend/src/routes/change-requests.routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
const changeRequestsRouter = express.Router();
1515

1616
changeRequestsRouter.get('/', ChangeRequestsController.getAllChangeRequests);
17+
changeRequestsRouter.get('/guest', ChangeRequestsController.getAllGuestChangeRequests);
1718

1819
changeRequestsRouter.get('/to-review', ChangeRequestsController.getToReviewChangeRequests);
1920
changeRequestsRouter.get('/unreviewed', ChangeRequestsController.getUnreviewedChangeRequests);

src/backend/src/routes/recruitment.routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ recruitmentRouter.post(
5151
recruitmentRouter.delete('/faq/:faqId/delete', RecruitmentController.deleteFaq);
5252

5353
recruitmentRouter.post(
54-
'/guestDefinition/create',
54+
'/guestdefinition/create',
5555
nonEmptyString(body('term')),
5656
nonEmptyString(body('description')),
5757
body('order').isInt(),
@@ -62,6 +62,6 @@ recruitmentRouter.post(
6262
RecruitmentController.createGuestDefinition
6363
);
6464

65-
recruitmentRouter.get('/guestDefinitions', RecruitmentController.getAllGuestDefintions);
65+
recruitmentRouter.get('/guestdefinitions', RecruitmentController.getAllGuestDefintions);
6666

6767
export default recruitmentRouter;

src/backend/src/services/change-requests.services.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ import {
2828
DeletedException,
2929
InvalidOrganizationException
3030
} from '../utils/errors.utils.js';
31-
import changeRequestTransformer, { changeRequestManyTransformer } from '../transformers/change-requests.transformer.js';
31+
import changeRequestTransformer, {
32+
changeRequestManyTransformer,
33+
guestChangeRequestTransformer
34+
} from '../transformers/change-requests.transformer.js';
3235
import {
3336
allChangeRequestsReviewed,
3437
validateProposedChangesFields,
@@ -55,11 +58,13 @@ import {
5558
ChangeRequestWithProjectAndWorkPackageQueryArgs,
5659
getChangeRequestQueryArgs,
5760
getChangeRequestWithProjectAndWorkPackageQueryArgs,
61+
getGuestChangeRequestQueryArgs,
5862
getManyChangeRequestQueryArgs
5963
} from '../prisma-query-args/change-requests.query-args.js';
6064
import proposedSolutionTransformer from '../transformers/proposed-solutions.transformer.js';
6165
import { getProposedSolutionQueryArgs } from '../prisma-query-args/proposed-solutions.query-args.js';
6266
import { sendCrRequestReviewPopUp, sendCrReviewedPopUp } from '../utils/pop-up.utils.js';
67+
import { GuestChangeRequest } from '../../../shared/src/types/change-request-types.js';
6368

6469
export default class ChangeRequestsService {
6570
/**
@@ -97,6 +102,20 @@ export default class ChangeRequestsService {
97102
return changeRequests.map(changeRequestManyTransformer);
98103
}
99104

105+
/**
106+
* gets all the change requests in the database for the given organization, tailored to the guest cr page
107+
* @param organization The organization the user is currently in
108+
* @returns All of the change requests
109+
*/
110+
static async getAllGuestChangeRequests(organization: Organization): Promise<GuestChangeRequest[]> {
111+
const changeRequests = await prisma.change_Request.findMany({
112+
where: { dateDeleted: null, organizationId: organization.organizationId },
113+
...getGuestChangeRequestQueryArgs(organization.organizationId)
114+
});
115+
116+
return changeRequests.map(guestChangeRequestTransformer);
117+
}
118+
100119
/**
101120
* Gets a users change requests that they have been requested reviewer for or, if they are leadership, their teams change requests as well
102121
*

src/backend/src/transformers/change-requests.transformer.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
WorkPackageStage,
1111
BudgetChangeRequest,
1212
isWorkPackageWbs,
13-
LeadershipChangeRequest
13+
LeadershipChangeRequest,
14+
ChangeRequestStatus
1415
} from 'shared';
1516
import { wbsNumOf } from '../utils/utils.js';
1617
import { calculateChangeRequestStatus, convertCRScopeWhyType } from '../utils/change-requests.utils.js';
@@ -25,10 +26,12 @@ import {
2526
} from '../prisma-query-args/scope-change-requests.query-args.js';
2627
import { HttpException } from '../utils/errors.utils.js';
2728
import {
29+
ChangeRequestGuestQueryArgs,
2830
ChangeRequestManyQueryArgs,
2931
ChangeRequestWithProjectAndWorkPackageQueryArgs
3032
} from '../prisma-query-args/change-requests.query-args.js';
3133
import { accountCodeTransformer, otherProductReasonTransformer } from './reimbursement-requests.transformer.js';
34+
import { GuestChangeRequest } from '../../../shared/src/types/change-request-types.js';
3235

3336
const projectProposedChangesTransformer = (
3437
wbsProposedChanges: Prisma.Wbs_Proposed_ChangesGetPayload<WbsProposedChangeQueryArgs>
@@ -229,3 +232,41 @@ const changeRequestTransformer = (
229232
};
230233

231234
export default changeRequestTransformer;
235+
236+
export const guestChangeRequestTransformer = (
237+
changeRequest: Prisma.Change_RequestGetPayload<ChangeRequestGuestQueryArgs>
238+
): GuestChangeRequest => {
239+
const status = changeRequest.changes.length
240+
? ChangeRequestStatus.Implemented
241+
: changeRequest.accepted && changeRequest.dateReviewed
242+
? ChangeRequestStatus.Accepted
243+
: changeRequest.dateReviewed
244+
? ChangeRequestStatus.Denied
245+
: ChangeRequestStatus.Open;
246+
247+
const wbsName = changeRequest.wbsElement
248+
? !isWorkPackageWbs(changeRequest.wbsElement)
249+
? changeRequest.wbsElement?.name
250+
: `${changeRequest.wbsElement?.workPackage?.project.wbsElement.name} - ${changeRequest.wbsElement?.name}`
251+
: undefined;
252+
253+
return {
254+
crId: changeRequest.crId,
255+
submitter: userTransformer(changeRequest.submitter),
256+
identifier: changeRequest.identifier,
257+
type: changeRequest.type,
258+
status,
259+
teamTypeNames: changeRequest.wbsElement
260+
? isWorkPackageWbs(changeRequest.wbsElement)
261+
? (changeRequest.wbsElement.workPackage?.project?.teams
262+
.map((team) => team.teamType?.name)
263+
.filter((name) => name !== undefined) ?? [])
264+
: (changeRequest.wbsElement.project?.teams.map((team) => team.teamType?.name).filter((name) => name !== undefined) ??
265+
[])
266+
: [],
267+
accepted: changeRequest.accepted ?? undefined,
268+
reviewer: changeRequest.reviewer ? userTransformer(changeRequest.reviewer) : undefined,
269+
wbsNum: changeRequest.wbsElement ? wbsNumOf(changeRequest.wbsElement) : undefined,
270+
wbsName
271+
};
272+
};

src/frontend/src/apis/change-requests.api.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import axios from '../utils/axios';
7-
import { ChangeRequest, WbsNumber, ChangeRequestType } from 'shared';
7+
import { ChangeRequest, WbsNumber, ChangeRequestType, GuestChangeRequest } from 'shared';
88
import { apiUrls } from '../utils/urls';
99
import { changeRequestTransformer } from './transformers/change-requests.transformers';
1010
import { CreateStandardChangeRequestPayload } from '../hooks/change-requests.hooks';
@@ -18,6 +18,12 @@ export const getAllChangeRequests = () => {
1818
});
1919
};
2020

21+
export const getAllGuestChangeRequests = () => {
22+
return axios.get<GuestChangeRequest[]>(apiUrls.guestChangeRequests(), {
23+
transformResponse: (data) => JSON.parse(data)
24+
});
25+
};
26+
2127
export const getToReviewChangeRequests = () => {
2228
return axios.get<ChangeRequest[]>(apiUrls.toReviewChangeRequests(), {
2329
transformResponse: (data) => JSON.parse(data).map(changeRequestTransformer)

src/frontend/src/hooks/change-requests.hooks.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
ProposedSolutionCreateArgs,
1313
WbsNumber,
1414
WorkPackageProposedChangesCreateArgs,
15-
LeadershipChangeCreateArgs
15+
LeadershipChangeCreateArgs,
16+
GuestChangeRequest
1617
} from 'shared';
1718
import {
1819
createActivationChangeRequest,
@@ -28,7 +29,8 @@ import {
2829
getUnreviewedChangeRequests,
2930
getApprovedChangeRequests,
3031
createBudgetChangeRequest,
31-
createLeadershipChangeRequest
32+
createLeadershipChangeRequest,
33+
getAllGuestChangeRequests
3234
} from '../apis/change-requests.api';
3335

3436
/**
@@ -41,6 +43,13 @@ export const useAllChangeRequests = () => {
4143
});
4244
};
4345

46+
export const useAllGuestChangeRequests = () => {
47+
return useQuery<GuestChangeRequest[], Error>(['guest change requests'], async () => {
48+
const { data } = await getAllGuestChangeRequests();
49+
return data;
50+
});
51+
};
52+
4453
export const useGetToReviewChangeRequests = () => {
4554
return useQuery<ChangeRequest[], Error>(['change requests', 'to-review'], async () => {
4655
const { data } = await getToReviewChangeRequests();

src/frontend/src/pages/ChangeRequestsPage/ChangeRequestsView.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ChangeRequestsOverview from './ChangeRequestsOverview';
99
import ChangeRequestsTable from './ChangeRequestsTable';
1010
import PageLayout from '../../components/PageLayout';
1111
import FullPageTabs from '../../components/FullPageTabs';
12+
import GuestChangeRequestsPage from './GuestChangeRequestsPage';
1213

1314
const ChangeRequestsView: React.FC = () => {
1415
const history = useHistory();
@@ -17,6 +18,9 @@ const ChangeRequestsView: React.FC = () => {
1718
// Default to the "overview" tab
1819
const [tabIndex, setTabIndex] = useState<number>(0);
1920

21+
if (isGuest(user.role)) {
22+
return <GuestChangeRequestsPage />;
23+
}
2024
const headerRight = (
2125
<NERButton
2226
variant="contained"

0 commit comments

Comments
 (0)