4150 i should be able to view my emails even if ive set my account visibility to metadata (#4156)
* improve timeline messaging to allow users to view the threads to which they participated * working * improvement * improvements * improvements * fix * remove unnecessary type
This commit is contained in:
@ -3,9 +3,9 @@ import { Module } from '@nestjs/common';
|
||||
import { TimelineMessagingResolver } from 'src/core/messaging/timeline-messaging.resolver';
|
||||
import { TimelineMessagingService } from 'src/core/messaging/timeline-messaging.service';
|
||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||
|
||||
import { UserModule } from 'src/core/user/user.module';
|
||||
@Module({
|
||||
imports: [WorkspaceDataSourceModule],
|
||||
imports: [WorkspaceDataSourceModule, UserModule],
|
||||
exports: [],
|
||||
providers: [TimelineMessagingResolver, TimelineMessagingService],
|
||||
})
|
||||
|
||||
@ -17,6 +17,9 @@ import { AuthWorkspace } from 'src/decorators/auth/auth-workspace.decorator';
|
||||
import { TimelineMessagingService } from 'src/core/messaging/timeline-messaging.service';
|
||||
import { TIMELINE_THREADS_MAX_PAGE_SIZE } from 'src/core/messaging/constants/messaging.constants';
|
||||
import { TimelineThreadsWithTotal } from 'src/core/messaging/dtos/timeline-threads-with-total.dto';
|
||||
import { AuthUser } from 'src/decorators/auth/auth-user.decorator';
|
||||
import { UserService } from 'src/core/user/services/user.service';
|
||||
import { User } from 'src/core/user/user.entity';
|
||||
|
||||
@ArgsType()
|
||||
class GetTimelineThreadsFromPersonIdArgs {
|
||||
@ -49,15 +52,24 @@ class GetTimelineThreadsFromCompanyIdArgs {
|
||||
export class TimelineMessagingResolver {
|
||||
constructor(
|
||||
private readonly timelineMessagingService: TimelineMessagingService,
|
||||
private readonly userService: UserService,
|
||||
) {}
|
||||
|
||||
@Query(() => TimelineThreadsWithTotal)
|
||||
async getTimelineThreadsFromPersonId(
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
@AuthUser() user: User,
|
||||
@Args() { personId, page, pageSize }: GetTimelineThreadsFromPersonIdArgs,
|
||||
) {
|
||||
const workspaceMember = await this.userService.loadWorkspaceMember(user);
|
||||
|
||||
if (!workspaceMember) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timelineThreads =
|
||||
await this.timelineMessagingService.getMessagesFromPersonIds(
|
||||
workspaceMember.id,
|
||||
workspaceId,
|
||||
[personId],
|
||||
page,
|
||||
@ -70,10 +82,18 @@ export class TimelineMessagingResolver {
|
||||
@Query(() => TimelineThreadsWithTotal)
|
||||
async getTimelineThreadsFromCompanyId(
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
@AuthUser() user: User,
|
||||
@Args() { companyId, page, pageSize }: GetTimelineThreadsFromCompanyIdArgs,
|
||||
) {
|
||||
const workspaceMember = await this.userService.loadWorkspaceMember(user);
|
||||
|
||||
if (!workspaceMember) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timelineThreads =
|
||||
await this.timelineMessagingService.getMessagesFromCompanyId(
|
||||
workspaceMember.id,
|
||||
workspaceId,
|
||||
companyId,
|
||||
page,
|
||||
|
||||
@ -21,6 +21,7 @@ export class TimelineMessagingService {
|
||||
) {}
|
||||
|
||||
async getMessagesFromPersonIds(
|
||||
workspaceMemberId: string,
|
||||
workspaceId: string,
|
||||
personIds: string[],
|
||||
page: number = 1,
|
||||
@ -178,13 +179,14 @@ export class TimelineMessagingService {
|
||||
{},
|
||||
);
|
||||
|
||||
const threadMessagesFromActiveParticipants:
|
||||
const threadMessagesParticipants:
|
||||
| {
|
||||
id: string;
|
||||
messageId: string;
|
||||
receivedAt: Date;
|
||||
body: string;
|
||||
subject: string;
|
||||
role: string;
|
||||
personId: string;
|
||||
workspaceMemberId: string;
|
||||
handle: string;
|
||||
@ -203,6 +205,7 @@ export class TimelineMessagingService {
|
||||
message."receivedAt",
|
||||
message.text,
|
||||
message."subject",
|
||||
"messageParticipant"."role",
|
||||
"messageParticipant"."personId",
|
||||
"messageParticipant"."workspaceMemberId",
|
||||
"messageParticipant".handle,
|
||||
@ -216,7 +219,7 @@ export class TimelineMessagingService {
|
||||
FROM
|
||||
${dataSourceSchema}."message" message
|
||||
LEFT JOIN
|
||||
(SELECT * FROM ${dataSourceSchema}."messageParticipant" WHERE "messageParticipant".role = 'from') "messageParticipant" ON "messageParticipant"."messageId" = message.id
|
||||
${dataSourceSchema}."messageParticipant" "messageParticipant" ON "messageParticipant"."messageId" = message.id
|
||||
LEFT JOIN
|
||||
${dataSourceSchema}."person" person ON person."id" = "messageParticipant"."personId"
|
||||
LEFT JOIN
|
||||
@ -230,6 +233,11 @@ export class TimelineMessagingService {
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const threadMessagesFromActiveParticipants =
|
||||
threadMessagesParticipants?.filter(
|
||||
(threadMessage) => threadMessage.role === 'from',
|
||||
);
|
||||
|
||||
const totalNumberOfThreads =
|
||||
await this.workspaceDataSourceService.executeRawQuery(
|
||||
`
|
||||
@ -245,14 +253,14 @@ export class TimelineMessagingService {
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const threadParticipantsByThreadId: {
|
||||
const threadActiveParticipantsByThreadId: {
|
||||
[key: string]: TimelineThreadParticipant[];
|
||||
} = messageThreadIds.reduce((messageThreadIdAcc, messageThreadId) => {
|
||||
const threadMessages = threadMessagesFromActiveParticipants?.filter(
|
||||
(threadMessage) => threadMessage.id === messageThreadId,
|
||||
);
|
||||
|
||||
const threadParticipants = threadMessages?.reduce(
|
||||
const threadActiveParticipants = threadMessages?.reduce(
|
||||
(
|
||||
threadMessageAcc,
|
||||
threadMessage,
|
||||
@ -296,13 +304,36 @@ export class TimelineMessagingService {
|
||||
{},
|
||||
);
|
||||
|
||||
messageThreadIdAcc[messageThreadId] = threadParticipants
|
||||
? Object.values(threadParticipants)
|
||||
messageThreadIdAcc[messageThreadId] = threadActiveParticipants
|
||||
? Object.values(threadActiveParticipants)
|
||||
: [];
|
||||
|
||||
return messageThreadIdAcc;
|
||||
}, {});
|
||||
|
||||
const messageThreadIdsForWhichWorkspaceMemberIsNotInParticipants =
|
||||
messageThreadIds.reduce(
|
||||
(
|
||||
messageThreadIdsForWhichWorkspaceMemberIsInNotParticipantsAcc: string[],
|
||||
messageThreadId,
|
||||
) => {
|
||||
const threadMessagesWithWorkspaceMemberInParticipants =
|
||||
threadMessagesParticipants?.filter(
|
||||
(threadMessage) =>
|
||||
threadMessage.id === messageThreadId &&
|
||||
threadMessage.workspaceMemberId === workspaceMemberId,
|
||||
) ?? [];
|
||||
|
||||
if (threadMessagesWithWorkspaceMemberInParticipants.length === 0)
|
||||
messageThreadIdsForWhichWorkspaceMemberIsInNotParticipantsAcc.push(
|
||||
messageThreadId,
|
||||
);
|
||||
|
||||
return messageThreadIdsForWhichWorkspaceMemberIsInNotParticipantsAcc;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const threadVisibility:
|
||||
| {
|
||||
id: string;
|
||||
@ -322,13 +353,13 @@ export class TimelineMessagingService {
|
||||
WHERE
|
||||
message."messageThreadId" = ANY($1)
|
||||
`,
|
||||
[messageThreadIds],
|
||||
[messageThreadIdsForWhichWorkspaceMemberIsNotInParticipants],
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const visibilityValues = ['metadata', 'subject', 'share_everything'];
|
||||
|
||||
const threadVisibilityByThreadId:
|
||||
const threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants:
|
||||
| {
|
||||
[key: string]: 'metadata' | 'subject' | 'share_everything';
|
||||
}
|
||||
@ -349,13 +380,30 @@ export class TimelineMessagingService {
|
||||
{},
|
||||
);
|
||||
|
||||
const threadVisibilityByThreadId: {
|
||||
[key: string]: 'metadata' | 'subject' | 'share_everything';
|
||||
} = messageThreadIds.reduce((threadVisibilityAcc, messageThreadId) => {
|
||||
// If the workspace member is not in the participants of the thread, use the visibility value from the query
|
||||
threadVisibilityAcc[messageThreadId] =
|
||||
messageThreadIdsForWhichWorkspaceMemberIsNotInParticipants.includes(
|
||||
messageThreadId,
|
||||
)
|
||||
? threadVisibilityByThreadIdForWhichWorkspaceMemberIsNotInParticipants?.[
|
||||
messageThreadId
|
||||
] ?? 'metadata'
|
||||
: 'share_everything';
|
||||
|
||||
return threadVisibilityAcc;
|
||||
}, {});
|
||||
|
||||
const timelineThreads = messageThreadIds.map((messageThreadId) => {
|
||||
const threadParticipants = threadParticipantsByThreadId[messageThreadId];
|
||||
const threadActiveParticipants =
|
||||
threadActiveParticipantsByThreadId[messageThreadId];
|
||||
|
||||
const firstParticipant = threadParticipants[0];
|
||||
const firstParticipant = threadActiveParticipants[0];
|
||||
|
||||
const threadParticipantsWithoutFirstParticipant =
|
||||
threadParticipants.filter(
|
||||
const threadActiveParticipantsWithoutFirstParticipant =
|
||||
threadActiveParticipants.filter(
|
||||
(threadParticipant) =>
|
||||
threadParticipant.handle !== firstParticipant.handle,
|
||||
);
|
||||
@ -363,20 +411,22 @@ export class TimelineMessagingService {
|
||||
const lastTwoParticipants: TimelineThreadParticipant[] = [];
|
||||
|
||||
const lastParticipant =
|
||||
threadParticipantsWithoutFirstParticipant.slice(-1)[0];
|
||||
threadActiveParticipantsWithoutFirstParticipant.slice(-1)[0];
|
||||
|
||||
if (lastParticipant) {
|
||||
lastTwoParticipants.push(lastParticipant);
|
||||
|
||||
const threadParticipantsWithoutFirstAndLastParticipants =
|
||||
threadParticipantsWithoutFirstParticipant.filter(
|
||||
const threadActiveParticipantsWithoutFirstAndLastParticipants =
|
||||
threadActiveParticipantsWithoutFirstParticipant.filter(
|
||||
(threadParticipant) =>
|
||||
threadParticipant.handle !== lastParticipant.handle,
|
||||
);
|
||||
|
||||
if (threadParticipantsWithoutFirstAndLastParticipants.length > 0)
|
||||
if (threadActiveParticipantsWithoutFirstAndLastParticipants.length > 0)
|
||||
lastTwoParticipants.push(
|
||||
threadParticipantsWithoutFirstAndLastParticipants.slice(-1)[0],
|
||||
threadActiveParticipantsWithoutFirstAndLastParticipants.slice(
|
||||
-1,
|
||||
)[0],
|
||||
);
|
||||
}
|
||||
|
||||
@ -399,7 +449,7 @@ export class TimelineMessagingService {
|
||||
visibility: threadVisibilityByThreadId?.[messageThreadId] ?? 'metadata',
|
||||
subject: threadSubject,
|
||||
numberOfMessagesInThread: numberOfMessages,
|
||||
participantCount: threadParticipants.length,
|
||||
participantCount: threadActiveParticipants.length,
|
||||
};
|
||||
});
|
||||
|
||||
@ -410,6 +460,7 @@ export class TimelineMessagingService {
|
||||
}
|
||||
|
||||
async getMessagesFromCompanyId(
|
||||
workspaceMemberId: string,
|
||||
workspaceId: string,
|
||||
companyId: string,
|
||||
page: number = 1,
|
||||
@ -443,6 +494,7 @@ export class TimelineMessagingService {
|
||||
);
|
||||
|
||||
const messageThreads = await this.getMessagesFromPersonIds(
|
||||
workspaceMemberId,
|
||||
workspaceId,
|
||||
formattedPersonIds,
|
||||
page,
|
||||
|
||||
Reference in New Issue
Block a user