Skip to content

Commit c364736

Browse files
yoganandanessgithub-actions[bot]
authored andcommitted
wip
1 parent 41d51cb commit c364736

13 files changed

Lines changed: 123 additions & 37 deletions

File tree

apps/backend/src/datasources/InviteDataSource.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface InviteDataSource {
2828
isClaimed?: boolean
2929
): Promise<Invite[]>;
3030
getInvites(filter: GetInvitesFilter): Promise<Invite[]>;
31+
getProposalInvites(filter: GetInvitesFilter): Promise<Invite[]>;
3132

3233
update(args: {
3334
id: number;

apps/backend/src/datasources/mockups/InviteDataSource.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,7 @@ export class InviteDataSourceMock implements InviteDataSource {
177177

178178
return invite;
179179
}
180+
getProposalInvites(filter: GetInvitesFilter): Promise<Invite[]> {
181+
throw new Error('Method not implemented.');
182+
}
180183
}

apps/backend/src/datasources/postgres/InviteDataSource.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,43 @@ export default class PostgresInviteDataSource implements InviteDataSource {
107107
.then((invites: InviteRecord[]) => invites.map(createInviteObject));
108108
}
109109

110+
getProposalInvites(filter: GetInvitesFilter): Promise<Invite[]> {
111+
return database
112+
.select('*')
113+
.from('invites')
114+
.join(
115+
'co_proposer_claims',
116+
'invites.invite_id',
117+
'co_proposer_claims.invite_id'
118+
)
119+
.modify((query) => {
120+
if (filter.createdBefore) {
121+
query.where('created_at', '<', filter.createdBefore);
122+
}
123+
124+
if (filter.createdAfter) {
125+
query.where('created_at', '>', filter.createdAfter);
126+
}
127+
128+
if (filter.isClaimed !== undefined) {
129+
if (filter.isClaimed) {
130+
query.whereNotNull('claimed_at');
131+
} else {
132+
query.whereNull('claimed_at');
133+
}
134+
}
135+
136+
if (filter.isExpired) {
137+
query.where('expires_at', '<', new Date());
138+
}
139+
140+
if (filter.email) {
141+
query.where('email', filter.email);
142+
}
143+
})
144+
.then((invites: InviteRecord[]) => invites.map(createInviteObject));
145+
}
146+
110147
async create(args: {
111148
code: string;
112149
email: string;

apps/backend/src/datasources/postgres/ProposalDataSource.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,14 +1316,17 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
13161316
const proposals: InvitedProposalRecord[] | undefined = await database
13171317
.select(
13181318
'proposals.proposal_id',
1319-
'proposals.title',
1319+
'proposer.firstname as proposer_name',
13201320
'proposals.abstract',
1321-
'proposals.proposer_id'
1321+
'proposals.title'
13221322
)
13231323
.from('co_proposer_claims')
13241324
.join('proposals', {
13251325
'co_proposer_claims.proposal_pk': 'proposals.proposal_pk',
13261326
})
1327+
.join('users as proposer', {
1328+
'proposals.proposer_id': 'proposer.user_id',
1329+
})
13271330
.where('invite_id', inviteId);
13281331

13291332
return proposals ? createInvitedProposalObject(proposals[0]) : null;

apps/backend/src/datasources/postgres/records.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export interface ProposalViewRecord {
179179

180180
export interface InvitedProposalRecord {
181181
readonly proposal_id: string;
182-
readonly proposer_id: number;
182+
readonly proposer_name: string;
183183
readonly title: string;
184184
readonly abstract: string;
185185
}
@@ -915,7 +915,7 @@ export const createProposalViewObject = (proposal: ProposalViewRecord) => {
915915
export const createInvitedProposalObject = (record: InvitedProposalRecord) => {
916916
return new InvitedProposal(
917917
record.proposal_id,
918-
record.proposer_id,
918+
record.proposer_name,
919919
record.title,
920920
record.abstract
921921
);

apps/backend/src/models/Proposal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class Proposal {
5555
export class InvitedProposal {
5656
constructor(
5757
public proposalId: string,
58-
public proposerId: number,
58+
public proposerName: string,
5959
public title: string,
6060
public abstract: string
6161
) {}

apps/backend/src/queries/InviteQueries.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ export default class InviteQueries {
5959
}
6060

6161
@Authorized()
62-
async getUserInvites(agent: UserWithRole | null) {
62+
async getProposalInvites(agent: UserWithRole | null) {
6363
if (!agent) {
6464
return [];
6565
}
6666

67-
const invites = await this.dataSource.getInvites({
67+
const invites = await this.dataSource.getProposalInvites({
6868
email: agent.email,
6969
isClaimed: false,
7070
isExpired: false,

apps/backend/src/resolvers/types/Proposal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ export class InvitedProposal implements Partial<InvitedProposalOrigin> {
107107
@Field(() => String)
108108
public proposalId: string;
109109

110-
@Field(() => Int)
111-
public proposerId: number;
110+
@Field(() => String)
111+
public proposerName: string;
112112

113113
@Field(() => String)
114114
public title: string;

apps/backend/src/resolvers/types/User.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ export class UserResolver {
164164
}
165165

166166
@FieldResolver(() => [Invite])
167-
async invites(@Root() user: User, @Ctx() context: ResolverContext) {
168-
return context.queries.invite.getUserInvites(context.user);
167+
async proposalInvites(@Root() user: User, @Ctx() context: ResolverContext) {
168+
return context.queries.invite.getProposalInvites(context.user);
169169
}
170170

171171
@FieldResolver(() => [Experiment])

apps/frontend/src/components/notification/ProposalInviteNotification.tsx

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import DialogTitle from '@mui/material/DialogTitle';
77
import Typography from '@mui/material/Typography';
88
import React, { useState } from 'react';
99

10-
import { useProposalInvites } from 'hooks/proposal/useProposalInvites';
10+
import { useProposalInvites } from 'hooks/invite/useProposalInvites';
1111

1212
interface ProposalInviteNotificationProps {
1313
// We'll fetch the invites directly rather than passing count
@@ -20,7 +20,7 @@ const ProposalInviteNotification: React.FC<
2020
const [processingInviteId, setProcessingInviteId] = useState<number | null>(
2121
null
2222
);
23-
const { invites, loading, acceptInvite, declineInvite } =
23+
const { proposalInvites, loading, acceptInvite, declineInvite } =
2424
useProposalInvites();
2525

2626
const handleViewInvites = () => {
@@ -32,30 +32,30 @@ const ProposalInviteNotification: React.FC<
3232
};
3333

3434
const handleAcceptInvite = async (inviteId: number) => {
35-
setProcessingInviteId(inviteId);
36-
const success = await acceptInvite(inviteId);
37-
setProcessingInviteId(null);
38-
if (success && invites.length === 1) {
39-
// If this was the last invite, close the dialog
40-
setIsDialogOpen(false);
41-
}
35+
// setProcessingInviteId(inviteId);
36+
// const success = await acceptInvite(inviteId);
37+
// setProcessingInviteId(null);
38+
// if (success && userProposalInvites.length === 1) {
39+
// // If this was the last invite, close the dialog
40+
// setIsDialogOpen(false);
41+
// }
4242
};
4343

4444
const handleDeclineInvite = async (inviteId: number) => {
45-
setProcessingInviteId(inviteId);
46-
const success = await declineInvite(inviteId);
47-
setProcessingInviteId(null);
48-
if (success && invites.length === 1) {
49-
// If this was the last invite, close the dialog
50-
setIsDialogOpen(false);
51-
}
45+
// setProcessingInviteId(inviteId);
46+
// const success = await declineInvite(inviteId);
47+
// setProcessingInviteId(null);
48+
// if (success && userProposalInvites.length === 1) {
49+
// // If this was the last invite, close the dialog
50+
// setIsDialogOpen(false);
51+
// }
5252
};
5353

54-
if (invites.length === 0) {
54+
if (proposalInvites.length === 0) {
5555
return null;
5656
}
5757

58-
const inviteCount = invites.length;
58+
const inviteCount = proposalInvites.length;
5959

6060
return (
6161
<>
@@ -97,12 +97,12 @@ const ProposalInviteNotification: React.FC<
9797
<Typography variant="h6">Proposal Invitations</Typography>
9898
</DialogTitle>
9999
<DialogContent>
100-
{invites.length === 0 ? (
100+
{proposalInvites.length === 0 ? (
101101
<Typography variant="body1" color="textSecondary">
102102
No pending invitations found.
103103
</Typography>
104104
) : (
105-
invites.map((invite) => (
105+
proposalInvites.map((invite) => (
106106
<Alert
107107
key={invite.id}
108108
severity="info"
@@ -141,10 +141,10 @@ const ProposalInviteNotification: React.FC<
141141
>
142142
<div>
143143
<Typography variant="subtitle2" fontWeight="bold">
144-
{invite.proposalTitle}
144+
{invite.proposal?.title || 'No Title'}
145145
</Typography>
146146
<Typography variant="body2" color="textSecondary">
147-
Principal Investigator: {invite.principalInvestigatorName}
147+
Principal Investigator: asd
148148
</Typography>
149149
<Typography variant="caption" color="textSecondary">
150150
Invited on:{' '}

0 commit comments

Comments
 (0)