mirror of
https://github.com/lingble/twenty.git
synced 2025-11-03 06:07:56 +00:00
4485 create a custom resolver for calendar events (#4568)
* create timeline calendar event resolver * working on getCalendarEventsFromPersonIds * add count query * add calendarEventVisibility and add typing * update calendarEvent dto * modify calendarEvent dto * compute calendar event visibility * fix types * add FieldMetadata in timeline calendar dtos and create queries and fragments * remove fieldMatadata * fix naming * update resolver * add getCalendarEventsFromCompanyId * fix queries * refactor queries * fix visibility * fix calendar event attendees bug * visibility is working * remove @IDField * update gql queries * update dto * add error * add enum * throw http exception * modify error * Refactor calendar event visibility check * use enum
This commit is contained in:
@@ -61,7 +61,7 @@ export type AuthTokens = {
|
|||||||
export type Billing = {
|
export type Billing = {
|
||||||
__typename?: 'Billing';
|
__typename?: 'Billing';
|
||||||
billingFreeTrialDurationInDays?: Maybe<Scalars['Float']>;
|
billingFreeTrialDurationInDays?: Maybe<Scalars['Float']>;
|
||||||
billingUrl: Scalars['String'];
|
billingUrl?: Maybe<Scalars['String']>;
|
||||||
isBillingEnabled: Scalars['Boolean'];
|
isBillingEnabled: Scalars['Boolean'];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -417,6 +417,8 @@ export type Query = {
|
|||||||
currentWorkspace: Workspace;
|
currentWorkspace: Workspace;
|
||||||
findWorkspaceFromInviteHash: Workspace;
|
findWorkspaceFromInviteHash: Workspace;
|
||||||
getProductPrices: ProductPricesEntity;
|
getProductPrices: ProductPricesEntity;
|
||||||
|
getTimelineCalendarEventsFromCompanyId: TimelineCalendarEventsWithTotal;
|
||||||
|
getTimelineCalendarEventsFromPersonId: TimelineCalendarEventsWithTotal;
|
||||||
getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal;
|
getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal;
|
||||||
getTimelineThreadsFromPersonId: TimelineThreadsWithTotal;
|
getTimelineThreadsFromPersonId: TimelineThreadsWithTotal;
|
||||||
object: Object;
|
object: Object;
|
||||||
@@ -450,6 +452,20 @@ export type QueryGetProductPricesArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type QueryGetTimelineCalendarEventsFromCompanyIdArgs = {
|
||||||
|
companyId: Scalars['ID'];
|
||||||
|
page: Scalars['Int'];
|
||||||
|
pageSize: Scalars['Int'];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type QueryGetTimelineCalendarEventsFromPersonIdArgs = {
|
||||||
|
page: Scalars['Int'];
|
||||||
|
pageSize: Scalars['Int'];
|
||||||
|
personId: Scalars['ID'];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type QueryGetTimelineThreadsFromCompanyIdArgs = {
|
export type QueryGetTimelineThreadsFromCompanyIdArgs = {
|
||||||
companyId: Scalars['ID'];
|
companyId: Scalars['ID'];
|
||||||
page: Scalars['Int'];
|
page: Scalars['Int'];
|
||||||
@@ -492,6 +508,23 @@ export type RelationConnection = {
|
|||||||
pageInfo: PageInfo;
|
pageInfo: PageInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RelationDefinition = {
|
||||||
|
__typename?: 'RelationDefinition';
|
||||||
|
direction: RelationDefinitionType;
|
||||||
|
sourceFieldMetadata: Field;
|
||||||
|
sourceObjectMetadata: Object;
|
||||||
|
targetFieldMetadata: Field;
|
||||||
|
targetObjectMetadata: Object;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Relation definition type */
|
||||||
|
export enum RelationDefinitionType {
|
||||||
|
ManyToMany = 'MANY_TO_MANY',
|
||||||
|
ManyToOne = 'MANY_TO_ONE',
|
||||||
|
OneToMany = 'ONE_TO_MANY',
|
||||||
|
OneToOne = 'ONE_TO_ONE'
|
||||||
|
}
|
||||||
|
|
||||||
export type RelationDeleteResponse = {
|
export type RelationDeleteResponse = {
|
||||||
__typename?: 'RelationDeleteResponse';
|
__typename?: 'RelationDeleteResponse';
|
||||||
createdAt?: Maybe<Scalars['DateTime']>;
|
createdAt?: Maybe<Scalars['DateTime']>;
|
||||||
@@ -545,6 +578,45 @@ export type Telemetry = {
|
|||||||
enabled: Scalars['Boolean'];
|
enabled: Scalars['Boolean'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TimelineCalendarEvent = {
|
||||||
|
__typename?: 'TimelineCalendarEvent';
|
||||||
|
attendees: Array<TimelineCalendarEventAttendee>;
|
||||||
|
conferenceSolution: Scalars['String'];
|
||||||
|
conferenceUri: Scalars['String'];
|
||||||
|
description: Scalars['String'];
|
||||||
|
endsAt: Scalars['DateTime'];
|
||||||
|
id: Scalars['ID'];
|
||||||
|
isCanceled: Scalars['Boolean'];
|
||||||
|
isFullDay: Scalars['Boolean'];
|
||||||
|
location: Scalars['String'];
|
||||||
|
startsAt: Scalars['DateTime'];
|
||||||
|
title: Scalars['String'];
|
||||||
|
visibility: TimelineCalendarEventVisibility;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TimelineCalendarEventAttendee = {
|
||||||
|
__typename?: 'TimelineCalendarEventAttendee';
|
||||||
|
avatarUrl: Scalars['String'];
|
||||||
|
displayName: Scalars['String'];
|
||||||
|
firstName: Scalars['String'];
|
||||||
|
handle: Scalars['String'];
|
||||||
|
lastName: Scalars['String'];
|
||||||
|
personId?: Maybe<Scalars['ID']>;
|
||||||
|
workspaceMemberId?: Maybe<Scalars['ID']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Visibility of the calendar event */
|
||||||
|
export enum TimelineCalendarEventVisibility {
|
||||||
|
Metadata = 'METADATA',
|
||||||
|
ShareEverything = 'SHARE_EVERYTHING'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TimelineCalendarEventsWithTotal = {
|
||||||
|
__typename?: 'TimelineCalendarEventsWithTotal';
|
||||||
|
timelineCalendarEvents: Array<TimelineCalendarEvent>;
|
||||||
|
totalNumberOfCalendarEvents: Scalars['Int'];
|
||||||
|
};
|
||||||
|
|
||||||
export type TimelineThread = {
|
export type TimelineThread = {
|
||||||
__typename?: 'TimelineThread';
|
__typename?: 'TimelineThread';
|
||||||
firstParticipant: TimelineThreadParticipant;
|
firstParticipant: TimelineThreadParticipant;
|
||||||
@@ -716,6 +788,7 @@ export type Field = {
|
|||||||
label: Scalars['String'];
|
label: Scalars['String'];
|
||||||
name: Scalars['String'];
|
name: Scalars['String'];
|
||||||
options?: Maybe<Scalars['JSON']>;
|
options?: Maybe<Scalars['JSON']>;
|
||||||
|
relationDefinition?: Maybe<RelationDefinition>;
|
||||||
toRelationMetadata?: Maybe<Relation>;
|
toRelationMetadata?: Maybe<Relation>;
|
||||||
type: FieldMetadataType;
|
type: FieldMetadataType;
|
||||||
updatedAt: Scalars['DateTime'];
|
updatedAt: Scalars['DateTime'];
|
||||||
@@ -794,6 +867,30 @@ export type RelationEdge = {
|
|||||||
node: Relation;
|
node: Relation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AttendeeFragmentFragment = { __typename?: 'TimelineCalendarEventAttendee', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
||||||
|
|
||||||
|
export type CalendarEventFragmentFragment = { __typename?: 'TimelineCalendarEvent', id: string, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, attendees: Array<{ __typename?: 'TimelineCalendarEventAttendee', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
||||||
|
|
||||||
|
export type TimelineCalendarEventsWithTotalFragmentFragment = { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: string, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, attendees: Array<{ __typename?: 'TimelineCalendarEventAttendee', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> };
|
||||||
|
|
||||||
|
export type GetTimelineCalendarEventsFromCompanyIdQueryVariables = Exact<{
|
||||||
|
companyId: Scalars['ID'];
|
||||||
|
page: Scalars['Int'];
|
||||||
|
pageSize: Scalars['Int'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetTimelineCalendarEventsFromCompanyIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromCompanyId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: string, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, attendees: Array<{ __typename?: 'TimelineCalendarEventAttendee', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
|
export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
||||||
|
personId: Scalars['ID'];
|
||||||
|
page: Scalars['Int'];
|
||||||
|
pageSize: Scalars['Int'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetTimelineCalendarEventsFromPersonIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromPersonId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: string, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, attendees: Array<{ __typename?: 'TimelineCalendarEventAttendee', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||||
|
|
||||||
export type ParticipantFragmentFragment = { __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
export type ParticipantFragmentFragment = { __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
||||||
|
|
||||||
export type TimelineThreadFragmentFragment = { __typename?: 'TimelineThread', id: string, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
export type TimelineThreadFragmentFragment = { __typename?: 'TimelineThread', id: string, read: boolean, visibility: string, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: string | null, workspaceMemberId?: string | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> };
|
||||||
@@ -937,7 +1034,7 @@ export type GetProductPricesQuery = { __typename?: 'Query', getProductPrices: {
|
|||||||
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, signUpDisabled: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl: string, billingFreeTrialDurationInDays?: number | null }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null } } };
|
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, signUpDisabled: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null } } };
|
||||||
|
|
||||||
export type UploadFileMutationVariables = Exact<{
|
export type UploadFileMutationVariables = Exact<{
|
||||||
file: Scalars['Upload'];
|
file: Scalars['Upload'];
|
||||||
@@ -1007,6 +1104,39 @@ export type GetWorkspaceFromInviteHashQueryVariables = Exact<{
|
|||||||
|
|
||||||
export type GetWorkspaceFromInviteHashQuery = { __typename?: 'Query', findWorkspaceFromInviteHash: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, allowImpersonation: boolean } };
|
export type GetWorkspaceFromInviteHashQuery = { __typename?: 'Query', findWorkspaceFromInviteHash: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, allowImpersonation: boolean } };
|
||||||
|
|
||||||
|
export const AttendeeFragmentFragmentDoc = gql`
|
||||||
|
fragment AttendeeFragment on TimelineCalendarEventAttendee {
|
||||||
|
personId
|
||||||
|
workspaceMemberId
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
displayName
|
||||||
|
avatarUrl
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const CalendarEventFragmentFragmentDoc = gql`
|
||||||
|
fragment CalendarEventFragment on TimelineCalendarEvent {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
description
|
||||||
|
location
|
||||||
|
startsAt
|
||||||
|
endsAt
|
||||||
|
isFullDay
|
||||||
|
attendees {
|
||||||
|
...AttendeeFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${AttendeeFragmentFragmentDoc}`;
|
||||||
|
export const TimelineCalendarEventsWithTotalFragmentFragmentDoc = gql`
|
||||||
|
fragment TimelineCalendarEventsWithTotalFragment on TimelineCalendarEventsWithTotal {
|
||||||
|
totalNumberOfCalendarEvents
|
||||||
|
timelineCalendarEvents {
|
||||||
|
...CalendarEventFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${CalendarEventFragmentFragmentDoc}`;
|
||||||
export const ParticipantFragmentFragmentDoc = gql`
|
export const ParticipantFragmentFragmentDoc = gql`
|
||||||
fragment ParticipantFragment on TimelineThreadParticipant {
|
fragment ParticipantFragment on TimelineThreadParticipant {
|
||||||
personId
|
personId
|
||||||
@@ -1103,6 +1233,88 @@ export const UserQueryFragmentFragmentDoc = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
export const GetTimelineCalendarEventsFromCompanyIdDocument = gql`
|
||||||
|
query GetTimelineCalendarEventsFromCompanyId($companyId: ID!, $page: Int!, $pageSize: Int!) {
|
||||||
|
getTimelineCalendarEventsFromCompanyId(
|
||||||
|
companyId: $companyId
|
||||||
|
page: $page
|
||||||
|
pageSize: $pageSize
|
||||||
|
) {
|
||||||
|
...TimelineCalendarEventsWithTotalFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${TimelineCalendarEventsWithTotalFragmentFragmentDoc}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetTimelineCalendarEventsFromCompanyIdQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetTimelineCalendarEventsFromCompanyIdQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetTimelineCalendarEventsFromCompanyIdQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetTimelineCalendarEventsFromCompanyIdQuery({
|
||||||
|
* variables: {
|
||||||
|
* companyId: // value for 'companyId'
|
||||||
|
* page: // value for 'page'
|
||||||
|
* pageSize: // value for 'pageSize'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetTimelineCalendarEventsFromCompanyIdQuery(baseOptions: Apollo.QueryHookOptions<GetTimelineCalendarEventsFromCompanyIdQuery, GetTimelineCalendarEventsFromCompanyIdQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<GetTimelineCalendarEventsFromCompanyIdQuery, GetTimelineCalendarEventsFromCompanyIdQueryVariables>(GetTimelineCalendarEventsFromCompanyIdDocument, options);
|
||||||
|
}
|
||||||
|
export function useGetTimelineCalendarEventsFromCompanyIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetTimelineCalendarEventsFromCompanyIdQuery, GetTimelineCalendarEventsFromCompanyIdQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<GetTimelineCalendarEventsFromCompanyIdQuery, GetTimelineCalendarEventsFromCompanyIdQueryVariables>(GetTimelineCalendarEventsFromCompanyIdDocument, options);
|
||||||
|
}
|
||||||
|
export type GetTimelineCalendarEventsFromCompanyIdQueryHookResult = ReturnType<typeof useGetTimelineCalendarEventsFromCompanyIdQuery>;
|
||||||
|
export type GetTimelineCalendarEventsFromCompanyIdLazyQueryHookResult = ReturnType<typeof useGetTimelineCalendarEventsFromCompanyIdLazyQuery>;
|
||||||
|
export type GetTimelineCalendarEventsFromCompanyIdQueryResult = Apollo.QueryResult<GetTimelineCalendarEventsFromCompanyIdQuery, GetTimelineCalendarEventsFromCompanyIdQueryVariables>;
|
||||||
|
export const GetTimelineCalendarEventsFromPersonIdDocument = gql`
|
||||||
|
query GetTimelineCalendarEventsFromPersonId($personId: ID!, $page: Int!, $pageSize: Int!) {
|
||||||
|
getTimelineCalendarEventsFromPersonId(
|
||||||
|
personId: $personId
|
||||||
|
page: $page
|
||||||
|
pageSize: $pageSize
|
||||||
|
) {
|
||||||
|
...TimelineCalendarEventsWithTotalFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${TimelineCalendarEventsWithTotalFragmentFragmentDoc}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetTimelineCalendarEventsFromPersonIdQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetTimelineCalendarEventsFromPersonIdQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetTimelineCalendarEventsFromPersonIdQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetTimelineCalendarEventsFromPersonIdQuery({
|
||||||
|
* variables: {
|
||||||
|
* personId: // value for 'personId'
|
||||||
|
* page: // value for 'page'
|
||||||
|
* pageSize: // value for 'pageSize'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetTimelineCalendarEventsFromPersonIdQuery(baseOptions: Apollo.QueryHookOptions<GetTimelineCalendarEventsFromPersonIdQuery, GetTimelineCalendarEventsFromPersonIdQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<GetTimelineCalendarEventsFromPersonIdQuery, GetTimelineCalendarEventsFromPersonIdQueryVariables>(GetTimelineCalendarEventsFromPersonIdDocument, options);
|
||||||
|
}
|
||||||
|
export function useGetTimelineCalendarEventsFromPersonIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetTimelineCalendarEventsFromPersonIdQuery, GetTimelineCalendarEventsFromPersonIdQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<GetTimelineCalendarEventsFromPersonIdQuery, GetTimelineCalendarEventsFromPersonIdQueryVariables>(GetTimelineCalendarEventsFromPersonIdDocument, options);
|
||||||
|
}
|
||||||
|
export type GetTimelineCalendarEventsFromPersonIdQueryHookResult = ReturnType<typeof useGetTimelineCalendarEventsFromPersonIdQuery>;
|
||||||
|
export type GetTimelineCalendarEventsFromPersonIdLazyQueryHookResult = ReturnType<typeof useGetTimelineCalendarEventsFromPersonIdLazyQuery>;
|
||||||
|
export type GetTimelineCalendarEventsFromPersonIdQueryResult = Apollo.QueryResult<GetTimelineCalendarEventsFromPersonIdQuery, GetTimelineCalendarEventsFromPersonIdQueryVariables>;
|
||||||
export const GetTimelineThreadsFromCompanyIdDocument = gql`
|
export const GetTimelineThreadsFromCompanyIdDocument = gql`
|
||||||
query GetTimelineThreadsFromCompanyId($companyId: ID!, $page: Int!, $pageSize: Int!) {
|
query GetTimelineThreadsFromCompanyId($companyId: ID!, $page: Int!, $pageSize: Int!) {
|
||||||
getTimelineThreadsFromCompanyId(
|
getTimelineThreadsFromCompanyId(
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const attendeeFragment = gql`
|
||||||
|
fragment AttendeeFragment on TimelineCalendarEventAttendee {
|
||||||
|
personId
|
||||||
|
workspaceMemberId
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
displayName
|
||||||
|
avatarUrl
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { attendeeFragment } from '@/activities/calendar/queries/fragments/attendeeFragment';
|
||||||
|
|
||||||
|
export const calendarEventFragment = gql`
|
||||||
|
fragment CalendarEventFragment on TimelineCalendarEvent {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
description
|
||||||
|
location
|
||||||
|
startsAt
|
||||||
|
endsAt
|
||||||
|
isFullDay
|
||||||
|
attendees {
|
||||||
|
...AttendeeFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${attendeeFragment}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { calendarEventFragment } from '@/activities/calendar/queries/fragments/calendarEventFragment';
|
||||||
|
|
||||||
|
export const timelineCalendarEventWithTotalFragment = gql`
|
||||||
|
fragment TimelineCalendarEventsWithTotalFragment on TimelineCalendarEventsWithTotal {
|
||||||
|
totalNumberOfCalendarEvents
|
||||||
|
timelineCalendarEvents {
|
||||||
|
...CalendarEventFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${calendarEventFragment}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { timelineCalendarEventWithTotalFragment } from '@/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment';
|
||||||
|
|
||||||
|
export const getTimelineCalendarEventsFromCompanyId = gql`
|
||||||
|
query GetTimelineCalendarEventsFromCompanyId(
|
||||||
|
$companyId: ID!
|
||||||
|
$page: Int!
|
||||||
|
$pageSize: Int!
|
||||||
|
) {
|
||||||
|
getTimelineCalendarEventsFromCompanyId(
|
||||||
|
companyId: $companyId
|
||||||
|
page: $page
|
||||||
|
pageSize: $pageSize
|
||||||
|
) {
|
||||||
|
...TimelineCalendarEventsWithTotalFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${timelineCalendarEventWithTotalFragment}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { timelineCalendarEventWithTotalFragment } from '@/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment';
|
||||||
|
|
||||||
|
export const getTimelineCalendarEventsFromPersonId = gql`
|
||||||
|
query GetTimelineCalendarEventsFromPersonId(
|
||||||
|
$personId: ID!
|
||||||
|
$page: Int!
|
||||||
|
$pageSize: Int!
|
||||||
|
) {
|
||||||
|
getTimelineCalendarEventsFromPersonId(
|
||||||
|
personId: $personId
|
||||||
|
page: $page
|
||||||
|
pageSize: $pageSize
|
||||||
|
) {
|
||||||
|
...TimelineCalendarEventsWithTotalFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${timelineCalendarEventWithTotalFragment}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export const TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE = 20;
|
||||||
|
export const TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE = 50;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { ObjectType, Field, ID } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
@ObjectType('TimelineCalendarEventAttendee')
|
||||||
|
export class TimelineCalendarEventAttendee {
|
||||||
|
@Field(() => ID, { nullable: true })
|
||||||
|
personId: string;
|
||||||
|
|
||||||
|
@Field(() => ID, { nullable: true })
|
||||||
|
workspaceMemberId: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
firstName: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
lastName: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
avatarUrl: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
handle: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { ObjectType, ID, Field, registerEnumType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { TimelineCalendarEventAttendee } from 'src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto';
|
||||||
|
|
||||||
|
export enum TimelineCalendarEventVisibility {
|
||||||
|
METADATA = 'METADATA',
|
||||||
|
SHARE_EVERYTHING = 'SHARE_EVERYTHING',
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEnumType(TimelineCalendarEventVisibility, {
|
||||||
|
name: 'TimelineCalendarEventVisibility',
|
||||||
|
description: 'Visibility of the calendar event',
|
||||||
|
});
|
||||||
|
|
||||||
|
@ObjectType('TimelineCalendarEvent')
|
||||||
|
export class TimelineCalendarEvent {
|
||||||
|
@Field(() => ID)
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
isCanceled: boolean;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
isFullDay: boolean;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
startsAt: Date;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
endsAt: Date;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
location: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
conferenceSolution: string;
|
||||||
|
|
||||||
|
@Field()
|
||||||
|
conferenceUri: string;
|
||||||
|
|
||||||
|
@Field(() => [TimelineCalendarEventAttendee])
|
||||||
|
attendees: TimelineCalendarEventAttendee[];
|
||||||
|
|
||||||
|
@Field(() => TimelineCalendarEventVisibility)
|
||||||
|
visibility: TimelineCalendarEventVisibility;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Field, Int, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { TimelineCalendarEvent } from 'src/engine/modules/calendar/dtos/timeline-calendar-event.dto';
|
||||||
|
|
||||||
|
@ObjectType('TimelineCalendarEventsWithTotal')
|
||||||
|
export class TimelineCalendarEventsWithTotal {
|
||||||
|
@Field(() => Int)
|
||||||
|
totalNumberOfCalendarEvents: number;
|
||||||
|
|
||||||
|
@Field(() => [TimelineCalendarEvent])
|
||||||
|
timelineCalendarEvents: TimelineCalendarEvent[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||||
|
import { UserModule } from 'src/engine/modules/user/user.module';
|
||||||
|
import { TimelineCalendarEventResolver } from 'src/engine/modules/calendar/timeline-calendar-event.resolver';
|
||||||
|
import { TimelineCalendarEventService } from 'src/engine/modules/calendar/timeline-calendar-event.service';
|
||||||
|
@Module({
|
||||||
|
imports: [WorkspaceDataSourceModule, UserModule],
|
||||||
|
exports: [],
|
||||||
|
providers: [TimelineCalendarEventResolver, TimelineCalendarEventService],
|
||||||
|
})
|
||||||
|
export class TimelineCalendarEventModule {}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import { UseGuards } from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
Query,
|
||||||
|
Args,
|
||||||
|
ArgsType,
|
||||||
|
Field,
|
||||||
|
ID,
|
||||||
|
Int,
|
||||||
|
Resolver,
|
||||||
|
} from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { Max } from 'class-validator';
|
||||||
|
|
||||||
|
import { User } from 'src/engine/modules/user/user.entity';
|
||||||
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
import { TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE } from 'src/engine/modules/calendar/constants/calendar.constants';
|
||||||
|
import { TimelineCalendarEventsWithTotal } from 'src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto';
|
||||||
|
import { TimelineCalendarEventService } from 'src/engine/modules/calendar/timeline-calendar-event.service';
|
||||||
|
import { UserService } from 'src/engine/modules/user/services/user.service';
|
||||||
|
import { Workspace } from 'src/engine/modules/workspace/workspace.entity';
|
||||||
|
import { NotFoundError } from 'src/engine/filters/utils/graphql-errors.util';
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
class GetTimelineCalendarEventsFromPersonIdArgs {
|
||||||
|
@Field(() => ID)
|
||||||
|
personId: string;
|
||||||
|
|
||||||
|
@Field(() => Int)
|
||||||
|
page: number;
|
||||||
|
|
||||||
|
@Field(() => Int)
|
||||||
|
@Max(TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE)
|
||||||
|
pageSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
class GetTimelineCalendarEventsFromCompanyIdArgs {
|
||||||
|
@Field(() => ID)
|
||||||
|
companyId: string;
|
||||||
|
|
||||||
|
@Field(() => Int)
|
||||||
|
page: number;
|
||||||
|
|
||||||
|
@Field(() => Int)
|
||||||
|
@Max(TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE)
|
||||||
|
pageSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Resolver(() => TimelineCalendarEventsWithTotal)
|
||||||
|
export class TimelineCalendarEventResolver {
|
||||||
|
constructor(
|
||||||
|
private readonly timelineCalendarEventService: TimelineCalendarEventService,
|
||||||
|
private readonly userService: UserService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Query(() => TimelineCalendarEventsWithTotal)
|
||||||
|
async getTimelineCalendarEventsFromPersonId(
|
||||||
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
|
@AuthUser() user: User,
|
||||||
|
@Args()
|
||||||
|
{ personId, page, pageSize }: GetTimelineCalendarEventsFromPersonIdArgs,
|
||||||
|
) {
|
||||||
|
const workspaceMember = await this.userService.loadWorkspaceMember(user);
|
||||||
|
|
||||||
|
if (!workspaceMember) {
|
||||||
|
throw new NotFoundError('Workspace member not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const timelineCalendarEvents =
|
||||||
|
await this.timelineCalendarEventService.getCalendarEventsFromPersonIds(
|
||||||
|
workspaceMember.id,
|
||||||
|
workspaceId,
|
||||||
|
[personId],
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
return timelineCalendarEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => TimelineCalendarEventsWithTotal)
|
||||||
|
async getTimelineCalendarEventsFromCompanyId(
|
||||||
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
|
@AuthUser() user: User,
|
||||||
|
@Args()
|
||||||
|
{ companyId, page, pageSize }: GetTimelineCalendarEventsFromCompanyIdArgs,
|
||||||
|
) {
|
||||||
|
const workspaceMember = await this.userService.loadWorkspaceMember(user);
|
||||||
|
|
||||||
|
if (!workspaceMember) {
|
||||||
|
throw new NotFoundError('Workspace member not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const timelineCalendarEvents =
|
||||||
|
await this.timelineCalendarEventService.getCalendarEventsFromCompanyId(
|
||||||
|
workspaceMember.id,
|
||||||
|
workspaceId,
|
||||||
|
companyId,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
return timelineCalendarEvents;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import groupBy from 'lodash.groupBy';
|
||||||
|
|
||||||
|
import { TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE } from 'src/engine/modules/calendar/constants/calendar.constants';
|
||||||
|
import { TimelineCalendarEventAttendee } from 'src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto';
|
||||||
|
import {
|
||||||
|
TimelineCalendarEvent,
|
||||||
|
TimelineCalendarEventVisibility,
|
||||||
|
} from 'src/engine/modules/calendar/dtos/timeline-calendar-event.dto';
|
||||||
|
import { TimelineCalendarEventsWithTotal } from 'src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto';
|
||||||
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
|
import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record';
|
||||||
|
import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata';
|
||||||
|
|
||||||
|
type TimelineCalendarEventAttendeeWithPersonInformation =
|
||||||
|
ObjectRecord<CalendarEventAttendeeObjectMetadata> & {
|
||||||
|
personFirstName: string;
|
||||||
|
personLastName: string;
|
||||||
|
personAvatarUrl: string;
|
||||||
|
workspaceMemberFirstName: string;
|
||||||
|
workspaceMemberLastName: string;
|
||||||
|
workspaceMemberAvatarUrl: string;
|
||||||
|
};
|
||||||
|
@Injectable()
|
||||||
|
export class TimelineCalendarEventService {
|
||||||
|
constructor(
|
||||||
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async getCalendarEventsFromPersonIds(
|
||||||
|
workspaceMemberId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
personIds: string[],
|
||||||
|
page: number = 1,
|
||||||
|
pageSize: number = TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE,
|
||||||
|
): Promise<TimelineCalendarEventsWithTotal> {
|
||||||
|
const offset = (page - 1) * pageSize;
|
||||||
|
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const calendarEvents: Omit<TimelineCalendarEvent, 'attendees'>[] =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT
|
||||||
|
"calendarEvent".*
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."calendarEvent" "calendarEvent"
|
||||||
|
LEFT JOIN
|
||||||
|
${dataSourceSchema}."calendarEventAttendee" "calendarEventAttendee" ON "calendarEvent".id = "calendarEventAttendee"."calendarEventId"
|
||||||
|
LEFT JOIN
|
||||||
|
${dataSourceSchema}."person" "person" ON "calendarEventAttendee"."personId" = "person".id
|
||||||
|
WHERE
|
||||||
|
"calendarEventAttendee"."personId" = ANY($1)
|
||||||
|
GROUP BY
|
||||||
|
"calendarEvent".id
|
||||||
|
ORDER BY
|
||||||
|
"calendarEvent"."startsAt" DESC
|
||||||
|
LIMIT $2
|
||||||
|
OFFSET $3`,
|
||||||
|
[personIds, pageSize, offset],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!calendarEvents) {
|
||||||
|
return {
|
||||||
|
totalNumberOfCalendarEvents: 0,
|
||||||
|
timelineCalendarEvents: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const calendarEventAttendees: TimelineCalendarEventAttendeeWithPersonInformation[] =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT
|
||||||
|
"calendarEventAttendee".*,
|
||||||
|
"person"."nameFirstName" as "personFirstName",
|
||||||
|
"person"."nameLastName" as "personLastName",
|
||||||
|
"person"."avatarUrl" as "personAvatarUrl",
|
||||||
|
"workspaceMember"."nameFirstName" as "workspaceMemberFirstName",
|
||||||
|
"workspaceMember"."nameLastName" as "workspaceMemberLastName",
|
||||||
|
"workspaceMember"."avatarUrl" as "workspaceMemberAvatarUrl"
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."calendarEventAttendee" "calendarEventAttendee"
|
||||||
|
LEFT JOIN
|
||||||
|
${dataSourceSchema}."person" "person" ON "calendarEventAttendee"."personId" = "person".id
|
||||||
|
LEFT JOIN
|
||||||
|
${dataSourceSchema}."workspaceMember" "workspaceMember" ON "calendarEventAttendee"."workspaceMemberId" = "workspaceMember".id
|
||||||
|
WHERE
|
||||||
|
"calendarEventAttendee"."calendarEventId" = ANY($1)`,
|
||||||
|
[calendarEvents.map((event) => event.id)],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const formattedCalendarEventAttendees: TimelineCalendarEventAttendee[] =
|
||||||
|
calendarEventAttendees.map((attendee) => {
|
||||||
|
const firstName =
|
||||||
|
attendee.personFirstName || attendee.workspaceMemberFirstName || '';
|
||||||
|
|
||||||
|
const lastName =
|
||||||
|
attendee.personLastName || attendee.workspaceMemberLastName || '';
|
||||||
|
|
||||||
|
const displayName =
|
||||||
|
firstName || attendee.displayName || attendee.handle;
|
||||||
|
|
||||||
|
const avatarUrl =
|
||||||
|
attendee.personAvatarUrl || attendee.workspaceMemberAvatarUrl || '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
calendarEventId: attendee.calendarEventId,
|
||||||
|
personId: attendee.personId,
|
||||||
|
workspaceMemberId: attendee.workspaceMemberId,
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
displayName,
|
||||||
|
avatarUrl,
|
||||||
|
handle: attendee.handle,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const calendarEventAttendeesByEventId: {
|
||||||
|
[calendarEventId: string]: TimelineCalendarEventAttendee[];
|
||||||
|
} = groupBy(formattedCalendarEventAttendees, 'calendarEventId');
|
||||||
|
|
||||||
|
const totalNumberOfCalendarEvents: { count: number }[] =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT "calendarEventId")
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."calendarEventAttendee" "calendarEventAttendee"
|
||||||
|
WHERE
|
||||||
|
"calendarEventAttendee"."personId" = ANY($1)
|
||||||
|
`,
|
||||||
|
[personIds],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const timelineCalendarEvents = calendarEvents.map((event) => {
|
||||||
|
const attendees = calendarEventAttendeesByEventId[event.id] || [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...event,
|
||||||
|
attendees,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const calendarEventIdsWithWorkspaceMemberInAttendees =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
"calendarEventId"
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."calendarEventAttendee" "calendarEventAttendee"
|
||||||
|
WHERE
|
||||||
|
"calendarEventAttendee"."workspaceMemberId" = $1
|
||||||
|
`,
|
||||||
|
[workspaceMemberId],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const calendarEventIdsWithWorkspaceMemberInAttendeesFormatted =
|
||||||
|
calendarEventIdsWithWorkspaceMemberInAttendees.map(
|
||||||
|
(event: { calendarEventId: string }) => event.calendarEventId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const calendarEventIdsToFetchVisibilityFor = timelineCalendarEvents
|
||||||
|
.filter(
|
||||||
|
(event) =>
|
||||||
|
!calendarEventIdsWithWorkspaceMemberInAttendeesFormatted.includes(
|
||||||
|
event.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map((event) => event.id);
|
||||||
|
|
||||||
|
const calendarEventIdsForWhichVisibilityIsMetadata:
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
}[]
|
||||||
|
| undefined = await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
"calendarChannelEventAssociation"."calendarEventId" AS "id"
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."calendarChannel" "calendarChannel"
|
||||||
|
LEFT JOIN
|
||||||
|
${dataSourceSchema}."calendarChannelEventAssociation" "calendarChannelEventAssociation" ON "calendarChannel".id = "calendarChannelEventAssociation"."calendarChannelId"
|
||||||
|
WHERE
|
||||||
|
"calendarChannelEventAssociation"."calendarEventId" = ANY($1)
|
||||||
|
AND
|
||||||
|
"calendarChannel"."visibility" = 'METADATA'
|
||||||
|
`,
|
||||||
|
[calendarEventIdsToFetchVisibilityFor],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!calendarEventIdsForWhichVisibilityIsMetadata) {
|
||||||
|
throw new Error('Failed to fetch calendar event visibility');
|
||||||
|
}
|
||||||
|
|
||||||
|
const calendarEventIdsForWhichVisibilityIsMetadataMap = new Map(
|
||||||
|
calendarEventIdsForWhichVisibilityIsMetadata.map((event) => [
|
||||||
|
event.id,
|
||||||
|
TimelineCalendarEventVisibility.METADATA,
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
timelineCalendarEvents.forEach((event) => {
|
||||||
|
event.visibility =
|
||||||
|
calendarEventIdsForWhichVisibilityIsMetadataMap.get(event.id) ??
|
||||||
|
TimelineCalendarEventVisibility.SHARE_EVERYTHING;
|
||||||
|
|
||||||
|
if (event.visibility === TimelineCalendarEventVisibility.METADATA) {
|
||||||
|
event.title = '';
|
||||||
|
event.description = '';
|
||||||
|
event.location = '';
|
||||||
|
event.conferenceSolution = '';
|
||||||
|
event.conferenceUri = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
totalNumberOfCalendarEvents: totalNumberOfCalendarEvents[0].count,
|
||||||
|
timelineCalendarEvents,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCalendarEventsFromCompanyId(
|
||||||
|
workspaceMemberId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
companyId: string,
|
||||||
|
page: number = 1,
|
||||||
|
pageSize: number = TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE,
|
||||||
|
): Promise<TimelineCalendarEventsWithTotal> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const personIds = await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
p."id"
|
||||||
|
FROM
|
||||||
|
${dataSourceSchema}."person" p
|
||||||
|
WHERE
|
||||||
|
p."companyId" = $1
|
||||||
|
`,
|
||||||
|
[companyId],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!personIds) {
|
||||||
|
return {
|
||||||
|
totalNumberOfCalendarEvents: 0,
|
||||||
|
timelineCalendarEvents: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const formattedPersonIds = personIds.map(
|
||||||
|
(personId: { id: string }) => personId.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageThreads = await this.getCalendarEventsFromPersonIds(
|
||||||
|
workspaceMemberId,
|
||||||
|
workspaceId,
|
||||||
|
formattedPersonIds,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
return messageThreads;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import { OpenApiModule } from 'src/engine/modules/open-api/open-api.module';
|
|||||||
import { TimelineMessagingModule } from 'src/engine/modules/messaging/timeline-messaging.module';
|
import { TimelineMessagingModule } from 'src/engine/modules/messaging/timeline-messaging.module';
|
||||||
import { BillingModule } from 'src/engine/modules/billing/billing.module';
|
import { BillingModule } from 'src/engine/modules/billing/billing.module';
|
||||||
import { HealthModule } from 'src/engine/modules/health/health.module';
|
import { HealthModule } from 'src/engine/modules/health/health.module';
|
||||||
|
import { TimelineCalendarEventModule } from 'src/engine/modules/calendar/timeline-calendar-event.module';
|
||||||
|
|
||||||
import { AnalyticsModule } from './analytics/analytics.module';
|
import { AnalyticsModule } from './analytics/analytics.module';
|
||||||
import { FileModule } from './file/file.module';
|
import { FileModule } from './file/file.module';
|
||||||
@@ -26,6 +27,7 @@ import { ClientConfigModule } from './client-config/client-config.module';
|
|||||||
OpenApiModule,
|
OpenApiModule,
|
||||||
RefreshTokenModule,
|
RefreshTokenModule,
|
||||||
TimelineMessagingModule,
|
TimelineMessagingModule,
|
||||||
|
TimelineCalendarEventModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
],
|
],
|
||||||
@@ -34,6 +36,7 @@ import { ClientConfigModule } from './client-config/client-config.module';
|
|||||||
AuthModule,
|
AuthModule,
|
||||||
FeatureFlagModule,
|
FeatureFlagModule,
|
||||||
TimelineMessagingModule,
|
TimelineMessagingModule,
|
||||||
|
TimelineCalendarEventModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { ObjectType, Field, ID } from '@nestjs/graphql';
|
import { ObjectType, Field, ID } from '@nestjs/graphql';
|
||||||
|
|
||||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
|
||||||
|
|
||||||
import { TimelineThreadParticipant } from 'src/engine/modules/messaging/dtos/timeline-thread-participant.dto';
|
import { TimelineThreadParticipant } from 'src/engine/modules/messaging/dtos/timeline-thread-participant.dto';
|
||||||
|
|
||||||
@ObjectType('TimelineThread')
|
@ObjectType('TimelineThread')
|
||||||
export class TimelineThread {
|
export class TimelineThread {
|
||||||
@IDField(() => ID)
|
@Field(() => ID)
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
@Field()
|
@Field()
|
||||||
|
|||||||
Reference in New Issue
Block a user