Skip to content

Commit

Permalink
Use twentyORM in Timeline messaging (twentyhq#6595)
Browse files Browse the repository at this point in the history
- Remove raw queries and replace them by using `twentyORM`
- Refactor into services and utils

---------

Co-authored-by: Charles Bochet <[email protected]>
  • Loading branch information
bosiraphael and charlesBochet authored Aug 15, 2024
1 parent 6927f46 commit 08c7947
Show file tree
Hide file tree
Showing 19 changed files with 513 additions and 559 deletions.
2 changes: 1 addition & 1 deletion packages/twenty-front/src/hooks/useIsMatchingLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const useIsMatchingLocation = () => {
return useCallback(
(path: string, basePath?: AppBasePath) => {
const constructedPath = basePath
? (new URL(basePath + path, document.location.origin).pathname ?? '')
? new URL(basePath + path, document.location.origin).pathname ?? ''
: path;

return !!matchPath(constructedPath, location.pathname);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const MessageThreadSubscribersChip = ({
? `+${numberOfMessageThreadSubscribers - MAX_NUMBER_OF_AVATARS}`
: null;

const label = isPrivateThread ? privateLabel : (moreAvatarsLabel ?? '');
const label = isPrivateThread ? privateLabel : moreAvatarsLabel ?? '';

return (
<Chip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
export const generateDefaultRecordChipData = (record: ObjectRecord) => {
const name = isFieldFullNameValue(record.name)
? record.name.firstName + ' ' + record.name.lastName
: (record.name ?? '');
: record.name ?? '';

return {
name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ export const MultiSelectFieldInput = ({
const [searchFilter, setSearchFilter] = useState('');
const containerRef = useRef<HTMLDivElement>(null);

const selectedOptions = fieldDefinition.metadata.options.filter((option) =>
fieldValues?.includes(option.value),
const selectedOptions = fieldDefinition.metadata.options.filter(
(option) => fieldValues?.includes(option.value),
);

const optionsInDropDown = fieldDefinition.metadata.options;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const RecordDetailRelationSection = ({
const relationRecords: ObjectRecord[] =
fieldValue && isToOneObject
? [fieldValue as ObjectRecord]
: ((fieldValue as ObjectRecord[]) ?? []);
: (fieldValue as ObjectRecord[]) ?? [];

const relationRecordIds = relationRecords.map(({ id }) => id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ export const findUnmatchedRequiredFields = <T extends string>(
columns: Columns<T>,
) =>
fields
.filter((field) =>
field.fieldValidationDefinitions?.some(
(validation) => validation.rule === 'required',
),
.filter(
(field) =>
field.fieldValidationDefinitions?.some(
(validation) => validation.rule === 'required',
),
)
.filter(
(field) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type ContainerProps = {
const StyledContainer = styled.div<ContainerProps>`
align-items: center;
background-color: ${({ theme, isOn, color }) =>
isOn ? (color ?? theme.color.blue) : theme.background.quaternary};
isOn ? color ?? theme.color.blue : theme.background.quaternary};
border-radius: 10px;
cursor: pointer;
display: flex;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ObjectType, Field } from '@nestjs/graphql';
import { Field, ObjectType } from '@nestjs/graphql';

import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';

@ObjectType('TimelineThreadParticipant')
export class TimelineThreadParticipant {
@Field(() => UUIDScalarType, { nullable: true })
personId: string;
personId: string | null;

@Field(() => UUIDScalarType, { nullable: true })
workspaceMemberId: string;
workspaceMemberId: string | null;

@Field()
firstName: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Injectable } from '@nestjs/common';

import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/messaging/constants/messaging.constants';
import { TimelineThreadsWithTotal } from 'src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto';
import { TimelineMessagingService } from 'src/engine/core-modules/messaging/services/timeline-messaging.service';
import { formatThreads } from 'src/engine/core-modules/messaging/utils/format-threads.util';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';

@Injectable()
export class GetMessagesService {
constructor(
private readonly twentyORMManager: TwentyORMManager,
private readonly timelineMessagingService: TimelineMessagingService,
) {}

async getMessagesFromPersonIds(
workspaceMemberId: string,
personIds: string[],
page = 1,
pageSize: number = TIMELINE_THREADS_DEFAULT_PAGE_SIZE,
): Promise<TimelineThreadsWithTotal> {
const offset = (page - 1) * pageSize;

const { messageThreads, totalNumberOfThreads } =
await this.timelineMessagingService.getAndCountMessageThreads(
personIds,
offset,
pageSize,
);

if (!messageThreads) {
return {
totalNumberOfThreads: 0,
timelineThreads: [],
};
}

const messageThreadIds = messageThreads.map(
(messageThread) => messageThread.id,
);

const threadParticipantsByThreadId =
await this.timelineMessagingService.getThreadParticipantsByThreadId(
messageThreadIds,
);

const threadVisibilityByThreadId =
await this.timelineMessagingService.getThreadVisibilityByThreadId(
messageThreadIds,
workspaceMemberId,
);

return {
totalNumberOfThreads,
timelineThreads: formatThreads(
messageThreads,
threadParticipantsByThreadId,
threadVisibilityByThreadId,
),
};
}

async getMessagesFromCompanyId(
workspaceMemberId: string,
companyId: string,
page = 1,
pageSize: number = TIMELINE_THREADS_DEFAULT_PAGE_SIZE,
): Promise<TimelineThreadsWithTotal> {
const personRepository =
await this.twentyORMManager.getRepository<PersonWorkspaceEntity>(
'person',
);
const personIds = (
await personRepository.find({
where: {
companyId,
},
select: {
id: true,
},
})
).map((person) => person.id);

if (personIds.length === 0) {
return {
totalNumberOfThreads: 0,
timelineThreads: [],
};
}

const messageThreads = await this.getMessagesFromPersonIds(
workspaceMemberId,
personIds,
page,
pageSize,
);

return messageThreads;
}
}
Loading

0 comments on commit 08c7947

Please sign in to comment.