From 235e71ca02780a441f21fd095c897b43b437dd0a Mon Sep 17 00:00:00 2001 From: Danil <124579979+ProcrastinatorMuffin@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:19:27 +0100 Subject: [PATCH 01/44] Update backdrop-filter in OverlayBackground.ts (#4436) * Update backdrop-filter in OverlayBackground.ts * Fix backdrop-filter in OverlayBackground.ts * Update opacity of menu item, to be constantly 0 * Fixes --------- Co-authored-by: Lucas Bordeau --- .../options/modules/ui/theme/constants/BackgroundDark.ts | 1 + .../modules/ui/theme/constants/BackgroundLight.ts | 1 + .../modules/ui/theme/constants/OverlayBackground.ts | 4 ++-- .../ui/layout/dropdown/components/DropdownMenu.tsx | 9 +++++++-- .../internals/components/StyledMenuItemBase.tsx | 6 ------ .../src/modules/ui/theme/constants/BackgroundDark.ts | 1 + .../src/modules/ui/theme/constants/BackgroundLight.ts | 1 + .../src/modules/ui/theme/constants/OverlayBackground.ts | 4 ++-- packages/twenty-ui/src/theme/constants/BackgroundDark.ts | 1 + .../twenty-ui/src/theme/constants/BackgroundLight.ts | 1 + .../twenty-ui/src/theme/constants/OverlayBackground.ts | 4 ++-- 11 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundDark.ts b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundDark.ts index 5a7802dfb287..d4687782b729 100644 --- a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundDark.ts +++ b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundDark.ts @@ -19,6 +19,7 @@ export const BACKGROUND_DARK = { light: RGBA(GRAY_SCALE.gray0, 0.06), lighter: RGBA(GRAY_SCALE.gray0, 0.03), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray80, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundLight.ts b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundLight.ts index a096887d16ba..e72ff80f98f7 100644 --- a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundLight.ts +++ b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/BackgroundLight.ts @@ -19,6 +19,7 @@ export const BACKGROUND_LIGHT = { light: RGBA(GRAY_SCALE.gray100, 0.04), lighter: RGBA(GRAY_SCALE.gray100, 0.02), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray10, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/OverlayBackground.ts b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/OverlayBackground.ts index 50fe3a0ef8db..e23e08f33d79 100644 --- a/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/OverlayBackground.ts +++ b/packages/twenty-chrome-extension/src/options/modules/ui/theme/constants/OverlayBackground.ts @@ -3,7 +3,7 @@ import { css } from '@emotion/react'; import { ThemeType } from '@/ui/theme/constants/ThemeLight'; export const OVERLAY_BACKGROUND = (props: { theme: ThemeType }) => css` - backdrop-filter: blur(8px); - background: ${props.theme.background.transparent.secondary}; + backdrop-filter: blur(12px) saturate(200%) contrast(50%) brightness(130%); + background: ${props.theme.background.transparent.forBackdropFilter}; box-shadow: ${props.theme.boxShadow.strong}; `; diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx index 8dc52fabee06..d7b910460f08 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenu.tsx @@ -4,8 +4,13 @@ const StyledDropdownMenu = styled.div<{ disableBlur?: boolean; width?: `${string}px` | `${number}%` | 'auto' | number; }>` - backdrop-filter: ${({ disableBlur }) => (disableBlur ? 'none' : 'blur(8px)')}; - background: ${({ theme }) => theme.background.transparent.secondary}; + backdrop-filter: ${({ disableBlur }) => + disableBlur + ? 'none' + : 'blur(12px) saturate(200%) contrast(50%) brightness(130%)'}; + + background: ${({ theme }) => theme.background.transparent.forBackdropFilter}; + border: 1px solid ${({ theme }) => theme.border.color.medium}; border-radius: ${({ theme }) => theme.border.radius.md}; diff --git a/packages/twenty-front/src/modules/ui/navigation/menu-item/internals/components/StyledMenuItemBase.tsx b/packages/twenty-front/src/modules/ui/navigation/menu-item/internals/components/StyledMenuItemBase.tsx index a1dc523c1953..a3e91a8807cb 100644 --- a/packages/twenty-front/src/modules/ui/navigation/menu-item/internals/components/StyledMenuItemBase.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/menu-item/internals/components/StyledMenuItemBase.tsx @@ -16,10 +16,6 @@ export const StyledMenuItemBase = styled.li` align-items: center; - background: ${({ isKeySelected, theme }) => - isKeySelected - ? theme.background.transparent.light - : theme.background.secondary}; border-radius: ${({ theme }) => theme.border.radius.sm}; cursor: pointer; @@ -108,7 +104,6 @@ export const StyledHoverableMenuItemBase = styled(StyledMenuItemBase)<{ isMenuOpen: boolean; }>` & .hoverable-buttons { - opacity: ${({ isMenuOpen }) => (isMenuOpen ? 1 : 0)}; pointer-events: none; position: fixed; right: ${({ theme }) => theme.spacing(2)}; @@ -117,7 +112,6 @@ export const StyledHoverableMenuItemBase = styled(StyledMenuItemBase)<{ &:hover { & .hoverable-buttons { - opacity: 1; pointer-events: auto; position: static; } diff --git a/packages/twenty-front/src/modules/ui/theme/constants/BackgroundDark.ts b/packages/twenty-front/src/modules/ui/theme/constants/BackgroundDark.ts index c5204dbbaf33..e91329882d07 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/BackgroundDark.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/BackgroundDark.ts @@ -20,6 +20,7 @@ export const BACKGROUND_DARK = { light: RGBA(GRAY_SCALE.gray0, 0.06), lighter: RGBA(GRAY_SCALE.gray0, 0.03), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray80, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-front/src/modules/ui/theme/constants/BackgroundLight.ts b/packages/twenty-front/src/modules/ui/theme/constants/BackgroundLight.ts index 3247f5f9fbf5..e78f8e6bb5cc 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/BackgroundLight.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/BackgroundLight.ts @@ -20,6 +20,7 @@ export const BACKGROUND_LIGHT = { light: RGBA(GRAY_SCALE.gray100, 0.04), lighter: RGBA(GRAY_SCALE.gray100, 0.02), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray10, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-front/src/modules/ui/theme/constants/OverlayBackground.ts b/packages/twenty-front/src/modules/ui/theme/constants/OverlayBackground.ts index b86741fff75a..25bcbe4493fe 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/OverlayBackground.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/OverlayBackground.ts @@ -3,7 +3,7 @@ import { css } from '@emotion/react'; import { ThemeType } from './ThemeLight'; export const OVERLAY_BACKGROUND = (props: { theme: ThemeType }) => css` - backdrop-filter: blur(8px); - background: ${props.theme.background.transparent.secondary}; + backdrop-filter: blur(12px) saturate(200%) contrast(50%) brightness(130%); + background: ${props.theme.background.transparent.forBackdropFilter}; box-shadow: ${props.theme.boxShadow.strong}; `; diff --git a/packages/twenty-ui/src/theme/constants/BackgroundDark.ts b/packages/twenty-ui/src/theme/constants/BackgroundDark.ts index c9aa752aa99d..299edc7e7501 100644 --- a/packages/twenty-ui/src/theme/constants/BackgroundDark.ts +++ b/packages/twenty-ui/src/theme/constants/BackgroundDark.ts @@ -20,6 +20,7 @@ export const BACKGROUND_DARK = { light: RGBA(GRAY_SCALE.gray0, 0.06), lighter: RGBA(GRAY_SCALE.gray0, 0.03), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray80, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-ui/src/theme/constants/BackgroundLight.ts b/packages/twenty-ui/src/theme/constants/BackgroundLight.ts index e36c08281270..ff2475a49cbc 100644 --- a/packages/twenty-ui/src/theme/constants/BackgroundLight.ts +++ b/packages/twenty-ui/src/theme/constants/BackgroundLight.ts @@ -20,6 +20,7 @@ export const BACKGROUND_LIGHT = { light: RGBA(GRAY_SCALE.gray100, 0.04), lighter: RGBA(GRAY_SCALE.gray100, 0.02), danger: RGBA(COLOR.red, 0.08), + forBackdropFilter: RGBA(GRAY_SCALE.gray10, 0.5), }, overlay: RGBA(GRAY_SCALE.gray80, 0.8), radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${GRAY_SCALE.gray60} 100%)`, diff --git a/packages/twenty-ui/src/theme/constants/OverlayBackground.ts b/packages/twenty-ui/src/theme/constants/OverlayBackground.ts index 379d66ae76e9..a61aa50fe57c 100644 --- a/packages/twenty-ui/src/theme/constants/OverlayBackground.ts +++ b/packages/twenty-ui/src/theme/constants/OverlayBackground.ts @@ -3,7 +3,7 @@ import { css } from '@emotion/react'; import { ThemeType } from '..'; export const OVERLAY_BACKGROUND = (props: { theme: ThemeType }) => css` - backdrop-filter: blur(8px); - background: ${props.theme.background.transparent.secondary}; + backdrop-filter: blur(12px) saturate(200%) contrast(50%) brightness(130%); + background: ${props.theme.background.transparent.forBackdropFilter}; box-shadow: ${props.theme.boxShadow.strong}; `; From 680bb11f19b46912f01d8389a560efa94afaef18 Mon Sep 17 00:00:00 2001 From: Ravan <69167444+RamK777-stack@users.noreply.github.com> Date: Fri, 15 Mar 2024 22:06:11 +0530 Subject: [PATCH 02/44] Changed Filter/sort labels font weight to medium instead of bold. (#4500) * changed font weight to 500 for filter/sort labels * Removed isSort prop and StyledChipProps type --- .../modules/views/components/EditableSortChip.tsx | 1 - .../modules/views/components/SortOrFilterChip.tsx | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/twenty-front/src/modules/views/components/EditableSortChip.tsx b/packages/twenty-front/src/modules/views/components/EditableSortChip.tsx index 4dbd7f6e93ba..47ce4df1fbda 100644 --- a/packages/twenty-front/src/modules/views/components/EditableSortChip.tsx +++ b/packages/twenty-front/src/modules/views/components/EditableSortChip.tsx @@ -27,7 +27,6 @@ export const EditableSortChip = ({ viewSort }: EditableSortChipProps) => { testId={viewSort.fieldMetadataId} labelValue={viewSort.definition.label} Icon={viewSort.direction === 'desc' ? IconArrowDown : IconArrowUp} - isSort onRemove={handleRemoveClick} onClick={handleClick} /> diff --git a/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx b/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx index b7fb3717c123..13fe04c9358b 100644 --- a/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx +++ b/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx @@ -4,11 +4,7 @@ import styled from '@emotion/styled'; import { IconX } from '@/ui/display/icon/index'; import { IconComponent } from '@/ui/display/icon/types/IconComponent'; -type StyledChipProps = { - isSort?: boolean; -}; - -const StyledChip = styled.div` +const StyledChip = styled.div` align-items: center; background-color: ${({ theme }) => theme.accent.quaternary}; border: 1px solid ${({ theme }) => theme.accent.tertiary}; @@ -19,7 +15,7 @@ const StyledChip = styled.div` flex-direction: row; flex-shrink: 0; font-size: ${({ theme }) => theme.font.size.sm}; - font-weight: ${({ isSort }) => (isSort ? 'bold' : 'normal')}; + font-weight: ${({ theme }) => theme.font.weight.medium}; padding: ${({ theme }) => theme.spacing(1) + ' ' + theme.spacing(2)}; user-select: none; `; @@ -54,7 +50,6 @@ type SortOrFilterChipProps = { Icon?: IconComponent; onRemove: () => void; onClick?: () => void; - isSort?: boolean; testId?: string; }; @@ -63,7 +58,6 @@ export const SortOrFilterChip = ({ labelValue, Icon, onRemove, - isSort, testId, onClick, }: SortOrFilterChipProps) => { @@ -75,7 +69,7 @@ export const SortOrFilterChip = ({ }; return ( - + {Icon && ( From 38f28de4a6e4a4ecdcb8a77972f43209933ed6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Fri, 15 Mar 2024 13:37:36 -0300 Subject: [PATCH 03/44] feat: open event details drawer on event row click (#4464) * feat: open event details drawer on event row click Closes #4294 * feat: review - display Calendar Event details Inline Cells in readonly mode * fix: fix calendar event field values not being set * chore: review - reactivate no-extra-boolean-cast eslint rule --- .../calendar/components/Calendar.tsx | 21 ++- .../components/CalendarCurrentEventCursor.tsx | 17 +- .../components/CalendarDayCardContent.tsx | 7 +- .../components/CalendarEventDetails.tsx | 146 ++++++++++++++++ .../calendar/components/CalendarEventRow.tsx | 32 +++- .../calendar/contexts/CalendarContext.ts | 3 +- .../calendar/hooks/useCalendarEvents.ts | 12 +- .../components/RightDrawerCalendarEvent.tsx | 22 +++ .../hooks/useOpenCalendarEventRightDrawer.ts | 23 +++ .../states/viewableCalendarEventIdState.ts | 6 + .../calendar/types/CalendarEvent.ts | 10 +- .../calendar/utils/getCalendarEventEndDate.ts | 6 +- .../utils/getCalendarEventStartDate.ts | 5 + .../calendar/utils/hasCalendarEventStarted.ts | 3 +- .../calendar/utils/sortCalendarEvents.ts | 17 +- .../RightDrawerEmailThreadTopBar.tsx | 24 --- .../RightDrawerEmailThreadTopBar.stories.tsx | 26 --- .../components/RightDrawerActivityTopBar.tsx | 11 +- .../types/CoreObjectNameSingular.ts | 1 + .../record-field/hooks/useIsFieldInputOnly.ts | 6 +- .../components/RecordInlineCell.tsx | 7 +- .../components/RecordInlineCellContainer.tsx | 32 +++- .../components/RecordTableWithWrappers.tsx | 2 +- .../ui/display/chip/components/Chip.tsx | 163 ++++++++++-------- .../ui/display/icon/constants/index.ts | 26 +-- .../components/RightDrawerRouter.tsx | 43 ++--- .../right-drawer/types/RightDrawerPages.ts | 1 + .../accounts/SettingsAccountsCalendars.tsx | 5 +- .../src/testing/mock-data/calendar.ts | 30 ++-- .../data-seed-dev-workspace.command.ts | 6 +- .../workspace/calendar-events.ts | 48 ++++++ 31 files changed, 530 insertions(+), 231 deletions(-) create mode 100644 packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx create mode 100644 packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx create mode 100644 packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/states/viewableCalendarEventIdState.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventStartDate.ts delete mode 100644 packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar.tsx delete mode 100644 packages/twenty-front/src/modules/activities/emails/right-drawer/components/__stories__/RightDrawerEmailThreadTopBar.stories.tsx create mode 100644 packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts diff --git a/packages/twenty-front/src/modules/activities/calendar/components/Calendar.tsx b/packages/twenty-front/src/modules/activities/calendar/components/Calendar.tsx index efd85a128263..59981e9479a4 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/Calendar.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/Calendar.tsx @@ -4,10 +4,11 @@ import { format, getYear } from 'date-fns'; import { CalendarMonthCard } from '@/activities/calendar/components/CalendarMonthCard'; import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext'; import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents'; -import { sortCalendarEventsDesc } from '@/activities/calendar/utils/sortCalendarEvents'; +import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { H3Title } from '@/ui/display/typography/components/H3Title'; import { Section } from '@/ui/layout/section/components/Section'; -import { mockedCalendarEvents } from '~/testing/mock-data/calendar'; const StyledContainer = styled.div` box-sizing: border-box; @@ -23,9 +24,11 @@ const StyledYear = styled.span` `; export const Calendar = () => { - const sortedCalendarEvents = [...mockedCalendarEvents].sort( - sortCalendarEventsDesc, - ); + const { records: calendarEvents } = useFindManyRecords({ + objectNameSingular: CoreObjectNameSingular.CalendarEvent, + orderBy: { startsAt: 'DescNullsLast', endsAt: 'DescNullsLast' }, + useRecordsWithoutConnection: true, + }); const { calendarEventsByDayTime, @@ -35,7 +38,13 @@ export const Calendar = () => { monthTimes, monthTimesByYear, updateCurrentCalendarEvent, - } = useCalendarEvents(sortedCalendarEvents); + } = useCalendarEvents( + calendarEvents.map((calendarEvent) => ({ + ...calendarEvent, + // TODO: retrieve CalendarChannel visibility from backend + visibility: 'SHARE_EVERYTHING', + })), + ); return ( { const theme = useTheme(); - const endOfDayDate = endOfDay(calendarEvents[0].startsAt); - const endsIn = differenceInSeconds(endOfDayDate, Date.now()); + const endOfDayDate = endOfDay(getCalendarEventStartDate(calendarEvents[0])); + const dayEndsIn = differenceInSeconds(endOfDayDate, Date.now()); const weekDayLabel = format(endOfDayDate, 'EE'); const monthDayLabel = format(endOfDayDate, 'dd'); @@ -71,7 +72,7 @@ export const CalendarDayCardContent = ({ animate="ended" variants={upcomingDayCardContentVariants} transition={{ - delay: Math.max(0, endsIn), + delay: Math.max(0, dayEndsIn), duration: theme.animation.duration.fast, }} > diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx new file mode 100644 index 000000000000..ce919021fd94 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx @@ -0,0 +1,146 @@ +import { css, useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; + +import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; +import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition'; +import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; +import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; +import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; +import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; +import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; +import { + Chip, + ChipAccent, + ChipSize, + ChipVariant, +} from '@/ui/display/chip/components/Chip'; +import { IconCalendarEvent } from '@/ui/display/icon'; +import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; +import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; + +type CalendarEventDetailsProps = { + calendarEvent: CalendarEvent; +}; + +const StyledContainer = styled.div` + background: ${({ theme }) => theme.background.secondary}; + align-items: flex-start; + border-bottom: 1px solid ${({ theme }) => theme.border.color.medium}; + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(6)}; + padding: ${({ theme }) => theme.spacing(6)}; +`; + +const StyledEventChip = styled(Chip)` + gap: ${({ theme }) => theme.spacing(2)}; + padding-left: ${({ theme }) => theme.spacing(2)}; + padding-right: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledHeader = styled.header``; + +const StyledTitle = styled.h2<{ canceled?: boolean }>` + color: ${({ theme }) => theme.font.color.primary}; + font-weight: ${({ theme }) => theme.font.weight.semiBold}; + margin: ${({ theme }) => theme.spacing(0, 0, 2)}; + + ${({ canceled }) => + canceled && + css` + text-decoration: line-through; + `} +`; + +const StyledCreatedAt = styled.div` + color: ${({ theme }) => theme.font.color.tertiary}; +`; + +const StyledFields = styled.div` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(3)}; +`; + +const StyledPropertyBox = styled(PropertyBox)` + height: ${({ theme }) => theme.spacing(6)}; + padding: 0; +`; + +export const CalendarEventDetails = ({ + calendarEvent, +}: CalendarEventDetailsProps) => { + const theme = useTheme(); + const { objectMetadataItem } = useObjectMetadataItemOnly({ + objectNameSingular: CoreObjectNameSingular.CalendarEvent, + }); + + const fieldsToDisplay: Partial< + Record< + keyof CalendarEvent, + Partial, 'label'>> + > + > = { + startsAt: { label: 'Start Date' }, + endsAt: { label: 'End Date' }, + conferenceUri: { label: 'Meet link' }, + location: {}, + description: {}, + }; + const fieldsByName = mapArrayToObject( + objectMetadataItem.fields, + ({ name }) => name, + ); + + return ( + + } + label="Event" + /> + + + {calendarEvent.title} + + + Created{' '} + {beautifyPastDateRelativeToNow( + new Date(calendarEvent.externalCreatedAt), + )} + + + + {Object.entries(fieldsToDisplay).map(([fieldName, fieldOverride]) => ( + + [() => undefined, { loading: false }], + }} + > + + + + ))} + + + ); +}; diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx index 8523de07244a..da0c22a72d38 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx @@ -6,8 +6,10 @@ import { useRecoilValue } from 'recoil'; import { CalendarCurrentEventCursor } from '@/activities/calendar/components/CalendarCurrentEventCursor'; import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext'; +import { useOpenCalendarEventRightDrawer } from '@/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; import { getCalendarEventEndDate } from '@/activities/calendar/utils/getCalendarEventEndDate'; +import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEventEnded'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { IconArrowRight, IconLock } from '@/ui/display/icon'; @@ -22,12 +24,13 @@ type CalendarEventRowProps = { className?: string; }; -const StyledContainer = styled.div` +const StyledContainer = styled.div<{ showTitle?: boolean }>` align-items: center; display: inline-flex; gap: ${({ theme }) => theme.spacing(3)}; height: ${({ theme }) => theme.spacing(6)}; position: relative; + cursor: ${({ showTitle }) => (showTitle ? 'pointer' : 'not-allowed')}; `; const StyledAttendanceIndicator = styled.div<{ active?: boolean }>` @@ -101,21 +104,32 @@ export const CalendarEventRow = ({ const theme = useTheme(); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); const { displayCurrentEventCursor = false } = useContext(CalendarContext); + const { openCalendarEventRightDrawer } = useOpenCalendarEventRightDrawer(); + const startsAt = getCalendarEventStartDate(calendarEvent); const endsAt = getCalendarEventEndDate(calendarEvent); const hasEnded = hasCalendarEventEnded(calendarEvent); const startTimeLabel = calendarEvent.isFullDay ? 'All day' - : format(calendarEvent.startsAt, 'HH:mm'); + : format(startsAt, 'HH:mm'); const endTimeLabel = calendarEvent.isFullDay ? '' : format(endsAt, 'HH:mm'); - const isCurrentWorkspaceMemberAttending = !!calendarEvent.attendees?.find( + const isCurrentWorkspaceMemberAttending = calendarEvent.attendees?.some( ({ workspaceMemberId }) => workspaceMemberId === currentWorkspaceMember?.id, ); + const showTitle = calendarEvent.visibility === 'SHARE_EVERYTHING'; return ( - + openCalendarEventRightDrawer(calendarEvent.id) + : undefined + } + > @@ -127,17 +141,17 @@ export const CalendarEventRow = ({ )} - {calendarEvent.visibility === 'METADATA' ? ( + {showTitle ? ( + + {calendarEvent.title} + + ) : ( Not shared - ) : ( - - {calendarEvent.title} - )} {!!calendarEvent.attendees?.length && ( diff --git a/packages/twenty-front/src/modules/activities/calendar/contexts/CalendarContext.ts b/packages/twenty-front/src/modules/activities/calendar/contexts/CalendarContext.ts index ff81adcf6d00..4370ec88bcb6 100644 --- a/packages/twenty-front/src/modules/activities/calendar/contexts/CalendarContext.ts +++ b/packages/twenty-front/src/modules/activities/calendar/contexts/CalendarContext.ts @@ -4,7 +4,7 @@ import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; type CalendarContextValue = { calendarEventsByDayTime: Record; - currentCalendarEvent: CalendarEvent; + currentCalendarEvent?: CalendarEvent; displayCurrentEventCursor?: boolean; getNextCalendarEvent: ( calendarEvent: CalendarEvent, @@ -14,7 +14,6 @@ type CalendarContextValue = { export const CalendarContext = createContext({ calendarEventsByDayTime: {}, - currentCalendarEvent: {} as CalendarEvent, getNextCalendarEvent: () => undefined, updateCurrentCalendarEvent: () => {}, }); diff --git a/packages/twenty-front/src/modules/activities/calendar/hooks/useCalendarEvents.ts b/packages/twenty-front/src/modules/activities/calendar/hooks/useCalendarEvents.ts index 3621c942e654..6552541bfb08 100644 --- a/packages/twenty-front/src/modules/activities/calendar/hooks/useCalendarEvents.ts +++ b/packages/twenty-front/src/modules/activities/calendar/hooks/useCalendarEvents.ts @@ -3,6 +3,7 @@ import { getYear, isThisMonth, startOfDay, startOfMonth } from 'date-fns'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; import { findUpcomingCalendarEvent } from '@/activities/calendar/utils/findUpcomingCalendarEvent'; +import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; import { groupArrayItemsBy } from '~/utils/array/groupArrayItemsBy'; import { isDefined } from '~/utils/isDefined'; import { sortDesc } from '~/utils/sort'; @@ -10,7 +11,8 @@ import { sortDesc } from '~/utils/sort'; export const useCalendarEvents = (calendarEvents: CalendarEvent[]) => { const calendarEventsByDayTime = groupArrayItemsBy( calendarEvents, - ({ startsAt }) => startOfDay(startsAt).getTime(), + (calendarEvent) => + startOfDay(getCalendarEventStartDate(calendarEvent)).getTime(), ); const sortedDayTimes = Object.keys(calendarEventsByDayTime) @@ -45,17 +47,21 @@ export const useCalendarEvents = (calendarEvents: CalendarEvent[]) => { () => findUpcomingCalendarEvent(calendarEvents), [calendarEvents], ); - const lastEventInCalendar = calendarEvents[0]; + const lastEventInCalendar = calendarEvents.length + ? calendarEvents[0] + : undefined; const [currentCalendarEvent, setCurrentCalendarEvent] = useState( (initialUpcomingCalendarEvent && - (isThisMonth(initialUpcomingCalendarEvent.startsAt) + (isThisMonth(getCalendarEventStartDate(initialUpcomingCalendarEvent)) ? initialUpcomingCalendarEvent : getPreviousCalendarEvent(initialUpcomingCalendarEvent))) || lastEventInCalendar, ); const updateCurrentCalendarEvent = () => { + if (!currentCalendarEvent) return; + const nextCurrentCalendarEvent = getNextCalendarEvent(currentCalendarEvent); if (isDefined(nextCurrentCalendarEvent)) { diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx new file mode 100644 index 000000000000..2a60859646f7 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx @@ -0,0 +1,22 @@ +import { useRecoilValue } from 'recoil'; + +import { CalendarEventDetails } from '@/activities/calendar/components/CalendarEventDetails'; +import { viewableCalendarEventIdState } from '@/activities/calendar/states/viewableCalendarEventIdState'; +import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; +import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore'; + +export const RightDrawerCalendarEvent = () => { + const { setRecords } = useSetRecordInStore(); + const calendarEventId = useRecoilValue(viewableCalendarEventIdState()); + const { record: calendarEvent } = useFindOneRecord({ + objectNameSingular: CoreObjectNameSingular.CalendarEvent, + objectRecordId: calendarEventId ?? '', + onCompleted: (record) => setRecords([record]), + }); + + if (!calendarEvent) return null; + + return ; +}; diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts new file mode 100644 index 000000000000..ccf3e4fce57a --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts @@ -0,0 +1,23 @@ +import { useSetRecoilState } from 'recoil'; + +import { viewableCalendarEventIdState } from '@/activities/calendar/states/viewableCalendarEventIdState'; +import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; +import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope'; +import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages'; +import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; + +export const useOpenCalendarEventRightDrawer = () => { + const { openRightDrawer } = useRightDrawer(); + const setHotkeyScope = useSetHotkeyScope(); + const setViewableCalendarEventId = useSetRecoilState( + viewableCalendarEventIdState(), + ); + + const openCalendarEventRightDrawer = (calendarEventId: string) => { + setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); + openRightDrawer(RightDrawerPages.ViewCalendarEvent); + setViewableCalendarEventId(calendarEventId); + }; + + return { openCalendarEventRightDrawer }; +}; diff --git a/packages/twenty-front/src/modules/activities/calendar/states/viewableCalendarEventIdState.ts b/packages/twenty-front/src/modules/activities/calendar/states/viewableCalendarEventIdState.ts new file mode 100644 index 000000000000..8ecfe54f3699 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/states/viewableCalendarEventIdState.ts @@ -0,0 +1,6 @@ +import { createState } from '@/ui/utilities/state/utils/createState'; + +export const viewableCalendarEventIdState = createState({ + key: 'viewableCalendarEventIdState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts index c12c5f19feb1..1e3cfb85067b 100644 --- a/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts +++ b/packages/twenty-front/src/modules/activities/calendar/types/CalendarEvent.ts @@ -1,10 +1,14 @@ // TODO: use backend CalendarEvent type when ready export type CalendarEvent = { - endsAt?: Date; + conferenceUri?: string; + description?: string; + endsAt?: string; + externalCreatedAt: string; id: string; - isFullDay: boolean; - startsAt: Date; isCanceled?: boolean; + isFullDay: boolean; + location?: string; + startsAt: string; title?: string; visibility: 'METADATA' | 'SHARE_EVERYTHING'; attendees?: { diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventEndDate.ts b/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventEndDate.ts index 0d25a605bb8e..8463f2236faa 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventEndDate.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventEndDate.ts @@ -1,7 +1,11 @@ import { endOfDay } from 'date-fns'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; +import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; export const getCalendarEventEndDate = ( calendarEvent: Pick, -) => calendarEvent.endsAt ?? endOfDay(calendarEvent.startsAt); +) => + calendarEvent.endsAt + ? new Date(calendarEvent.endsAt) + : endOfDay(getCalendarEventStartDate(calendarEvent)); diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventStartDate.ts b/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventStartDate.ts new file mode 100644 index 000000000000..db7a08de3ee3 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/utils/getCalendarEventStartDate.ts @@ -0,0 +1,5 @@ +import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; + +export const getCalendarEventStartDate = ( + calendarEvent: Pick, +) => new Date(calendarEvent.startsAt); diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/hasCalendarEventStarted.ts b/packages/twenty-front/src/modules/activities/calendar/utils/hasCalendarEventStarted.ts index ec7d7a2c5d7f..f351edc9d90d 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/hasCalendarEventStarted.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/hasCalendarEventStarted.ts @@ -1,7 +1,8 @@ import { isPast } from 'date-fns'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; +import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; export const hasCalendarEventStarted = ( calendarEvent: Pick, -) => isPast(calendarEvent.startsAt); +) => isPast(getCalendarEventStartDate(calendarEvent)); diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/sortCalendarEvents.ts b/packages/twenty-front/src/modules/activities/calendar/utils/sortCalendarEvents.ts index fc3b77353886..8ea50406c36c 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/sortCalendarEvents.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/sortCalendarEvents.ts @@ -1,5 +1,6 @@ import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; import { getCalendarEventEndDate } from '@/activities/calendar/utils/getCalendarEventEndDate'; +import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; import { sortAsc } from '~/utils/sort'; export const sortCalendarEventsAsc = ( @@ -7,18 +8,16 @@ export const sortCalendarEventsAsc = ( calendarEventB: Pick, ) => { const startsAtSort = sortAsc( - calendarEventA.startsAt.getTime(), - calendarEventB.startsAt.getTime(), + getCalendarEventStartDate(calendarEventA).getTime(), + getCalendarEventStartDate(calendarEventB).getTime(), ); - if (startsAtSort === 0) { - const endsAtA = getCalendarEventEndDate(calendarEventA); - const endsAtB = getCalendarEventEndDate(calendarEventB); + if (startsAtSort !== 0) return startsAtSort; - return sortAsc(endsAtA.getTime(), endsAtB.getTime()); - } - - return startsAtSort; + return sortAsc( + getCalendarEventEndDate(calendarEventA).getTime(), + getCalendarEventEndDate(calendarEventB).getTime(), + ); }; export const sortCalendarEventsDesc = ( diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar.tsx deleted file mode 100644 index 29e71fe6e127..000000000000 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import styled from '@emotion/styled'; - -import { StyledRightDrawerTopBar } from '@/ui/layout/right-drawer/components/StyledRightDrawerTopBar'; -import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; - -import { RightDrawerTopBarCloseButton } from '../../../../ui/layout/right-drawer/components/RightDrawerTopBarCloseButton'; -import { RightDrawerTopBarExpandButton } from '../../../../ui/layout/right-drawer/components/RightDrawerTopBarExpandButton'; - -const StyledTopBarWrapper = styled.div` - display: flex; -`; - -export const RightDrawerEmailThreadTopBar = () => { - const isMobile = useIsMobile(); - - return ( - - - - {!isMobile && } - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/__stories__/RightDrawerEmailThreadTopBar.stories.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/__stories__/RightDrawerEmailThreadTopBar.stories.tsx deleted file mode 100644 index ebbfc80dcb92..000000000000 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/__stories__/RightDrawerEmailThreadTopBar.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; - -import { RightDrawerEmailThreadTopBar } from '@/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar'; -import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; - -const meta: Meta = { - title: 'Modules/Activities/Emails/RightDrawer/RightDrawerEmailThreadTopBar', - component: RightDrawerEmailThreadTopBar, - decorators: [ - (Story) => ( -
- -
- ), - ComponentDecorator, - ], - parameters: { - msw: graphqlMocks, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivityTopBar.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivityTopBar.tsx index 628fc3893d8f..2e3c35fe4cf2 100644 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivityTopBar.tsx +++ b/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivityTopBar.tsx @@ -1,17 +1,20 @@ import styled from '@emotion/styled'; import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar'; +import { RightDrawerTopBarCloseButton } from '@/ui/layout/right-drawer/components/RightDrawerTopBarCloseButton'; +import { RightDrawerTopBarExpandButton } from '@/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton'; import { StyledRightDrawerTopBar } from '@/ui/layout/right-drawer/components/StyledRightDrawerTopBar'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; -import { RightDrawerTopBarCloseButton } from '../../../ui/layout/right-drawer/components/RightDrawerTopBarCloseButton'; -import { RightDrawerTopBarExpandButton } from '../../../ui/layout/right-drawer/components/RightDrawerTopBarExpandButton'; +type RightDrawerActivityTopBarProps = { showActionBar?: boolean }; const StyledTopBarWrapper = styled.div` display: flex; `; -export const RightDrawerActivityTopBar = () => { +export const RightDrawerActivityTopBar = ({ + showActionBar = true, +}: RightDrawerActivityTopBarProps) => { const isMobile = useIsMobile(); return ( @@ -20,7 +23,7 @@ export const RightDrawerActivityTopBar = () => { {!isMobile && } - + {showActionBar && } ); }; diff --git a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts index e148338d90e4..13591a07d002 100644 --- a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts @@ -4,6 +4,7 @@ export enum CoreObjectNameSingular { ApiKey = 'apiKey', Attachment = 'attachment', Blocklist = 'blocklist', + CalendarEvent = 'calendarEvent', Comment = 'comment', Company = 'company', ConnectedAccount = 'connectedAccount', diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldInputOnly.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldInputOnly.ts index d1566823ce98..750ea8b0b463 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldInputOnly.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldInputOnly.ts @@ -7,9 +7,5 @@ import { isFieldRating } from '../types/guards/isFieldRating'; export const useIsFieldInputOnly = () => { const { fieldDefinition } = useContext(FieldContext); - if (isFieldBoolean(fieldDefinition) || isFieldRating(fieldDefinition)) { - return true; - } - - return false; + return isFieldBoolean(fieldDefinition) || isFieldRating(fieldDefinition); }; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx index fd677eecdcab..bb2c8fc6bd9a 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx @@ -15,7 +15,11 @@ import { useInlineCell } from '../hooks/useInlineCell'; import { RecordInlineCellContainer } from './RecordInlineCellContainer'; -export const RecordInlineCell = () => { +type RecordInlineCellProps = { + readonly?: boolean; +}; + +export const RecordInlineCell = ({ readonly }: RecordInlineCellProps) => { const { fieldDefinition, entityId } = useContext(FieldContext); const buttonIcon = useGetButtonIcon(); @@ -63,6 +67,7 @@ export const RecordInlineCell = () => { return ( ` display: flex; gap: ${({ theme }) => theme.spacing(1)}; width: 100%; + + ${({ readonly }) => + !readonly && + css` + cursor: pointer; + `}; `; const StyledInlineCellBaseContainer = styled.div` @@ -83,6 +88,7 @@ const StyledTooltip = styled(Tooltip)` `; type RecordInlineCellContainerProps = { + readonly?: boolean; IconLabel?: IconComponent; label?: string; labelWidth?: number; @@ -98,6 +104,7 @@ type RecordInlineCellContainerProps = { }; export const RecordInlineCellContainer = ({ + readonly, IconLabel, label, labelWidth, @@ -115,17 +122,21 @@ export const RecordInlineCellContainer = ({ const [isHovered, setIsHovered] = useState(false); const handleContainerMouseEnter = () => { - setIsHovered(true); + if (!readonly) { + setIsHovered(true); + } }; const handleContainerMouseLeave = () => { - setIsHovered(false); + if (!readonly) { + setIsHovered(false); + } }; const { isInlineCellInEditMode, openInlineCell } = useInlineCell(); const handleDisplayModeClick = () => { - if (!editModeContentOnly) { + if (!readonly && !editModeContentOnly) { openInlineCell(customEditHotkeyScope); } }; @@ -167,10 +178,10 @@ export const RecordInlineCellContainer = ({ )} - {isInlineCellInEditMode ? ( + {!readonly && isInlineCellInEditMode ? ( {editModeContent} ) : editModeContentOnly ? ( - + ) : ( - + diff --git a/packages/twenty-front/src/modules/ui/display/chip/components/Chip.tsx b/packages/twenty-front/src/modules/ui/display/chip/components/Chip.tsx index 9e6f5843d5a1..cec0483d2620 100644 --- a/packages/twenty-front/src/modules/ui/display/chip/components/Chip.tsx +++ b/packages/twenty-front/src/modules/ui/display/chip/components/Chip.tsx @@ -1,4 +1,5 @@ import { MouseEvent, ReactNode } from 'react'; +import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { OverflowingTextWithTooltip } from '../../tooltip/OverflowingTextWithTooltip'; @@ -34,86 +35,108 @@ type ChipProps = { onClick?: (event: MouseEvent) => void; }; -const StyledContainer = styled.div>` - align-items: center; +const StyledContainer = styled.div< + Pick< + ChipProps, + 'accent' | 'clickable' | 'disabled' | 'maxWidth' | 'size' | 'variant' + > +>` + --chip-horizontal-padding: ${({ theme }) => theme.spacing(1)}; + --chip-vertical-padding: ${({ theme }) => theme.spacing(1)}; - background-color: ${({ theme, variant }) => - variant === ChipVariant.Highlighted - ? theme.background.transparent.light - : variant === ChipVariant.Rounded - ? theme.background.transparent.lighter - : 'transparent'}; - border-color: ${({ theme, variant }) => - variant === ChipVariant.Rounded ? theme.border.color.medium : 'none'}; - border-radius: ${({ theme, variant }) => - variant === ChipVariant.Rounded ? '50px' : theme.border.radius.sm}; - border-style: ${({ variant }) => - variant === ChipVariant.Rounded ? 'solid' : 'none'}; - border-width: ${({ variant }) => - variant === ChipVariant.Rounded ? '1px' : '0px'}; - - color: ${({ theme, disabled, accent }) => - disabled - ? theme.font.color.light - : accent === ChipAccent.TextPrimary - ? theme.font.color.primary - : theme.font.color.secondary}; - cursor: ${({ clickable, disabled, variant }) => - disabled || variant === ChipVariant.Transparent - ? 'inherit' - : clickable - ? 'pointer' - : 'inherit'}; + align-items: center; + border-radius: ${({ theme }) => theme.border.radius.sm}; + color: ${({ theme, disabled }) => + disabled ? theme.font.color.light : theme.font.color.secondary}; + cursor: ${({ clickable, disabled }) => + clickable ? 'pointer' : disabled ? 'not-allowed' : 'inherit'}; display: inline-flex; - font-weight: ${({ theme, accent }) => - accent === ChipAccent.TextSecondary ? theme.font.weight.medium : 'inherit'}; gap: ${({ theme }) => theme.spacing(1)}; - - height: ${({ size }) => (size === ChipSize.Large ? '16px' : '12px')}; - --chip-horizontal-padding: ${({ theme, variant }) => - variant === ChipVariant.Rounded ? theme.spacing(2) : theme.spacing(1)}; + height: ${({ theme }) => theme.spacing(3)}; max-width: ${({ maxWidth }) => maxWidth - ? `calc( ${maxWidth}px - 2*var(--chip-horizontal-padding))` + ? `calc(${maxWidth}px - 2 * var(--chip-horizontal-padding))` : '200px'}; - - --chip-vertical-padding: ${({ theme, variant }) => - variant === ChipVariant.Rounded ? '3px' : theme.spacing(1)}; - overflow: hidden; padding: var(--chip-vertical-padding) var(--chip-horizontal-padding); user-select: none; - :hover { - ${({ variant, theme, disabled }) => { - if (!disabled) { - return ( - 'background-color: ' + - (variant === ChipVariant.Highlighted - ? theme.background.transparent.medium - : variant === ChipVariant.Regular - ? theme.background.transparent.light - : 'transparent') + - ';' - ); - } - }} - } - :active { - ${({ variant, theme, disabled }) => { - if (!disabled) { - return ( - 'background-color: ' + - (variant === ChipVariant.Highlighted - ? theme.background.transparent.strong - : variant === ChipVariant.Regular - ? theme.background.transparent.medium - : 'transparent') + - ';' - ); - } - }} - } + // Accent style overrides + ${({ accent, disabled, theme }) => { + if (accent === ChipAccent.TextPrimary) { + return ( + !disabled && + css` + color: ${theme.font.color.primary}; + ` + ); + } + + if (accent === ChipAccent.TextSecondary) { + return css` + font-weight: ${theme.font.weight.medium}; + `; + } + }} + + // Size style overrides + ${({ theme, size }) => + size === ChipSize.Large && + css` + height: ${theme.spacing(4)}; + `} + + // Variant style overrides + ${({ disabled, theme, variant }) => { + if (variant === ChipVariant.Regular) { + return ( + !disabled && + css` + :hover { + background-color: ${theme.background.transparent.light}; + } + + :active { + background-color: ${theme.background.transparent.medium}; + } + ` + ); + } + + if (variant === ChipVariant.Highlighted) { + return css` + background-color: ${theme.background.transparent.light}; + + ${!disabled && + css` + :hover { + background-color: ${theme.background.transparent.medium}; + } + + :active { + background-color: ${theme.background.transparent.strong}; + } + `} + `; + } + + if (variant === ChipVariant.Rounded) { + return css` + --chip-horizontal-padding: ${theme.spacing(2)}; + --chip-vertical-padding: 3px; + + background-color: ${theme.background.transparent.lighter}; + border: 1px solid ${theme.border.color.medium}; + border-radius: 50px; + `; + } + + if (variant === ChipVariant.Transparent) { + return css` + cursor: inherit; + `; + } + }} `; const StyledLabel = styled.span` diff --git a/packages/twenty-front/src/modules/ui/display/icon/constants/index.ts b/packages/twenty-front/src/modules/ui/display/icon/constants/index.ts index becf2f91bb37..cc521b61a0c6 100644 --- a/packages/twenty-front/src/modules/ui/display/icon/constants/index.ts +++ b/packages/twenty-front/src/modules/ui/display/icon/constants/index.ts @@ -950,6 +950,7 @@ import { IconCalendarBolt, IconCalendarCancel, IconCalendarCheck, + IconCalendarClock, IconCalendarCode, IconCalendarCog, IconCalendarDollar, @@ -4199,14 +4200,14 @@ import { } from '@tabler/icons-react'; export default { + Icon123, + Icon24Hours, Icon2fa, + Icon360, + Icon360View, Icon3dCubeSphere, Icon3dCubeSphereOff, Icon3dRotate, - Icon24Hours, - Icon123, - Icon360, - Icon360View, IconAB, IconAB2, IconAbacus, @@ -5149,6 +5150,7 @@ export default { IconCalendarBolt, IconCalendarCancel, IconCalendarCheck, + IconCalendarClock, IconCalendarCode, IconCalendarCog, IconCalendarDollar, @@ -5440,6 +5442,9 @@ export default { IconClockExclamation, IconClockHeart, IconClockHour1, + IconClockHour10, + IconClockHour11, + IconClockHour12, IconClockHour2, IconClockHour3, IconClockHour4, @@ -5448,9 +5453,6 @@ export default { IconClockHour7, IconClockHour8, IconClockHour9, - IconClockHour10, - IconClockHour11, - IconClockHour12, IconClockMinus, IconClockOff, IconClockPause, @@ -7117,10 +7119,10 @@ export default { IconMovieOff, IconMug, IconMugOff, - IconMultiplier1x, - IconMultiplier2x, IconMultiplier05x, IconMultiplier15x, + IconMultiplier1x, + IconMultiplier2x, IconMushroom, IconMushroomOff, IconMusic, @@ -7515,20 +7517,20 @@ export default { IconReservedLine, IconResize, IconRestore, - IconRewindBackward5, IconRewindBackward10, IconRewindBackward15, IconRewindBackward20, IconRewindBackward30, IconRewindBackward40, + IconRewindBackward5, IconRewindBackward50, IconRewindBackward60, - IconRewindForward5, IconRewindForward10, IconRewindForward15, IconRewindForward20, IconRewindForward30, IconRewindForward40, + IconRewindForward5, IconRewindForward50, IconRewindForward60, IconRibbonHealth, @@ -8080,11 +8082,11 @@ export default { IconTiltShift, IconTiltShiftOff, IconTimeDuration0, - IconTimeDuration5, IconTimeDuration10, IconTimeDuration15, IconTimeDuration30, IconTimeDuration45, + IconTimeDuration5, IconTimeDuration60, IconTimeDuration90, IconTimeDurationOff, diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx index cb981739beb8..7eced58ff4a8 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx @@ -1,8 +1,8 @@ import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; +import { RightDrawerCalendarEvent } from '@/activities/calendar/right-drawer/components/RightDrawerCalendarEvent'; import { RightDrawerEmailThread } from '@/activities/emails/right-drawer/components/RightDrawerEmailThread'; -import { RightDrawerEmailThreadTopBar } from '@/activities/emails/right-drawer/components/RightDrawerEmailThreadTopBar'; import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity'; import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity'; @@ -27,28 +27,31 @@ const StyledRightDrawerBody = styled.div` position: relative; `; +const RIGHT_DRAWER_PAGES_CONFIG = { + [RightDrawerPages.CreateActivity]: { + page: , + topBar: , + }, + [RightDrawerPages.EditActivity]: { + page: , + topBar: , + }, + [RightDrawerPages.ViewEmailThread]: { + page: , + topBar: , + }, + [RightDrawerPages.ViewCalendarEvent]: { + page: , + topBar: , + }, +}; + export const RightDrawerRouter = () => { const [rightDrawerPage] = useRecoilState(rightDrawerPageState()); - let page = <>; - let topBar = <>; - - switch (rightDrawerPage) { - case RightDrawerPages.CreateActivity: - page = ; - topBar = ; - break; - case RightDrawerPages.EditActivity: - page = ; - topBar = ; - break; - case RightDrawerPages.ViewEmailThread: - page = ; - topBar = ; - break; - default: - break; - } + const { topBar = null, page = null } = rightDrawerPage + ? RIGHT_DRAWER_PAGES_CONFIG[rightDrawerPage] + : {}; return ( diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts index e0028a7c5e08..df0cd28ca53c 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts @@ -2,4 +2,5 @@ export enum RightDrawerPages { CreateActivity = 'create-activity', EditActivity = 'edit-activity', ViewEmailThread = 'view-email-thread', + ViewCalendarEvent = 'view-calendar-event', } diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx index 9d4a537b8cc0..d4960b0731bb 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx @@ -50,9 +50,10 @@ export const SettingsAccountsCalendars = () => { workspaceMemberId: currentWorkspaceMember?.id ?? '', }, ], - endsAt: exampleEndDate, + endsAt: exampleEndDate.toISOString(), + externalCreatedAt: new Date().toISOString(), isFullDay: false, - startsAt: exampleStartDate, + startsAt: exampleStartDate.toISOString(), title: 'Onboarding call', visibility: 'SHARE_EVERYTHING', }; diff --git a/packages/twenty-front/src/testing/mock-data/calendar.ts b/packages/twenty-front/src/testing/mock-data/calendar.ts index 1f1d8c760695..e0d671b6a4ee 100644 --- a/packages/twenty-front/src/testing/mock-data/calendar.ts +++ b/packages/twenty-front/src/testing/mock-data/calendar.ts @@ -1,13 +1,14 @@ -import { addDays, subMonths } from 'date-fns'; +import { addDays, subHours, subMonths } from 'date-fns'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; export const mockedCalendarEvents: CalendarEvent[] = [ { + externalCreatedAt: new Date().toISOString(), + endsAt: addDays(new Date().setHours(11, 30), 1).toISOString(), id: '9a6b35f1-6078-415b-9540-f62671bb81d0', - endsAt: addDays(new Date().setHours(11, 30), 1), isFullDay: false, - startsAt: addDays(new Date().setHours(10, 0), 1), + startsAt: addDays(new Date().setHours(10, 0), 1).toISOString(), visibility: 'METADATA', attendees: [ { displayName: 'John Doe', workspaceMemberId: 'john-doe' }, @@ -16,41 +17,46 @@ export const mockedCalendarEvents: CalendarEvent[] = [ ], }, { + externalCreatedAt: subHours(new Date(), 2).toISOString(), id: '19b32878-a950-4968-9e3b-ce5da514ea41', - endsAt: new Date(new Date().setHours(18, 40)), + endsAt: new Date(new Date().setHours(18, 40)).toISOString(), isCanceled: true, isFullDay: false, - startsAt: new Date(new Date().setHours(18, 0)), + startsAt: new Date(new Date().setHours(18, 0)).toISOString(), title: 'Bug solving', visibility: 'SHARE_EVERYTHING', }, { + externalCreatedAt: subHours(new Date(), 2).toISOString(), id: '6ad1cbcb-2ac4-409e-aff0-48165556fc0c', - endsAt: new Date(new Date().setHours(16, 30)), + endsAt: new Date(new Date().setHours(16, 30)).toISOString(), isFullDay: false, - startsAt: new Date(new Date().setHours(15, 15)), + startsAt: new Date(new Date().setHours(15, 15)).toISOString(), title: 'Onboarding Follow-Up Call', visibility: 'SHARE_EVERYTHING', }, { + externalCreatedAt: subHours(new Date(), 2).toISOString(), id: '52cc83e3-f3dc-4c25-8a7d-5ff857612142', - endsAt: new Date(new Date().setHours(10, 30)), + endsAt: new Date(new Date().setHours(10, 30)).toISOString(), isFullDay: false, - startsAt: new Date(new Date().setHours(10, 0)), + startsAt: new Date(new Date().setHours(10, 0)).toISOString(), title: 'Onboarding Call', visibility: 'SHARE_EVERYTHING', }, { + externalCreatedAt: subHours(new Date(), 2).toISOString(), id: '5a792d11-259a-4099-af51-59eb85e15d83', isFullDay: true, - startsAt: subMonths(new Date().setHours(8, 0), 1), + startsAt: subMonths(new Date().setHours(8, 0), 1).toISOString(), visibility: 'METADATA', }, { + externalCreatedAt: subHours(new Date(), 2).toISOString(), id: '89e2a1c7-3d3f-4e79-a492-aa5de3785fc5', - endsAt: subMonths(new Date().setHours(14, 30), 3), + endsAt: subMonths(new Date().setHours(14, 30), 3).toISOString(), isFullDay: false, - startsAt: subMonths(new Date().setHours(14, 0), 3), + startsAt: subMonths(new Date().setHours(14, 0), 3).toISOString(), title: 'Alan x Garry', visibility: 'SHARE_EVERYTHING', }, diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index 1bf8793d943e..669177abb66a 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -11,9 +11,10 @@ import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/worksp import { seedPeople } from 'src/database/typeorm-seeds/workspace/people'; import { seedCoreSchema } from 'src/database/typeorm-seeds/core'; import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; // TODO: implement dry-run @Command({ @@ -105,6 +106,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner { await seedPeople(workspaceDataSource, dataSourceMetadata.schema); await seedPipelineStep(workspaceDataSource, dataSourceMetadata.schema); await seedOpportunity(workspaceDataSource, dataSourceMetadata.schema); + await seedCalendarEvents(workspaceDataSource, dataSourceMetadata.schema); await seedViews( workspaceDataSource, diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts new file mode 100644 index 000000000000..8f2f23db0fa9 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts @@ -0,0 +1,48 @@ +import { DataSource } from 'typeorm'; + +const tableName = 'calendarEvent'; + +export const seedCalendarEvents = async ( + workspaceDataSource: DataSource, + schemaName: string, +) => { + await workspaceDataSource + .createQueryBuilder() + .insert() + .into(`${schemaName}.${tableName}`, [ + 'id', + 'title', + 'isCanceled', + 'isFullDay', + 'startsAt', + 'endsAt', + 'externalCreatedAt', + 'externalUpdatedAt', + 'description', + 'location', + 'iCalUID', + 'conferenceSolution', + 'conferenceUri', + 'recurringEventExternalId', + ]) + .orIgnore() + .values([ + { + id: '86083141-1c0e-494c-a1b6-85b1c6fefaa5', + title: 'Meeting with Christoph', + isCanceled: false, + isFullDay: false, + startsAt: new Date(new Date().setHours(10, 0)).toISOString(), + endsAt: new Date(new Date().setHours(11, 0)).toISOString(), + externalCreatedAt: new Date().toISOString(), + externalUpdatedAt: new Date().toISOString(), + description: 'Discuss project progress', + location: 'Seattle', + iCalUID: 'event1@calendar.com', + conferenceSolution: 'Zoom', + conferenceUri: 'https://zoom.us/j/1234567890', + recurringEventExternalId: 'recurring1', + }, + ]) + .execute(); +}; From afb9b3e37517cfb7907ed38df4b5a8ff7f1e7e0a Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 18:35:40 +0100 Subject: [PATCH 04/44] Prefetching views and favorites (#4421) * wip * Push * Complete work on prefetch * Add comment * Fix * Fix * Fix * Fix * Remove dead code * Simplify * Fix tests * Fix tests * Fix according to review * Fix according to review --------- Co-authored-by: Lucas Bordeau --- .../src/hooks/useDefaultHomePagePath.tsx | 18 ++---- packages/twenty-front/src/index.tsx | 27 +++++---- .../modules/favorites/hooks/useFavorites.ts | 20 +++---- .../components/ObjectMetadataNavItems.tsx | 30 ++-------- .../utils/mapObjectMetadataToGraphQLQuery.ts | 2 +- .../cache/hooks/useCachedRootQuery.ts | 47 ---------------- .../useUpsertFindManyRecordsQueryInCache.ts | 5 +- .../cache/utils/getRecordEdgeFromRecord.ts | 18 +++++- ...anyRecordsForMultipleMetadataItemsQuery.ts | 8 ++- .../query-keys/types/QueryKey.ts | 7 +++ .../__tests__/useMultiObjectSearch.test.tsx | 3 +- .../components/PrefetchDataProvider.tsx | 12 ++++ .../components/PrefetchRunQueriesEffect.tsx | 53 ++++++++++++++++++ .../prefetch/constants/PrefetchConfig.ts | 9 +++ .../hooks/internal/usePrefetchRunQuery.ts | 55 +++++++++++++++++++ .../prefetch/hooks/usePrefetchedData.ts | 27 +++++++++ .../query-keys/AllFavoritesQueryKey.ts | 8 +++ .../prefetch/query-keys/AllViewsQueryKey.ts | 8 +++ .../states/prefetchIsLoadedFamilyState.ts | 10 ++++ .../src/modules/prefetch/types/PrefetchKey.ts | 4 ++ .../views/components/ViewBarEffect.tsx | 37 +++++++------ 21 files changed, 279 insertions(+), 129 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/cache/hooks/useCachedRootQuery.ts create mode 100644 packages/twenty-front/src/modules/object-record/query-keys/types/QueryKey.ts create mode 100644 packages/twenty-front/src/modules/prefetch/components/PrefetchDataProvider.tsx create mode 100644 packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx create mode 100644 packages/twenty-front/src/modules/prefetch/constants/PrefetchConfig.ts create mode 100644 packages/twenty-front/src/modules/prefetch/hooks/internal/usePrefetchRunQuery.ts create mode 100644 packages/twenty-front/src/modules/prefetch/hooks/usePrefetchedData.ts create mode 100644 packages/twenty-front/src/modules/prefetch/query-keys/AllFavoritesQueryKey.ts create mode 100644 packages/twenty-front/src/modules/prefetch/query-keys/AllViewsQueryKey.ts create mode 100644 packages/twenty-front/src/modules/prefetch/states/prefetchIsLoadedFamilyState.ts create mode 100644 packages/twenty-front/src/modules/prefetch/types/PrefetchKey.ts diff --git a/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx b/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx index d8d59950864b..c0f332791709 100644 --- a/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx +++ b/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx @@ -1,24 +1,18 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { QueryMethodName } from '@/object-metadata/types/QueryMethodName'; -import { useCachedRootQuery } from '@/object-record/cache/hooks/useCachedRootQuery'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; export const useDefaultHomePagePath = () => { const { objectMetadataItem: companyObjectMetadataItem } = useObjectMetadataItem({ objectNameSingular: CoreObjectNameSingular.Company, }); - const { objectMetadataItem: viewObjectMetadataItem } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.View, - }); - const { cachedRootQuery } = useCachedRootQuery({ - objectMetadataItem: viewObjectMetadataItem, - queryMethodName: QueryMethodName.FindMany, - }); - const companyViewId = cachedRootQuery?.views?.edges?.find( - (view: any) => - view?.node?.objectMetadataId === companyObjectMetadataItem.id, + const { records } = usePrefetchedData(PrefetchKey.AllViews); + + const companyViewId = records.find( + (view: any) => view?.objectMetadataId === companyObjectMetadataItem.id, )?.node.id; const defaultHomePagePath = '/objects/companies' + (companyViewId ? `?view=${companyViewId}` : ''); diff --git a/packages/twenty-front/src/index.tsx b/packages/twenty-front/src/index.tsx index c30daece204d..c23babc438ea 100644 --- a/packages/twenty-front/src/index.tsx +++ b/packages/twenty-front/src/index.tsx @@ -13,6 +13,7 @@ import { ExceptionHandlerProvider } from '@/error-handler/components/ExceptionHa import { PromiseRejectionEffect } from '@/error-handler/components/PromiseRejectionEffect'; import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider'; import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider'; +import { PrefetchDataProvider } from '@/prefetch/components/PrefetchDataProvider'; import { IconsProvider } from '@/ui/display/icon/components/IconsProvider'; import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager'; import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; @@ -47,18 +48,20 @@ root.render( - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts index cf5f646aa34c..25595a40980a 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts @@ -6,38 +6,38 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe import { Favorite } from '@/favorites/types/Favorite'; import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { isDefined } from '~/utils/isDefined'; export const useFavorites = () => { const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); - const favoriteObjectNameSingular = 'favorite'; - const { objectMetadataItem: favoriteObjectMetadataItem } = useObjectMetadataItem({ - objectNameSingular: favoriteObjectNameSingular, + objectNameSingular: CoreObjectNameSingular.Favorite, }); const { deleteOneRecord } = useDeleteOneRecord({ - objectNameSingular: favoriteObjectNameSingular, + objectNameSingular: CoreObjectNameSingular.Favorite, }); const { updateOneRecord: updateOneFavorite } = useUpdateOneRecord({ - objectNameSingular: favoriteObjectNameSingular, + objectNameSingular: CoreObjectNameSingular.Favorite, }); const { createOneRecord: createOneFavorite } = useCreateOneRecord({ - objectNameSingular: favoriteObjectNameSingular, + objectNameSingular: CoreObjectNameSingular.Favorite, }); - const { records: favorites } = useFindManyRecords({ - objectNameSingular: favoriteObjectNameSingular, - }); + const { records: favorites } = usePrefetchedData( + PrefetchKey.AllFavorites, + ); const favoriteRelationFieldMetadataItems = useMemo( () => diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx index 547a7e67f574..43f5210bdff2 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx @@ -1,37 +1,19 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { QueryMethodName } from '@/object-metadata/types/QueryMethodName'; -import { useCachedRootQuery } from '@/object-record/cache/hooks/useCachedRootQuery'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useIcons } from '@/ui/display/icon/hooks/useIcons'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { GraphQLView } from '@/views/types/GraphQLView'; export const ObjectMetadataNavItems = () => { - const { activeObjectMetadataItems, findObjectMetadataItemByNamePlural } = - useObjectMetadataItemForSettings(); + const { activeObjectMetadataItems } = useObjectMetadataItemForSettings(); const navigate = useNavigate(); const { getIcon } = useIcons(); const currentPath = useLocation().pathname; - const viewObjectMetadataItem = findObjectMetadataItemByNamePlural('views'); - - const { cachedRootQuery } = useCachedRootQuery({ - objectMetadataItem: viewObjectMetadataItem, - queryMethodName: QueryMethodName.FindMany, - }); - - const { records } = useFindManyRecords({ - skip: cachedRootQuery?.views, - objectNameSingular: CoreObjectNameSingular.View, - useRecordsWithoutConnection: true, - }); - - const views = - records.length > 0 - ? records - : cachedRootQuery?.views?.edges?.map((edge: any) => edge?.node); + const { records } = usePrefetchedData(PrefetchKey.AllViews); return ( <> @@ -63,7 +45,7 @@ export const ObjectMetadataNavItems = () => { : -1; }), ].map((objectMetadataItem) => { - const viewId = views?.find( + const viewId = records?.find( (view: any) => view?.objectMetadataId === objectMetadataItem.id, )?.id; diff --git a/packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts b/packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts index e56fff7e12f6..444c566f2b80 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts @@ -11,7 +11,7 @@ export const mapObjectMetadataToGraphQLQuery = ({ eagerLoadedRelations, }: { objectMetadataItems: ObjectMetadataItem[]; - objectMetadataItem: Pick; + objectMetadataItem: Pick; depth?: number; eagerLoadedRelations?: Record; }): any => { diff --git a/packages/twenty-front/src/modules/object-record/cache/hooks/useCachedRootQuery.ts b/packages/twenty-front/src/modules/object-record/cache/hooks/useCachedRootQuery.ts deleted file mode 100644 index 8ffd3ad71555..000000000000 --- a/packages/twenty-front/src/modules/object-record/cache/hooks/useCachedRootQuery.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { useApolloClient } from '@apollo/client/react/hooks/useApolloClient'; -import gql from 'graphql-tag'; -import { useRecoilValue } from 'recoil'; - -import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { QueryMethodName } from '@/object-metadata/types/QueryMethodName'; -import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery'; - -export const useCachedRootQuery = ({ - objectMetadataItem, - queryMethodName, -}: { - objectMetadataItem: ObjectMetadataItem | undefined; - queryMethodName: QueryMethodName; -}) => { - const apolloClient = useApolloClient(); - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); - - if (!objectMetadataItem) { - return { cachedRootQuery: null }; - } - - const cacheReadFragment = gql` - fragment RootQuery on Query { - ${ - QueryMethodName.FindMany === queryMethodName - ? objectMetadataItem.namePlural - : objectMetadataItem.nameSingular - } - ${QueryMethodName.FindMany === queryMethodName ? '{ edges { node ' : ''} - ${mapObjectMetadataToGraphQLQuery({ - objectMetadataItems, - objectMetadataItem, - depth: 0, - })} - ${QueryMethodName.FindMany === queryMethodName ? '}}' : ''} - } - `; - - const cachedRootQuery = apolloClient.readFragment({ - id: 'ROOT_QUERY', - fragment: cacheReadFragment, - }); - - return { cachedRootQuery }; -}; diff --git a/packages/twenty-front/src/modules/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache.ts b/packages/twenty-front/src/modules/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache.ts index 9a11224b1372..297be5db3c36 100644 --- a/packages/twenty-front/src/modules/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache.ts +++ b/packages/twenty-front/src/modules/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache.ts @@ -10,7 +10,10 @@ import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQu export const useUpsertFindManyRecordsQueryInCache = ({ objectMetadataItem, }: { - objectMetadataItem: ObjectMetadataItem; + objectMetadataItem: Pick< + ObjectMetadataItem, + 'fields' | 'namePlural' | 'nameSingular' + >; }) => { const apolloClient = useApolloClient(); diff --git a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts index 8921edae21e7..b82b77ff847a 100644 --- a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts +++ b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts @@ -1,5 +1,6 @@ import { getEdgeTypename } from '@/object-record/cache/utils/getEdgeTypename'; import { getNodeTypename } from '@/object-record/cache/utils/getNodeTypename'; +import { getRecordConnectionFromRecords } from '@/object-record/cache/utils/getRecordConnectionFromRecords'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge'; @@ -10,11 +11,26 @@ export const getRecordEdgeFromRecord = ({ objectNameSingular: string; record: T; }) => { + const nestedRecord = Object.fromEntries( + Object.entries(record).map(([key, value]) => { + if (Array.isArray(value)) { + return [ + key, + getRecordConnectionFromRecords({ + objectNameSingular: key, + records: value as ObjectRecord[], + }), + ]; + } + return [key, value]; + }), + ) as T; // Todo fix typing once we have investigated apollo edges / nodes removal + return { __typename: getEdgeTypename({ objectNameSingular }), node: { __typename: getNodeTypename({ objectNameSingular }), - ...record, + ...nestedRecord, }, cursor: '', } as ObjectRecordEdge; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts index c453b0c1bcb4..a85b4068d623 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts @@ -1,5 +1,7 @@ import { gql } from '@apollo/client'; +import { useRecoilValue } from 'recoil'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery'; import { isNonEmptyArray } from '~/utils/isNonEmptyArray'; @@ -12,6 +14,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ objectMetadataItems: ObjectMetadataItem[]; depth?: number; }) => { + const allObjectMetadataItems = useRecoilValue(objectMetadataItemsState()); const capitalizedObjectNameSingulars = objectMetadataItems.map( ({ nameSingular }) => capitalize(nameSingular), ); @@ -44,7 +47,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ const limitPerMetadataItemArray = capitalizedObjectNameSingulars .map( (capitalizedObjectNameSingular) => - `$limit${capitalizedObjectNameSingular}: Float = 5`, + `$limit${capitalizedObjectNameSingular}: Float`, ) .join(', '); @@ -69,7 +72,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ )}){ edges { node ${mapObjectMetadataToGraphQLQuery({ - objectMetadataItems, + objectMetadataItems: allObjectMetadataItems, objectMetadataItem, depth, })} @@ -80,6 +83,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ startCursor endCursor } + totalCount }`, ) .join('\n')} diff --git a/packages/twenty-front/src/modules/object-record/query-keys/types/QueryKey.ts b/packages/twenty-front/src/modules/object-record/query-keys/types/QueryKey.ts new file mode 100644 index 000000000000..fc1c16a14e99 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/query-keys/types/QueryKey.ts @@ -0,0 +1,7 @@ +import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables'; + +export type QueryKey = { + objectNameSingular: string; + variables: ObjectRecordQueryVariables; + depth: number; +}; diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx index 9ce41b117496..d48688e51d41 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx @@ -13,7 +13,7 @@ const query = gql` $filterNameSingular: NameSingularFilterInput $orderByNameSingular: NameSingularOrderByInput $lastCursorNameSingular: String - $limitNameSingular: Float = 5 + $limitNameSingular: Float ) { namePlural( filter: $filterNameSingular @@ -33,6 +33,7 @@ const query = gql` startCursor endCursor } + totalCount } } `; diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchDataProvider.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchDataProvider.tsx new file mode 100644 index 000000000000..837d2498e576 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchDataProvider.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +import { PrefetchRunQueriesEffect } from '@/prefetch/components/PrefetchRunQueriesEffect'; + +export const PrefetchDataProvider = ({ children }: React.PropsWithChildren) => { + return ( + <> + + {children} + + ); +}; diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx new file mode 100644 index 000000000000..18a73506f99b --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx @@ -0,0 +1,53 @@ +import { useEffect } from 'react'; +import { useQuery } from '@apollo/client'; + +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useGenerateFindManyRecordsForMultipleMetadataItemsQuery } from '@/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery'; +import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray'; +import { usePrefetchRunQuery } from '@/prefetch/hooks/internal/usePrefetchRunQuery'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; +import { isDefined } from '~/utils/isDefined'; + +export const PrefetchRunQueriesEffect = () => { + const { + objectMetadataItem: objectMetadataItemView, + upsertRecordsInCache: upsertViewsInCache, + } = usePrefetchRunQuery({ + prefetchKey: PrefetchKey.AllViews, + objectNameSingular: CoreObjectNameSingular.View, + }); + + const { + objectMetadataItem: objectMetadataItemFavorite, + upsertRecordsInCache: upsertFavoritesInCache, + } = usePrefetchRunQuery({ + prefetchKey: PrefetchKey.AllFavorites, + objectNameSingular: CoreObjectNameSingular.Favorite, + }); + + const prefetchFindManyQuery = + useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ + objectMetadataItems: [objectMetadataItemView, objectMetadataItemFavorite], + depth: 2, + }); + + if (!isDefined(prefetchFindManyQuery)) { + throw new Error('Could not prefetch recrds'); + } + + const { data } = useQuery( + prefetchFindManyQuery, + ); + + useEffect(() => { + if (isDefined(data?.views)) { + upsertViewsInCache(data.views); + } + + if (isDefined(data?.favorites)) { + upsertFavoritesInCache(data.favorites); + } + }, [data, upsertViewsInCache, upsertFavoritesInCache]); + + return <>; +}; diff --git a/packages/twenty-front/src/modules/prefetch/constants/PrefetchConfig.ts b/packages/twenty-front/src/modules/prefetch/constants/PrefetchConfig.ts new file mode 100644 index 000000000000..a79631158314 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/constants/PrefetchConfig.ts @@ -0,0 +1,9 @@ +import { QueryKey } from '@/object-record/query-keys/types/QueryKey'; +import { ALL_FAVORITES_QUERY_KEY } from '@/prefetch/query-keys/AllFavoritesQueryKey'; +import { ALL_VIEWS_QUERY_KEY } from '@/prefetch/query-keys/AllViewsQueryKey'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; + +export const PREFETCH_CONFIG: Record = { + ALL_VIEWS: ALL_VIEWS_QUERY_KEY, + ALL_FAVORITES: ALL_FAVORITES_QUERY_KEY, +}; diff --git a/packages/twenty-front/src/modules/prefetch/hooks/internal/usePrefetchRunQuery.ts b/packages/twenty-front/src/modules/prefetch/hooks/internal/usePrefetchRunQuery.ts new file mode 100644 index 000000000000..294c138a7553 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/hooks/internal/usePrefetchRunQuery.ts @@ -0,0 +1,55 @@ +import { useSetRecoilState } from 'recoil'; + +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache'; +import { useMapConnectionToRecords } from '@/object-record/hooks/useMapConnectionToRecords'; +import { ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { ObjectRecordConnection } from '@/object-record/types/ObjectRecordConnection'; +import { ALL_VIEWS_QUERY_KEY } from '@/prefetch/query-keys/AllViewsQueryKey'; +import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedFamilyState'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; + +export type UsePrefetchRunQuery = { + prefetchKey: PrefetchKey; + objectNameSingular: CoreObjectNameSingular; +}; + +export const usePrefetchRunQuery = ({ + prefetchKey, + objectNameSingular, +}: UsePrefetchRunQuery) => { + const setPrefetchDataIsLoadedLoaded = useSetRecoilState( + prefetchIsLoadedFamilyState(prefetchKey), + ); + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular: objectNameSingular, + }); + + const { upsertFindManyRecordsQueryInCache } = + useUpsertFindManyRecordsQueryInCache({ + objectMetadataItem: objectMetadataItem, + }); + + const mapConnectionToRecords = useMapConnectionToRecords(); + + const upsertRecordsInCache = (records: ObjectRecordConnection) => { + upsertFindManyRecordsQueryInCache({ + queryVariables: ALL_VIEWS_QUERY_KEY.variables, + depth: ALL_VIEWS_QUERY_KEY.depth, + objectRecordsToOverwrite: + mapConnectionToRecords({ + objectRecordConnection: records, + objectNameSingular: CoreObjectNameSingular.View, + depth: 2, + }) ?? [], + }); + setPrefetchDataIsLoadedLoaded(true); + }; + + return { + objectMetadataItem, + setPrefetchDataIsLoadedLoaded, + upsertRecordsInCache, + }; +}; diff --git a/packages/twenty-front/src/modules/prefetch/hooks/usePrefetchedData.ts b/packages/twenty-front/src/modules/prefetch/hooks/usePrefetchedData.ts new file mode 100644 index 000000000000..3997bae7318d --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/hooks/usePrefetchedData.ts @@ -0,0 +1,27 @@ +import { useRecoilValue } from 'recoil'; + +import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; +import { ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { PREFETCH_CONFIG } from '@/prefetch/constants/PrefetchConfig'; +import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedFamilyState'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; + +export const usePrefetchedData = ( + prefetchKey: PrefetchKey, +) => { + const isDataPrefetched = useRecoilValue( + prefetchIsLoadedFamilyState(prefetchKey), + ); + const prefetchQueryKey = PREFETCH_CONFIG[prefetchKey]; + + const { records } = useFindManyRecords({ + skip: !isDataPrefetched, + ...prefetchQueryKey, + useRecordsWithoutConnection: true, + }); + + return { + isDataPrefetched, + records, + }; +}; diff --git a/packages/twenty-front/src/modules/prefetch/query-keys/AllFavoritesQueryKey.ts b/packages/twenty-front/src/modules/prefetch/query-keys/AllFavoritesQueryKey.ts new file mode 100644 index 000000000000..a5e442715881 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/query-keys/AllFavoritesQueryKey.ts @@ -0,0 +1,8 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { QueryKey } from '@/object-record/query-keys/types/QueryKey'; + +export const ALL_FAVORITES_QUERY_KEY: QueryKey = { + objectNameSingular: CoreObjectNameSingular.Favorite, + variables: {}, + depth: 1, +}; diff --git a/packages/twenty-front/src/modules/prefetch/query-keys/AllViewsQueryKey.ts b/packages/twenty-front/src/modules/prefetch/query-keys/AllViewsQueryKey.ts new file mode 100644 index 000000000000..df1c78163048 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/query-keys/AllViewsQueryKey.ts @@ -0,0 +1,8 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { QueryKey } from '@/object-record/query-keys/types/QueryKey'; + +export const ALL_VIEWS_QUERY_KEY: QueryKey = { + objectNameSingular: CoreObjectNameSingular.View, + variables: {}, + depth: 1, +}; diff --git a/packages/twenty-front/src/modules/prefetch/states/prefetchIsLoadedFamilyState.ts b/packages/twenty-front/src/modules/prefetch/states/prefetchIsLoadedFamilyState.ts new file mode 100644 index 000000000000..38069ee05801 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/states/prefetchIsLoadedFamilyState.ts @@ -0,0 +1,10 @@ +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; +import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState'; + +export const prefetchIsLoadedFamilyState = createFamilyState< + boolean, + PrefetchKey +>({ + key: 'prefetchIsLoadedFamilyState', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/prefetch/types/PrefetchKey.ts b/packages/twenty-front/src/modules/prefetch/types/PrefetchKey.ts new file mode 100644 index 000000000000..f7ebf434e916 --- /dev/null +++ b/packages/twenty-front/src/modules/prefetch/types/PrefetchKey.ts @@ -0,0 +1,4 @@ +export enum PrefetchKey { + AllViews = 'ALL_VIEWS', + AllFavorites = 'ALL_FAVORITES', +} diff --git a/packages/twenty-front/src/modules/views/components/ViewBarEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarEffect.tsx index b5e8dd3e36fe..b0b645f8395d 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarEffect.tsx @@ -2,8 +2,8 @@ import { useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useViewBar } from '@/views/hooks/useViewBar'; import { GraphQLView } from '@/views/types/GraphQLView'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; @@ -31,25 +31,26 @@ export const ViewBarEffect = () => { const viewObjectMetadataId = useRecoilValue(viewObjectMetadataIdState); const setCurrentViewId = useSetRecoilState(currentViewIdState); - const { records: newViews } = useFindManyRecords({ - skip: !viewObjectMetadataId, - objectNameSingular: CoreObjectNameSingular.View, - filter: { - objectMetadataId: { eq: viewObjectMetadataId }, - }, - useRecordsWithoutConnection: true, - }); + const { records: newViews } = usePrefetchedData( + PrefetchKey.AllViews, + ); + + const newViewsOnCurrentObject = newViews.filter( + (view) => view.objectMetadataId === viewObjectMetadataId, + ); useEffect(() => { - if (!newViews.length) return; + if (!newViewsOnCurrentObject.length) return; - if (!isDeeplyEqual(views, newViews)) { - setViews(newViews); + if (!isDeeplyEqual(views, newViewsOnCurrentObject)) { + setViews(newViewsOnCurrentObject); } const currentView = - newViews.find((view) => view.id === currentViewIdFromUrl) ?? - newViews[0] ?? + newViewsOnCurrentObject.find( + (view) => view.id === currentViewIdFromUrl, + ) ?? + newViewsOnCurrentObject[0] ?? null; if (isUndefinedOrNull(currentView)) return; @@ -69,17 +70,17 @@ export const ViewBarEffect = () => { loadViewFields, loadViewFilters, loadViewSorts, - newViews, + newViewsOnCurrentObject, setCurrentViewId, setViews, views, ]); useEffect(() => { - if (!currentViewIdFromUrl || !newViews.length) return; + if (!currentViewIdFromUrl || !newViewsOnCurrentObject.length) return; loadView(currentViewIdFromUrl); - }, [currentViewIdFromUrl, loadView, newViews]); + }, [currentViewIdFromUrl, loadView, newViewsOnCurrentObject]); return <>; }; From 2c09096edd407a2a0f702f2dff970dd91a17aa73 Mon Sep 17 00:00:00 2001 From: Weiko Date: Fri, 15 Mar 2024 18:37:09 +0100 Subject: [PATCH 05/44] Refactor backend folder structure (#4505) * Refactor backend folder structure Co-authored-by: Charles Bochet * fix tests * fix * move yoga hooks --------- Co-authored-by: Charles Bochet --- packages/twenty-server/jest.config.ts | 2 +- packages/twenty-server/package.json | 4 +- packages/twenty-server/project.json | 2 +- .../factories/factories.ts | 29 ---- .../input-factories/filter-input.factory.ts | 25 --- ...ld-metadata-to-graphql-query.utils.spec.ts | 35 ---- .../src/api/rest/api-rest.module.ts | 17 -- packages/twenty-server/src/app.module.ts | 18 +- .../src/business/modules/business.module.ts | 11 -- .../modules/calendar/calendar.module.ts | 41 ----- .../providers/calendar-providers.module.ts | 11 -- .../modules/message/messaging.module.ts | 76 -------- .../messaging-query-hook.module.ts | 28 --- .../repositories/message/message.module.ts | 23 --- .../providers/messaging-providers.module.ts | 11 -- .../{commands => command}/command-logger.ts | 0 .../src/{ => command}/command.module.ts | 12 +- .../src/{ => command}/command.ts | 8 +- ...t-data-seed-demo-workspace.cron.command.ts | 4 +- ...p-data-seed-demo-workspace.cron.command.ts | 4 +- .../data-seed-demo-workspace.module.ts | 2 +- .../jobs/data-seed-demo-workspace.job.ts | 2 +- .../data-seed-demo-workspace.service.ts | 2 +- .../data-seed-dev-workspace.command.ts | 4 +- .../src/database/typeorm/typeorm.module.ts | 2 +- .../src/database/typeorm/typeorm.service.ts | 2 +- .../graphql-config.module.ts | 4 +- .../graphql-config.service.ts | 18 +- .../hooks/use-throttler.ts | 0 .../field-metadata/field-metadata.service.ts | 2 +- .../metadata.module-factory.ts | 10 +- .../src/engine-metadata/metadata.module.ts | 4 +- .../object-metadata.service.ts | 4 +- .../relation-metadata.service.ts | 2 +- .../create-company-and-contact.module.ts | 21 --- .../utils/compute-field-target-column.util.ts | 21 --- .../__mocks__/object-metadata-item.mock.ts} | 12 +- .../__tests__}/workspace.factory.spec.ts | 11 +- .../graphql/core-graphql-api.module.ts} | 10 +- .../services/scalars-explorer.service.ts | 2 +- .../workspace-query-builder-options.mock.ts | 13 ++ .../__tests__/args-string.factory.spec.ts | 4 +- .../find-duplicates-query.factory.spec.ts | 37 ++-- .../record-position-query.factory.spec.ts | 2 +- .../factories/args-alias.factory.ts | 0 .../factories/args-string.factory.ts | 2 +- .../factories/create-many-query.factory.ts | 10 +- .../factories/delete-many-query.factory.ts | 8 +- .../factories/delete-one-query.factory.ts | 6 +- .../factories/factories.ts | 0 .../factories/field-alias.factory.ts | 0 .../factories/fields-string.factory.ts | 2 +- .../find-duplicates-query.factory.ts | 14 +- .../factories/find-many-query.factory.ts | 8 +- .../factories/find-one-query.factory.ts | 8 +- .../record-position-query.factory.ts | 0 .../factories/relation-field-alias.factory.ts | 8 +- .../factories/update-many-query.factory.ts | 14 +- .../factories/update-one-query.factory.ts | 10 +- .../interfaces/record.interface.ts | 0 ...rkspace-query-builder-options.interface.ts | 0 .../stringify-without-key-quote.spec.ts | 2 +- .../utils/get-field-arguments-by-key.util.ts | 0 .../utils/stringify-without-key-quote.util.ts | 0 .../workspace-query-builder.factory.ts | 6 +- .../workspace-query-builder.module.ts | 4 +- .../query-runner-args.factory.spec.ts | 6 +- .../__tests__/record-position.factory.spec.ts | 4 +- .../workspace-query-runner/factories/index.ts | 0 .../factories/query-runner-args.factory.ts | 2 +- .../factories/record-position.factory.ts | 2 +- .../interfaces/connection.interface.ts | 2 +- .../interfaces/edge.interface.ts | 0 .../interfaces/page-info.interface.ts | 0 .../interfaces/pg-graphql.interface.ts | 2 +- .../query-runner-option.interface.ts | 0 .../jobs/call-webhook-jobs.job.ts | 8 +- .../jobs/call-webhook.job.ts | 2 +- .../jobs/record-position-backfill.job.ts | 4 +- .../listeners/record-position.listener.ts | 8 +- .../record-position-backfill-module.ts | 6 +- .../record-position-backfill-service.ts | 4 +- .../utils/__tests__/parse-result.spec.ts | 2 +- .../utils/compute-pg-graphql-error.util.ts | 0 .../utils/parse-result.util.ts | 0 .../workspace-pre-query-hook.interface.ts | 2 +- .../types/workspace-query-hook.type.ts | 2 +- .../workspace-pre-query-hook.config.ts | 11 ++ .../workspace-pre-query-hook.module.ts | 11 ++ .../workspace-pre-query-hook.service.ts | 6 +- .../workspace-query-runner.module.ts | 8 +- .../workspace-query-runner.service.ts | 30 ++-- .../constants/duplicate-criteria.constants.ts | 2 +- .../factories/create-many-resolver.factory.ts | 8 +- .../factories/create-one-resolver.factory.ts | 8 +- .../factories/delete-many-resolver.factory.ts | 8 +- .../factories/delete-one-resolver.factory.ts | 8 +- ...te-quick-action-on-one-resolver.factory.ts | 12 +- .../factories/factories.ts | 2 +- .../find-duplicates-resolver.factory.ts | 8 +- .../factories/find-many-resolver.factory.ts | 8 +- .../factories/find-one-resolver.factory.ts | 8 +- .../factories/update-many-resolver.factory.ts | 8 +- .../factories/update-one-resolver.factory.ts | 8 +- .../interfaces/pg-graphql.interface.ts | 2 +- ...pace-resolver-builder-factory.interface.ts | 2 +- .../workspace-resolvers-builder.interface.ts | 4 +- .../workspace-resolver-builder.module.ts | 2 +- .../workspace-resolver.factory.ts | 8 +- .../factories/args.factory.ts | 8 +- .../connection-type-definition.factory.ts | 2 +- .../factories/connection-type.factory.ts | 8 +- .../factories/edge-type-definition.factory.ts | 2 +- .../factories/edge-type.factory.ts | 8 +- .../factories/enum-type-definition.factory.ts | 2 +- .../extend-object-type-definition.factory.ts | 12 +- .../factories/factories.ts | 2 +- .../filter-type-definition.factory.ts | 6 +- .../factories/filter-type.factory.ts | 8 +- .../input-type-definition.factory.ts | 4 +- .../factories/input-type.factory.ts | 6 +- .../factories/mutation-type.factory.ts | 4 +- .../object-type-definition.factory.ts | 4 +- .../order-by-type-definition.factory.ts | 4 +- .../factories/order-by-type.factory.ts | 6 +- .../factories/orphaned-types.factory.ts | 2 +- .../factories/output-type.factory.ts | 6 +- .../factories/query-type.factory.ts | 4 +- .../factories/relation-type.factory.ts | 4 +- .../factories/root-type.factory.ts | 12 +- .../graphql-types/enum/index.ts | 0 .../enum/order-by-direction.enum-type.ts | 0 .../input/big-float-filter.input-type.ts | 4 +- .../input/big-int-filter.input-type.ts | 2 +- .../input/boolean-filter.input-type.ts | 2 +- .../input/date-filter.input-type.ts | 4 +- .../input/date-time-filter.input-type.ts | 4 +- .../input/filter-is.input-type.ts | 0 .../input/float-filter.input-type.ts | 2 +- .../graphql-types/input/index.ts | 0 .../input/int-filter.input-type.ts | 2 +- .../input/string-filter.input-type.ts | 2 +- .../input/time-filter.input-type.ts | 4 +- .../input/uuid-filter.input-type.ts | 4 +- .../graphql-types/object/index.ts | 0 .../object/page-into.object-type.ts | 0 .../graphql-types/scalars/big-float.scalar.ts | 0 .../graphql-types/scalars/big-int.scalar.ts | 0 .../graphql-types/scalars/cursor.scalar.ts | 0 .../graphql-types/scalars/date-time.scalar.ts | 0 .../graphql-types/scalars/date.scalar.ts | 0 .../graphql-types/scalars/index.ts | 0 .../graphql-types/scalars/position.scalar.ts | 0 .../graphql-types/scalars/time.scalar.ts | 0 .../graphql-types/scalars/uuid.scalar.ts | 0 .../interfaces/param-metadata.interface.ts | 2 +- ...rkspace-build-schema-optionts.interface.ts | 0 ...kspace-schema-builder-context.interface.ts | 0 .../services/type-mapper.service.ts | 10 +- .../storages/type-definitions.storage.ts | 6 +- .../type-definitions.generator.ts | 2 +- .../utils/__tests__/clean-entity-name.spec.ts | 2 +- .../__tests__/get-field-metadata-type.spec.ts | 2 +- .../utils/__tests__/get-resolver-args.spec.ts | 6 +- .../utils/clean-entity-name.util.ts | 0 .../utils/get-field-metadata-type.util.ts | 0 .../utils/get-resolver-args.util.ts | 6 +- .../utils/object-contains-relation-field.ts | 2 +- .../workspace-graphql-schema.factory.ts | 2 +- .../workspace-schema-builder.module.ts | 0 .../workspace-schema-storage.module.ts | 2 +- .../workspace-schema-storage.service.ts | 4 +- .../{ => api}/graphql/workspace.factory.ts | 10 +- .../api-rest.controller.utils.spec.ts | 2 +- .../rest/__tests__}/api-rest.service.spec.ts | 6 +- .../api-rest-query-builder.factory.spec.ts | 22 +-- .../api-rest-query-builder.factory.ts | 26 +-- .../api-rest-query-builder.module.ts | 4 +- .../factories/create-query.factory.ts | 2 +- .../factories/create-variables.factory.ts | 2 +- .../factories/delete-query.factory.ts | 0 .../factories/delete-variables.factory.ts | 2 +- .../factories/factories.ts | 29 ++++ .../factories/find-many-query.factory.ts | 2 +- .../factories/find-one-query.factory.ts | 2 +- .../factories/get-variables.factory.ts | 10 +- .../__tests__/filter-input.factory.spec.ts | 6 +- .../last-cursor-input.factory.spec.ts | 2 +- .../__tests__/limit-input.factory.spec.ts | 2 +- .../__tests__/order-by-input.factory.spec.ts | 8 +- .../input-factories/filter-input.factory.ts | 25 +++ .../add-default-conjunction.utils.spec.ts | 2 +- .../check-filter-query.utils.spec.ts | 2 +- .../format-field-values.utils.spec.ts | 2 +- .../__tests__/parse-base-filter.utils.spec.ts | 2 +- .../parse-filter-content.utils.spec.ts | 2 +- .../__tests__/parse-filter.utils.spec.ts | 14 +- .../add-default-conjunction.utils.ts | 2 +- .../filter-utils/check-filter-query.utils.ts | 0 .../filter-utils/format-field-values.utils.ts | 2 +- .../filter-utils/parse-base-filter.utils.ts | 0 .../parse-filter-content.utils.ts | 0 .../filter-utils/parse-filter.utils.ts | 10 +- .../last-cursor-input.factory.ts | 0 .../input-factories/limit-input.factory.ts | 0 .../input-factories/order-by-input.factory.ts | 4 +- .../factories/update-query.factory.ts | 2 +- .../factories/update-variables.factory.ts | 2 +- .../__tests__/compute-depth.utils.spec.ts | 2 +- .../utils/__tests__/fields.utils.spec.ts | 12 +- ...ld-metadata-to-graphql-query.utils.spec.ts | 37 ++++ .../utils/__tests__/parse-path.utils.spec.ts | 2 +- .../utils/compute-depth.utils.ts | 0 .../utils/fields.utils.ts | 2 +- ...p-field-metadata-to-graphql-query.utils.ts | 0 .../utils/parse-path.utils.ts | 0 .../api/rest/api-rest.controller.ts | 4 +- .../api/rest/api-rest.controller.utils.ts | 2 +- .../src/engine/api/rest/api-rest.module.ts | 17 ++ .../{ => engine}/api/rest/api-rest.service.ts | 8 +- .../api/rest/metadata-rest.controller.ts | 4 +- .../api/rest/metadata-rest.service.ts | 8 +- .../rest/types/api-rest-field-value.type.ts | 0 .../types/api-rest-query-variables.type.ts | 0 .../api/rest/types/api-rest-query.type.ts | 0 .../api/rest/types/api-rest-response.type.ts | 0 .../utils/global-exception-handler.util.ts | 4 +- .../workspace-query-builder-options.ts | 13 -- .../workspace-pre-query-hook.config.ts | 11 -- .../workspace-pre-query-hook.module.ts | 11 -- .../__tests__/cache-storage.service.spec.ts | 4 +- .../cache-storage.module-factory.ts | 4 +- .../cache-storage/cache-storage.module.ts | 8 +- .../cache-storage/cache-storage.service.ts | 2 +- .../types/cache-storage-namespace.enum.ts | 0 .../types/cache-storage-type.enum.ts | 0 .../interfaces/email-driver.interface.ts | 0 .../email/drivers/logger.driver.ts | 2 +- .../integrations/email/drivers/smtp.driver.ts | 2 +- .../integrations/email/email-sender.job.ts | 4 +- .../email/email-sender.service.ts | 4 +- .../integrations/email/email.constants.ts | 0 .../email/email.module-factory.ts | 4 +- .../integrations/email/email.module.ts | 12 +- .../integrations/email/email.service.ts | 6 +- .../email/interfaces/email.interface.ts | 0 .../cast-to-log-level-array.decorator.spec.ts | 2 +- .../cast-to-positive-number.decorator.spec.ts | 2 +- .../decorators/cast-to-boolean.decorator.ts | 0 .../cast-to-log-level-array.decorator.ts | 0 .../cast-to-positive-number.decorator.ts | 0 .../cast-to-string-array.decorator.ts | 0 .../decorators/is-aws-region.decorator.ts | 0 .../decorators/is-duration.decorator.ts | 0 .../is-strictly-lower-than.decorator.ts | 0 .../environment/environment-variables.ts | 12 +- .../environment/environment.default.ts | 14 +- .../environment.module-definition.ts | 0 .../environment/environment.module.ts | 0 .../environment/environment.service.spec.ts | 0 .../environment/environment.service.ts | 4 +- .../interfaces/aws-region.interface.ts | 0 .../interfaces/support.interface.ts | 0 .../types/object-record-create.event.ts | 0 .../types/object-record-delete.event.ts | 0 .../types/object-record-update.event.ts | 0 .../object-record-changed-properties.util.ts | 0 .../exception-handler.service.spec.ts | 5 +- .../drivers/console.driver.ts | 6 +- .../drivers/sentry.driver.ts | 6 +- .../exception-handler.constants.ts | 0 .../exception-handler.module-definition.ts | 0 .../exception-handler.module-factory.ts | 6 +- .../exception-handler.module.ts | 4 +- .../exception-handler.service.ts | 6 +- .../hooks/use-exception-handler.hook.ts | 2 +- .../hooks/use-sentry-tracing.ts} | 0 .../exception-handler-driver.interface.ts | 0 .../exception-handler-options.interface.ts | 0 .../exception-handler-user.interface.ts | 0 .../interfaces/exception-handler.interface.ts | 0 .../exception-handler/interfaces/index.ts | 0 .../__tests__}/file-storage.service.spec.ts | 4 +- .../interfaces/storage-driver.interface.ts | 0 .../file-storage/drivers/local.driver.ts | 0 .../file-storage/drivers/s3.driver.ts | 0 .../file-storage/file-storage.constants.ts | 0 .../file-storage.module-definition.ts | 0 .../file-storage.module-factory.ts | 4 +- .../file-storage/file-storage.module.ts | 0 .../file-storage/file-storage.service.ts | 0 .../interfaces/file-storage.interface.ts | 4 +- .../file-storage/interfaces/index.ts | 0 .../integrations/integrations.module.ts | 16 +- .../logger/__tests__}/logger.service.spec.ts | 4 +- .../integrations/logger/interfaces/index.ts | 0 .../logger/interfaces/logger.interface.ts | 0 .../integrations/logger/logger.constants.ts | 0 .../logger/logger.module-definition.ts | 0 .../logger/logger.module-factory.ts | 4 +- .../integrations/logger/logger.module.ts | 2 +- .../integrations/logger/logger.service.ts | 0 .../message-queue/drivers/bullmq.driver.ts | 4 +- .../interfaces/job-options.interface.ts | 0 .../message-queue-driver.interface.ts | 6 +- .../message-queue/drivers/pg-boss.driver.ts | 4 +- .../message-queue/drivers/sync.driver.ts | 8 +- .../message-queue/interfaces/index.ts | 0 .../interfaces/message-queue-job.interface.ts | 0 .../interfaces/message-queue.interface.ts | 4 +- .../integrations/message-queue/jobs.module.ts | 44 ++--- .../message-queue/message-queue.constants.ts | 0 .../message-queue.module-factory.ts | 4 +- .../message-queue/message-queue.module.ts | 16 +- ...essage-queue-task-assigned.service.spec.ts | 6 +- .../services/message-queue.service.ts | 8 +- .../utils/get-job-class-name.util.ts | 0 .../analytics/analytics.resolver.spec.ts | 2 +- .../analytics/analytics.service.spec.ts | 2 +- .../modules/analytics/analytics.service.ts | 2 +- .../src/engine/modules/auth/auth.module.ts | 2 +- .../google-apis-auth.controller.ts | 2 +- .../controllers/google-auth.controller.ts | 2 +- .../google-gmail-auth.controller.ts | 2 +- .../google-apis-provider-enabled.guard.ts | 2 +- .../google-gmail-provider-enabled.guard.ts | 2 +- .../guards/google-provider-enabled.guard.ts | 2 +- .../auth/services/auth.service.spec.ts | 4 +- .../modules/auth/services/auth.service.ts | 4 +- .../auth/services/google-apis.service.ts | 10 +- .../auth/services/sign-up.service.spec.ts | 2 +- .../modules/auth/services/sign-up.service.ts | 2 +- .../auth/services/token.service.spec.ts | 4 +- .../modules/auth/services/token.service.ts | 4 +- .../strategies/google-apis.auth.strategy.ts | 2 +- .../auth/strategies/google.auth.strategy.ts | 2 +- .../auth/strategies/jwt.auth.strategy.ts | 2 +- .../engine/modules/billing/billing.service.ts | 2 +- .../billing/jobs/update-subscription.job.ts | 2 +- .../billing-workspace-member.listener.ts | 8 +- .../modules/billing/stripe/stripe.service.ts | 2 +- .../client-config.resolver.spec.ts | 2 +- .../client-config/client-config.resolver.ts | 2 +- ...ion.module.ts => engine-modules.module.ts} | 2 +- .../file/services/file-upload.service.spec.ts | 4 +- .../file/services/file-upload.service.ts | 2 +- .../file/services/file.service.spec.ts | 4 +- .../modules/file/services/file.service.ts | 2 +- .../modules/open-api/open-api.service.spec.ts | 2 +- .../modules/open-api/open-api.service.ts | 2 +- .../utils/__tests__/components.utils.spec.ts | 6 +- .../utils/__tests__/parameters.utils.spec.ts | 10 +- .../open-api/utils/parameters.utils.ts | 10 +- .../quick-actions/intelligence.service.ts | 2 +- .../quick-actions/quick-actions.module.ts | 2 +- .../quick-actions/quick-actions.service.ts | 6 +- .../user-workspace/user-workspace.service.ts | 4 +- .../src/engine/modules/user/user.resolver.ts | 4 +- .../modules/workspace/workspace.resolver.ts | 2 +- .../deduce-relation-direction.spec.ts | 2 +- .../utils/__tests__/get-resolver-name.spec.ts | 4 +- .../utils/compute-custom-name.util.ts | 0 .../utils/compute-object-target-table.util.ts | 0 .../utils/deduce-relation-direction.util.ts | 0 .../utils/get-resolver-name.util.ts | 2 +- .../is-relation-field-metadata-type.util.ts | 0 .../utils/render-apollo-playground.util.ts | 0 .../clean-inactive-workspaces.command.ts | 4 +- ...-clean-inactive-workspaces.cron.command.ts | 4 +- ...-clean-inactive-workspaces.cron.command.ts | 4 +- .../crons/clean-inactive-workspace.job.ts | 8 +- .../commands/workspace-health.command.ts | 2 +- .../workspace-target-column-map.fixer.ts | 2 +- .../services/database-structure.service.ts | 2 +- .../services/field-metadata-health.service.ts | 4 +- .../object-metadata-health.service.ts | 2 +- .../relation-metadata.health.service.ts | 4 +- .../workspace-health.service.ts | 2 +- .../workspace-migration-field.factory.ts | 2 +- .../workspace-migration-object.factory.ts | 2 +- .../workspace-migration-relation.factory.ts | 2 +- .../services/sync-workspace-logger.service.ts | 2 +- .../custom-objects/custom.object-metadata.ts | 6 +- .../standard-objects/index.ts | 54 +++--- packages/twenty-server/src/main.ts | 4 +- .../activity-target.object-metadata.ts | 8 +- .../activity.object-metadata.ts | 8 +- .../comment.object-metadata.ts | 4 +- .../api-key.object-metadata.ts | 0 .../attachment.object-metadata.ts | 10 +- .../src/modules/calendar/calendar.module.ts | 41 +++++ .../google-calendar-full-sync.command.ts | 8 +- ...workspace-calendar-sync-commands.module.ts | 4 +- .../jobs/google-calendar-full-sync.job.ts | 6 +- ...alendar-channel-event-assocation.module.ts | 2 +- ...endar-channel-event-association.service.ts | 4 +- .../calendar-channel.module.ts | 2 +- .../calendar-channel.service.ts | 2 +- .../calendar-event-attendee.module.ts | 2 +- .../calendar-event-attendee.service.ts | 6 +- .../calendar-event/calendar-event.module.ts | 2 +- .../calendar-event/calendar-event.service.ts | 8 +- .../calendar-event-cleaner.module.ts | 4 +- .../calendar-event-cleaner.service.ts | 4 +- .../google-calendar-full-sync.service.ts | 24 +-- .../providers/calendar-providers.module.ts | 11 ++ .../google-calendar.provider.ts | 2 +- ...annel-event-association.object-metadata.ts | 2 +- .../calendar-channel.object-metadata.ts | 4 +- ...calendar-event-attendee.object-metadata.ts | 6 +- .../calendar-event.object-metadata.ts | 4 +- .../modules/calendar/types/calendar-event.ts | 4 +- .../format-google-calendar-event.util.ts | 4 +- ...uesAndValuesStringForBatchRawQuery.util.ts | 0 .../google-calendar-search-filter.util.ts | 0 .../company.object-metadata.ts | 12 +- .../create-company-and-contact.module.ts | 21 +++ .../create-company-and-contact.service.ts | 16 +- .../create-company/create-company.module.ts | 4 +- .../create-company/create-company.service.ts | 4 +- .../create-contact/create-contact.module.ts | 4 +- .../create-contact/create-contact.service.ts | 4 +- .../blocklist/blocklist.module.ts | 2 +- .../blocklist/blocklist.service.ts | 2 +- .../connected-account.module.ts | 2 +- .../connected-account.service.ts | 2 +- ...oogle-apis-refresh-access-token.service.ts | 4 +- .../blocklist.object-metadata.ts | 2 +- .../connected-account.object-metadata.ts | 6 +- .../favorite.object-metadata.ts | 8 +- ...ch-all-workspaces-messages.cron.pattern.ts | 0 .../fetch-all-workspaces-messages.job.ts | 10 +- ...etch-workspace-messages-commands.module.ts | 10 +- .../commands/gmail-full-sync.command.ts | 8 +- .../commands/gmail-partial-sync.command.ts | 8 +- ...ch-all-workspaces-messages.cron.command.ts | 8 +- ...ch-all-workspaces-messages.cron.command.ts | 8 +- ...e-companies-and-contacts-after-sync.job.ts | 8 +- ...ed-account-associated-calendar-data.job.ts | 4 +- ...d-account-associated-messaging-data.job.ts | 4 +- .../messaging}/jobs/gmail-full-sync.job.ts | 6 +- .../messaging}/jobs/gmail-partial-sync.job.ts | 6 +- .../jobs/match-message-participant.job.ts | 4 +- .../messaging-connected-account.listener.ts | 12 +- .../messaging-message-channel.listener.ts | 12 +- .../listeners/messaging-person.listener.ts | 14 +- .../messaging-workspace-member.listener.ts | 14 +- .../src/modules/messaging/messaging.module.ts | 76 ++++++++ .../message-find-many.pre-query.hook.ts | 12 +- .../message-find-one.pre-query-hook.ts | 4 +- .../messaging-query-hook.module.ts | 28 +++ .../repositories/company/company.module.ts | 2 +- .../repositories/company/company.service.ts | 0 ...ssage-channel-message-assocation.module.ts | 2 +- ...age-channel-message-association.service.ts | 2 +- .../message-channel/message-channel.module.ts | 2 +- .../message-channel.service.ts | 2 +- .../message-participant.module.ts | 4 +- .../message-participant.service.ts | 6 +- .../message-thread/message-thread.module.ts | 6 +- .../message-thread/message-thread.service.ts | 4 +- .../repositories/message/message.module.ts | 23 +++ .../repositories/message/message.service.ts | 12 +- .../services/fetch-by-batch.service.ts | 4 +- .../fetch-messages-by-batches.service.ts | 10 +- .../services/gmail-full-sync.service.ts | 24 +-- .../services/gmail-partial-sync.service.ts | 26 +-- .../providers/gmail/gmail-client.provider.ts | 2 +- .../providers/messaging-providers.module.ts | 11 ++ ...ve-messages-and-create-contacts.service.ts | 12 +- .../thread-cleaner/thread-cleaner.module.ts | 6 +- .../thread-cleaner/thread-cleaner.service.ts | 6 +- .../delete-using-pagination.util.spec.ts | 0 .../utils/delete-using-pagination.util.ts | 0 ...ddress-object-as-participants.util.spec.ts | 2 +- ...mat-address-object-as-participants.util.ts | 2 +- ...nel-message-association.object-metadata.ts | 6 +- .../message-channel.object-metadata.ts | 4 +- .../message-participant.object-metadata.ts | 6 +- .../message-thread.object-metadata.ts | 4 +- .../message.object-metadata.ts | 6 +- .../messaging}/types/batch-queries.ts | 0 .../types/gmail-message-parsed-response.ts | 0 .../messaging}/types/gmail-message.ts | 0 .../messaging}/types/gmail-thread.ts | 0 .../types/message-or-thread-query.ts | 0 .../create-queries-from-message-ids.util.ts | 2 +- ...icipants-from-company-or-workspace.util.ts | 6 +- .../get-company-name-from-domain-name.util.ts | 0 .../utils/get-domain-name-from-handle.util.ts | 0 ...-name-from-handle-and-display-name.util.ts | 0 ...et-unique-participants-and-handles.util.ts | 2 +- .../utils/gmail-search-filter.util.ts | 0 .../messaging}/utils/is-person-email.util.ts | 0 .../src/modules/modules.module.ts | 11 ++ .../opportunity.object-metadata.ts | 12 +- .../repositories/person/person.module.ts | 2 +- .../repositories/person/person.service.ts | 2 +- .../person.object-metadata.ts | 14 +- .../pipeline-step.object-metadata.ts | 2 +- .../view-field.object-metadata.ts | 2 +- .../view-filter.object-metadata.ts | 2 +- .../view-sort.object-metadata.ts | 2 +- .../standard-objects}/view.object-metadata.ts | 6 +- .../webhook.object-metadata.ts | 0 .../workspace-member.module.ts | 2 +- .../workspace-member.service.ts | 2 +- .../workspace-member.object-metadata.ts | 18 +- .../twenty-server/src/queue-worker.module.ts | 9 - .../src/queue-worker/queue-worker.module.ts | 9 + .../src/{ => queue-worker}/queue-worker.ts | 19 +- .../pagination/find-many-cursor-connection.ts | 162 ------------------ .../src/utils/pagination/index.ts | 2 - .../connection-arguments.interface.ts | 15 -- .../interfaces/connection-cursor.type.ts | 1 - .../find-many-aguments.interface.ts | 5 - .../interfaces/options.interface.ts | 19 -- .../src/utils/pagination/page-info.ts | 19 -- .../src/utils/pagination/paginated.ts | 77 --------- .../src/utils/pagination/utils/cursor.ts | 54 ------ .../utils/pagination/utils/default-options.ts | 42 ----- .../pagination/utils/pagination-direction.ts | 17 -- .../utils/pagination/utils/validate-args.ts | 38 ---- 523 files changed, 1386 insertions(+), 1856 deletions(-) delete mode 100644 packages/twenty-server/src/api/rest/api-rest-query-builder/factories/factories.ts delete mode 100644 packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts delete mode 100644 packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts delete mode 100644 packages/twenty-server/src/api/rest/api-rest.module.ts delete mode 100644 packages/twenty-server/src/business/modules/business.module.ts delete mode 100644 packages/twenty-server/src/business/modules/calendar/calendar.module.ts delete mode 100644 packages/twenty-server/src/business/modules/calendar/services/providers/calendar-providers.module.ts delete mode 100644 packages/twenty-server/src/business/modules/message/messaging.module.ts delete mode 100644 packages/twenty-server/src/business/modules/message/query-hooks/messaging-query-hook.module.ts delete mode 100644 packages/twenty-server/src/business/modules/message/repositories/message/message.module.ts delete mode 100644 packages/twenty-server/src/business/modules/message/services/providers/messaging-providers.module.ts rename packages/twenty-server/src/{commands => command}/command-logger.ts (100%) rename packages/twenty-server/src/{ => command}/command.module.ts (53%) rename packages/twenty-server/src/{ => command}/command.ts (73%) rename packages/twenty-server/src/{integrations/throttler => engine-graphql-config}/hooks/use-throttler.ts (100%) delete mode 100644 packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts delete mode 100644 packages/twenty-server/src/engine-workspace/utils/compute-field-target-column.util.ts rename packages/twenty-server/src/{utils/utils-test/object-metadata-item.ts => engine/api/__mocks__/object-metadata-item.mock.ts} (77%) rename packages/twenty-server/src/engine/{graphql => api/graphql/__tests__}/workspace.factory.spec.ts (67%) rename packages/twenty-server/src/engine/{graphql/workspace.module.ts => api/graphql/core-graphql-api.module.ts} (55%) rename packages/twenty-server/src/{engine-workspace => engine/api/graphql}/services/scalars-explorer.service.ts (93%) create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts (76%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts (96%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/args-alias.factory.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/args-string.factory.ts (94%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/create-many-query.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/delete-many-query.factory.ts (65%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/delete-one-query.factory.ts (69%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/factories.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/field-alias.factory.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/fields-string.factory.ts (96%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts (82%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/find-many-query.factory.ts (72%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/find-one-query.factory.ts (70%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/record-position-query.factory.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/update-many-query.factory.ts (62%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/factories/update-one-query.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/interfaces/record.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/utils/stringify-without-key-quote.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/workspace-query-builder.factory.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-builder/workspace-query-builder.module.ts (69%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts (81%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts (88%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/factories/index.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/factories/query-runner-args.factory.ts (93%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/factories/record-position.factory.ts (92%) rename packages/twenty-server/src/{utils/pagination => engine/api/graphql/workspace-query-runner}/interfaces/connection.interface.ts (100%) rename packages/twenty-server/src/{utils/pagination => engine/api/graphql/workspace-query-runner}/interfaces/edge.interface.ts (100%) rename packages/twenty-server/src/{utils/pagination => engine/api/graphql/workspace-query-runner}/interfaces/page-info.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts (71%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts (88%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/jobs/call-webhook.job.ts (89%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts (71%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/listeners/record-position.listener.ts (77%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/services/record-position-backfill-module.ts (50%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/services/record-position-backfill-service.ts (86%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts (96%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/utils/parse-result.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts (54%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts (92%) create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/workspace-query-runner.module.ts (52%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-query-runner/workspace-query-runner.service.ts (89%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts (87%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts (74%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/factories.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts (69%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts (55%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts (93%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts (81%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-resolver-builder/workspace-resolver.factory.ts (91%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/args.factory.ts (82%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts (93%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/connection-type.factory.ts (78%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/edge-type.factory.ts (77%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts (94%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts (86%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/factories.ts (93%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts (87%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/filter-type.factory.ts (85%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts (89%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/input-type.factory.ts (82%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/mutation-type.factory.ts (77%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts (89%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts (88%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/order-by-type.factory.ts (81%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts (82%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/output-type.factory.ts (82%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/query-type.factory.ts (77%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/relation-type.factory.ts (89%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/factories/root-type.factory.ts (83%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/enum/index.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/enum/order-by-direction.enum-type.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts (70%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts (80%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts (67%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts (68%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts (70%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts (81%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/index.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts (80%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts (85%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts (68%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts (58%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/object/index.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/object/page-into.object-type.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/big-float.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/big-int.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/cursor.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/date-time.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/date.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/index.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/time.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/graphql-types/scalars/uuid.scalar.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts (74%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/services/type-mapper.service.ts (90%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/storages/type-definitions.storage.ts (87%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/type-definitions.generator.ts (98%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts (86%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts (83%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts (85%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/clean-entity-name.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts (88%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts (74%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts (92%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-builder/workspace-schema-builder.module.ts (100%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-storage/workspace-schema-storage.module.ts (78%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace-schema-storage/workspace-schema-storage.service.ts (93%) rename packages/twenty-server/src/engine/{ => api}/graphql/workspace.factory.ts (86%) rename packages/twenty-server/src/{api/rest => engine/api/rest/__tests__}/api-rest.controller.utils.spec.ts (93%) rename packages/twenty-server/src/{api/rest => engine/api/rest/__tests__}/api-rest.service.spec.ts (75%) rename packages/twenty-server/src/{api/rest/api-rest-query-builder => engine/api/rest/api-rest-query-builder/__tests__}/api-rest-query-builder.factory.spec.ts (51%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts (76%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts (64%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/create-query.factory.ts (84%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/create-variables.factory.ts (67%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/delete-query.factory.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts (65%) create mode 100644 packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/factories.ts rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts (90%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts (84%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/get-variables.factory.ts (58%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts (93%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts (90%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts (90%) create mode 100644 packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts (71%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts (86%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts (92%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts (90%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts (91%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts (68%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts (93%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts (71%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts (91%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/update-query.factory.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/factories/update-variables.factory.ts (69%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts (50%) create mode 100644 packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts (82%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/compute-depth.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/fields.utils.ts (90%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest-query-builder/utils/parse-path.utils.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest.controller.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/api-rest.controller.utils.ts (91%) create mode 100644 packages/twenty-server/src/engine/api/rest/api-rest.module.ts rename packages/twenty-server/src/{ => engine}/api/rest/api-rest.service.ts (85%) rename packages/twenty-server/src/{ => engine}/api/rest/metadata-rest.controller.ts (84%) rename packages/twenty-server/src/{ => engine}/api/rest/metadata-rest.service.ts (95%) rename packages/twenty-server/src/{ => engine}/api/rest/types/api-rest-field-value.type.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/types/api-rest-query-variables.type.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/types/api-rest-query.type.ts (100%) rename packages/twenty-server/src/{ => engine}/api/rest/types/api-rest-response.type.ts (100%) delete mode 100644 packages/twenty-server/src/engine/graphql/workspace-query-builder/utils-test/workspace-query-builder-options.ts delete mode 100644 packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts delete mode 100644 packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/__tests__/cache-storage.service.spec.ts (90%) rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/cache-storage.module-factory.ts (85%) rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/cache-storage.module.ts (65%) rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/cache-storage.service.ts (85%) rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/types/cache-storage-namespace.enum.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/cache-storage/types/cache-storage-type.enum.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/email/drivers/interfaces/email-driver.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/email/drivers/logger.driver.ts (84%) rename packages/twenty-server/src/{ => engine}/integrations/email/drivers/smtp.driver.ts (88%) rename packages/twenty-server/src/{ => engine}/integrations/email/email-sender.job.ts (64%) rename packages/twenty-server/src/{ => engine}/integrations/email/email-sender.service.ts (66%) rename packages/twenty-server/src/{ => engine}/integrations/email/email.constants.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/email/email.module-factory.ts (86%) rename packages/twenty-server/src/{ => engine}/integrations/email/email.module.ts (54%) rename packages/twenty-server/src/{ => engine}/integrations/email/email.service.ts (62%) rename packages/twenty-server/src/{ => engine}/integrations/email/interfaces/email.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts (94%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts (92%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/cast-to-boolean.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/cast-to-log-level-array.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/cast-to-positive-number.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/cast-to-string-array.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/is-aws-region.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/is-duration.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/decorators/is-strictly-lower-than.decorator.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment-variables.ts (91%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment.default.ts (84%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment.module-definition.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment.module.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment.service.spec.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/environment.service.ts (86%) rename packages/twenty-server/src/{ => engine}/integrations/environment/interfaces/aws-region.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/environment/interfaces/support.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/event-emitter/types/object-record-create.event.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/event-emitter/types/object-record-delete.event.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/event-emitter/types/object-record-update.event.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/event-emitter/utils/object-record-changed-properties.util.ts (100%) rename packages/twenty-server/src/{integrations/exception-handler => engine/integrations/exception-handler/__tests__}/exception-handler.service.spec.ts (71%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/drivers/console.driver.ts (59%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/drivers/sentry.driver.ts (90%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/exception-handler.constants.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/exception-handler.module-definition.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/exception-handler.module-factory.ts (77%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/exception-handler.module.ts (88%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/exception-handler.service.ts (53%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/hooks/use-exception-handler.hook.ts (97%) rename packages/twenty-server/src/{integrations/tracing/useSentryTracing.ts => engine/integrations/exception-handler/hooks/use-sentry-tracing.ts} (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/interfaces/exception-handler-options.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/interfaces/exception-handler-user.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/interfaces/exception-handler.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/exception-handler/interfaces/index.ts (100%) rename packages/twenty-server/src/{integrations/file-storage => engine/integrations/file-storage/__tests__}/file-storage.service.spec.ts (73%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/drivers/interfaces/storage-driver.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/drivers/local.driver.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/drivers/s3.driver.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/file-storage.constants.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/file-storage.module-definition.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/file-storage.module-factory.ts (90%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/file-storage.module.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/file-storage.service.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/interfaces/file-storage.interface.ts (78%) rename packages/twenty-server/src/{ => engine}/integrations/file-storage/interfaces/index.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/integrations.module.ts (62%) rename packages/twenty-server/src/{integrations/logger => engine/integrations/logger/__tests__}/logger.service.spec.ts (76%) rename packages/twenty-server/src/{ => engine}/integrations/logger/interfaces/index.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/logger/interfaces/logger.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/logger/logger.constants.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/logger/logger.module-definition.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/logger/logger.module-factory.ts (82%) rename packages/twenty-server/src/{ => engine}/integrations/logger/logger.module.ts (95%) rename packages/twenty-server/src/{ => engine}/integrations/logger/logger.service.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/drivers/bullmq.driver.ts (92%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/drivers/interfaces/job-options.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts (67%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/drivers/pg-boss.driver.ts (87%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/drivers/sync.driver.ts (76%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/interfaces/index.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/interfaces/message-queue-job.interface.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/interfaces/message-queue.interface.ts (81%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/jobs.module.ts (62%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/message-queue.constants.ts (100%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/message-queue.module-factory.ts (89%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/message-queue.module.ts (65%) rename packages/twenty-server/src/{integrations/message-queue/services => engine/integrations/message-queue/services/__tests__}/message-queue-task-assigned.service.spec.ts (77%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/services/message-queue.service.ts (75%) rename packages/twenty-server/src/{ => engine}/integrations/message-queue/utils/get-job-class-name.util.ts (100%) rename packages/twenty-server/src/engine/modules/{foundation.module.ts => engine-modules.module.ts} (97%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/__tests__/deduce-relation-direction.spec.ts (98%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/__tests__/get-resolver-name.spec.ts (84%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/compute-custom-name.util.ts (100%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/compute-object-target-table.util.ts (100%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/deduce-relation-direction.util.ts (100%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/get-resolver-name.util.ts (94%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/is-relation-field-metadata-type.util.ts (100%) rename packages/twenty-server/src/{engine-workspace => engine}/utils/render-apollo-playground.util.ts (100%) rename packages/twenty-server/src/{business/modules/activity => modules/activity/standard-objects}/activity-target.object-metadata.ts (88%) rename packages/twenty-server/src/{business/modules/activity => modules/activity/standard-objects}/activity.object-metadata.ts (90%) rename packages/twenty-server/src/{business/modules/comment => modules/activity/standard-objects}/comment.object-metadata.ts (88%) rename packages/twenty-server/src/{business/modules/api-key => modules/api-key/standard-objects}/api-key.object-metadata.ts (100%) rename packages/twenty-server/src/{business/modules/attachment => modules/attachment/standard-objects}/attachment.object-metadata.ts (87%) create mode 100644 packages/twenty-server/src/modules/calendar/calendar.module.ts rename packages/twenty-server/src/{business => }/modules/calendar/commands/google-calendar-full-sync.command.ts (79%) rename packages/twenty-server/src/{business => }/modules/calendar/commands/workspace-calendar-sync-commands.module.ts (69%) rename packages/twenty-server/src/{business => }/modules/calendar/jobs/google-calendar-full-sync.job.ts (78%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts (66%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts (96%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts (71%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts (95%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts (69%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts (93%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-event/calendar-event.module.ts (71%) rename packages/twenty-server/src/{business => }/modules/calendar/repositories/calendar-event/calendar-event.service.ts (93%) rename packages/twenty-server/src/{business => }/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts (61%) rename packages/twenty-server/src/{business => }/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts (67%) rename packages/twenty-server/src/{business => }/modules/calendar/services/google-calendar-full-sync.service.ts (84%) create mode 100644 packages/twenty-server/src/modules/calendar/services/providers/calendar-providers.module.ts rename packages/twenty-server/src/{business => }/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts (92%) rename packages/twenty-server/src/{business/modules/calendar => modules/calendar/standard-objects}/calendar-channel-event-association.object-metadata.ts (95%) rename packages/twenty-server/src/{business/modules/calendar => modules/calendar/standard-objects}/calendar-channel.object-metadata.ts (95%) rename packages/twenty-server/src/{business/modules/calendar => modules/calendar/standard-objects}/calendar-event-attendee.object-metadata.ts (92%) rename packages/twenty-server/src/{business/modules/calendar => modules/calendar/standard-objects}/calendar-event.object-metadata.ts (96%) rename packages/twenty-server/src/{business => }/modules/calendar/types/calendar-event.ts (73%) rename packages/twenty-server/src/{business => }/modules/calendar/utils/format-google-calendar-event.util.ts (88%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/calendar}/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util.ts (100%) rename packages/twenty-server/src/{business => }/modules/calendar/utils/google-calendar-search-filter.util.ts (100%) rename packages/twenty-server/src/{business/modules/company => modules/company/standard-objects}/company.object-metadata.ts (90%) create mode 100644 packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts rename packages/twenty-server/src/{engine-workspace => modules/connected-account}/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts (77%) rename packages/twenty-server/src/{engine-workspace => modules/connected-account}/auto-companies-and-contacts-creation/create-company/create-company.module.ts (57%) rename packages/twenty-server/src/{engine-workspace => modules/connected-account}/auto-companies-and-contacts-creation/create-company/create-company.service.ts (92%) rename packages/twenty-server/src/{engine-workspace => modules/connected-account}/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts (58%) rename packages/twenty-server/src/{engine-workspace => modules/connected-account}/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts (87%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/connected-account}/repositories/blocklist/blocklist.module.ts (71%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/connected-account}/repositories/blocklist/blocklist.service.ts (89%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/connected-account}/repositories/connected-account/connected-account.module.ts (68%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/connected-account}/repositories/connected-account/connected-account.service.ts (97%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/connected-account}/services/google-apis-refresh-access-token.service.ts (87%) rename packages/twenty-server/src/{business/modules/calendar => modules/connected-account/standard-objects}/blocklist.object-metadata.ts (92%) rename packages/twenty-server/src/{business/modules/connected-account => modules/connected-account/standard-objects}/connected-account.object-metadata.ts (91%) rename packages/twenty-server/src/{business/modules/favorite => modules/favorite/standard-objects}/favorite.object-metadata.ts (88%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/crons/fetch-all-workspaces-messages.cron.pattern.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/crons/fetch-all-workspaces-messages.job.ts (81%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/fetch-workspace-messages-commands.module.ts (57%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/gmail-full-sync.command.ts (78%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/gmail-partial-sync.command.ts (78%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/start-fetch-all-workspaces-messages.cron.command.ts (58%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/commands/stop-fetch-all-workspaces-messages.cron.command.ts (57%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/create-companies-and-contacts-after-sync.job.ts (78%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/delete-connected-account-associated-calendar-data.job.ts (81%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/delete-connected-account-associated-messaging-data.job.ts (82%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/gmail-full-sync.job.ts (78%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/gmail-partial-sync.job.ts (76%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/jobs/match-message-participant.job.ts (83%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/listeners/messaging-connected-account.listener.ts (67%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/listeners/messaging-message-channel.listener.ts (61%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/listeners/messaging-person.listener.ts (67%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/listeners/messaging-workspace-member.listener.ts (67%) create mode 100644 packages/twenty-server/src/modules/messaging/messaging.module.ts rename packages/twenty-server/src/{business/modules/message => modules/messaging}/query-hooks/message/message-find-many.pre-query.hook.ts (73%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/query-hooks/message/message-find-one.pre-query-hook.ts (57%) create mode 100644 packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/company/company.module.ts (77%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/company/company.service.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-channel-message-association/message-channel-message-assocation.module.ts (66%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-channel-message-association/message-channel-message-association.service.ts (98%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-channel/message-channel.module.ts (71%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-channel/message-channel.service.ts (95%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-participant/message-participant.module.ts (60%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-participant/message-participant.service.ts (96%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-thread/message-thread.module.ts (50%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message-thread/message-thread.service.ts (92%) create mode 100644 packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts rename packages/twenty-server/src/{business/modules/message => modules/messaging}/repositories/message/message.service.ts (93%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/fetch-by-batch.service.ts (93%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/fetch-messages-by-batches.service.ts (89%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/gmail-full-sync.service.ts (83%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/gmail-partial-sync.service.ts (89%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/providers/gmail/gmail-client.provider.ts (91%) create mode 100644 packages/twenty-server/src/modules/messaging/services/providers/messaging-providers.module.ts rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/save-messages-and-create-contacts.service.ts (88%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/thread-cleaner/thread-cleaner.module.ts (56%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/thread-cleaner/thread-cleaner.service.ts (75%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/thread-cleaner/utils/delete-using-pagination.util.spec.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/thread-cleaner/utils/delete-using-pagination.util.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/utils/__tests__/format-address-object-as-participants.util.spec.ts (86%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/services/utils/format-address-object-as-participants.util.ts (92%) rename packages/twenty-server/src/{business/modules/message => modules/messaging/standard-objects}/message-channel-message-association.object-metadata.ts (89%) rename packages/twenty-server/src/{business/modules/message => modules/messaging/standard-objects}/message-channel.object-metadata.ts (94%) rename packages/twenty-server/src/{business/modules/message => modules/messaging/standard-objects}/message-participant.object-metadata.ts (90%) rename packages/twenty-server/src/{business/modules/message => modules/messaging/standard-objects}/message-thread.object-metadata.ts (92%) rename packages/twenty-server/src/{business/modules/message => modules/messaging/standard-objects}/message.object-metadata.ts (92%) rename packages/twenty-server/src/{business/modules/calendar-and-messaging => modules/messaging}/types/batch-queries.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/types/gmail-message-parsed-response.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/types/gmail-message.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/types/gmail-thread.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/types/message-or-thread-query.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/create-queries-from-message-ids.util.ts (71%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/filter-out-participants-from-company-or-workspace.util.ts (70%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/get-company-name-from-domain-name.util.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/get-domain-name-from-handle.util.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/get-first-name-and-last-name-from-handle-and-display-name.util.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/get-unique-participants-and-handles.util.ts (86%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/gmail-search-filter.util.ts (100%) rename packages/twenty-server/src/{business/modules/message => modules/messaging}/utils/is-person-email.util.ts (100%) create mode 100644 packages/twenty-server/src/modules/modules.module.ts rename packages/twenty-server/src/{business/modules/opportunity => modules/opportunity/standard-objects}/opportunity.object-metadata.ts (89%) rename packages/twenty-server/src/{engine-workspace => modules/person}/repositories/person/person.module.ts (76%) rename packages/twenty-server/src/{engine-workspace => modules/person}/repositories/person/person.service.ts (95%) rename packages/twenty-server/src/{business/modules/person => modules/person/standard-objects}/person.object-metadata.ts (89%) rename packages/twenty-server/src/{business/modules/pipeline-step => modules/pipeline-step/standard-objects}/pipeline-step.object-metadata.ts (95%) rename packages/twenty-server/src/{business/modules/view => modules/view/standard-objects}/view-field.object-metadata.ts (96%) rename packages/twenty-server/src/{business/modules/view => modules/view/standard-objects}/view-filter.object-metadata.ts (96%) rename packages/twenty-server/src/{business/modules/view => modules/view/standard-objects}/view-sort.object-metadata.ts (95%) rename packages/twenty-server/src/{business/modules/view => modules/view/standard-objects}/view.object-metadata.ts (92%) rename packages/twenty-server/src/{business/modules/webhook => modules/webhook/standard-objects}/webhook.object-metadata.ts (100%) rename packages/twenty-server/src/{engine-workspace => modules/workspace-member}/repositories/workspace-member/workspace-member.module.ts (71%) rename packages/twenty-server/src/{engine-workspace => modules/workspace-member}/repositories/workspace-member/workspace-member.service.ts (94%) rename packages/twenty-server/src/{business/modules/workspace => modules/workspace-member/standard-objects}/workspace-member.object-metadata.ts (88%) delete mode 100644 packages/twenty-server/src/queue-worker.module.ts create mode 100644 packages/twenty-server/src/queue-worker/queue-worker.module.ts rename packages/twenty-server/src/{ => queue-worker}/queue-worker.ts (64%) delete mode 100644 packages/twenty-server/src/utils/pagination/find-many-cursor-connection.ts delete mode 100644 packages/twenty-server/src/utils/pagination/index.ts delete mode 100644 packages/twenty-server/src/utils/pagination/interfaces/connection-arguments.interface.ts delete mode 100644 packages/twenty-server/src/utils/pagination/interfaces/connection-cursor.type.ts delete mode 100644 packages/twenty-server/src/utils/pagination/interfaces/find-many-aguments.interface.ts delete mode 100644 packages/twenty-server/src/utils/pagination/interfaces/options.interface.ts delete mode 100644 packages/twenty-server/src/utils/pagination/page-info.ts delete mode 100644 packages/twenty-server/src/utils/pagination/paginated.ts delete mode 100644 packages/twenty-server/src/utils/pagination/utils/cursor.ts delete mode 100644 packages/twenty-server/src/utils/pagination/utils/default-options.ts delete mode 100644 packages/twenty-server/src/utils/pagination/utils/pagination-direction.ts delete mode 100644 packages/twenty-server/src/utils/pagination/utils/validate-args.ts diff --git a/packages/twenty-server/jest.config.ts b/packages/twenty-server/jest.config.ts index 53d10fd3ec79..2a5ea0df6323 100644 --- a/packages/twenty-server/jest.config.ts +++ b/packages/twenty-server/jest.config.ts @@ -4,7 +4,7 @@ module.exports = { clearMocks: true, preset: 'ts-jest', testEnvironment: 'node', - + modulePathIgnorePatterns: ['/dist'], moduleFileExtensions: ['js', 'json', 'ts'], moduleNameMapper: { '^src/(.*)': '/src/$1', diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 79f40dc71f2e..5330a9569bc3 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -28,8 +28,8 @@ "database:seed:dev": "npx nx command -- workspace:seed:dev", "database:seed:demo": "npx nx command -- workspace:seed:demo", "database:reset": "npx nx database:truncate && npx nx database:init", - "command": "node dist/src/command", - "queue:work": "node dist/src/queue-worker" + "command": "node dist/src/command/command", + "queue:work": "node dist/src/queue-worker/queue-worker" }, "dependencies": { "@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga+nestjs+2.1.0.patch", diff --git a/packages/twenty-server/project.json b/packages/twenty-server/project.json index c3e44979982a..358c38cb5034 100644 --- a/packages/twenty-server/project.json +++ b/packages/twenty-server/project.json @@ -22,7 +22,7 @@ ], "options": { "cwd": "packages/twenty-server", - "command": "node dist/src/command.js" + "command": "node dist/src/command/command.js" } }, "test:debug": { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/factories.ts b/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/factories.ts deleted file mode 100644 index e6f4f822f65e..000000000000 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/factories.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { DeleteQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-query.factory'; -import { CreateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/create-query.factory'; -import { UpdateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/update-query.factory'; -import { FindOneQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-one-query.factory'; -import { FindManyQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-many-query.factory'; -import { DeleteVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-variables.factory'; -import { CreateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/create-variables.factory'; -import { UpdateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/update-variables.factory'; -import { GetVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/get-variables.factory'; -import { LastCursorInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; -import { LimitInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; -import { OrderByInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; -import { FilterInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; - -export const apiRestQueryBuilderFactories = [ - DeleteQueryFactory, - CreateQueryFactory, - UpdateQueryFactory, - FindOneQueryFactory, - FindManyQueryFactory, - DeleteVariablesFactory, - CreateVariablesFactory, - UpdateVariablesFactory, - GetVariablesFactory, - LastCursorInputFactory, - LimitInputFactory, - OrderByInputFactory, - FilterInputFactory, -]; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts b/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts deleted file mode 100644 index 355ccce52cb2..000000000000 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { Request } from 'express'; - -import { addDefaultConjunctionIfMissing } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; -import { checkFilterQuery } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils'; -import { parseFilter } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; -import { FieldValue } from 'src/api/rest/types/api-rest-field-value.type'; - -@Injectable() -export class FilterInputFactory { - create(request: Request, objectMetadata): Record { - let filterQuery = request.query.filter; - - if (typeof filterQuery !== 'string') { - return {}; - } - - checkFilterQuery(filterQuery); - - filterQuery = addDefaultConjunctionIfMissing(filterQuery); - - return parseFilter(filterQuery, objectMetadata.objectMetadataItem); - } -} diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts b/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts deleted file mode 100644 index d4ce695a191e..000000000000 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - fieldCurrency, - fieldLink, - fieldNumber, - fieldString, - objectMetadataItem, -} from 'src/utils/utils-test/object-metadata-item'; -import { mapFieldMetadataToGraphqlQuery } from 'src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; - -describe('mapFieldMetadataToGraphqlQuery', () => { - it('should map properly', () => { - expect( - mapFieldMetadataToGraphqlQuery(objectMetadataItem, fieldNumber), - ).toEqual('fieldNumber'); - expect( - mapFieldMetadataToGraphqlQuery(objectMetadataItem, fieldString), - ).toEqual('fieldString'); - expect(mapFieldMetadataToGraphqlQuery(objectMetadataItem, fieldLink)) - .toEqual(` - fieldLink - { - label - url - } - `); - expect(mapFieldMetadataToGraphqlQuery(objectMetadataItem, fieldCurrency)) - .toEqual(` - fieldCurrency - { - amountMicros - currencyCode - } - `); - }); -}); diff --git a/packages/twenty-server/src/api/rest/api-rest.module.ts b/packages/twenty-server/src/api/rest/api-rest.module.ts deleted file mode 100644 index 6e3371294794..000000000000 --- a/packages/twenty-server/src/api/rest/api-rest.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Module } from '@nestjs/common'; -import { HttpModule } from '@nestjs/axios'; - -import { ApiRestController } from 'src/api/rest/api-rest.controller'; -import { ApiRestService } from 'src/api/rest/api-rest.service'; -import { ApiRestQueryBuilderModule } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.module'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; -import { ApiRestMetadataController } from 'src/api/rest/metadata-rest.controller'; -import { ApiRestMetadataService } from 'src/api/rest/metadata-rest.service'; - -@Module({ - imports: [ApiRestQueryBuilderModule, AuthModule, HttpModule], - controllers: [ApiRestMetadataController, ApiRestController], - providers: [ApiRestMetadataService, ApiRestService], - exports: [ApiRestMetadataService], -}) -export class ApiRestModule {} diff --git a/packages/twenty-server/src/app.module.ts b/packages/twenty-server/src/app.module.ts index dbc019e2944f..04025def2de0 100644 --- a/packages/twenty-server/src/app.module.ts +++ b/packages/twenty-server/src/app.module.ts @@ -9,12 +9,12 @@ import { join } from 'path'; import { YogaDriver, YogaDriverConfig } from '@graphql-yoga/nestjs'; import { GraphQLConfigService } from 'src/engine-graphql-config/graphql-config.service'; -import { ApiRestModule } from 'src/api/rest/api-rest.module'; -import { BusinessModule } from 'src/business/modules/business.module'; +import { ApiRestModule } from 'src/engine/api/rest/api-rest.module'; +import { ModulesModule } from 'src/modules/modules.module'; -import { FoundationModule } from './engine/modules/foundation.module'; -import { IntegrationsModule } from './integrations/integrations.module'; -import { WorkspaceModule } from './engine/graphql/workspace.module'; +import { EngineModulesModule } from './engine/modules/engine-modules.module'; +import { IntegrationsModule } from './engine/integrations/integrations.module'; +import { CoreGraphqlApiModule } from './engine/api/graphql/core-graphql-api.module'; import { GraphQLConfigModule } from './engine-graphql-config/graphql-config.module'; @Module({ @@ -27,14 +27,14 @@ import { GraphQLConfigModule } from './engine-graphql-config/graphql-config.modu }), GraphQLModule.forRootAsync({ driver: YogaDriver, - imports: [FoundationModule, GraphQLConfigModule], + imports: [EngineModulesModule, GraphQLConfigModule], useClass: GraphQLConfigService, }), IntegrationsModule, - FoundationModule, - BusinessModule, + EngineModulesModule, + ModulesModule, ApiRestModule, - WorkspaceModule, + CoreGraphqlApiModule, ...AppModule.getConditionalModules(), ], }) diff --git a/packages/twenty-server/src/business/modules/business.module.ts b/packages/twenty-server/src/business/modules/business.module.ts deleted file mode 100644 index d3e41e2c35aa..000000000000 --- a/packages/twenty-server/src/business/modules/business.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CalendarModule } from 'src/business/modules/calendar/calendar.module'; -import { MessagingModule } from 'src/business/modules/message/messaging.module'; - -@Module({ - imports: [MessagingModule, CalendarModule], - providers: [], - exports: [], -}) -export class BusinessModule {} diff --git a/packages/twenty-server/src/business/modules/calendar/calendar.module.ts b/packages/twenty-server/src/business/modules/calendar/calendar.module.ts deleted file mode 100644 index be3037d13920..000000000000 --- a/packages/twenty-server/src/business/modules/calendar/calendar.module.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; -import { CreateCompaniesAndContactsModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { BlocklistModule } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.module'; -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { CalendarChannelEventAssociationModule } from 'src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module'; -import { CalendarChannelModule } from 'src/business/modules/calendar/repositories/calendar-channel/calendar-channel.module'; -import { CalendarEventAttendeeModule } from 'src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module'; -import { CalendarEventModule } from 'src/business/modules/calendar/repositories/calendar-event/calendar-event.module'; -import { CalendarEventCleanerModule } from 'src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; -import { GoogleCalendarFullSyncService } from 'src/business/modules/calendar/services/google-calendar-full-sync.service'; -import { GoogleCalendarClientProvider } from 'src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider'; -import { CompanyModule } from 'src/business/modules/message/repositories/company/company.module'; -import { PersonModule } from 'src/engine-workspace/repositories/person/person.module'; -import { WorkspaceMemberModule } from 'src/engine-workspace/repositories/workspace-member/workspace-member.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [ - EnvironmentModule, - WorkspaceDataSourceModule, - ConnectedAccountModule, - CalendarChannelModule, - CalendarChannelEventAssociationModule, - CalendarEventModule, - CalendarEventAttendeeModule, - CreateCompaniesAndContactsModule, - WorkspaceMemberModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - CompanyModule, - PersonModule, - BlocklistModule, - CalendarEventCleanerModule, - ], - providers: [GoogleCalendarFullSyncService, GoogleCalendarClientProvider], - exports: [GoogleCalendarFullSyncService], -}) -export class CalendarModule {} diff --git a/packages/twenty-server/src/business/modules/calendar/services/providers/calendar-providers.module.ts b/packages/twenty-server/src/business/modules/calendar/services/providers/calendar-providers.module.ts deleted file mode 100644 index 49b3cc4ab349..000000000000 --- a/packages/twenty-server/src/business/modules/calendar/services/providers/calendar-providers.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; -import { GoogleCalendarClientProvider } from 'src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider'; - -@Module({ - imports: [EnvironmentModule], - providers: [GoogleCalendarClientProvider], - exports: [GoogleCalendarClientProvider], -}) -export class CalendarProvidersModule {} diff --git a/packages/twenty-server/src/business/modules/message/messaging.module.ts b/packages/twenty-server/src/business/modules/message/messaging.module.ts deleted file mode 100644 index e42a706d6a13..000000000000 --- a/packages/twenty-server/src/business/modules/message/messaging.module.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { HttpModule } from '@nestjs/axios'; - -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { MessageChannelMessageAssociationModule } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageChannelModule } from 'src/business/modules/message/repositories/message-channel/message-channel.module'; -import { MessageThreadModule } from 'src/business/modules/message/repositories/message-thread/message-thread.module'; -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; -import { MessagingPersonListener } from 'src/business/modules/message/listeners/messaging-person.listener'; -import { MessageModule } from 'src/business/modules/message/repositories/message/message.module'; -import { GmailClientProvider } from 'src/business/modules/message/services/providers/gmail/gmail-client.provider'; -import { CreateContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { CreateCompanyService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service'; -import { FetchMessagesByBatchesService } from 'src/business/modules/message/services/fetch-messages-by-batches.service'; -import { GmailFullSyncService } from 'src/business/modules/message/services/gmail-full-sync.service'; -import { GmailPartialSyncService } from 'src/business/modules/message/services/gmail-partial-sync.service'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { MessageParticipantModule } from 'src/business/modules/message/repositories/message-participant/message-participant.module'; -import { MessagingWorkspaceMemberListener } from 'src/business/modules/message/listeners/messaging-workspace-member.listener'; -import { MessagingMessageChannelListener } from 'src/business/modules/message/listeners/messaging-message-channel.listener'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; -import { WorkspaceMemberModule } from 'src/engine-workspace/repositories/workspace-member/workspace-member.module'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { CreateCompaniesAndContactsModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { CompanyModule } from 'src/business/modules/message/repositories/company/company.module'; -import { PersonModule } from 'src/engine-workspace/repositories/person/person.module'; -import { SaveMessagesAndCreateContactsService } from 'src/business/modules/message/services/save-messages-and-create-contacts.service'; -import { MessagingConnectedAccountListener } from 'src/business/modules/message/listeners/messaging-connected-account.listener'; -import { BlocklistModule } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.module'; -import { FetchByBatchesService } from 'src/business/modules/message/services/fetch-by-batch.service'; -@Module({ - imports: [ - EnvironmentModule, - WorkspaceDataSourceModule, - ConnectedAccountModule, - MessageChannelModule, - MessageChannelMessageAssociationModule, - MessageModule, - MessageThreadModule, - MessageParticipantModule, - CreateCompaniesAndContactsModule, - WorkspaceMemberModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - CompanyModule, - PersonModule, - BlocklistModule, - HttpModule.register({ - baseURL: 'https://www.googleapis.com/batch/gmail/v1', - }), - ], - providers: [ - GmailFullSyncService, - GmailPartialSyncService, - FetchMessagesByBatchesService, - GoogleAPIsRefreshAccessTokenService, - GmailClientProvider, - CreateContactService, - CreateCompanyService, - MessagingPersonListener, - MessagingWorkspaceMemberListener, - MessagingMessageChannelListener, - MessageService, - SaveMessagesAndCreateContactsService, - MessagingConnectedAccountListener, - FetchByBatchesService, - ], - exports: [ - GmailPartialSyncService, - GmailFullSyncService, - GoogleAPIsRefreshAccessTokenService, - FetchByBatchesService, - ], -}) -export class MessagingModule {} diff --git a/packages/twenty-server/src/business/modules/message/query-hooks/messaging-query-hook.module.ts b/packages/twenty-server/src/business/modules/message/query-hooks/messaging-query-hook.module.ts deleted file mode 100644 index 14293b38c613..000000000000 --- a/packages/twenty-server/src/business/modules/message/query-hooks/messaging-query-hook.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { MessageFindManyPreQueryHook } from 'src/business/modules/message/query-hooks/message/message-find-many.pre-query.hook'; -import { MessageFindOnePreQueryHook } from 'src/business/modules/message/query-hooks/message/message-find-one.pre-query-hook'; -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { MessageChannelMessageAssociationModule } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageChannelModule } from 'src/business/modules/message/repositories/message-channel/message-channel.module'; -import { WorkspaceMemberModule } from 'src/engine-workspace/repositories/workspace-member/workspace-member.module'; - -@Module({ - imports: [ - MessageChannelMessageAssociationModule, - MessageChannelModule, - ConnectedAccountModule, - WorkspaceMemberModule, - ], - providers: [ - { - provide: MessageFindOnePreQueryHook.name, - useClass: MessageFindOnePreQueryHook, - }, - { - provide: MessageFindManyPreQueryHook.name, - useClass: MessageFindManyPreQueryHook, - }, - ], -}) -export class MessagingQueryHookModule {} diff --git a/packages/twenty-server/src/business/modules/message/repositories/message/message.module.ts b/packages/twenty-server/src/business/modules/message/repositories/message/message.module.ts deleted file mode 100644 index cfe909ae7c10..000000000000 --- a/packages/twenty-server/src/business/modules/message/repositories/message/message.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Module, forwardRef } from '@nestjs/common'; - -import { MessageChannelModule } from 'src/business/modules/message/repositories/message-channel/message-channel.module'; -import { MessageChannelMessageAssociationModule } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageParticipantModule } from 'src/business/modules/message/repositories/message-participant/message-participant.module'; -import { MessageThreadModule } from 'src/business/modules/message/repositories/message-thread/message-thread.module'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { CreateCompaniesAndContactsModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; - -@Module({ - imports: [ - WorkspaceDataSourceModule, - forwardRef(() => MessageThreadModule), - MessageParticipantModule, - MessageChannelMessageAssociationModule, - MessageChannelModule, - CreateCompaniesAndContactsModule, - ], - providers: [MessageService], - exports: [MessageService], -}) -export class MessageModule {} diff --git a/packages/twenty-server/src/business/modules/message/services/providers/messaging-providers.module.ts b/packages/twenty-server/src/business/modules/message/services/providers/messaging-providers.module.ts deleted file mode 100644 index cbe4c1c0fb9c..000000000000 --- a/packages/twenty-server/src/business/modules/message/services/providers/messaging-providers.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; -import { GmailClientProvider } from 'src/business/modules/message/services/providers/gmail/gmail-client.provider'; - -@Module({ - imports: [EnvironmentModule], - providers: [GmailClientProvider], - exports: [GmailClientProvider], -}) -export class MessagingProvidersModule {} diff --git a/packages/twenty-server/src/commands/command-logger.ts b/packages/twenty-server/src/command/command-logger.ts similarity index 100% rename from packages/twenty-server/src/commands/command-logger.ts rename to packages/twenty-server/src/command/command-logger.ts diff --git a/packages/twenty-server/src/command.module.ts b/packages/twenty-server/src/command/command.module.ts similarity index 53% rename from packages/twenty-server/src/command.module.ts rename to packages/twenty-server/src/command/command.module.ts index 4ed9b4d4eb70..6926124aa1b5 100644 --- a/packages/twenty-server/src/command.module.ts +++ b/packages/twenty-server/src/command/command.module.ts @@ -1,15 +1,13 @@ import { Module } from '@nestjs/common'; import { DatabaseCommandModule } from 'src/database/commands/database-command.module'; -import { FetchWorkspaceMessagesCommandsModule } from 'src/business/modules/message/commands/fetch-workspace-messages-commands.module'; +import { FetchWorkspaceMessagesCommandsModule } from 'src/modules/messaging/commands/fetch-workspace-messages-commands.module'; import { WorkspaceHealthCommandModule } from 'src/engine/workspace-manager/workspace-health/commands/workspace-health-command.module'; import { WorkspaceCleanerModule } from 'src/engine/workspace-manager/workspace-cleaner/workspace-cleaner.module'; -import { WorkspaceCalendarSyncCommandsModule } from 'src/business/modules/calendar/commands/workspace-calendar-sync-commands.module'; - -import { AppModule } from './app.module'; - -import { WorkspaceSyncMetadataCommandsModule } from './engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module'; -import { WorkspaceMigrationRunnerCommandsModule } from './engine/workspace-manager/workspace-migration-runner/commands/workspace-sync-metadata-commands.module'; +import { WorkspaceCalendarSyncCommandsModule } from 'src/modules/calendar/commands/workspace-calendar-sync-commands.module'; +import { AppModule } from 'src/app.module'; +import { WorkspaceMigrationRunnerCommandsModule } from 'src/engine/workspace-manager/workspace-migration-runner/commands/workspace-sync-metadata-commands.module'; +import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module'; @Module({ imports: [ diff --git a/packages/twenty-server/src/command.ts b/packages/twenty-server/src/command/command.ts similarity index 73% rename from packages/twenty-server/src/command.ts rename to packages/twenty-server/src/command/command.ts index 5281c14c8f3e..bf1774bbe3e1 100644 --- a/packages/twenty-server/src/command.ts +++ b/packages/twenty-server/src/command/command.ts @@ -1,10 +1,10 @@ import { CommandFactory } from 'nest-commander'; -import { CommandModule } from './command.module'; +import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; +import { LoggerService } from 'src/engine/integrations/logger/logger.service'; -import { LoggerService } from './integrations/logger/logger.service'; -import { ExceptionHandlerService } from './integrations/exception-handler/exception-handler.service'; -import { filterException } from './engine/filters/utils/global-exception-handler.util'; +import { CommandModule } from './command.module'; async function bootstrap() { const errorHandler = (err: Error) => { diff --git a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command.ts b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command.ts index cfc1196e262d..1bcf5c58d7f7 100644 --- a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command.ts @@ -4,8 +4,8 @@ import { Command, CommandRunner } from 'nest-commander'; import { dataSeedDemoWorkspaceCronPattern } from 'src/database/commands/data-seed-demo-workspace/crons/data-seed-demo-workspace-cron-pattern'; import { DataSeedDemoWorkspaceJob } from 'src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; @Command({ name: 'workspace-seed-demo:cron:start', diff --git a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command.ts b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command.ts index 844424a0f29a..84cd4a28df16 100644 --- a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command.ts @@ -4,8 +4,8 @@ import { Command, CommandRunner } from 'nest-commander'; import { dataSeedDemoWorkspaceCronPattern } from 'src/database/commands/data-seed-demo-workspace/crons/data-seed-demo-workspace-cron-pattern'; import { DataSeedDemoWorkspaceJob } from 'src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; @Command({ name: 'workspace-seed-demo:cron:stop', diff --git a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module.ts b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module.ts index 1a3bc3e2ee78..10d644c03f44 100644 --- a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module.ts +++ b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { DataSeedDemoWorkspaceService } from 'src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service'; diff --git a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job.ts b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job.ts index f4e33fa20ed1..e7b963d62008 100644 --- a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job.ts +++ b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; import { DataSeedDemoWorkspaceService } from 'src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service'; diff --git a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service.ts b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service.ts index fbf959cd10b9..adc84e677898 100644 --- a/packages/twenty-server/src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service.ts +++ b/packages/twenty-server/src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { deleteCoreSchema, diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index 669177abb66a..b038227318ec 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -10,11 +10,11 @@ import { seedPipelineStep } from 'src/database/typeorm-seeds/workspace/pipeline- import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/workspaceMember'; import { seedPeople } from 'src/database/typeorm-seeds/workspace/people'; import { seedCoreSchema } from 'src/database/typeorm-seeds/core'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; +import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; // TODO: implement dry-run @Command({ diff --git a/packages/twenty-server/src/database/typeorm/typeorm.module.ts b/packages/twenty-server/src/database/typeorm/typeorm.module.ts index 6866a6d4a0d7..b24fe05bad94 100644 --- a/packages/twenty-server/src/database/typeorm/typeorm.module.ts +++ b/packages/twenty-server/src/database/typeorm/typeorm.module.ts @@ -2,7 +2,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'; import { typeORMCoreModuleOptions } from 'src/database/typeorm/core/core.datasource'; -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; import { TypeORMService } from './typeorm.service'; diff --git a/packages/twenty-server/src/database/typeorm/typeorm.service.ts b/packages/twenty-server/src/database/typeorm/typeorm.service.ts index 893a6abc0ab3..595e0a3d929c 100644 --- a/packages/twenty-server/src/database/typeorm/typeorm.service.ts +++ b/packages/twenty-server/src/database/typeorm/typeorm.service.ts @@ -2,7 +2,7 @@ import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; diff --git a/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts b/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts index 6604f6412cc8..4106ae69a2f6 100644 --- a/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts +++ b/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; -import { FoundationModule } from 'src/engine/modules/foundation.module'; +import { EngineModulesModule } from 'src/engine/modules/engine-modules.module'; import { graphQLFactories } from 'src/engine-graphql-config/factories'; @Module({ - imports: [FoundationModule], + imports: [EngineModulesModule], providers: [...graphQLFactories], exports: [...graphQLFactories], }) diff --git a/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts b/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts index 994024cd56db..fb9212e3671c 100644 --- a/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts +++ b/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts @@ -13,18 +13,18 @@ import { GraphQLSchemaWithContext, YogaInitialContext } from 'graphql-yoga'; import * as Sentry from '@sentry/node'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { FoundationModule } from 'src/engine/modules/foundation.module'; +import { EngineModulesModule } from 'src/engine/modules/engine-modules.module'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { WorkspaceFactory } from 'src/engine/graphql/workspace.factory'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; +import { WorkspaceFactory } from 'src/engine/api/graphql/workspace.factory'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { handleExceptionAndConvertToGraphQLError } from 'src/engine/filters/utils/global-exception-handler.util'; -import { renderApolloPlayground } from 'src/engine-workspace/utils/render-apollo-playground.util'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { useExceptionHandler } from 'src/integrations/exception-handler/hooks/use-exception-handler.hook'; +import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { useExceptionHandler } from 'src/engine/integrations/exception-handler/hooks/use-exception-handler.hook'; import { User } from 'src/engine/modules/user/user.entity'; -import { useThrottler } from 'src/integrations/throttler/hooks/use-throttler'; +import { useThrottler } from 'src/engine-graphql-config/hooks/use-throttler'; import { JwtData } from 'src/engine/modules/auth/types/jwt-data.type'; -import { useSentryTracing } from 'src/integrations/tracing/useSentryTracing'; +import { useSentryTracing } from 'src/engine/integrations/exception-handler/hooks/use-sentry-tracing'; import { CreateContextFactory } from './factories/create-context.factory'; @@ -67,7 +67,7 @@ export class GraphQLConfigService const config: YogaDriverConfig = { context: (context) => this.createContextFactory.create(context), autoSchemaFile: true, - include: [FoundationModule], + include: [EngineModulesModule], conditionalSchema: async (context) => { let user: User | undefined; let workspace: Workspace | undefined; diff --git a/packages/twenty-server/src/integrations/throttler/hooks/use-throttler.ts b/packages/twenty-server/src/engine-graphql-config/hooks/use-throttler.ts similarity index 100% rename from packages/twenty-server/src/integrations/throttler/hooks/use-throttler.ts rename to packages/twenty-server/src/engine-graphql-config/hooks/use-throttler.ts diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts index e4fcfec4bbc8..038b0a83c5d5 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts @@ -23,7 +23,7 @@ import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { UpdateFieldInput } from 'src/engine-metadata/field-metadata/dtos/update-field.input'; import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; import { generateNullable } from 'src/engine-metadata/field-metadata/utils/generate-nullable'; import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; diff --git a/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts b/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts index 882dd492a7dc..a11c05e71d4f 100644 --- a/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts +++ b/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts @@ -2,12 +2,12 @@ import { YogaDriverConfig } from '@graphql-yoga/nestjs'; import GraphQLJSON from 'graphql-type-json'; import { CreateContextFactory } from 'src/engine-graphql-config/factories/create-context.factory'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; -import { useExceptionHandler } from 'src/integrations/exception-handler/hooks/use-exception-handler.hook'; -import { useThrottler } from 'src/integrations/throttler/hooks/use-throttler'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; +import { useExceptionHandler } from 'src/engine/integrations/exception-handler/hooks/use-exception-handler.hook'; +import { useThrottler } from 'src/engine-graphql-config/hooks/use-throttler'; import { MetadataModule } from 'src/engine-metadata/metadata.module'; -import { renderApolloPlayground } from 'src/engine-workspace/utils/render-apollo-playground.util'; +import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util'; export const metadataModuleFactory = async ( environmentService: EnvironmentService, diff --git a/packages/twenty-server/src/engine-metadata/metadata.module.ts b/packages/twenty-server/src/engine-metadata/metadata.module.ts index f012d1ab55dc..8702088754c2 100644 --- a/packages/twenty-server/src/engine-metadata/metadata.module.ts +++ b/packages/twenty-server/src/engine-metadata/metadata.module.ts @@ -6,8 +6,8 @@ import { YogaDriverConfig, YogaDriver } from '@graphql-yoga/nestjs'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; import { metadataModuleFactory } from 'src/engine-metadata/metadata.module-factory'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { GraphQLConfigModule } from 'src/engine-graphql-config/graphql-config.module'; import { CreateContextFactory } from 'src/engine-graphql-config/factories/create-context.factory'; diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts index 7090aa4def84..6fde2aca992f 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts @@ -30,8 +30,8 @@ import { RelationMetadataType, RelationOnDeleteAction, } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { computeCustomName } from 'src/engine-workspace/utils/compute-custom-name.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeCustomName } from 'src/engine/utils/compute-custom-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { DeleteOneObjectInput } from 'src/engine-metadata/object-metadata/dtos/delete-object.input'; import { RelationToDelete } from 'src/engine-metadata/relation-metadata/types/relation-to-delete'; import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts b/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts index 78da00486661..3620989390e7 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts +++ b/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts @@ -20,7 +20,7 @@ import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-meta import { WorkspaceMigrationColumnActionType } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; import { createCustomColumnName } from 'src/engine-metadata/utils/create-custom-column-name.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { createRelationForeignKeyColumnName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util'; import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts b/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts deleted file mode 100644 index f8f32010e558..000000000000 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { PersonModule } from 'src/engine-workspace/repositories/person/person.module'; -import { WorkspaceMemberModule } from 'src/engine-workspace/repositories/workspace-member/workspace-member.module'; -import { CreateCompanyAndContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; -import { CreateCompanyModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.module'; -import { CreateContactModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [ - WorkspaceDataSourceModule, - CreateContactModule, - CreateCompanyModule, - WorkspaceMemberModule, - PersonModule, - ], - providers: [CreateCompanyAndContactService], - exports: [CreateCompanyAndContactService], -}) -export class CreateCompaniesAndContactsModule {} diff --git a/packages/twenty-server/src/engine-workspace/utils/compute-field-target-column.util.ts b/packages/twenty-server/src/engine-workspace/utils/compute-field-target-column.util.ts deleted file mode 100644 index b60b6da640b7..000000000000 --- a/packages/twenty-server/src/engine-workspace/utils/compute-field-target-column.util.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; - -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; -import { BasicFieldMetadataType } from 'src/engine-metadata/workspace-migration/factories/basic-column-action.factory'; - -import { computeCustomName } from './compute-custom-name.util'; - -export const computeFieldTargetColumn = ( - fieldMetadata: - | FieldMetadataEntity - | FieldMetadataInterface, -) => { - if (isCompositeFieldMetadataType(fieldMetadata.type)) { - throw new Error( - "Composite field metadata should not be computed here, as they're split into multiple fields.", - ); - } - - return computeCustomName(fieldMetadata.name, fieldMetadata.isCustom ?? false); -}; diff --git a/packages/twenty-server/src/utils/utils-test/object-metadata-item.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts similarity index 77% rename from packages/twenty-server/src/utils/utils-test/object-metadata-item.ts rename to packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index 7bb0881b721e..04860d38203b 100644 --- a/packages/twenty-server/src/utils/utils-test/object-metadata-item.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -1,7 +1,7 @@ import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -export const fieldNumber = { +export const fieldNumberMock = { name: 'fieldNumber', type: FieldMetadataType.NUMBER, isNullable: false, @@ -9,7 +9,7 @@ export const fieldNumber = { targetColumnMap: { value: 'fieldNumber' }, }; -export const fieldString = { +export const fieldStringMock = { name: 'fieldString', type: FieldMetadataType.TEXT, isNullable: true, @@ -17,7 +17,7 @@ export const fieldString = { targetColumnMap: { value: 'fieldString' }, }; -export const fieldLink = { +export const fieldLinkMock = { name: 'fieldLink', type: FieldMetadataType.LINK, isNullable: false, @@ -25,7 +25,7 @@ export const fieldLink = { targetColumnMap: { label: 'fieldLinkLabel', url: 'fieldLinkUrl' }, }; -export const fieldCurrency = { +export const fieldCurrencyMock = { name: 'fieldCurrency', type: FieldMetadataType.CURRENCY, isNullable: true, @@ -36,9 +36,9 @@ export const fieldCurrency = { }, }; -export const objectMetadataItem: DeepPartial = { +export const objectMetadataItemMock: DeepPartial = { targetTableName: 'testingObject', nameSingular: 'objectName', namePlural: 'objectsName', - fields: [fieldNumber, fieldString, fieldLink, fieldCurrency], + fields: [fieldNumberMock, fieldStringMock, fieldLinkMock, fieldCurrencyMock], }; diff --git a/packages/twenty-server/src/engine/graphql/workspace.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts index 05cfa2fcb2b3..3883c85e178a 100644 --- a/packages/twenty-server/src/engine/graphql/workspace.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts @@ -2,12 +2,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { WorkspaceSchemaStorageService } from 'src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service'; -import { ScalarsExplorerService } from 'src/engine-workspace/services/scalars-explorer.service'; -import { WorkspaceResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/workspace-resolver.factory'; -import { WorkspaceGraphQLSchemaFactory } from 'src/engine/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; - -import { WorkspaceFactory } from './workspace.factory'; +import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; +import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; +import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory'; +import { WorkspaceGraphQLSchemaFactory } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; +import { WorkspaceFactory } from 'src/engine/api/graphql/workspace.factory'; describe('WorkspaceFactory', () => { let service: WorkspaceFactory; diff --git a/packages/twenty-server/src/engine/graphql/workspace.module.ts b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts similarity index 55% rename from packages/twenty-server/src/engine/graphql/workspace.module.ts rename to packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts index 143d06a8ad72..8bbcda974521 100644 --- a/packages/twenty-server/src/engine/graphql/workspace.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts @@ -2,11 +2,11 @@ import { Module } from '@nestjs/common'; import { MetadataModule } from 'src/engine-metadata/metadata.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { WorkspaceSchemaStorageModule } from 'src/engine/graphql/workspace-schema-storage/workspace-schema-storage.module'; +import { WorkspaceSchemaStorageModule } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module'; import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { ScalarsExplorerService } from 'src/engine-workspace/services/scalars-explorer.service'; -import { WorkspaceSchemaBuilderModule } from 'src/engine/graphql/workspace-schema-builder/workspace-schema-builder.module'; -import { WorkspaceResolverBuilderModule } from 'src/engine/graphql/workspace-resolver-builder/workspace-resolver-builder.module'; +import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; +import { WorkspaceSchemaBuilderModule } from 'src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module'; +import { WorkspaceResolverBuilderModule } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module'; import { WorkspaceFactory } from './workspace.factory'; @@ -22,4 +22,4 @@ import { WorkspaceFactory } from './workspace.factory'; providers: [WorkspaceFactory, ScalarsExplorerService], exports: [WorkspaceFactory], }) -export class WorkspaceModule {} +export class CoreGraphqlApiModule {} diff --git a/packages/twenty-server/src/engine-workspace/services/scalars-explorer.service.ts b/packages/twenty-server/src/engine/api/graphql/services/scalars-explorer.service.ts similarity index 93% rename from packages/twenty-server/src/engine-workspace/services/scalars-explorer.service.ts rename to packages/twenty-server/src/engine/api/graphql/services/scalars-explorer.service.ts index c8a958cbabfd..84460fe5d7bd 100644 --- a/packages/twenty-server/src/engine-workspace/services/scalars-explorer.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/services/scalars-explorer.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { GraphQLScalarType, GraphQLSchema, isScalarType } from 'graphql'; -import { scalars } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { scalars } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; @Injectable() export class ScalarsExplorerService { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts new file mode 100644 index 000000000000..1f1f4fdb8006 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts @@ -0,0 +1,13 @@ +import { GraphQLResolveInfo } from 'graphql'; + +import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; + +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; + +export const workspaceQueryBuilderOptionsMock: WorkspaceQueryBuilderOptions = { + fieldMetadataCollection: [], + info: {} as GraphQLResolveInfo, + objectMetadataCollection: [], + objectMetadataItem: objectMetadataItemMock as ObjectMetadataInterface, +}; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts index 8049ff73767e..4cc9394e1adb 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts @@ -1,7 +1,7 @@ import { TestingModule, Test } from '@nestjs/testing'; -import { ArgsAliasFactory } from 'src/engine/graphql/workspace-query-builder/factories/args-alias.factory'; -import { ArgsStringFactory } from 'src/engine/graphql/workspace-query-builder/factories/args-string.factory'; +import { ArgsAliasFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory'; +import { ArgsStringFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/args-string.factory'; describe('ArgsStringFactory', () => { let service: ArgsStringFactory; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts similarity index 76% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts index 17dbade3eddb..27610b802f99 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/find-duplicates-query.factory.spec.ts @@ -1,12 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { RecordFilter } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { FindDuplicatesResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { RecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { FindDuplicatesResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ArgsAliasFactory } from 'src/engine/graphql/workspace-query-builder/factories/args-alias.factory'; -import { FieldsStringFactory } from 'src/engine/graphql/workspace-query-builder/factories/fields-string.factory'; -import { FindDuplicatesQueryFactory } from 'src/engine/graphql/workspace-query-builder/factories/find-duplicates-query.factory'; -import { workspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/utils-test/workspace-query-builder-options'; +import { ArgsAliasFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory'; +import { FieldsStringFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory'; +import { FindDuplicatesQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory'; +import { workspaceQueryBuilderOptionsMock } from 'src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock'; describe('FindDuplicatesQueryFactory', () => { let service: FindDuplicatesQueryFactory; @@ -48,7 +48,10 @@ describe('FindDuplicatesQueryFactory', () => { it('should return (first: 0) as a filter when args are missing', async () => { const args: FindDuplicatesResolverArgs = {}; - const query = await service.create(args, workspaceQueryBuilderOptions); + const query = await service.create( + args, + workspaceQueryBuilderOptionsMock, + ); expect(query.trim()).toEqual(`query { objectNameCollection(first: 0) { @@ -73,9 +76,9 @@ describe('FindDuplicatesQueryFactory', () => { }; const query = await service.create(args, { - ...workspaceQueryBuilderOptions, + ...workspaceQueryBuilderOptionsMock, objectMetadataItem: { - ...workspaceQueryBuilderOptions.objectMetadataItem, + ...workspaceQueryBuilderOptionsMock.objectMetadataItem, nameSingular: 'person', }, }); @@ -101,9 +104,9 @@ describe('FindDuplicatesQueryFactory', () => { }; const query = await service.create(args, { - ...workspaceQueryBuilderOptions, + ...workspaceQueryBuilderOptionsMock, objectMetadataItem: { - ...workspaceQueryBuilderOptions.objectMetadataItem, + ...workspaceQueryBuilderOptionsMock.objectMetadataItem, nameSingular: 'person', }, }); @@ -129,9 +132,9 @@ describe('FindDuplicatesQueryFactory', () => { }; const query = await service.create(args, { - ...workspaceQueryBuilderOptions, + ...workspaceQueryBuilderOptionsMock, objectMetadataItem: { - ...workspaceQueryBuilderOptions.objectMetadataItem, + ...workspaceQueryBuilderOptionsMock.objectMetadataItem, nameSingular: 'person', }, }); @@ -155,9 +158,9 @@ describe('FindDuplicatesQueryFactory', () => { const query = await service.create( args, { - ...workspaceQueryBuilderOptions, + ...workspaceQueryBuilderOptionsMock, objectMetadataItem: { - ...workspaceQueryBuilderOptions.objectMetadataItem, + ...workspaceQueryBuilderOptionsMock.objectMetadataItem, nameSingular: 'person', }, }, @@ -178,9 +181,9 @@ describe('FindDuplicatesQueryFactory', () => { describe('buildQueryForExistingRecord', () => { it(`should include all the fields that exist for person inside "duplicateCriteriaCollection" constant`, async () => { const query = service.buildQueryForExistingRecord('uuid', { - ...workspaceQueryBuilderOptions, + ...workspaceQueryBuilderOptionsMock, objectMetadataItem: { - ...workspaceQueryBuilderOptions.objectMetadataItem, + ...workspaceQueryBuilderOptionsMock.objectMetadataItem, nameSingular: 'person', }, }); diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts similarity index 96% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts index 7c701045278d..455e5186425c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/__tests__/record-position-query.factory.spec.ts @@ -1,7 +1,7 @@ import { RecordPositionQueryFactory, RecordPositionQueryType, -} from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; +} from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; describe('RecordPositionQueryFactory', () => { const objectMetadataItem = { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/args-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/args-alias.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/args-string.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts similarity index 94% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/args-string.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts index d51c121aad36..df11f1611bbc 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/args-string.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; import { ArgsAliasFactory } from './args-alias.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/create-many-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/create-many-query.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/create-many-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/create-many-query.factory.ts index 5b5526708069..b667472a3d3e 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/create-many-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/create-many-query.factory.ts @@ -2,12 +2,12 @@ import { Injectable, Logger } from '@nestjs/common'; import { v4 as uuidv4 } from 'uuid'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { CreateManyResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { CreateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; import { ArgsAliasFactory } from './args-alias.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-many-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-many-query.factory.ts similarity index 65% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-many-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-many-query.factory.ts index 8581537e43d4..f24090c66540 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-many-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-many-query.factory.ts @@ -1,10 +1,10 @@ import { Injectable } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { DeleteManyResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { DeleteManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-one-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-one-query.factory.ts similarity index 69% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-one-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-one-query.factory.ts index d6f12e8abcab..690621b78ac6 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/delete-one-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/delete-one-query.factory.ts @@ -1,9 +1,9 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { DeleteOneResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/factories.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/factories.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/factories.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/factories.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/field-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/field-alias.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/fields-string.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts similarity index 96% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/fields-string.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts index 636efe8f5607..2dfc3eba88a6 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/fields-string.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts @@ -7,7 +7,7 @@ import isEmpty from 'lodash.isempty'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { FieldAliasFactory } from './field-alias.factory'; import { RelationFieldAliasFactory } from './relation-field-alias.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts similarity index 82% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts index 9c3ca711fbe7..c8f8bff1366e 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts @@ -2,15 +2,15 @@ import { Injectable, Logger } from '@nestjs/common'; import isEmpty from 'lodash.isempty'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { RecordFilter } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { FindDuplicatesResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { RecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { FindDuplicatesResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { ArgsAliasFactory } from 'src/engine/graphql/workspace-query-builder/factories/args-alias.factory'; -import { duplicateCriteriaCollection } from 'src/engine/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { ArgsAliasFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory'; +import { duplicateCriteriaCollection } from 'src/engine/api/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants'; import { settings } from 'src/engine/constants/settings'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-many-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-many-query.factory.ts similarity index 72% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-many-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-many-query.factory.ts index eb1f029efc88..ec8420abb439 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-many-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-many-query.factory.ts @@ -1,13 +1,13 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; import { RecordFilter, RecordOrderBy, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { FindManyResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { ArgsStringFactory } from './args-string.factory'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-one-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-one-query.factory.ts similarity index 70% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-one-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-one-query.factory.ts index 727f9d553364..80bbf3c9eea0 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/find-one-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-one-query.factory.ts @@ -1,10 +1,10 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { RecordFilter } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { FindOneResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { RecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { ArgsStringFactory } from './args-string.factory'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/record-position-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/record-position-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts index df767655ed30..c58b071ad268 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts @@ -5,15 +5,15 @@ import { GraphQLResolveInfo } from 'graphql'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; import { deduceRelationDirection, RelationDirection, -} from 'src/engine-workspace/utils/deduce-relation-direction.util'; -import { getFieldArgumentsByKey } from 'src/engine/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util'; +} from 'src/engine/utils/deduce-relation-direction.util'; +import { getFieldArgumentsByKey } from 'src/engine/api/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; import { ArgsStringFactory } from './args-string.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-many-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-many-query.factory.ts similarity index 62% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-many-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-many-query.factory.ts index a767c206fb3c..936013110d3d 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-many-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-many-query.factory.ts @@ -3,14 +3,14 @@ import { Injectable } from '@nestjs/common'; import { Record as IRecord, RecordFilter, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { UpdateManyResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { UpdateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { FieldsStringFactory } from 'src/engine/graphql/workspace-query-builder/factories/fields-string.factory'; -import { ArgsAliasFactory } from 'src/engine/graphql/workspace-query-builder/factories/args-alias.factory'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { FieldsStringFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory'; +import { ArgsAliasFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export interface UpdateManyQueryFactoryOptions extends WorkspaceQueryBuilderOptions { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-one-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-one-query.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-one-query.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-one-query.factory.ts index 4b8b6072f611..ba86a60fcdb7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/factories/update-one-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/update-one-query.factory.ts @@ -1,11 +1,11 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { UpdateOneResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; import { ArgsAliasFactory } from './args-alias.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/interfaces/record.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/record.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/interfaces/record.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/record.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts index 66dd4517a40f..ec52852ea502 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/__tests__/stringify-without-key-quote.spec.ts @@ -1,4 +1,4 @@ -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; describe('stringifyWithoutKeyQuote', () => { test('should stringify object correctly without quotes around keys', () => { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.factory.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.factory.ts index 65abfa013fd8..451821dc8b4c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.factory.ts @@ -1,11 +1,11 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; +import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; import { Record as IRecord, RecordFilter, RecordOrderBy, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; import { FindManyResolverArgs, FindOneResolverArgs, @@ -15,7 +15,7 @@ import { UpdateManyResolverArgs, DeleteManyResolverArgs, FindDuplicatesResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { FindManyQueryFactory } from './factories/find-many-query.factory'; import { FindOneQueryFactory } from './factories/find-one-query.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts similarity index 69% rename from packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts index 1ae38791c172..0325af39e03d 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/workspace-query-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { FieldsStringFactory } from 'src/engine/graphql/workspace-query-builder/factories/fields-string.factory'; -import { RecordPositionQueryFactory } from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; +import { FieldsStringFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory'; +import { RecordPositionQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; import { WorkspaceQueryBuilderFactory } from './workspace-query-builder.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts similarity index 81% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts index 8e1f4b8a2cf9..ea9076a2c9cc 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts @@ -1,11 +1,11 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { WorkspaceQueryRunnerOptions } from 'src/engine/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; +import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { QueryRunnerArgsFactory } from 'src/engine/graphql/workspace-query-runner/factories/query-runner-args.factory'; +import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RecordPositionFactory } from 'src/engine/graphql/workspace-query-runner/factories/record-position.factory'; +import { RecordPositionFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/record-position.factory'; describe('QueryRunnerArgsFactory', () => { const recordPositionFactory = { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts similarity index 88% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts index 2daa76157e13..e556e1514d34 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/record-position.factory.spec.ts @@ -1,8 +1,8 @@ import { TestingModule, Test } from '@nestjs/testing'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { RecordPositionQueryFactory } from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; -import { RecordPositionFactory } from 'src/engine/graphql/workspace-query-runner/factories/record-position.factory'; +import { RecordPositionQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; +import { RecordPositionFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/record-position.factory'; describe('RecordPositionFactory', () => { const recordPositionQueryFactory = { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/index.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/query-runner-args.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts similarity index 93% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/query-runner-args.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts index 80c6f8b6127d..8bc5df46320b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/query-runner-args.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { WorkspaceQueryRunnerOptions } from 'src/engine/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; +import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/record-position.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/record-position.factory.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/record-position.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/record-position.factory.ts index 97ab15c20f9b..1548977144e7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/factories/record-position.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/record-position.factory.ts @@ -4,7 +4,7 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work import { RecordPositionQueryFactory, RecordPositionQueryType, -} from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; +} from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; @Injectable() export class RecordPositionFactory { diff --git a/packages/twenty-server/src/utils/pagination/interfaces/connection.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface.ts similarity index 100% rename from packages/twenty-server/src/utils/pagination/interfaces/connection.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface.ts index 95fa6d5db86d..9f5ae3b9ed72 100644 --- a/packages/twenty-server/src/utils/pagination/interfaces/connection.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface.ts @@ -1,5 +1,5 @@ -import { IEdge } from './edge.interface'; import { IPageInfo } from './page-info.interface'; +import { IEdge } from './edge.interface'; export interface IConnection = IEdge> { edges: Array; diff --git a/packages/twenty-server/src/utils/pagination/interfaces/edge.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface.ts similarity index 100% rename from packages/twenty-server/src/utils/pagination/interfaces/edge.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface.ts diff --git a/packages/twenty-server/src/utils/pagination/interfaces/page-info.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/page-info.interface.ts similarity index 100% rename from packages/twenty-server/src/utils/pagination/interfaces/page-info.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/page-info.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts similarity index 71% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts index 98c71a1209c6..c015f34a3b86 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/pg-graphql.interface.ts @@ -1,4 +1,4 @@ -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; export interface PGGraphQLResponse { resolve: { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts similarity index 88% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts index 45108bca4d25..c05e094e47db 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts @@ -1,17 +1,17 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { CallWebhookJob, CallWebhookJobData, -} from 'src/engine/graphql/workspace-query-runner/jobs/call-webhook.job'; +} from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job'; export enum CallWebhookJobsJobOperation { create = 'create', diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job.ts similarity index 89% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook.job.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job.ts index 5945b68c198c..5ce75b717f4b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/call-webhook.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; export type CallWebhookJobData = { targetUrl: string; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts similarity index 71% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts index dcc5ab8bf409..bbd777e35dc2 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { RecordPositionBackfillService } from 'src/engine/graphql/workspace-query-runner/services/record-position-backfill-service'; +import { RecordPositionBackfillService } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service'; export type RecordPositionBackfillJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/listeners/record-position.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts similarity index 77% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/listeners/record-position.listener.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts index 3ea32791ab88..c3fc08c61e06 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/listeners/record-position.listener.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts @@ -4,13 +4,13 @@ import { OnEvent } from '@nestjs/event-emitter'; import { CreatedObjectMetadata, ObjectRecordCreateEvent, -} from 'src/integrations/event-emitter/types/object-record-create.event'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +} from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { RecordPositionBackfillJob, RecordPositionBackfillJobData, -} from 'src/engine/graphql/workspace-query-runner/jobs/record-position-backfill.job'; +} from 'src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job'; @Injectable() export class RecordPositionListener { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module.ts similarity index 50% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module.ts index a56ccb85b851..1a058a46ed35 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module.ts @@ -1,9 +1,9 @@ import { Module } from '@nestjs/common'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { RecordPositionQueryFactory } from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; -import { RecordPositionFactory } from 'src/engine/graphql/workspace-query-runner/factories/record-position.factory'; -import { RecordPositionBackfillService } from 'src/engine/graphql/workspace-query-runner/services/record-position-backfill-service'; +import { RecordPositionQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; +import { RecordPositionFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/record-position.factory'; +import { RecordPositionBackfillService } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service'; @Module({ imports: [WorkspaceDataSourceModule], diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts similarity index 86% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-service.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts index 13b7b0e9a474..a8fb36582c0c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/services/record-position-backfill-service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts @@ -6,8 +6,8 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work import { RecordPositionQueryFactory, RecordPositionQueryType, -} from 'src/engine/graphql/workspace-query-builder/factories/record-position-query.factory'; -import { RecordPositionFactory } from 'src/engine/graphql/workspace-query-runner/factories/record-position.factory'; +} from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; +import { RecordPositionFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/record-position.factory'; @Injectable() export class RecordPositionBackfillService { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts similarity index 96% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts index 0ec0a5d65a8e..3b731d627b6c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/__tests__/parse-result.spec.ts @@ -2,7 +2,7 @@ import { isSpecialKey, handleSpecialKey, parseResult, -} from 'src/engine/graphql/workspace-query-runner/utils/parse-result.util'; +} from 'src/engine/api/graphql/workspace-query-runner/utils/parse-result.util'; describe('isSpecialKey', () => { test('should return true if the key starts with "___"', () => { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/parse-result.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/parse-result.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/utils/parse-result.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/parse-result.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts similarity index 54% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts index 7ab7f16465bb..60a782e8c443 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface.ts @@ -1,4 +1,4 @@ -import { ResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { ResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; export interface WorkspacePreQueryHook { execute( diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts index 55e731b53604..84d75b1358b9 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type.ts @@ -8,7 +8,7 @@ import { FindOneResolverArgs, UpdateManyResolverArgs, UpdateOneResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; export type ExecutePreHookMethod = | 'createMany' diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts new file mode 100644 index 000000000000..c0472264fe80 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts @@ -0,0 +1,11 @@ +import { MessageFindManyPreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook'; +import { MessageFindOnePreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook'; +import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type'; + +// TODO: move to a decorator +export const workspacePreQueryHooks: WorkspaceQueryHook = { + message: { + findOne: [MessageFindOnePreQueryHook.name], + findMany: [MessageFindManyPreQueryHook.name], + }, +}; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts new file mode 100644 index 000000000000..3887e39e56f3 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { MessagingQueryHookModule } from 'src/modules/messaging/query-hooks/messaging-query-hook.module'; +import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service'; + +@Module({ + imports: [MessagingQueryHookModule], + providers: [WorkspacePreQueryHookService], + exports: [WorkspacePreQueryHookService], +}) +export class WorkspacePreQueryHookModule {} diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts index e18fc942f5a0..28681e0b965b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts @@ -1,13 +1,13 @@ import { Injectable } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; -import { WorkspacePreQueryHook } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; +import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; import { ExecutePreHookMethod, WorkspacePreQueryHookPayload, -} from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type'; -import { workspacePreQueryHooks } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config'; +} from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type'; +import { workspacePreQueryHooks } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config'; @Injectable() export class WorkspacePreQueryHookService { diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts similarity index 52% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index 4399fc492a57..86384c7b1425 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -1,10 +1,10 @@ import { Module } from '@nestjs/common'; -import { WorkspaceQueryBuilderModule } from 'src/engine/graphql/workspace-query-builder/workspace-query-builder.module'; +import { WorkspaceQueryBuilderModule } from 'src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { WorkspacePreQueryHookModule } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module'; -import { workspaceQueryRunnerFactories } from 'src/engine/graphql/workspace-query-runner/factories'; -import { RecordPositionListener } from 'src/engine/graphql/workspace-query-runner/listeners/record-position.listener'; +import { WorkspacePreQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module'; +import { workspaceQueryRunnerFactories } from 'src/engine/api/graphql/workspace-query-runner/factories'; +import { RecordPositionListener } from 'src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener'; import { WorkspaceQueryRunnerService } from './workspace-query-runner.service'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts similarity index 89% rename from packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.service.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index 6206bcf09bd5..cc7573571488 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -8,12 +8,12 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import isEmpty from 'lodash.isempty'; -import { IConnection } from 'src/utils/pagination/interfaces/connection.interface'; +import { IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface'; import { Record as IRecord, RecordFilter, RecordOrderBy, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; import { CreateManyResolverArgs, CreateOneResolverArgs, @@ -24,27 +24,27 @@ import { FindOneResolverArgs, UpdateManyResolverArgs, UpdateOneResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { WorkspaceQueryBuilderFactory } from 'src/engine/graphql/workspace-query-builder/workspace-query-builder.factory'; +import { WorkspaceQueryBuilderFactory } from 'src/engine/api/graphql/workspace-query-builder/workspace-query-builder.factory'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { CallWebhookJobsJob, CallWebhookJobsJobData, CallWebhookJobsJobOperation, -} from 'src/engine/graphql/workspace-query-runner/jobs/call-webhook-jobs.job'; -import { parseResult } from 'src/engine/graphql/workspace-query-runner/utils/parse-result.util'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; -import { ObjectRecordDeleteEvent } from 'src/integrations/event-emitter/types/object-record-delete.event'; -import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event'; -import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event'; -import { WorkspacePreQueryHookService } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +} from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job'; +import { parseResult } from 'src/engine/api/graphql/workspace-query-runner/utils/parse-result.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; +import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; +import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { NotFoundError } from 'src/engine/filters/utils/graphql-errors.util'; -import { QueryRunnerArgsFactory } from 'src/engine/graphql/workspace-query-runner/factories/query-runner-args.factory'; +import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory'; import { WorkspaceQueryRunnerOptions } from './interfaces/query-runner-option.interface'; import { diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts similarity index 87% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts index dd7193745c17..1ca7d55dcce2 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/constants/duplicate-criteria.constants.ts @@ -1,4 +1,4 @@ -import { RecordDuplicateCriteria } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { RecordDuplicateCriteria } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; /** * objectName: directly reference the name of the object from the metadata tables. diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts index 53f3f90491a9..dc1942eccc19 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-many-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { CreateManyResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class CreateManyResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts index 37845421bf58..01583f0de9bd 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/create-one-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { CreateOneResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class CreateOneResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts index 6f55c2110267..e74685bb12d7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { DeleteManyResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class DeleteManyResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts index 6d3ff14adb53..f02676182915 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/delete-one-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { DeleteOneResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class DeleteOneResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts similarity index 74% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts index c99f023c4c09..6ab4c61be6e4 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts @@ -5,13 +5,13 @@ import { FindOneResolverArgs, ExecuteQuickActionOnOneResolverArgs, DeleteOneResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerOptions } from 'src/engine/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; import { QuickActionsService } from 'src/engine/modules/quick-actions/quick-actions.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/factories.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/factories.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts index da369eedddf7..9bd0f4432e7c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/factories.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/factories.ts @@ -1,4 +1,4 @@ -import { UpdateManyResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; +import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; import { FindDuplicatesResolverFactory } from './find-duplicates-resolver.factory'; import { FindManyResolverFactory } from './find-many-resolver.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts index edb4edcf957c..ee288c708efa 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { FindDuplicatesResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class FindDuplicatesResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts index 686dd4b0f2a8..deead28be2e0 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-many-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { FindManyResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class FindManyResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts index 83d4294a1096..1e8ce6d52da1 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/find-one-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { FindOneResolverArgs, Resolver, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class FindOneResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts index 4f4904bafdd8..470f4e793531 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { Resolver, UpdateManyResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class UpdateManyResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts index 751963e9fe46..0851c54c8007 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/update-one-resolver.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { Resolver, UpdateOneResolverArgs, -} from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; -import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; +} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; @Injectable() export class UpdateOneResolverFactory diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts similarity index 69% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts index f5f72566228b..4a3f3e13fa13 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/pg-graphql.interface.ts @@ -1,4 +1,4 @@ -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; export interface PGGraphQLResponse { resolve: { diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts similarity index 55% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts index 848847abee79..709e99ff76b7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface.ts @@ -1,4 +1,4 @@ -import { WorkspaceSchemaBuilderContext } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; +import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface'; import { Resolver } from './workspace-resolvers-builder.interface'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts similarity index 93% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts index 78355c86b991..20cae32749e8 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface.ts @@ -4,9 +4,9 @@ import { Record, RecordFilter, RecordOrderBy, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; -import { workspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/factories/factories'; +import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/factories/factories'; export type Resolver = GraphQLFieldResolver; diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts similarity index 81% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts index 34eed955d0ea..3cbef4cf4c00 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { WorkspaceQueryRunnerModule } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.module'; +import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module'; import { QuickActionsModule } from 'src/engine/modules/quick-actions/quick-actions.module'; import { WorkspaceResolverFactory } from './workspace-resolver.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts similarity index 91% rename from packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts index 096aae9b75f8..8e2a548d897c 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-resolver-builder/workspace-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts @@ -4,10 +4,10 @@ import { IResolvers } from '@graphql-tools/utils'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { getResolverName } from 'src/engine-workspace/utils/get-resolver-name.util'; -import { UpdateManyResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; -import { DeleteManyResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory'; -import { ExecuteQuickActionOnOneResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory'; +import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; +import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; +import { DeleteManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory'; +import { ExecuteQuickActionOnOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory'; import { FindDuplicatesResolverFactory } from './factories/find-duplicates-resolver.factory'; import { FindManyResolverFactory } from './factories/find-many-resolver.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/args.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/args.factory.ts similarity index 82% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/args.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/args.factory.ts index 5940e3b64a1e..7f316119cc21 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/args.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/args.factory.ts @@ -2,11 +2,11 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigArgumentMap } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ArgsMetadata } from 'src/engine/graphql/workspace-schema-builder/interfaces/param-metadata.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { ArgsMetadata } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { TypeMapperService } from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; @Injectable() export class ArgsFactory { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts similarity index 93% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts index beecc865ac75..ef9d88548052 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLInt, GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts similarity index 78% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts index 13ea80d2363b..41919c7157a7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/connection-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts @@ -2,15 +2,15 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { PageInfoType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/object'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { PageInfoType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/object'; import { ConnectionTypeDefinitionKind } from './connection-type-definition.factory'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts index 61e2dab44923..877a6e9b22d3 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts similarity index 77% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts index 65b7fe94a931..ea1bdaafdbd3 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/edge-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts @@ -2,15 +2,15 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { CursorScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { CursorScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; import { EdgeTypeDefinitionKind } from './edge-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts similarity index 94% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts index 1a2cd5889c4f..def7d1095a48 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLEnumType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts similarity index 86% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts index 2a66698099c9..98766740b62a 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts @@ -6,17 +6,17 @@ import { GraphQLObjectType, } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { objectContainsRelationField } from 'src/engine/graphql/workspace-schema-builder/utils/object-contains-relation-field'; -import { getResolverArgs } from 'src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { objectContainsRelationField } from 'src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field'; +import { getResolverArgs } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { RelationDirection, deduceRelationDirection, -} from 'src/engine-workspace/utils/deduce-relation-direction.util'; +} from 'src/engine/utils/deduce-relation-direction.util'; import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; import { RelationTypeFactory } from './relation-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/factories.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/factories.ts similarity index 93% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/factories.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/factories.ts index 65fafba8dc9c..71663a0d0b7a 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/factories.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/factories.ts @@ -1,4 +1,4 @@ -import { EnumTypeDefinitionFactory } from 'src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; +import { EnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; import { ArgsFactory } from './args.factory'; import { InputTypeFactory } from './input-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts similarity index 87% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts index 46aff0b726cb..c2c558e5d554 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts @@ -2,12 +2,12 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; -import { TypeMapperService } from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { FilterTypeFactory } from './filter-type.factory'; import { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts similarity index 85% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts index cd621fd757fd..19477e8cb30e 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/filter-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts @@ -7,17 +7,17 @@ import { GraphQLScalarType, } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; import { isEnumFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts similarity index 89% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts index 4f8bc56463f1..9511b44280a2 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; import { InputTypeFactory } from './input-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts similarity index 82% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts index 8b3878618859..7a5a5e10f743 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/input-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts @@ -2,14 +2,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLInputType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/mutation-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts similarity index 77% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/mutation-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts index b52731125220..dbcb506cd74b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/mutation-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts @@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common'; import { GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { WorkspaceResolverBuilderMutationMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceResolverBuilderMutationMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { ObjectTypeName, RootTypeFactory } from './root-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts similarity index 89% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts index c97632e29f1b..343df7faae9f 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; import { OutputTypeFactory } from './output-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts similarity index 88% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts index fc079c31c540..0b10df54c1a8 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { InputTypeDefinition, diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts similarity index 81% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts index 0175c9b03aba..d452538a26a7 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/order-by-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts @@ -2,14 +2,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLInputType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts similarity index 82% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts index 6cff06f660ac..4cb29d234e42 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/orphaned-types.factory.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { GraphQLNamedType } from 'graphql'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; @Injectable() export class OrphanedTypesFactory { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/output-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts similarity index 82% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/output-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts index 127f8e30e84f..7ba617ebfc86 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/output-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts @@ -2,14 +2,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, -} from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; +} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/query-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts similarity index 77% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/query-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts index 981a4becae5b..2275cdca3441 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/query-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts @@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common'; import { GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { WorkspaceResolverBuilderQueryMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceResolverBuilderQueryMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { ObjectTypeName, RootTypeFactory } from './root-type.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/relation-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts similarity index 89% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/relation-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts index b93ae26a5468..c4a68a6b2d1b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/relation-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts @@ -6,8 +6,8 @@ import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/inter import { RelationMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/relation-metadata.interface'; import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { RelationDirection } from 'src/engine-workspace/utils/deduce-relation-direction.util'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { RelationDirection } from 'src/engine/utils/deduce-relation-direction.util'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/root-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts similarity index 83% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/root-type.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts index ae2a768ff34f..b5ec65507924 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/factories/root-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts @@ -2,14 +2,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; -import { WorkspaceBuildSchemaOptions } from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { WorkspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { TypeDefinitionsStorage } from 'src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { getResolverName } from 'src/engine-workspace/utils/get-resolver-name.util'; -import { getResolverArgs } from 'src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util'; -import { TypeMapperService } from 'src/engine/graphql/workspace-schema-builder/services/type-mapper.service'; +import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; +import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; +import { getResolverArgs } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { ArgsFactory } from './args.factory'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/enum/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/enum/index.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/enum/index.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/enum/index.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/enum/order-by-direction.enum-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/enum/order-by-direction.enum-type.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/enum/order-by-direction.enum-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/enum/order-by-direction.enum-type.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts similarity index 70% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts index 895e9981ee42..b9db4a6a4ae6 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-float-filter.input-type.ts @@ -1,7 +1,7 @@ import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -import { BigFloatScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { BigFloatScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; export const BigFloatFilterType = new GraphQLInputObjectType({ name: 'BigFloatFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts similarity index 80% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts index fe0254f4e941..fed62dc16f2d 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/big-int-filter.input-type.ts @@ -5,7 +5,7 @@ import { GraphQLInt, } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; export const BigIntFilterType = new GraphQLInputObjectType({ name: 'BigIntFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts similarity index 67% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts index ba3bfb040220..1ea6346481b5 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/boolean-filter.input-type.ts @@ -1,6 +1,6 @@ import { GraphQLBoolean, GraphQLInputObjectType } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; export const BooleanFilterType = new GraphQLInputObjectType({ name: 'BooleanFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts similarity index 68% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts index 159e530adaef..43499e96e430 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-filter.input-type.ts @@ -1,7 +1,7 @@ import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -import { DateScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { DateScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; export const DateFilterType = new GraphQLInputObjectType({ name: 'DateFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts similarity index 70% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts index 18b85d368381..278eff46dbdc 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/date-time-filter.input-type.ts @@ -1,7 +1,7 @@ import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -import { DateTimeScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { DateTimeScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; export const DatetimeFilterType = new GraphQLInputObjectType({ name: 'DateTimeFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts similarity index 81% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts index 82da74d3d20d..24be95056c48 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/float-filter.input-type.ts @@ -5,7 +5,7 @@ import { GraphQLNonNull, } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; export const FloatFilterType = new GraphQLInputObjectType({ name: 'FloatFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/index.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts similarity index 80% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts index b0022af2f29e..4b2d1dc80091 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/int-filter.input-type.ts @@ -5,7 +5,7 @@ import { GraphQLInt, } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; export const IntFilterType = new GraphQLInputObjectType({ name: 'IntFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts similarity index 85% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts index 3a7c9197dbf2..3ea34f85b0dd 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/string-filter.input-type.ts @@ -5,7 +5,7 @@ import { GraphQLString, } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; export const StringFilterType = new GraphQLInputObjectType({ name: 'StringFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts similarity index 68% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts index bc08a3eb9417..58d1b7bab1a4 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/time-filter.input-type.ts @@ -1,7 +1,7 @@ import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -import { TimeScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { TimeScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; export const TimeFilterType = new GraphQLInputObjectType({ name: 'TimeFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts similarity index 58% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts index 3eebe14b7e7d..4935e4d94400 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/uuid-filter.input-type.ts @@ -1,7 +1,7 @@ import { GraphQLInputObjectType, GraphQLList } from 'graphql'; -import { FilterIs } from 'src/engine/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -import { UUIDScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; +import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; export const UUIDFilterType = new GraphQLInputObjectType({ name: 'UUIDFilter', diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/object/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/object/index.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/object/index.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/object/index.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/object/page-into.object-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/object/page-into.object-type.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/object/page-into.object-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/object/page-into.object-type.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/big-float.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/big-float.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/big-float.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/big-float.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/big-int.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/big-int.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/big-int.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/big-int.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/cursor.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/cursor.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/cursor.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/cursor.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/date-time.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/date-time.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/date-time.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/date-time.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/date.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/date.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/date.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/date.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/index.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/index.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/index.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/time.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/time.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/time.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/time.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/uuid.scalar.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/uuid.scalar.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/graphql-types/scalars/uuid.scalar.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/uuid.scalar.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts similarity index 74% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts index 9fd1e13f995e..d117c560eebf 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts @@ -1,4 +1,4 @@ -import { InputTypeDefinitionKind } from 'src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory'; +import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; export interface ArgMetadata { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts similarity index 90% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/services/type-mapper.service.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index 82badbf68dca..d2df890aaf81 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -19,7 +19,7 @@ import { import { DateScalarMode, NumberScalarMode, -} from 'src/engine/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; +} from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; import { @@ -31,10 +31,10 @@ import { IntFilterType, BooleanFilterType, BigFloatFilterType, -} from 'src/engine/graphql/workspace-schema-builder/graphql-types/input'; -import { OrderByDirectionType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/enum'; -import { BigFloatScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars'; -import { PositionScalarType } from 'src/engine/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar'; +} from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input'; +import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum'; +import { BigFloatScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; +import { PositionScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar'; export interface TypeOptions { nullable?: boolean; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts similarity index 87% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts index 3a2045c37e0e..9e539bc5d44a 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/storages/type-definitions.storage.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts @@ -7,15 +7,15 @@ import { } from 'graphql'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { EnumTypeDefinition } from 'src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; +import { EnumTypeDefinition } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; import { InputTypeDefinition, InputTypeDefinitionKind, -} from 'src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory'; +} from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; import { ObjectTypeDefinition, ObjectTypeDefinitionKind, -} from 'src/engine/graphql/workspace-schema-builder/factories/object-type-definition.factory'; +} from 'src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory'; // Must be scoped on REQUEST level @Injectable({ scope: Scope.REQUEST }) diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/type-definitions.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts similarity index 98% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/type-definitions.generator.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts index fa227d1c05da..595db1c6bd63 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/type-definitions.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts @@ -8,7 +8,7 @@ import { customTableDefaultColumns } from 'src/engine/workspace-manager/workspac import { fullNameObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/full-name.composite-type'; import { currencyObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/currency.composite-type'; import { linkObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/link.composite-type'; -import { EnumTypeDefinitionFactory } from 'src/engine/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; +import { EnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; import { TypeDefinitionsStorage } from './storages/type-definitions.storage'; import { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts similarity index 86% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts index 8069715d060f..3b95a01eb4be 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/clean-entity-name.spec.ts @@ -1,4 +1,4 @@ -import { cleanEntityName } from 'src/engine/graphql/workspace-schema-builder/utils/clean-entity-name.util'; +import { cleanEntityName } from 'src/engine/api/graphql/workspace-schema-builder/utils/clean-entity-name.util'; describe('cleanEntityName', () => { test('should camelCase strings', () => { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts similarity index 83% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts index 8d5f1899179b..459140af68dc 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts @@ -1,5 +1,5 @@ import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { getFieldMetadataType } from 'src/engine/graphql/workspace-schema-builder/utils/get-field-metadata-type.util'; +import { getFieldMetadataType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util'; describe('getFieldMetadataType', () => { it.each([ diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts similarity index 85% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts index d5ed07f98d3a..60d569aa815b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts @@ -1,8 +1,8 @@ -import { WorkspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { InputTypeDefinitionKind } from 'src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory'; -import { getResolverArgs } from 'src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util'; +import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; +import { getResolverArgs } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util'; describe('getResolverArgs', () => { const expectedOutputs = { diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/clean-entity-name.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/clean-entity-name.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/clean-entity-name.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/clean-entity-name.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts similarity index 88% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts index 350225482791..8d1dc4537912 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts @@ -1,8 +1,8 @@ -import { WorkspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ArgMetadata } from 'src/engine/graphql/workspace-schema-builder/interfaces/param-metadata.interface'; +import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { ArgMetadata } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { InputTypeDefinitionKind } from 'src/engine/graphql/workspace-schema-builder/factories/input-type-definition.factory'; +import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; export const getResolverArgs = ( type: WorkspaceResolverBuilderMethodNames, diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts similarity index 74% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts index e529a5e944c3..b705b2bb4bb1 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts @@ -1,6 +1,6 @@ import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; export const objectContainsRelationField = ( objectMetadata: ObjectMetadataInterface, diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts similarity index 92% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts index 12e09a16ba5c..eb25eaa1d664 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLSchema } from 'graphql'; -import { WorkspaceResolverBuilderMethods } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceResolverBuilderMethods } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { TypeDefinitionsGenerator } from './type-definitions.generator'; diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-builder/workspace-schema-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts similarity index 100% rename from packages/twenty-server/src/engine/graphql/workspace-schema-builder/workspace-schema-builder.module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts similarity index 78% rename from packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.module.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts index 5370a89cbb42..a24c410f48b0 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts @@ -2,7 +2,7 @@ import { Module } from '@nestjs/common'; import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; import { WorkspaceCacheVersionModule } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.module'; -import { WorkspaceSchemaStorageService } from 'src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service'; +import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; @Module({ imports: [ObjectMetadataModule, WorkspaceCacheVersionModule], diff --git a/packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts similarity index 93% rename from packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts index dfef2ce705fb..0ab8433db156 100644 --- a/packages/twenty-server/src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; -import { CacheStorageService } from 'src/integrations/cache-storage/cache-storage.service'; -import { CacheStorageNamespace } from 'src/integrations/cache-storage/types/cache-storage-namespace.enum'; +import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service'; +import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; import { WorkspaceCacheVersionService } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.service'; diff --git a/packages/twenty-server/src/engine/graphql/workspace.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace.factory.ts similarity index 86% rename from packages/twenty-server/src/engine/graphql/workspace.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace.factory.ts index 19eaa4556aa1..2951eaf5ee9b 100644 --- a/packages/twenty-server/src/engine/graphql/workspace.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace.factory.ts @@ -5,12 +5,12 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { gql } from 'graphql-tag'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { WorkspaceSchemaStorageService } from 'src/engine/graphql/workspace-schema-storage/workspace-schema-storage.service'; +import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { ScalarsExplorerService } from 'src/engine-workspace/services/scalars-explorer.service'; -import { WorkspaceGraphQLSchemaFactory } from 'src/engine/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; -import { workspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/factories/factories'; -import { WorkspaceResolverFactory } from 'src/engine/graphql/workspace-resolver-builder/workspace-resolver.factory'; +import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; +import { WorkspaceGraphQLSchemaFactory } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; +import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/factories/factories'; +import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory'; @Injectable() export class WorkspaceFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest.controller.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.controller.utils.spec.ts similarity index 93% rename from packages/twenty-server/src/api/rest/api-rest.controller.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/__tests__/api-rest.controller.utils.spec.ts index de19dd91a99d..4655a731fcb1 100644 --- a/packages/twenty-server/src/api/rest/api-rest.controller.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.controller.utils.spec.ts @@ -1,4 +1,4 @@ -import { cleanGraphQLResponse } from 'src/api/rest/api-rest.controller.utils'; +import { cleanGraphQLResponse } from 'src/engine/api/rest/api-rest.controller.utils'; describe('cleanGraphQLResponse', () => { it('should remove edges/node from results', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest.service.spec.ts b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts similarity index 75% rename from packages/twenty-server/src/api/rest/api-rest.service.spec.ts rename to packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts index e1522b6d952e..3427d320ed0f 100644 --- a/packages/twenty-server/src/api/rest/api-rest.service.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { HttpService } from '@nestjs/axios'; -import { ApiRestService } from 'src/api/rest/api-rest.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { ApiRestService } from 'src/engine/api/rest/api-rest.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { ApiRestQueryBuilderFactory } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; +import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; describe('ApiRestService', () => { let service: ApiRestService; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts similarity index 51% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts index 7ad9de1fcc41..3ba006091928 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts @@ -1,18 +1,18 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { ApiRestQueryBuilderFactory } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; -import { DeleteQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-query.factory'; -import { CreateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/create-query.factory'; -import { UpdateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/update-query.factory'; -import { FindOneQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-one-query.factory'; -import { FindManyQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-many-query.factory'; -import { DeleteVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-variables.factory'; -import { CreateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/create-variables.factory'; -import { UpdateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/update-variables.factory'; -import { GetVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/get-variables.factory'; +import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; +import { DeleteQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory'; +import { CreateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-query.factory'; +import { UpdateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-query.factory'; +import { FindOneQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory'; +import { FindManyQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory'; +import { DeleteVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory'; +import { CreateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory'; +import { UpdateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory'; +import { GetVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; describe('ApiRestQueryBuilderFactory', () => { let service: ApiRestQueryBuilderFactory; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts similarity index 76% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts index 4dc97f7ed001..74bfe7e0908b 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts @@ -2,22 +2,22 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { Request } from 'express'; -import { DeleteQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-query.factory'; +import { DeleteQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { CreateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/create-query.factory'; -import { UpdateQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/update-query.factory'; -import { FindOneQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-one-query.factory'; -import { FindManyQueryFactory } from 'src/api/rest/api-rest-query-builder/factories/find-many-query.factory'; -import { DeleteVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/delete-variables.factory'; -import { CreateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/create-variables.factory'; -import { UpdateVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/update-variables.factory'; -import { GetVariablesFactory } from 'src/api/rest/api-rest-query-builder/factories/get-variables.factory'; -import { parsePath } from 'src/api/rest/api-rest-query-builder/utils/parse-path.utils'; -import { computeDepth } from 'src/api/rest/api-rest-query-builder/utils/compute-depth.utils'; +import { CreateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-query.factory'; +import { UpdateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-query.factory'; +import { FindOneQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory'; +import { FindManyQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory'; +import { DeleteVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory'; +import { CreateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory'; +import { UpdateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory'; +import { GetVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory'; +import { parsePath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; +import { computeDepth } from 'src/engine/api/rest/api-rest-query-builder/utils/compute-depth.utils'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { ApiRestQuery } from 'src/api/rest/types/api-rest-query.type'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class ApiRestQueryBuilderFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts similarity index 64% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts index cb86544a0e05..f647be1d6332 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; -import { ApiRestQueryBuilderFactory } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; -import { apiRestQueryBuilderFactories } from 'src/api/rest/api-rest-query-builder/factories/factories'; +import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; +import { apiRestQueryBuilderFactories } from 'src/engine/api/rest/api-rest-query-builder/factories/factories'; import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; import { AuthModule } from 'src/engine/modules/auth/auth.module'; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-query.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-query.factory.ts similarity index 84% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-query.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-query.factory.ts index 238d8365fa70..731567e162e5 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-query.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-query.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { capitalize } from 'src/utils/capitalize'; -import { mapFieldMetadataToGraphqlQuery } from 'src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; +import { mapFieldMetadataToGraphqlQuery } from 'src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; @Injectable() export class CreateQueryFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-variables.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory.ts similarity index 67% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-variables.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory.ts index b7186628e706..190d50fd9b3c 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/create-variables.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { ApiRestQueryVariables } from 'src/api/rest/types/api-rest-query-variables.type'; +import { ApiRestQueryVariables } from 'src/engine/api/rest/types/api-rest-query-variables.type'; @Injectable() export class CreateVariablesFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/delete-query.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/delete-query.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts similarity index 65% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts index c0a7a4a59a31..4cd89b779550 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { ApiRestQueryVariables } from 'src/api/rest/types/api-rest-query-variables.type'; +import { ApiRestQueryVariables } from 'src/engine/api/rest/types/api-rest-query-variables.type'; @Injectable() export class DeleteVariablesFactory { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/factories.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/factories.ts new file mode 100644 index 000000000000..a2e3951a9939 --- /dev/null +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/factories.ts @@ -0,0 +1,29 @@ +import { DeleteQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory'; +import { CreateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-query.factory'; +import { UpdateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-query.factory'; +import { FindOneQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory'; +import { FindManyQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory'; +import { DeleteVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-variables.factory'; +import { CreateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory'; +import { UpdateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory'; +import { GetVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory'; +import { LastCursorInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; +import { LimitInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; +import { OrderByInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; +import { FilterInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; + +export const apiRestQueryBuilderFactories = [ + DeleteQueryFactory, + CreateQueryFactory, + UpdateQueryFactory, + FindOneQueryFactory, + FindManyQueryFactory, + DeleteVariablesFactory, + CreateVariablesFactory, + UpdateVariablesFactory, + GetVariablesFactory, + LastCursorInputFactory, + LimitInputFactory, + OrderByInputFactory, + FilterInputFactory, +]; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts similarity index 90% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts index 83ef66dba1f8..2f5a6b36daac 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-many-query.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { capitalize } from 'src/utils/capitalize'; -import { mapFieldMetadataToGraphqlQuery } from 'src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; +import { mapFieldMetadataToGraphqlQuery } from 'src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; @Injectable() export class FindManyQueryFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts similarity index 84% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts index 47a980b148c1..0ab363e409f7 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { capitalize } from 'src/utils/capitalize'; -import { mapFieldMetadataToGraphqlQuery } from 'src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; +import { mapFieldMetadataToGraphqlQuery } from 'src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; @Injectable() export class FindOneQueryFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/get-variables.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory.ts similarity index 58% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/get-variables.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory.ts index f9078a212bc9..dfe87ce77d5a 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/get-variables.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { Request } from 'express'; -import { LastCursorInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; -import { LimitInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; -import { OrderByInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; -import { FilterInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; -import { ApiRestQueryVariables } from 'src/api/rest/types/api-rest-query-variables.type'; +import { LastCursorInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; +import { LimitInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; +import { OrderByInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; +import { FilterInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; +import { ApiRestQueryVariables } from 'src/engine/api/rest/types/api-rest-query-variables.type'; @Injectable() export class GetVariablesFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts similarity index 93% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts index dddc306b32e4..d4e9e3cf85ca 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/filter-input.factory.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; -import { FilterInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; +import { FilterInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory'; describe('FilterInputFactory', () => { - const objectMetadata = { objectMetadataItem: objectMetadataItem }; + const objectMetadata = { objectMetadataItem: objectMetadataItemMock }; let service: FilterInputFactory; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts index 9a8532ea2441..58a7f1432828 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/last-cursor-input.factory.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { LastCursorInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; +import { LastCursorInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory'; describe('LastCursorInputFactory', () => { let service: LastCursorInputFactory; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts similarity index 90% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts index e9005f52b61e..a3e0fcdf6bd9 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/limit-input.factory.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { LimitInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; +import { LimitInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory'; describe('LimitInputFactory', () => { let service: LimitInputFactory; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts similarity index 90% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts index a8446defc80b..7e09cbc73a4f 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/__tests__/order-by-input.factory.spec.ts @@ -1,12 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { OrderByDirection } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; -import { OrderByInputFactory } from 'src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; +import { OrderByInputFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; describe('OrderByInputFactory', () => { - const objectMetadata = { objectMetadataItem: objectMetadataItem }; + const objectMetadata = { objectMetadataItem: objectMetadataItemMock }; let service: OrderByInputFactory; diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts new file mode 100644 index 000000000000..be2efdfbbd5e --- /dev/null +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-input.factory.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@nestjs/common'; + +import { Request } from 'express'; + +import { addDefaultConjunctionIfMissing } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; +import { checkFilterQuery } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils'; +import { parseFilter } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; +import { FieldValue } from 'src/engine/api/rest/types/api-rest-field-value.type'; + +@Injectable() +export class FilterInputFactory { + create(request: Request, objectMetadata): Record { + let filterQuery = request.query.filter; + + if (typeof filterQuery !== 'string') { + return {}; + } + + checkFilterQuery(filterQuery); + + filterQuery = addDefaultConjunctionIfMissing(filterQuery); + + return parseFilter(filterQuery, objectMetadata.objectMetadataItem); + } +} diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts similarity index 71% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts index 683c82eb9212..90a58f59caf9 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/add-default-conjunction.utils.spec.ts @@ -1,4 +1,4 @@ -import { addDefaultConjunctionIfMissing } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; +import { addDefaultConjunctionIfMissing } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; describe('addDefaultConjunctionIfMissing', () => { it('should add default conjunction if missing', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts similarity index 86% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts index b720f77bd7a9..88d08c661ce8 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/check-filter-query.utils.spec.ts @@ -1,4 +1,4 @@ -import { checkFilterQuery } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils'; +import { checkFilterQuery } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils'; describe('checkFilterQuery', () => { it('should check filter query', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts similarity index 92% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts index 8ac0fd878e3c..f012684d762f 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts @@ -1,5 +1,5 @@ import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { formatFieldValue } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils'; +import { formatFieldValue } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils'; describe('formatFieldValue', () => { it('should format fieldNumber value', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts similarity index 90% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts index e7497231125a..d335485abbee 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-base-filter.utils.spec.ts @@ -1,4 +1,4 @@ -import { parseBaseFilter } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; +import { parseBaseFilter } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; describe('parseBaseFilter', () => { it('should parse simple filter string test 1', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts similarity index 91% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts index 9ca181b3a9cd..fc08fc400df2 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter-content.utils.spec.ts @@ -1,4 +1,4 @@ -import { parseFilterContent } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils'; +import { parseFilterContent } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils'; describe('parseFilterContent', () => { it('should parse query filter test 1', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts index 45b88a6a60c1..a5c36b91dcfb 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/parse-filter.utils.spec.ts @@ -1,12 +1,12 @@ -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; -import { parseFilter } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; +import { parseFilter } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; describe('parseFilter', () => { it('should parse string filter test 1', () => { expect( parseFilter( 'and(fieldNumber[eq]:1,fieldNumber[eq]:2)', - objectMetadataItem, + objectMetadataItemMock, ), ).toEqual({ and: [{ fieldNumber: { eq: 1 } }, { fieldNumber: { eq: 2 } }], @@ -17,7 +17,7 @@ describe('parseFilter', () => { expect( parseFilter( 'and(fieldNumber[eq]:1,or(fieldNumber[eq]:2,fieldNumber[eq]:3))', - objectMetadataItem, + objectMetadataItemMock, ), ).toEqual({ and: [ @@ -31,7 +31,7 @@ describe('parseFilter', () => { expect( parseFilter( 'and(fieldNumber[eq]:1,or(fieldNumber[eq]:2,fieldNumber[eq]:3,and(fieldNumber[eq]:6,fieldNumber[eq]:7)),or(fieldNumber[eq]:4,fieldNumber[eq]:5))', - objectMetadataItem, + objectMetadataItemMock, ), ).toEqual({ and: [ @@ -52,7 +52,7 @@ describe('parseFilter', () => { expect( parseFilter( 'and(fieldString[gt]:"val,ue",or(fieldNumber[is]:NOT_NULL,not(fieldString[startsWith]:"val"),and(fieldNumber[eq]:6,fieldString[ilike]:"%val%")),or(fieldNumber[eq]:4,fieldString[is]:NULL))', - objectMetadataItem, + objectMetadataItemMock, ), ).toEqual({ and: [ @@ -78,7 +78,7 @@ describe('parseFilter', () => { expect( parseFilter( 'and(fieldNumber[eq]:1,not(fieldNumber[eq]:2))', - objectMetadataItem, + objectMetadataItemMock, ), ).toEqual({ and: [ diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts similarity index 68% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts index 2c9599d963ee..61606bb10b4f 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils.ts @@ -1,4 +1,4 @@ -import { Conjunctions } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; +import { Conjunctions } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; export const DEFAULT_CONJUNCTION = Conjunctions.and; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/check-filter-query.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts similarity index 93% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts index 442ecd77703a..5a7c1e976df0 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts @@ -1,7 +1,7 @@ import { BadRequestException } from '@nestjs/common'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { FieldValue } from 'src/api/rest/types/api-rest-field-value.type'; +import { FieldValue } from 'src/engine/api/rest/types/api-rest-field-value.type'; export const formatFieldValue = ( value: string, diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts similarity index 71% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts index 6eb4eeb88df8..3329d2c5d800 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils.ts @@ -1,13 +1,13 @@ import { BadRequestException } from '@nestjs/common'; -import { parseFilterContent } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils'; -import { parseBaseFilter } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; +import { parseFilterContent } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter-content.utils'; +import { parseBaseFilter } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; import { checkFields, getFieldType, -} from 'src/api/rest/api-rest-query-builder/utils/fields.utils'; -import { formatFieldValue } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils'; -import { FieldValue } from 'src/api/rest/types/api-rest-field-value.type'; +} from 'src/engine/api/rest/api-rest-query-builder/utils/fields.utils'; +import { formatFieldValue } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils'; +import { FieldValue } from 'src/engine/api/rest/types/api-rest-field-value.type'; export enum Conjunctions { or = 'or', diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/last-cursor-input.factory.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/limit-input.factory.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts similarity index 91% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts index 81d604129e7b..56720b1208ff 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory.ts @@ -5,9 +5,9 @@ import { Request } from 'express'; import { OrderByDirection, RecordOrderBy, -} from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; -import { checkFields } from 'src/api/rest/api-rest-query-builder/utils/fields.utils'; +import { checkFields } from 'src/engine/api/rest/api-rest-query-builder/utils/fields.utils'; export const DEFAULT_ORDER_DIRECTION = OrderByDirection.AscNullsFirst; diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-query.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-query.factory.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-query.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-query.factory.ts index 05f964e2141f..e289c94f2284 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-query.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-query.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { capitalize } from 'src/utils/capitalize'; -import { mapFieldMetadataToGraphqlQuery } from 'src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; +import { mapFieldMetadataToGraphqlQuery } from 'src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; @Injectable() export class UpdateQueryFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-variables.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory.ts similarity index 69% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-variables.factory.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory.ts index ca38e0b948a1..2d1bca67ef5e 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/factories/update-variables.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { ApiRestQueryVariables } from 'src/api/rest/types/api-rest-query-variables.type'; +import { ApiRestQueryVariables } from 'src/engine/api/rest/types/api-rest-query-variables.type'; @Injectable() export class UpdateVariablesFactory { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts index c5bd0f4e355e..3fc57097f5ac 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/compute-depth.utils.spec.ts @@ -1,4 +1,4 @@ -import { computeDepth } from 'src/api/rest/api-rest-query-builder/utils/compute-depth.utils'; +import { computeDepth } from 'src/engine/api/rest/api-rest-query-builder/utils/compute-depth.utils'; describe('computeDepth', () => { it('should compute depth from query', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts similarity index 50% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts index 6a6049ba06cb..474a1a203b52 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts @@ -1,14 +1,14 @@ -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; import { checkFields, getFieldType, -} from 'src/api/rest/api-rest-query-builder/utils/fields.utils'; +} from 'src/engine/api/rest/api-rest-query-builder/utils/fields.utils'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; describe('FieldUtils', () => { describe('getFieldType', () => { it('should get field type', () => { - expect(getFieldType(objectMetadataItem, 'fieldNumber')).toEqual( + expect(getFieldType(objectMetadataItemMock, 'fieldNumber')).toEqual( FieldMetadataType.NUMBER, ); }); @@ -17,13 +17,13 @@ describe('FieldUtils', () => { describe('checkFields', () => { it('should check field types', () => { expect(() => - checkFields(objectMetadataItem, ['fieldNumber']), + checkFields(objectMetadataItemMock, ['fieldNumber']), ).not.toThrow(); - expect(() => checkFields(objectMetadataItem, ['wrongField'])).toThrow(); + expect(() => checkFields(objectMetadataItemMock, ['wrongField'])).toThrow(); expect(() => - checkFields(objectMetadataItem, ['fieldNumber', 'wrongField']), + checkFields(objectMetadataItemMock, ['fieldNumber', 'wrongField']), ).toThrow(); }); }); diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts new file mode 100644 index 000000000000..fea18cb63bbe --- /dev/null +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts @@ -0,0 +1,37 @@ +import { + fieldCurrencyMock, + fieldLinkMock, + fieldNumberMock, + fieldStringMock, + objectMetadataItemMock, +} from 'src/engine/api/__mocks__/object-metadata-item.mock'; +import { mapFieldMetadataToGraphqlQuery } from 'src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils'; + +describe('mapFieldMetadataToGraphqlQuery', () => { + it('should map properly', () => { + expect( + mapFieldMetadataToGraphqlQuery(objectMetadataItemMock, fieldNumberMock), + ).toEqual('fieldNumber'); + expect( + mapFieldMetadataToGraphqlQuery(objectMetadataItemMock, fieldStringMock), + ).toEqual('fieldString'); + expect( + mapFieldMetadataToGraphqlQuery(objectMetadataItemMock, fieldLinkMock), + ).toEqual(` + fieldLink + { + label + url + } + `); + expect( + mapFieldMetadataToGraphqlQuery(objectMetadataItemMock, fieldCurrencyMock), + ).toEqual(` + fieldCurrency + { + amountMicros + currencyCode + } + `); + }); +}); diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts similarity index 82% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts index 36ff6de233bc..b81a46d5d031 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/parse-path.utils.spec.ts @@ -1,4 +1,4 @@ -import { parsePath } from 'src/api/rest/api-rest-query-builder/utils/parse-path.utils'; +import { parsePath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; describe('parsePath', () => { it('should parse object from request path', () => { diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/compute-depth.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/compute-depth.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/compute-depth.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/compute-depth.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/fields.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts similarity index 90% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/fields.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts index a9aca515c3c0..13a28bb7c592 100644 --- a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/fields.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts @@ -1,7 +1,7 @@ import { BadRequestException } from '@nestjs/common'; import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export const getFieldType = ( objectMetadataItem, diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest-query-builder/utils/parse-path.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils.ts similarity index 100% rename from packages/twenty-server/src/api/rest/api-rest-query-builder/utils/parse-path.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils.ts diff --git a/packages/twenty-server/src/api/rest/api-rest.controller.ts b/packages/twenty-server/src/engine/api/rest/api-rest.controller.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest.controller.ts rename to packages/twenty-server/src/engine/api/rest/api-rest.controller.ts index ffdd9ac36106..f1eee2cc3066 100644 --- a/packages/twenty-server/src/api/rest/api-rest.controller.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.controller.ts @@ -2,8 +2,8 @@ import { Controller, Delete, Get, Post, Put, Req, Res } from '@nestjs/common'; import { Request, Response } from 'express'; -import { ApiRestService } from 'src/api/rest/api-rest.service'; -import { handleResult } from 'src/api/rest/api-rest.controller.utils'; +import { ApiRestService } from 'src/engine/api/rest/api-rest.service'; +import { handleResult } from 'src/engine/api/rest/api-rest.controller.utils'; @Controller('rest/*') export class ApiRestController { diff --git a/packages/twenty-server/src/api/rest/api-rest.controller.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest.controller.utils.ts similarity index 91% rename from packages/twenty-server/src/api/rest/api-rest.controller.utils.ts rename to packages/twenty-server/src/engine/api/rest/api-rest.controller.utils.ts index 5af175eb0ef0..a45efb8a5fd6 100644 --- a/packages/twenty-server/src/api/rest/api-rest.controller.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.controller.utils.ts @@ -1,6 +1,6 @@ import { Response } from 'express'; -import { ApiRestResponse } from 'src/api/rest/types/api-rest-response.type'; +import { ApiRestResponse } from 'src/engine/api/rest/types/api-rest-response.type'; // https://gist.github.com/ManUtopiK/469aec75b655d6a4d912aeb3b75af3c9 export const cleanGraphQLResponse = (input) => { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest.module.ts b/packages/twenty-server/src/engine/api/rest/api-rest.module.ts new file mode 100644 index 000000000000..f064ac0cfcb3 --- /dev/null +++ b/packages/twenty-server/src/engine/api/rest/api-rest.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { HttpModule } from '@nestjs/axios'; + +import { ApiRestController } from 'src/engine/api/rest/api-rest.controller'; +import { ApiRestService } from 'src/engine/api/rest/api-rest.service'; +import { ApiRestQueryBuilderModule } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module'; +import { AuthModule } from 'src/engine/modules/auth/auth.module'; +import { ApiRestMetadataController } from 'src/engine/api/rest/metadata-rest.controller'; +import { ApiRestMetadataService } from 'src/engine/api/rest/metadata-rest.service'; + +@Module({ + imports: [ApiRestQueryBuilderModule, AuthModule, HttpModule], + controllers: [ApiRestMetadataController, ApiRestController], + providers: [ApiRestMetadataService, ApiRestService], + exports: [ApiRestMetadataService], +}) +export class ApiRestModule {} diff --git a/packages/twenty-server/src/api/rest/api-rest.service.ts b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts similarity index 85% rename from packages/twenty-server/src/api/rest/api-rest.service.ts rename to packages/twenty-server/src/engine/api/rest/api-rest.service.ts index 867c8c231b12..f5306b55ec1b 100644 --- a/packages/twenty-server/src/api/rest/api-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts @@ -3,11 +3,11 @@ import { HttpService } from '@nestjs/axios'; import { Request } from 'express'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { ApiRestQueryBuilderFactory } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { ApiRestResponse } from 'src/api/rest/types/api-rest-response.type'; -import { ApiRestQuery } from 'src/api/rest/types/api-rest-query.type'; +import { ApiRestResponse } from 'src/engine/api/rest/types/api-rest-response.type'; +import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; @Injectable() export class ApiRestService { diff --git a/packages/twenty-server/src/api/rest/metadata-rest.controller.ts b/packages/twenty-server/src/engine/api/rest/metadata-rest.controller.ts similarity index 84% rename from packages/twenty-server/src/api/rest/metadata-rest.controller.ts rename to packages/twenty-server/src/engine/api/rest/metadata-rest.controller.ts index d6d1f6b02c14..ea9728b86fc6 100644 --- a/packages/twenty-server/src/api/rest/metadata-rest.controller.ts +++ b/packages/twenty-server/src/engine/api/rest/metadata-rest.controller.ts @@ -2,8 +2,8 @@ import { Controller, Get, Delete, Post, Put, Req, Res } from '@nestjs/common'; import { Request, Response } from 'express'; -import { handleResult } from 'src/api/rest/api-rest.controller.utils'; -import { ApiRestMetadataService } from 'src/api/rest/metadata-rest.service'; +import { handleResult } from 'src/engine/api/rest/api-rest.controller.utils'; +import { ApiRestMetadataService } from 'src/engine/api/rest/metadata-rest.service'; @Controller('rest/metadata/*') export class ApiRestMetadataController { diff --git a/packages/twenty-server/src/api/rest/metadata-rest.service.ts b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts similarity index 95% rename from packages/twenty-server/src/api/rest/metadata-rest.service.ts rename to packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts index 2f83b08b2c73..4b460236d5be 100644 --- a/packages/twenty-server/src/api/rest/metadata-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts @@ -1,11 +1,11 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { ApiRestQueryBuilderFactory } from 'src/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; -import { ApiRestQuery } from 'src/api/rest/types/api-rest-query.type'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; +import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { parseMetadataPath } from 'src/api/rest/api-rest-query-builder/utils/parse-path.utils'; +import { parseMetadataPath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; import { capitalize } from 'src/utils/capitalize'; @Injectable() diff --git a/packages/twenty-server/src/api/rest/types/api-rest-field-value.type.ts b/packages/twenty-server/src/engine/api/rest/types/api-rest-field-value.type.ts similarity index 100% rename from packages/twenty-server/src/api/rest/types/api-rest-field-value.type.ts rename to packages/twenty-server/src/engine/api/rest/types/api-rest-field-value.type.ts diff --git a/packages/twenty-server/src/api/rest/types/api-rest-query-variables.type.ts b/packages/twenty-server/src/engine/api/rest/types/api-rest-query-variables.type.ts similarity index 100% rename from packages/twenty-server/src/api/rest/types/api-rest-query-variables.type.ts rename to packages/twenty-server/src/engine/api/rest/types/api-rest-query-variables.type.ts diff --git a/packages/twenty-server/src/api/rest/types/api-rest-query.type.ts b/packages/twenty-server/src/engine/api/rest/types/api-rest-query.type.ts similarity index 100% rename from packages/twenty-server/src/api/rest/types/api-rest-query.type.ts rename to packages/twenty-server/src/engine/api/rest/types/api-rest-query.type.ts diff --git a/packages/twenty-server/src/api/rest/types/api-rest-response.type.ts b/packages/twenty-server/src/engine/api/rest/types/api-rest-response.type.ts similarity index 100% rename from packages/twenty-server/src/api/rest/types/api-rest-response.type.ts rename to packages/twenty-server/src/engine/api/rest/types/api-rest-response.type.ts diff --git a/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts b/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts index 51739c32c109..cae610a89c34 100644 --- a/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts +++ b/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts @@ -1,6 +1,6 @@ import { HttpException } from '@nestjs/common'; -import { ExceptionHandlerUser } from 'src/integrations/exception-handler/interfaces/exception-handler-user.interface'; +import { ExceptionHandlerUser } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-user.interface'; import { AuthenticationError, @@ -10,7 +10,7 @@ import { NotFoundError, ConflictError, } from 'src/engine/filters/utils/graphql-errors.util'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; const graphQLPredefinedExceptions = { 400: ValidationError, diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils-test/workspace-query-builder-options.ts b/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils-test/workspace-query-builder-options.ts deleted file mode 100644 index b57b755db285..000000000000 --- a/packages/twenty-server/src/engine/graphql/workspace-query-builder/utils-test/workspace-query-builder-options.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GraphQLResolveInfo } from 'graphql'; - -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { WorkspaceQueryBuilderOptions } from 'src/engine/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; - -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; - -export const workspaceQueryBuilderOptions: WorkspaceQueryBuilderOptions = { - fieldMetadataCollection: [], - info: {} as GraphQLResolveInfo, - objectMetadataCollection: [], - objectMetadataItem: objectMetadataItem as ObjectMetadataInterface, -}; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts b/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts deleted file mode 100644 index b3adbf44acab..000000000000 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { MessageFindManyPreQueryHook } from 'src/business/modules/message/query-hooks/message/message-find-many.pre-query.hook'; -import { MessageFindOnePreQueryHook } from 'src/business/modules/message/query-hooks/message/message-find-one.pre-query-hook'; -import { WorkspaceQueryHook } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type'; - -// TODO: move to a decorator -export const workspacePreQueryHooks: WorkspaceQueryHook = { - message: { - findOne: [MessageFindOnePreQueryHook.name], - findMany: [MessageFindManyPreQueryHook.name], - }, -}; diff --git a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts b/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts deleted file mode 100644 index a62b0781291e..000000000000 --- a/packages/twenty-server/src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { MessagingQueryHookModule } from 'src/business/modules/message/query-hooks/messaging-query-hook.module'; -import { WorkspacePreQueryHookService } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service'; - -@Module({ - imports: [MessagingQueryHookModule], - providers: [WorkspacePreQueryHookService], - exports: [WorkspacePreQueryHookService], -}) -export class WorkspacePreQueryHookModule {} diff --git a/packages/twenty-server/src/integrations/cache-storage/__tests__/cache-storage.service.spec.ts b/packages/twenty-server/src/engine/integrations/cache-storage/__tests__/cache-storage.service.spec.ts similarity index 90% rename from packages/twenty-server/src/integrations/cache-storage/__tests__/cache-storage.service.spec.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/__tests__/cache-storage.service.spec.ts index c68233c5fade..d8ee9c8a58c7 100644 --- a/packages/twenty-server/src/integrations/cache-storage/__tests__/cache-storage.service.spec.ts +++ b/packages/twenty-server/src/engine/integrations/cache-storage/__tests__/cache-storage.service.spec.ts @@ -1,7 +1,7 @@ import { Cache } from '@nestjs/cache-manager'; -import { CacheStorageService } from 'src/integrations/cache-storage/cache-storage.service'; -import { CacheStorageNamespace } from 'src/integrations/cache-storage/types/cache-storage-namespace.enum'; +import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service'; +import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum'; const cacheStorageNamespace = CacheStorageNamespace.Messaging; diff --git a/packages/twenty-server/src/integrations/cache-storage/cache-storage.module-factory.ts b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module-factory.ts similarity index 85% rename from packages/twenty-server/src/integrations/cache-storage/cache-storage.module-factory.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module-factory.ts index b6957c808da8..79dedaf6bdc4 100644 --- a/packages/twenty-server/src/integrations/cache-storage/cache-storage.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module-factory.ts @@ -2,8 +2,8 @@ import { CacheModuleOptions } from '@nestjs/common'; import { redisStore } from 'cache-manager-redis-yet'; -import { CacheStorageType } from 'src/integrations/cache-storage/types/cache-storage-type.enum'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { CacheStorageType } from 'src/engine/integrations/cache-storage/types/cache-storage-type.enum'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; export const cacheStorageModuleFactory = ( environmentService: EnvironmentService, diff --git a/packages/twenty-server/src/integrations/cache-storage/cache-storage.module.ts b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module.ts similarity index 65% rename from packages/twenty-server/src/integrations/cache-storage/cache-storage.module.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module.ts index 32c31e7615c6..581919555d96 100644 --- a/packages/twenty-server/src/integrations/cache-storage/cache-storage.module.ts +++ b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.module.ts @@ -2,10 +2,10 @@ import { Module, Global } from '@nestjs/common'; import { CacheModule, CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; import { ConfigModule } from '@nestjs/config'; -import { CacheStorageService } from 'src/integrations/cache-storage/cache-storage.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { cacheStorageModuleFactory } from 'src/integrations/cache-storage/cache-storage.module-factory'; -import { CacheStorageNamespace } from 'src/integrations/cache-storage/types/cache-storage-namespace.enum'; +import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { cacheStorageModuleFactory } from 'src/engine/integrations/cache-storage/cache-storage.module-factory'; +import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum'; @Global() @Module({ diff --git a/packages/twenty-server/src/integrations/cache-storage/cache-storage.service.ts b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.service.ts similarity index 85% rename from packages/twenty-server/src/integrations/cache-storage/cache-storage.service.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.service.ts index fdc44ff1ff4f..e0b6fba9af0e 100644 --- a/packages/twenty-server/src/integrations/cache-storage/cache-storage.service.ts +++ b/packages/twenty-server/src/engine/integrations/cache-storage/cache-storage.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; -import { CacheStorageNamespace } from 'src/integrations/cache-storage/types/cache-storage-namespace.enum'; +import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum'; @Injectable() export class CacheStorageService { diff --git a/packages/twenty-server/src/integrations/cache-storage/types/cache-storage-namespace.enum.ts b/packages/twenty-server/src/engine/integrations/cache-storage/types/cache-storage-namespace.enum.ts similarity index 100% rename from packages/twenty-server/src/integrations/cache-storage/types/cache-storage-namespace.enum.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/types/cache-storage-namespace.enum.ts diff --git a/packages/twenty-server/src/integrations/cache-storage/types/cache-storage-type.enum.ts b/packages/twenty-server/src/engine/integrations/cache-storage/types/cache-storage-type.enum.ts similarity index 100% rename from packages/twenty-server/src/integrations/cache-storage/types/cache-storage-type.enum.ts rename to packages/twenty-server/src/engine/integrations/cache-storage/types/cache-storage-type.enum.ts diff --git a/packages/twenty-server/src/integrations/email/drivers/interfaces/email-driver.interface.ts b/packages/twenty-server/src/engine/integrations/email/drivers/interfaces/email-driver.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/email/drivers/interfaces/email-driver.interface.ts rename to packages/twenty-server/src/engine/integrations/email/drivers/interfaces/email-driver.interface.ts diff --git a/packages/twenty-server/src/integrations/email/drivers/logger.driver.ts b/packages/twenty-server/src/engine/integrations/email/drivers/logger.driver.ts similarity index 84% rename from packages/twenty-server/src/integrations/email/drivers/logger.driver.ts rename to packages/twenty-server/src/engine/integrations/email/drivers/logger.driver.ts index 90ca586b91dc..a3138de0bd36 100644 --- a/packages/twenty-server/src/integrations/email/drivers/logger.driver.ts +++ b/packages/twenty-server/src/engine/integrations/email/drivers/logger.driver.ts @@ -2,7 +2,7 @@ import { Logger } from '@nestjs/common'; import { SendMailOptions } from 'nodemailer'; -import { EmailDriver } from 'src/integrations/email/drivers/interfaces/email-driver.interface'; +import { EmailDriver } from 'src/engine/integrations/email/drivers/interfaces/email-driver.interface'; export class LoggerDriver implements EmailDriver { private readonly logger = new Logger(LoggerDriver.name); diff --git a/packages/twenty-server/src/integrations/email/drivers/smtp.driver.ts b/packages/twenty-server/src/engine/integrations/email/drivers/smtp.driver.ts similarity index 88% rename from packages/twenty-server/src/integrations/email/drivers/smtp.driver.ts rename to packages/twenty-server/src/engine/integrations/email/drivers/smtp.driver.ts index c4dfd77fb054..94445854ec06 100644 --- a/packages/twenty-server/src/integrations/email/drivers/smtp.driver.ts +++ b/packages/twenty-server/src/engine/integrations/email/drivers/smtp.driver.ts @@ -3,7 +3,7 @@ import { Logger } from '@nestjs/common'; import { createTransport, Transporter, SendMailOptions } from 'nodemailer'; import SMTPConnection from 'nodemailer/lib/smtp-connection'; -import { EmailDriver } from 'src/integrations/email/drivers/interfaces/email-driver.interface'; +import { EmailDriver } from 'src/engine/integrations/email/drivers/interfaces/email-driver.interface'; export class SmtpDriver implements EmailDriver { private readonly logger = new Logger(SmtpDriver.name); diff --git a/packages/twenty-server/src/integrations/email/email-sender.job.ts b/packages/twenty-server/src/engine/integrations/email/email-sender.job.ts similarity index 64% rename from packages/twenty-server/src/integrations/email/email-sender.job.ts rename to packages/twenty-server/src/engine/integrations/email/email-sender.job.ts index 1162f4ca0646..7b284d4b26c3 100644 --- a/packages/twenty-server/src/integrations/email/email-sender.job.ts +++ b/packages/twenty-server/src/engine/integrations/email/email-sender.job.ts @@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common'; import { SendMailOptions } from 'nodemailer'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { EmailSenderService } from 'src/integrations/email/email-sender.service'; +import { EmailSenderService } from 'src/engine/integrations/email/email-sender.service'; @Injectable() export class EmailSenderJob implements MessageQueueJob { diff --git a/packages/twenty-server/src/integrations/email/email-sender.service.ts b/packages/twenty-server/src/engine/integrations/email/email-sender.service.ts similarity index 66% rename from packages/twenty-server/src/integrations/email/email-sender.service.ts rename to packages/twenty-server/src/engine/integrations/email/email-sender.service.ts index 58b6c4a9c183..96ec2196f03d 100644 --- a/packages/twenty-server/src/integrations/email/email-sender.service.ts +++ b/packages/twenty-server/src/engine/integrations/email/email-sender.service.ts @@ -2,9 +2,9 @@ import { Inject, Injectable } from '@nestjs/common'; import { SendMailOptions } from 'nodemailer'; -import { EmailDriver } from 'src/integrations/email/drivers/interfaces/email-driver.interface'; +import { EmailDriver } from 'src/engine/integrations/email/drivers/interfaces/email-driver.interface'; -import { EMAIL_DRIVER } from 'src/integrations/email/email.constants'; +import { EMAIL_DRIVER } from 'src/engine/integrations/email/email.constants'; @Injectable() export class EmailSenderService implements EmailDriver { diff --git a/packages/twenty-server/src/integrations/email/email.constants.ts b/packages/twenty-server/src/engine/integrations/email/email.constants.ts similarity index 100% rename from packages/twenty-server/src/integrations/email/email.constants.ts rename to packages/twenty-server/src/engine/integrations/email/email.constants.ts diff --git a/packages/twenty-server/src/integrations/email/email.module-factory.ts b/packages/twenty-server/src/engine/integrations/email/email.module-factory.ts similarity index 86% rename from packages/twenty-server/src/integrations/email/email.module-factory.ts rename to packages/twenty-server/src/engine/integrations/email/email.module-factory.ts index 6b9a52d1ad1a..870f30db2fab 100644 --- a/packages/twenty-server/src/integrations/email/email.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/email/email.module-factory.ts @@ -1,9 +1,9 @@ import { EmailDriver, EmailModuleOptions, -} from 'src/integrations/email/interfaces/email.interface'; +} from 'src/engine/integrations/email/interfaces/email.interface'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; export const emailModuleFactory = ( environmentService: EnvironmentService, diff --git a/packages/twenty-server/src/integrations/email/email.module.ts b/packages/twenty-server/src/engine/integrations/email/email.module.ts similarity index 54% rename from packages/twenty-server/src/integrations/email/email.module.ts rename to packages/twenty-server/src/engine/integrations/email/email.module.ts index d18fa71fdbc9..f97c246ab664 100644 --- a/packages/twenty-server/src/integrations/email/email.module.ts +++ b/packages/twenty-server/src/engine/integrations/email/email.module.ts @@ -1,12 +1,12 @@ import { DynamicModule, Global } from '@nestjs/common'; -import { EmailModuleAsyncOptions } from 'src/integrations/email/interfaces/email.interface'; +import { EmailModuleAsyncOptions } from 'src/engine/integrations/email/interfaces/email.interface'; -import { EMAIL_DRIVER } from 'src/integrations/email/email.constants'; -import { LoggerDriver } from 'src/integrations/email/drivers/logger.driver'; -import { SmtpDriver } from 'src/integrations/email/drivers/smtp.driver'; -import { EmailService } from 'src/integrations/email/email.service'; -import { EmailSenderService } from 'src/integrations/email/email-sender.service'; +import { EMAIL_DRIVER } from 'src/engine/integrations/email/email.constants'; +import { LoggerDriver } from 'src/engine/integrations/email/drivers/logger.driver'; +import { SmtpDriver } from 'src/engine/integrations/email/drivers/smtp.driver'; +import { EmailService } from 'src/engine/integrations/email/email.service'; +import { EmailSenderService } from 'src/engine/integrations/email/email-sender.service'; @Global() export class EmailModule { diff --git a/packages/twenty-server/src/integrations/email/email.service.ts b/packages/twenty-server/src/engine/integrations/email/email.service.ts similarity index 62% rename from packages/twenty-server/src/integrations/email/email.service.ts rename to packages/twenty-server/src/engine/integrations/email/email.service.ts index 8963ce74d9c6..a149c78023b2 100644 --- a/packages/twenty-server/src/integrations/email/email.service.ts +++ b/packages/twenty-server/src/engine/integrations/email/email.service.ts @@ -2,9 +2,9 @@ import { Inject, Injectable } from '@nestjs/common'; import { SendMailOptions } from 'nodemailer'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { EmailSenderJob } from 'src/integrations/email/email-sender.job'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { EmailSenderJob } from 'src/engine/integrations/email/email-sender.job'; @Injectable() export class EmailService { diff --git a/packages/twenty-server/src/integrations/email/interfaces/email.interface.ts b/packages/twenty-server/src/engine/integrations/email/interfaces/email.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/email/interfaces/email.interface.ts rename to packages/twenty-server/src/engine/integrations/email/interfaces/email.interface.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts similarity index 94% rename from packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts index 26ba667e4e92..43447e2de1e8 100644 --- a/packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts +++ b/packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts @@ -1,6 +1,6 @@ import { plainToClass } from 'class-transformer'; -import { CastToLogLevelArray } from 'src/integrations/environment/decorators/cast-to-log-level-array.decorator'; +import { CastToLogLevelArray } from 'src/engine/integrations/environment/decorators/cast-to-log-level-array.decorator'; class TestClass { @CastToLogLevelArray() diff --git a/packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts similarity index 92% rename from packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts index b829404936ed..f3f77fb4c333 100644 --- a/packages/twenty-server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts +++ b/packages/twenty-server/src/engine/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts @@ -1,6 +1,6 @@ import { plainToClass } from 'class-transformer'; -import { CastToPositiveNumber } from 'src/integrations/environment/decorators/cast-to-positive-number.decorator'; +import { CastToPositiveNumber } from 'src/engine/integrations/environment/decorators/cast-to-positive-number.decorator'; class TestClass { @CastToPositiveNumber() diff --git a/packages/twenty-server/src/integrations/environment/decorators/cast-to-boolean.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-boolean.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/cast-to-boolean.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-boolean.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/cast-to-log-level-array.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-log-level-array.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/cast-to-log-level-array.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-log-level-array.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-positive-number.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-positive-number.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/cast-to-string-array.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-string-array.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/cast-to-string-array.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/cast-to-string-array.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/is-aws-region.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/is-aws-region.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/is-aws-region.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/is-aws-region.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/is-duration.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/is-duration.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/is-duration.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/is-duration.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/decorators/is-strictly-lower-than.decorator.ts b/packages/twenty-server/src/engine/integrations/environment/decorators/is-strictly-lower-than.decorator.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/decorators/is-strictly-lower-than.decorator.ts rename to packages/twenty-server/src/engine/integrations/environment/decorators/is-strictly-lower-than.decorator.ts diff --git a/packages/twenty-server/src/integrations/environment/environment-variables.ts b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts similarity index 91% rename from packages/twenty-server/src/integrations/environment/environment-variables.ts rename to packages/twenty-server/src/engine/integrations/environment/environment-variables.ts index 7aad5e72210c..62cc97c896a9 100644 --- a/packages/twenty-server/src/integrations/environment/environment-variables.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts @@ -13,14 +13,14 @@ import { IsDefined, } from 'class-validator'; -import { EmailDriver } from 'src/integrations/email/interfaces/email.interface'; +import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; import { assert } from 'src/utils/assert'; -import { CastToStringArray } from 'src/integrations/environment/decorators/cast-to-string-array.decorator'; -import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; -import { StorageDriverType } from 'src/integrations/file-storage/interfaces'; -import { LoggerDriverType } from 'src/integrations/logger/interfaces'; -import { IsStrictlyLowerThan } from 'src/integrations/environment/decorators/is-strictly-lower-than.decorator'; +import { CastToStringArray } from 'src/engine/integrations/environment/decorators/cast-to-string-array.decorator'; +import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; +import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; +import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; +import { IsStrictlyLowerThan } from 'src/engine/integrations/environment/decorators/is-strictly-lower-than.decorator'; import { IsDuration } from './decorators/is-duration.decorator'; import { AwsRegion } from './interfaces/aws-region.interface'; diff --git a/packages/twenty-server/src/integrations/environment/environment.default.ts b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts similarity index 84% rename from packages/twenty-server/src/integrations/environment/environment.default.ts rename to packages/twenty-server/src/engine/integrations/environment/environment.default.ts index 18dea0084209..9c724584d2b5 100644 --- a/packages/twenty-server/src/integrations/environment/environment.default.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts @@ -1,11 +1,11 @@ -import { EmailDriver } from 'src/integrations/email/interfaces/email.interface'; -import { SupportDriver } from 'src/integrations/environment/interfaces/support.interface'; +import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; +import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; -import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; -import { StorageDriverType } from 'src/integrations/file-storage/interfaces'; -import { LoggerDriverType } from 'src/integrations/logger/interfaces'; -import { MessageQueueDriverType } from 'src/integrations/message-queue/interfaces'; -import { EnvironmentVariables } from 'src/integrations/environment/environment-variables'; +import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; +import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; +import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; +import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; +import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; const EnvironmentDefault = new EnvironmentVariables(); diff --git a/packages/twenty-server/src/integrations/environment/environment.module-definition.ts b/packages/twenty-server/src/engine/integrations/environment/environment.module-definition.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/environment.module-definition.ts rename to packages/twenty-server/src/engine/integrations/environment/environment.module-definition.ts diff --git a/packages/twenty-server/src/integrations/environment/environment.module.ts b/packages/twenty-server/src/engine/integrations/environment/environment.module.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/environment.module.ts rename to packages/twenty-server/src/engine/integrations/environment/environment.module.ts diff --git a/packages/twenty-server/src/integrations/environment/environment.service.spec.ts b/packages/twenty-server/src/engine/integrations/environment/environment.service.spec.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/environment.service.spec.ts rename to packages/twenty-server/src/engine/integrations/environment/environment.service.spec.ts diff --git a/packages/twenty-server/src/integrations/environment/environment.service.ts b/packages/twenty-server/src/engine/integrations/environment/environment.service.ts similarity index 86% rename from packages/twenty-server/src/integrations/environment/environment.service.ts rename to packages/twenty-server/src/engine/integrations/environment/environment.service.ts index 2dc8d48c7688..275671a054af 100644 --- a/packages/twenty-server/src/integrations/environment/environment.service.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment.service.ts @@ -4,8 +4,8 @@ import { ConfigService } from '@nestjs/config'; import { Request } from 'express'; -import { EnvironmentVariables } from 'src/integrations/environment/environment-variables'; -import { EnvironmentDefault } from 'src/integrations/environment/environment.default'; +import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; +import { EnvironmentDefault } from 'src/engine/integrations/environment/environment.default'; @Injectable() export class EnvironmentService { diff --git a/packages/twenty-server/src/integrations/environment/interfaces/aws-region.interface.ts b/packages/twenty-server/src/engine/integrations/environment/interfaces/aws-region.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/interfaces/aws-region.interface.ts rename to packages/twenty-server/src/engine/integrations/environment/interfaces/aws-region.interface.ts diff --git a/packages/twenty-server/src/integrations/environment/interfaces/support.interface.ts b/packages/twenty-server/src/engine/integrations/environment/interfaces/support.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/environment/interfaces/support.interface.ts rename to packages/twenty-server/src/engine/integrations/environment/interfaces/support.interface.ts diff --git a/packages/twenty-server/src/integrations/event-emitter/types/object-record-create.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts similarity index 100% rename from packages/twenty-server/src/integrations/event-emitter/types/object-record-create.event.ts rename to packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts diff --git a/packages/twenty-server/src/integrations/event-emitter/types/object-record-delete.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts similarity index 100% rename from packages/twenty-server/src/integrations/event-emitter/types/object-record-delete.event.ts rename to packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts diff --git a/packages/twenty-server/src/integrations/event-emitter/types/object-record-update.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts similarity index 100% rename from packages/twenty-server/src/integrations/event-emitter/types/object-record-update.event.ts rename to packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts diff --git a/packages/twenty-server/src/integrations/event-emitter/utils/object-record-changed-properties.util.ts b/packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-properties.util.ts similarity index 100% rename from packages/twenty-server/src/integrations/event-emitter/utils/object-record-changed-properties.util.ts rename to packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-properties.util.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.service.spec.ts b/packages/twenty-server/src/engine/integrations/exception-handler/__tests__/exception-handler.service.spec.ts similarity index 71% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.service.spec.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/__tests__/exception-handler.service.spec.ts index f9d1e19b9691..bae07ba64875 100644 --- a/packages/twenty-server/src/integrations/exception-handler/exception-handler.service.spec.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/__tests__/exception-handler.service.spec.ts @@ -1,8 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; - -import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants'; +import { EXCEPTION_HANDLER_DRIVER } from 'src/engine/integrations/exception-handler/exception-handler.constants'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; describe('ExceptionHandlerService', () => { let service: ExceptionHandlerService; diff --git a/packages/twenty-server/src/integrations/exception-handler/drivers/console.driver.ts b/packages/twenty-server/src/engine/integrations/exception-handler/drivers/console.driver.ts similarity index 59% rename from packages/twenty-server/src/integrations/exception-handler/drivers/console.driver.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/drivers/console.driver.ts index cd38ef827a07..9f60db644eb0 100644 --- a/packages/twenty-server/src/integrations/exception-handler/drivers/console.driver.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/drivers/console.driver.ts @@ -1,7 +1,7 @@ -import { ExceptionHandlerUser } from 'src/integrations/exception-handler/interfaces/exception-handler-user.interface'; -import { ExceptionHandlerOptions } from 'src/integrations/exception-handler/interfaces/exception-handler-options.interface'; +import { ExceptionHandlerUser } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-user.interface'; +import { ExceptionHandlerOptions } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-options.interface'; -import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces'; +import { ExceptionHandlerDriverInterface } from 'src/engine/integrations/exception-handler/interfaces'; export class ExceptionHandlerConsoleDriver implements ExceptionHandlerDriverInterface diff --git a/packages/twenty-server/src/integrations/exception-handler/drivers/sentry.driver.ts b/packages/twenty-server/src/engine/integrations/exception-handler/drivers/sentry.driver.ts similarity index 90% rename from packages/twenty-server/src/integrations/exception-handler/drivers/sentry.driver.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/drivers/sentry.driver.ts index 81a5fb434871..fb8e1e2d6cfa 100644 --- a/packages/twenty-server/src/integrations/exception-handler/drivers/sentry.driver.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/drivers/sentry.driver.ts @@ -1,13 +1,13 @@ import * as Sentry from '@sentry/node'; import { ProfilingIntegration } from '@sentry/profiling-node'; -import { ExceptionHandlerUser } from 'src/integrations/exception-handler/interfaces/exception-handler-user.interface'; -import { ExceptionHandlerOptions } from 'src/integrations/exception-handler/interfaces/exception-handler-options.interface'; +import { ExceptionHandlerUser } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-user.interface'; +import { ExceptionHandlerOptions } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-options.interface'; import { ExceptionHandlerDriverInterface, ExceptionHandlerSentryDriverFactoryOptions, -} from 'src/integrations/exception-handler/interfaces'; +} from 'src/engine/integrations/exception-handler/interfaces'; export class ExceptionHandlerSentryDriver implements ExceptionHandlerDriverInterface diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.constants.ts b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.constants.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.constants.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.constants.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.module-definition.ts b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module-definition.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.module-definition.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module-definition.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.module-factory.ts b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module-factory.ts similarity index 77% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.module-factory.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module-factory.ts index 0b08aebd303f..70a4f4546dcb 100644 --- a/packages/twenty-server/src/integrations/exception-handler/exception-handler.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module-factory.ts @@ -1,8 +1,8 @@ import { HttpAdapterHost } from '@nestjs/core'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { OPTIONS_TYPE } from 'src/integrations/exception-handler/exception-handler.module-definition'; -import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { OPTIONS_TYPE } from 'src/engine/integrations/exception-handler/exception-handler.module-definition'; +import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; /** * ExceptionHandler Module factory diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.module.ts b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module.ts similarity index 88% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.module.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module.ts index e1221bcd2cb0..8c4ae87a8312 100644 --- a/packages/twenty-server/src/integrations/exception-handler/exception-handler.module.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.module.ts @@ -1,7 +1,7 @@ import { DynamicModule, Global, Module } from '@nestjs/common'; -import { ExceptionHandlerSentryDriver } from 'src/integrations/exception-handler/drivers/sentry.driver'; -import { ExceptionHandlerConsoleDriver } from 'src/integrations/exception-handler/drivers/console.driver'; +import { ExceptionHandlerSentryDriver } from 'src/engine/integrations/exception-handler/drivers/sentry.driver'; +import { ExceptionHandlerConsoleDriver } from 'src/engine/integrations/exception-handler/drivers/console.driver'; import { ExceptionHandlerService } from './exception-handler.service'; import { ExceptionHandlerDriver } from './interfaces'; diff --git a/packages/twenty-server/src/integrations/exception-handler/exception-handler.service.ts b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.service.ts similarity index 53% rename from packages/twenty-server/src/integrations/exception-handler/exception-handler.service.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.service.ts index 3dc02cad8284..ac46ae3465de 100644 --- a/packages/twenty-server/src/integrations/exception-handler/exception-handler.service.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/exception-handler.service.ts @@ -1,9 +1,9 @@ import { Inject, Injectable } from '@nestjs/common'; -import { ExceptionHandlerOptions } from 'src/integrations/exception-handler/interfaces/exception-handler-options.interface'; +import { ExceptionHandlerOptions } from 'src/engine/integrations/exception-handler/interfaces/exception-handler-options.interface'; -import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces'; -import { EXCEPTION_HANDLER_DRIVER } from 'src/integrations/exception-handler/exception-handler.constants'; +import { ExceptionHandlerDriverInterface } from 'src/engine/integrations/exception-handler/interfaces'; +import { EXCEPTION_HANDLER_DRIVER } from 'src/engine/integrations/exception-handler/exception-handler.constants'; @Injectable() export class ExceptionHandlerService { diff --git a/packages/twenty-server/src/integrations/exception-handler/hooks/use-exception-handler.hook.ts b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts similarity index 97% rename from packages/twenty-server/src/integrations/exception-handler/hooks/use-exception-handler.hook.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts index 0ab641fec56e..76212bacacdf 100644 --- a/packages/twenty-server/src/integrations/exception-handler/hooks/use-exception-handler.hook.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts @@ -8,7 +8,7 @@ import { import { GraphQLContext } from 'src/engine-graphql-config/interfaces/graphql-context.interface'; -import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { convertExceptionToGraphQLError, filterException, diff --git a/packages/twenty-server/src/integrations/tracing/useSentryTracing.ts b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts similarity index 100% rename from packages/twenty-server/src/integrations/tracing/useSentryTracing.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts b/packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-options.interface.ts b/packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-options.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-options.interface.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-options.interface.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-user.interface.ts b/packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-user.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler-user.interface.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler-user.interface.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts b/packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/interfaces/exception-handler.interface.ts diff --git a/packages/twenty-server/src/integrations/exception-handler/interfaces/index.ts b/packages/twenty-server/src/engine/integrations/exception-handler/interfaces/index.ts similarity index 100% rename from packages/twenty-server/src/integrations/exception-handler/interfaces/index.ts rename to packages/twenty-server/src/engine/integrations/exception-handler/interfaces/index.ts diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.service.spec.ts b/packages/twenty-server/src/engine/integrations/file-storage/__tests__/file-storage.service.spec.ts similarity index 73% rename from packages/twenty-server/src/integrations/file-storage/file-storage.service.spec.ts rename to packages/twenty-server/src/engine/integrations/file-storage/__tests__/file-storage.service.spec.ts index cc30e564b2f0..4ef268cf6ca5 100644 --- a/packages/twenty-server/src/integrations/file-storage/file-storage.service.spec.ts +++ b/packages/twenty-server/src/engine/integrations/file-storage/__tests__/file-storage.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { FileStorageService } from './file-storage.service'; -import { STORAGE_DRIVER } from './file-storage.constants'; +import { STORAGE_DRIVER } from 'src/engine/integrations/file-storage/file-storage.constants'; +import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; describe('FileStorageService', () => { let service: FileStorageService; diff --git a/packages/twenty-server/src/integrations/file-storage/drivers/interfaces/storage-driver.interface.ts b/packages/twenty-server/src/engine/integrations/file-storage/drivers/interfaces/storage-driver.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/drivers/interfaces/storage-driver.interface.ts rename to packages/twenty-server/src/engine/integrations/file-storage/drivers/interfaces/storage-driver.interface.ts diff --git a/packages/twenty-server/src/integrations/file-storage/drivers/local.driver.ts b/packages/twenty-server/src/engine/integrations/file-storage/drivers/local.driver.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/drivers/local.driver.ts rename to packages/twenty-server/src/engine/integrations/file-storage/drivers/local.driver.ts diff --git a/packages/twenty-server/src/integrations/file-storage/drivers/s3.driver.ts b/packages/twenty-server/src/engine/integrations/file-storage/drivers/s3.driver.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/drivers/s3.driver.ts rename to packages/twenty-server/src/engine/integrations/file-storage/drivers/s3.driver.ts diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.constants.ts b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.constants.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/file-storage.constants.ts rename to packages/twenty-server/src/engine/integrations/file-storage/file-storage.constants.ts diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.module-definition.ts b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.module-definition.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/file-storage.module-definition.ts rename to packages/twenty-server/src/engine/integrations/file-storage/file-storage.module-definition.ts diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.module-factory.ts b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.module-factory.ts similarity index 90% rename from packages/twenty-server/src/integrations/file-storage/file-storage.module-factory.ts rename to packages/twenty-server/src/engine/integrations/file-storage/file-storage.module-factory.ts index 22c1ee1af60e..fc625ce89ee2 100644 --- a/packages/twenty-server/src/integrations/file-storage/file-storage.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.module-factory.ts @@ -1,10 +1,10 @@ import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { FileStorageModuleOptions, StorageDriverType, -} from 'src/integrations/file-storage/interfaces'; +} from 'src/engine/integrations/file-storage/interfaces'; /** * FileStorage Module factory diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.module.ts b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.module.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/file-storage.module.ts rename to packages/twenty-server/src/engine/integrations/file-storage/file-storage.module.ts diff --git a/packages/twenty-server/src/integrations/file-storage/file-storage.service.ts b/packages/twenty-server/src/engine/integrations/file-storage/file-storage.service.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/file-storage.service.ts rename to packages/twenty-server/src/engine/integrations/file-storage/file-storage.service.ts diff --git a/packages/twenty-server/src/integrations/file-storage/interfaces/file-storage.interface.ts b/packages/twenty-server/src/engine/integrations/file-storage/interfaces/file-storage.interface.ts similarity index 78% rename from packages/twenty-server/src/integrations/file-storage/interfaces/file-storage.interface.ts rename to packages/twenty-server/src/engine/integrations/file-storage/interfaces/file-storage.interface.ts index 81151323a7c6..9d85a83ec554 100644 --- a/packages/twenty-server/src/integrations/file-storage/interfaces/file-storage.interface.ts +++ b/packages/twenty-server/src/engine/integrations/file-storage/interfaces/file-storage.interface.ts @@ -1,7 +1,7 @@ import { FactoryProvider, ModuleMetadata } from '@nestjs/common'; -import { S3DriverOptions } from 'src/integrations/file-storage/drivers/s3.driver'; -import { LocalDriverOptions } from 'src/integrations/file-storage/drivers/local.driver'; +import { S3DriverOptions } from 'src/engine/integrations/file-storage/drivers/s3.driver'; +import { LocalDriverOptions } from 'src/engine/integrations/file-storage/drivers/local.driver'; export enum StorageDriverType { S3 = 's3', diff --git a/packages/twenty-server/src/integrations/file-storage/interfaces/index.ts b/packages/twenty-server/src/engine/integrations/file-storage/interfaces/index.ts similarity index 100% rename from packages/twenty-server/src/integrations/file-storage/interfaces/index.ts rename to packages/twenty-server/src/engine/integrations/file-storage/interfaces/index.ts diff --git a/packages/twenty-server/src/integrations/integrations.module.ts b/packages/twenty-server/src/engine/integrations/integrations.module.ts similarity index 62% rename from packages/twenty-server/src/integrations/integrations.module.ts rename to packages/twenty-server/src/engine/integrations/integrations.module.ts index 04f23918e6c5..0f056fdf9e2f 100644 --- a/packages/twenty-server/src/integrations/integrations.module.ts +++ b/packages/twenty-server/src/engine/integrations/integrations.module.ts @@ -2,14 +2,14 @@ import { Module } from '@nestjs/common'; import { HttpAdapterHost } from '@nestjs/core'; import { EventEmitterModule } from '@nestjs/event-emitter'; -import { ExceptionHandlerModule } from 'src/integrations/exception-handler/exception-handler.module'; -import { exceptionHandlerModuleFactory } from 'src/integrations/exception-handler/exception-handler.module-factory'; -import { fileStorageModuleFactory } from 'src/integrations/file-storage/file-storage.module-factory'; -import { loggerModuleFactory } from 'src/integrations/logger/logger.module-factory'; -import { messageQueueModuleFactory } from 'src/integrations/message-queue/message-queue.module-factory'; -import { EmailModule } from 'src/integrations/email/email.module'; -import { emailModuleFactory } from 'src/integrations/email/email.module-factory'; -import { CacheStorageModule } from 'src/integrations/cache-storage/cache-storage.module'; +import { ExceptionHandlerModule } from 'src/engine/integrations/exception-handler/exception-handler.module'; +import { exceptionHandlerModuleFactory } from 'src/engine/integrations/exception-handler/exception-handler.module-factory'; +import { fileStorageModuleFactory } from 'src/engine/integrations/file-storage/file-storage.module-factory'; +import { loggerModuleFactory } from 'src/engine/integrations/logger/logger.module-factory'; +import { messageQueueModuleFactory } from 'src/engine/integrations/message-queue/message-queue.module-factory'; +import { EmailModule } from 'src/engine/integrations/email/email.module'; +import { emailModuleFactory } from 'src/engine/integrations/email/email.module-factory'; +import { CacheStorageModule } from 'src/engine/integrations/cache-storage/cache-storage.module'; import { EnvironmentModule } from './environment/environment.module'; import { EnvironmentService } from './environment/environment.service'; diff --git a/packages/twenty-server/src/integrations/logger/logger.service.spec.ts b/packages/twenty-server/src/engine/integrations/logger/__tests__/logger.service.spec.ts similarity index 76% rename from packages/twenty-server/src/integrations/logger/logger.service.spec.ts rename to packages/twenty-server/src/engine/integrations/logger/__tests__/logger.service.spec.ts index 319e2a46d8bf..b5d6f94c897e 100644 --- a/packages/twenty-server/src/integrations/logger/logger.service.spec.ts +++ b/packages/twenty-server/src/engine/integrations/logger/__tests__/logger.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { LoggerService } from './logger.service'; -import { LOGGER_DRIVER } from './logger.constants'; +import { LOGGER_DRIVER } from 'src/engine/integrations/logger/logger.constants'; +import { LoggerService } from 'src/engine/integrations/logger/logger.service'; describe('LoggerService', () => { let service: LoggerService; diff --git a/packages/twenty-server/src/integrations/logger/interfaces/index.ts b/packages/twenty-server/src/engine/integrations/logger/interfaces/index.ts similarity index 100% rename from packages/twenty-server/src/integrations/logger/interfaces/index.ts rename to packages/twenty-server/src/engine/integrations/logger/interfaces/index.ts diff --git a/packages/twenty-server/src/integrations/logger/interfaces/logger.interface.ts b/packages/twenty-server/src/engine/integrations/logger/interfaces/logger.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/logger/interfaces/logger.interface.ts rename to packages/twenty-server/src/engine/integrations/logger/interfaces/logger.interface.ts diff --git a/packages/twenty-server/src/integrations/logger/logger.constants.ts b/packages/twenty-server/src/engine/integrations/logger/logger.constants.ts similarity index 100% rename from packages/twenty-server/src/integrations/logger/logger.constants.ts rename to packages/twenty-server/src/engine/integrations/logger/logger.constants.ts diff --git a/packages/twenty-server/src/integrations/logger/logger.module-definition.ts b/packages/twenty-server/src/engine/integrations/logger/logger.module-definition.ts similarity index 100% rename from packages/twenty-server/src/integrations/logger/logger.module-definition.ts rename to packages/twenty-server/src/engine/integrations/logger/logger.module-definition.ts diff --git a/packages/twenty-server/src/integrations/logger/logger.module-factory.ts b/packages/twenty-server/src/engine/integrations/logger/logger.module-factory.ts similarity index 82% rename from packages/twenty-server/src/integrations/logger/logger.module-factory.ts rename to packages/twenty-server/src/engine/integrations/logger/logger.module-factory.ts index bed4bdc3b856..93701802a68a 100644 --- a/packages/twenty-server/src/integrations/logger/logger.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/logger/logger.module-factory.ts @@ -1,8 +1,8 @@ -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { LoggerModuleOptions, LoggerDriverType, -} from 'src/integrations/logger/interfaces'; +} from 'src/engine/integrations/logger/interfaces'; /** * Logger Module factory diff --git a/packages/twenty-server/src/integrations/logger/logger.module.ts b/packages/twenty-server/src/engine/integrations/logger/logger.module.ts similarity index 95% rename from packages/twenty-server/src/integrations/logger/logger.module.ts rename to packages/twenty-server/src/engine/integrations/logger/logger.module.ts index 1cd4a4ed8b67..778dbbf54d1a 100644 --- a/packages/twenty-server/src/integrations/logger/logger.module.ts +++ b/packages/twenty-server/src/engine/integrations/logger/logger.module.ts @@ -1,6 +1,6 @@ import { DynamicModule, Global, ConsoleLogger, Module } from '@nestjs/common'; -import { LoggerDriverType } from 'src/integrations/logger/interfaces'; +import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; import { LoggerService } from './logger.service'; import { LOGGER_DRIVER } from './logger.constants'; diff --git a/packages/twenty-server/src/integrations/logger/logger.service.ts b/packages/twenty-server/src/engine/integrations/logger/logger.service.ts similarity index 100% rename from packages/twenty-server/src/integrations/logger/logger.service.ts rename to packages/twenty-server/src/engine/integrations/logger/logger.service.ts diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/bullmq.driver.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/bullmq.driver.ts similarity index 92% rename from packages/twenty-server/src/integrations/message-queue/drivers/bullmq.driver.ts rename to packages/twenty-server/src/engine/integrations/message-queue/drivers/bullmq.driver.ts index 0ea7857de2e4..988f8716ddca 100644 --- a/packages/twenty-server/src/integrations/message-queue/drivers/bullmq.driver.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/drivers/bullmq.driver.ts @@ -1,8 +1,8 @@ import { Queue, QueueOptions, Worker } from 'bullmq'; -import { QueueJobOptions } from 'src/integrations/message-queue/drivers/interfaces/job-options.interface'; +import { QueueJobOptions } from 'src/engine/integrations/message-queue/drivers/interfaces/job-options.interface'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueDriver } from './interfaces/message-queue-driver.interface'; diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/interfaces/job-options.interface.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/interfaces/job-options.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/message-queue/drivers/interfaces/job-options.interface.ts rename to packages/twenty-server/src/engine/integrations/message-queue/drivers/interfaces/job-options.interface.ts diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts similarity index 67% rename from packages/twenty-server/src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts rename to packages/twenty-server/src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts index a0136672ac97..517125503eef 100644 --- a/packages/twenty-server/src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface.ts @@ -1,7 +1,7 @@ -import { QueueJobOptions } from 'src/integrations/message-queue/drivers/interfaces/job-options.interface'; -import { MessageQueueJobData } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { QueueJobOptions } from 'src/engine/integrations/message-queue/drivers/interfaces/job-options.interface'; +import { MessageQueueJobData } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; export interface MessageQueueDriver { add( diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/pg-boss.driver.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts similarity index 87% rename from packages/twenty-server/src/integrations/message-queue/drivers/pg-boss.driver.ts rename to packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts index fc306b6f4112..8911f2409ff7 100644 --- a/packages/twenty-server/src/integrations/message-queue/drivers/pg-boss.driver.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts @@ -1,8 +1,8 @@ import PgBoss from 'pg-boss'; -import { QueueJobOptions } from 'src/integrations/message-queue/drivers/interfaces/job-options.interface'; +import { QueueJobOptions } from 'src/engine/integrations/message-queue/drivers/interfaces/job-options.interface'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueDriver } from './interfaces/message-queue-driver.interface'; diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/sync.driver.ts similarity index 76% rename from packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts rename to packages/twenty-server/src/engine/integrations/message-queue/drivers/sync.driver.ts index 03515a103476..ec6d070be0bf 100644 --- a/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/drivers/sync.driver.ts @@ -1,15 +1,15 @@ import { ModuleRef } from '@nestjs/core'; import { Logger } from '@nestjs/common'; -import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; +import { MessageQueueDriver } from 'src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; import { MessageQueueCronJobData, MessageQueueJob, MessageQueueJobData, -} from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +} from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { getJobClassName } from 'src/integrations/message-queue/utils/get-job-class-name.util'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { getJobClassName } from 'src/engine/integrations/message-queue/utils/get-job-class-name.util'; export class SyncDriver implements MessageQueueDriver { private readonly logger = new Logger(SyncDriver.name); diff --git a/packages/twenty-server/src/integrations/message-queue/interfaces/index.ts b/packages/twenty-server/src/engine/integrations/message-queue/interfaces/index.ts similarity index 100% rename from packages/twenty-server/src/integrations/message-queue/interfaces/index.ts rename to packages/twenty-server/src/engine/integrations/message-queue/interfaces/index.ts diff --git a/packages/twenty-server/src/integrations/message-queue/interfaces/message-queue-job.interface.ts b/packages/twenty-server/src/engine/integrations/message-queue/interfaces/message-queue-job.interface.ts similarity index 100% rename from packages/twenty-server/src/integrations/message-queue/interfaces/message-queue-job.interface.ts rename to packages/twenty-server/src/engine/integrations/message-queue/interfaces/message-queue-job.interface.ts diff --git a/packages/twenty-server/src/integrations/message-queue/interfaces/message-queue.interface.ts b/packages/twenty-server/src/engine/integrations/message-queue/interfaces/message-queue.interface.ts similarity index 81% rename from packages/twenty-server/src/integrations/message-queue/interfaces/message-queue.interface.ts rename to packages/twenty-server/src/engine/integrations/message-queue/interfaces/message-queue.interface.ts index 91d910f6abb5..568e0819fc8e 100644 --- a/packages/twenty-server/src/integrations/message-queue/interfaces/message-queue.interface.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/interfaces/message-queue.interface.ts @@ -1,7 +1,7 @@ import { FactoryProvider, ModuleMetadata } from '@nestjs/common'; -import { BullMQDriverOptions } from 'src/integrations/message-queue/drivers/bullmq.driver'; -import { PgBossDriverOptions } from 'src/integrations/message-queue/drivers/pg-boss.driver'; +import { BullMQDriverOptions } from 'src/engine/integrations/message-queue/drivers/bullmq.driver'; +import { PgBossDriverOptions } from 'src/engine/integrations/message-queue/drivers/pg-boss.driver'; export enum MessageQueueDriverType { PgBoss = 'pg-boss', diff --git a/packages/twenty-server/src/integrations/message-queue/jobs.module.ts b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts similarity index 62% rename from packages/twenty-server/src/integrations/message-queue/jobs.module.ts rename to packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts index 800a389cd91f..f0dfa9a1efa9 100644 --- a/packages/twenty-server/src/integrations/message-queue/jobs.module.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts @@ -3,43 +3,43 @@ import { ModuleRef } from '@nestjs/core'; import { HttpModule } from '@nestjs/axios'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { GmailFullSyncJob } from 'src/business/modules/message/jobs/gmail-full-sync.job'; -import { CallWebhookJobsJob } from 'src/engine/graphql/workspace-query-runner/jobs/call-webhook-jobs.job'; -import { CallWebhookJob } from 'src/engine/graphql/workspace-query-runner/jobs/call-webhook.job'; +import { GmailFullSyncJob } from 'src/modules/messaging/jobs/gmail-full-sync.job'; +import { CallWebhookJobsJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job'; +import { CallWebhookJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { MessagingModule } from 'src/business/modules/message/messaging.module'; -import { GmailPartialSyncJob } from 'src/business/modules/message/jobs/gmail-partial-sync.job'; -import { EmailSenderJob } from 'src/integrations/email/email-sender.job'; +import { MessagingModule } from 'src/modules/messaging/messaging.module'; +import { GmailPartialSyncJob } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; +import { EmailSenderJob } from 'src/engine/integrations/email/email-sender.job'; import { UserModule } from 'src/engine/modules/user/user.module'; -import { EnvironmentModule } from 'src/integrations/environment/environment.module'; -import { FetchAllWorkspacesMessagesJob } from 'src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job'; -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { MatchMessageParticipantJob } from 'src/business/modules/message/jobs/match-message-participant.job'; -import { CreateCompaniesAndContactsAfterSyncJob } from 'src/business/modules/message/jobs/create-companies-and-contacts-after-sync.job'; -import { CreateCompaniesAndContactsModule } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { MessageChannelModule } from 'src/business/modules/message/repositories/message-channel/message-channel.module'; -import { MessageParticipantModule } from 'src/business/modules/message/repositories/message-participant/message-participant.module'; +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; +import { FetchAllWorkspacesMessagesJob } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job'; +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { MatchMessageParticipantJob } from 'src/modules/messaging/jobs/match-message-participant.job'; +import { CreateCompaniesAndContactsAfterSyncJob } from 'src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job'; +import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; +import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; +import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module'; import { DataSeedDemoWorkspaceJob } from 'src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job'; -import { DeleteConnectedAccountAssociatedMessagingDataJob } from 'src/business/modules/message/jobs/delete-connected-account-associated-messaging-data.job'; -import { ThreadCleanerModule } from 'src/business/modules/message/services/thread-cleaner/thread-cleaner.module'; +import { DeleteConnectedAccountAssociatedMessagingDataJob } from 'src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job'; +import { ThreadCleanerModule } from 'src/modules/messaging/services/thread-cleaner/thread-cleaner.module'; import { UpdateSubscriptionJob } from 'src/engine/modules/billing/jobs/update-subscription.job'; import { BillingModule } from 'src/engine/modules/billing/billing.module'; import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; import { StripeModule } from 'src/engine/modules/billing/stripe/stripe.module'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { CalendarModule } from 'src/business/modules/calendar/calendar.module'; +import { CalendarModule } from 'src/modules/calendar/calendar.module'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { GoogleCalendarFullSyncJob } from 'src/business/modules/calendar/jobs/google-calendar-full-sync.job'; -import { CalendarEventCleanerModule } from 'src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; -import { RecordPositionBackfillJob } from 'src/engine/graphql/workspace-query-runner/jobs/record-position-backfill.job'; -import { RecordPositionBackfillModule } from 'src/engine/graphql/workspace-query-runner/services/record-position-backfill-module'; -import { DeleteConnectedAccountAssociatedCalendarDataJob } from 'src/business/modules/message/jobs/delete-connected-account-associated-calendar-data.job'; +import { GoogleCalendarFullSyncJob } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; +import { CalendarEventCleanerModule } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; +import { RecordPositionBackfillJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job'; +import { RecordPositionBackfillModule } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module'; +import { DeleteConnectedAccountAssociatedCalendarDataJob } from 'src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job'; @Module({ imports: [ diff --git a/packages/twenty-server/src/integrations/message-queue/message-queue.constants.ts b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts similarity index 100% rename from packages/twenty-server/src/integrations/message-queue/message-queue.constants.ts rename to packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts diff --git a/packages/twenty-server/src/integrations/message-queue/message-queue.module-factory.ts b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.module-factory.ts similarity index 89% rename from packages/twenty-server/src/integrations/message-queue/message-queue.module-factory.ts rename to packages/twenty-server/src/engine/integrations/message-queue/message-queue.module-factory.ts index 8829c1dab1d5..603f550c39c1 100644 --- a/packages/twenty-server/src/integrations/message-queue/message-queue.module-factory.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.module-factory.ts @@ -1,8 +1,8 @@ -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { MessageQueueDriverType, MessageQueueModuleOptions, -} from 'src/integrations/message-queue/interfaces'; +} from 'src/engine/integrations/message-queue/interfaces'; /** * MessageQueue Module factory diff --git a/packages/twenty-server/src/integrations/message-queue/message-queue.module.ts b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.module.ts similarity index 65% rename from packages/twenty-server/src/integrations/message-queue/message-queue.module.ts rename to packages/twenty-server/src/engine/integrations/message-queue/message-queue.module.ts index 29f86895b372..7381c0ee96c8 100644 --- a/packages/twenty-server/src/integrations/message-queue/message-queue.module.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.module.ts @@ -1,20 +1,20 @@ import { DynamicModule, Global } from '@nestjs/common'; -import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; +import { MessageQueueDriver } from 'src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; import { MessageQueueDriverType, MessageQueueModuleAsyncOptions, -} from 'src/integrations/message-queue/interfaces'; +} from 'src/engine/integrations/message-queue/interfaces'; import { MessageQueue, QUEUE_DRIVER, -} from 'src/integrations/message-queue/message-queue.constants'; -import { PgBossDriver } from 'src/integrations/message-queue/drivers/pg-boss.driver'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { BullMQDriver } from 'src/integrations/message-queue/drivers/bullmq.driver'; -import { SyncDriver } from 'src/integrations/message-queue/drivers/sync.driver'; -import { JobsModule } from 'src/integrations/message-queue/jobs.module'; +} from 'src/engine/integrations/message-queue/message-queue.constants'; +import { PgBossDriver } from 'src/engine/integrations/message-queue/drivers/pg-boss.driver'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { BullMQDriver } from 'src/engine/integrations/message-queue/drivers/bullmq.driver'; +import { SyncDriver } from 'src/engine/integrations/message-queue/drivers/sync.driver'; +import { JobsModule } from 'src/engine/integrations/message-queue/jobs.module'; @Global() export class MessageQueueModule { diff --git a/packages/twenty-server/src/integrations/message-queue/services/message-queue-task-assigned.service.spec.ts b/packages/twenty-server/src/engine/integrations/message-queue/services/__tests__/message-queue-task-assigned.service.spec.ts similarity index 77% rename from packages/twenty-server/src/integrations/message-queue/services/message-queue-task-assigned.service.spec.ts rename to packages/twenty-server/src/engine/integrations/message-queue/services/__tests__/message-queue-task-assigned.service.spec.ts index 03d7dfcb4cd9..31e2b66ae978 100644 --- a/packages/twenty-server/src/integrations/message-queue/services/message-queue-task-assigned.service.spec.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/services/__tests__/message-queue-task-assigned.service.spec.ts @@ -1,12 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; +import { MessageQueueDriver } from 'src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; import { QUEUE_DRIVER, MessageQueue, -} from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +} from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; describe('MessageQueueTaskAssigned queue', () => { let service: MessageQueueService; diff --git a/packages/twenty-server/src/integrations/message-queue/services/message-queue.service.ts b/packages/twenty-server/src/engine/integrations/message-queue/services/message-queue.service.ts similarity index 75% rename from packages/twenty-server/src/integrations/message-queue/services/message-queue.service.ts rename to packages/twenty-server/src/engine/integrations/message-queue/services/message-queue.service.ts index 44c2d5121105..b082ec7cefc1 100644 --- a/packages/twenty-server/src/integrations/message-queue/services/message-queue.service.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/services/message-queue.service.ts @@ -1,13 +1,13 @@ import { Inject, Injectable, OnModuleDestroy } from '@nestjs/common'; -import { QueueJobOptions } from 'src/integrations/message-queue/drivers/interfaces/job-options.interface'; -import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; -import { MessageQueueJobData } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { QueueJobOptions } from 'src/engine/integrations/message-queue/drivers/interfaces/job-options.interface'; +import { MessageQueueDriver } from 'src/engine/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; +import { MessageQueueJobData } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; import { MessageQueue, QUEUE_DRIVER, -} from 'src/integrations/message-queue/message-queue.constants'; +} from 'src/engine/integrations/message-queue/message-queue.constants'; @Injectable() export class MessageQueueService implements OnModuleDestroy { diff --git a/packages/twenty-server/src/integrations/message-queue/utils/get-job-class-name.util.ts b/packages/twenty-server/src/engine/integrations/message-queue/utils/get-job-class-name.util.ts similarity index 100% rename from packages/twenty-server/src/integrations/message-queue/utils/get-job-class-name.util.ts rename to packages/twenty-server/src/engine/integrations/message-queue/utils/get-job-class-name.util.ts diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts b/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts index 5015f09df6dc..f6f1e07d422f 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts +++ b/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { HttpService } from '@nestjs/axios'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { AnalyticsResolver } from './analytics.resolver'; import { AnalyticsService } from './analytics.service'; diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts b/packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts index aecd70a70b27..c2cbd7a2f675 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { HttpService } from '@nestjs/axios'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { AnalyticsService } from './analytics.service'; diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts b/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts index f0a6fdf42597..dfb9477a05b9 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts +++ b/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts @@ -4,7 +4,7 @@ import { HttpService } from '@nestjs/axios'; import { Request } from 'express'; import { anonymize } from 'src/utils/anonymize'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; diff --git a/packages/twenty-server/src/engine/modules/auth/auth.module.ts b/packages/twenty-server/src/engine/modules/auth/auth.module.ts index 241b375c0f65..5d7995fd316c 100644 --- a/packages/twenty-server/src/engine/modules/auth/auth.module.ts +++ b/packages/twenty-server/src/engine/modules/auth/auth.module.ts @@ -4,7 +4,7 @@ import { JwtModule } from '@nestjs/jwt'; import { TypeOrmModule } from '@nestjs/typeorm'; import { HttpModule } from '@nestjs/axios'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { FileModule } from 'src/engine/modules/file/file.module'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts index 2f699b86f8fa..7cdb6279e814 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts @@ -7,7 +7,7 @@ import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Controller('auth/google-apis') export class GoogleAPIsAuthController { diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts index 6e956aec9917..df736e6fa234 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts @@ -12,7 +12,7 @@ import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { AuthService } from 'src/engine/modules/auth/services/auth.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Controller('auth/google') export class GoogleAuthController { diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts index 21682154d8e0..18e15db3739a 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts @@ -7,7 +7,7 @@ import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/g import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Controller('auth/google-gmail') export class GoogleGmailAuthController { diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts b/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts index 81bfd12d1f54..50792c44d026 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts @@ -3,7 +3,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; import { GoogleAPIsStrategy } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class GoogleAPIsProviderEnabledGuard implements CanActivate { diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts b/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts index 8fdca62a890d..a6c88275d4c9 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts @@ -3,7 +3,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; import { GoogleAPIsStrategy } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class GoogleGmailProviderEnabledGuard implements CanActivate { diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts b/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts index 9f016d6c9c59..feedac845fed 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts @@ -2,7 +2,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { GoogleStrategy } from 'src/engine/modules/auth/strategies/google.auth.strategy'; @Injectable() diff --git a/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts b/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts index 0fa78b16b23a..70ce4b8ebcb8 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts @@ -5,8 +5,8 @@ import { UserService } from 'src/engine/modules/user/services/user.service'; import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { EmailService } from 'src/integrations/email/email.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { EmailService } from 'src/engine/integrations/email/email.service'; import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; import { AuthService } from './auth.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts b/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts index 8503b91ffdd9..ad16d1d4f8ad 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts @@ -23,8 +23,8 @@ import { WorkspaceInviteHashValid } from 'src/engine/modules/auth/dto/workspace- import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { UserService } from 'src/engine/modules/user/services/user.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { EmailService } from 'src/integrations/email/email.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { EmailService } from 'src/engine/integrations/email/email.service'; import { UpdatePassword } from 'src/engine/modules/auth/dto/update-password.entity'; import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts b/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts index bf0cb71cecbe..19fd0aab175e 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts @@ -7,17 +7,17 @@ import { Repository } from 'typeorm'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { SaveConnectedAccountInput } from 'src/engine/modules/auth/dto/save-connected-account'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { GmailFullSyncJob, GmailFullSyncJobData, -} from 'src/business/modules/message/jobs/gmail-full-sync.job'; +} from 'src/modules/messaging/jobs/gmail-full-sync.job'; import { GoogleCalendarFullSyncJob, GoogleCalendarFullSyncJobData, -} from 'src/business/modules/calendar/jobs/google-calendar-full-sync.job'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +} from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { FeatureFlagEntity, FeatureFlagKeys, diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts index 529d2acf47a0..2fe72ca96947 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts @@ -4,7 +4,7 @@ import { HttpService } from '@nestjs/axios'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts index f58334cedcb2..f19f5cadd95f 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts @@ -20,7 +20,7 @@ import { import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { getImageBufferFromUrl } from 'src/utils/image'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts b/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts index 18287d1f4034..5fc239cae1d7 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts @@ -2,11 +2,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { JwtService } from '@nestjs/jwt'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; import { User } from 'src/engine/modules/user/user.entity'; import { JwtAuthStrategy } from 'src/engine/modules/auth/strategies/jwt.auth.strategy'; -import { EmailService } from 'src/integrations/email/email.service'; +import { EmailService } from 'src/engine/integrations/email/email.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts index 55af71123b37..30a573be4bf5 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts @@ -32,11 +32,11 @@ import { AuthTokens, PasswordResetToken, } from 'src/engine/modules/auth/dto/token.entity'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/modules/user/user.entity'; import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; import { ValidatePasswordResetToken } from 'src/engine/modules/auth/dto/validate-password-reset-token.entity'; -import { EmailService } from 'src/integrations/email/email.service'; +import { EmailService } from 'src/engine/integrations/email/email.service'; import { InvalidatePassword } from 'src/engine/modules/auth/dto/invalidate-password.entity'; import { EmailPasswordResetLink } from 'src/engine/modules/auth/dto/email-password-reset-link.entity'; import { JwtData } from 'src/engine/modules/auth/types/jwt-data.type'; diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts b/packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts index e0633e0722e5..2a389774ece1 100644 --- a/packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts +++ b/packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts @@ -4,7 +4,7 @@ import { Injectable } from '@nestjs/common'; import { Strategy, VerifyCallback } from 'passport-google-oauth20'; import { Request } from 'express'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; export type GoogleAPIsRequest = Request & { user: { diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts b/packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts index 670307ec8643..1b2ea68d27fa 100644 --- a/packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts +++ b/packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts @@ -4,7 +4,7 @@ import { Injectable } from '@nestjs/common'; import { Strategy, VerifyCallback } from 'passport-google-oauth20'; import { Request } from 'express'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; export type GoogleRequest = Request & { user: { diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts b/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts index 3d20de2cff20..f097a6513b7c 100644 --- a/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts +++ b/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts @@ -10,7 +10,7 @@ import { Strategy, ExtractJwt } from 'passport-jwt'; import { Repository } from 'typeorm'; import { assert } from 'src/utils/assert'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; diff --git a/packages/twenty-server/src/engine/modules/billing/billing.service.ts b/packages/twenty-server/src/engine/modules/billing/billing.service.ts index 00852acc1656..705c6e0aadcb 100644 --- a/packages/twenty-server/src/engine/modules/billing/billing.service.ts +++ b/packages/twenty-server/src/engine/modules/billing/billing.service.ts @@ -4,7 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import Stripe from 'stripe'; import { Not, Repository } from 'typeorm'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { StripeService } from 'src/engine/modules/billing/stripe/stripe.service'; import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; import { BillingSubscriptionItem } from 'src/engine/modules/billing/entities/billing-subscription-item.entity'; diff --git a/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts b/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts index 528a801be0e5..486d289fd398 100644 --- a/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts +++ b/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts @@ -1,6 +1,6 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; import { BillingService } from 'src/engine/modules/billing/billing.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts b/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts index e6808d9365dc..e9f982c4f7f1 100644 --- a/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts +++ b/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts @@ -1,10 +1,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { UpdateSubscriptionJob, UpdateSubscriptionJobData, diff --git a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts b/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts index 4e5cc08ffe82..c4e0cefec547 100644 --- a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts +++ b/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import Stripe from 'stripe'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/modules/user/user.entity'; @Injectable() diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts b/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts index 3004995e1584..a723405b2851 100644 --- a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts +++ b/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ClientConfigResolver } from './client-config.resolver'; diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts b/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts index 70e0aedbcd1f..0891de7085d1 100644 --- a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts +++ b/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts @@ -1,6 +1,6 @@ import { Resolver, Query } from '@nestjs/graphql'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ClientConfig } from './client-config.entity'; diff --git a/packages/twenty-server/src/engine/modules/foundation.module.ts b/packages/twenty-server/src/engine/modules/engine-modules.module.ts similarity index 97% rename from packages/twenty-server/src/engine/modules/foundation.module.ts rename to packages/twenty-server/src/engine/modules/engine-modules.module.ts index 378a4dbc6629..aa23a0f5221d 100644 --- a/packages/twenty-server/src/engine/modules/foundation.module.ts +++ b/packages/twenty-server/src/engine/modules/engine-modules.module.ts @@ -38,4 +38,4 @@ import { ClientConfigModule } from './client-config/client-config.module'; WorkspaceModule, ], }) -export class FoundationModule {} +export class EngineModulesModule {} diff --git a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts b/packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts index 52219e25d69d..c972a27c4342 100644 --- a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { FileStorageService } from 'src/integrations/file-storage/file-storage.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; import { FileUploadService } from './file-upload.service'; diff --git a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts b/packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts index 53399ea219c2..10d70bf08597 100644 --- a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts +++ b/packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts @@ -7,7 +7,7 @@ import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.inter import { getCropSize } from 'src/utils/image'; import { settings } from 'src/engine/constants/settings'; -import { FileStorageService } from 'src/integrations/file-storage/file-storage.service'; +import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; @Injectable() export class FileUploadService { diff --git a/packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts b/packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts index 89e8d98bddf2..da68c62a442e 100644 --- a/packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { FileStorageService } from 'src/integrations/file-storage/file-storage.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; import { FileService } from './file.service'; diff --git a/packages/twenty-server/src/engine/modules/file/services/file.service.ts b/packages/twenty-server/src/engine/modules/file/services/file.service.ts index f2fe510cd504..290a13f8bd9a 100644 --- a/packages/twenty-server/src/engine/modules/file/services/file.service.ts +++ b/packages/twenty-server/src/engine/modules/file/services/file.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { FileStorageService } from 'src/integrations/file-storage/file-storage.service'; +import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service'; @Injectable() export class FileService { diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts b/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts index 290e4659d046..eb277a13511f 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts @@ -3,7 +3,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { OpenApiService } from 'src/engine/modules/open-api/open-api.service'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; describe('OpenApiService', () => { let service: OpenApiService; diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts b/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts index a257b64b789b..40f5378e804e 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts +++ b/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts @@ -25,7 +25,7 @@ import { getSingleResultSuccessResponse, } from 'src/engine/modules/open-api/utils/responses.utils'; import { getRequestBody } from 'src/engine/modules/open-api/utils/request-body.utils'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class OpenApiService { diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts index be3155632775..5995f0a0e93a 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts @@ -1,11 +1,13 @@ import { computeSchemaComponents } from 'src/engine/modules/open-api/utils/components.utils'; -import { objectMetadataItem } from 'src/utils/utils-test/object-metadata-item'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; describe('computeSchemaComponents', () => { it('should compute schema components', () => { expect( - computeSchemaComponents([objectMetadataItem] as ObjectMetadataEntity[]), + computeSchemaComponents([ + objectMetadataItemMock, + ] as ObjectMetadataEntity[]), ).toEqual({ ObjectName: { type: 'object', diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts b/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts index d2a2106a2a79..b5d496a07227 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts +++ b/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts @@ -1,4 +1,4 @@ -import { OrderByDirection } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; import { computeDepthParameters, @@ -8,10 +8,10 @@ import { computeLimitParameters, computeOrderByParameters, } from 'src/engine/modules/open-api/utils/parameters.utils'; -import { DEFAULT_ORDER_DIRECTION } from 'src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; -import { FilterComparators } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; -import { Conjunctions } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; -import { DEFAULT_CONJUNCTION } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; +import { DEFAULT_ORDER_DIRECTION } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; +import { FilterComparators } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; +import { Conjunctions } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; +import { DEFAULT_CONJUNCTION } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; describe('computeParameters', () => { describe('computeLimit', () => { diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts b/packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts index 559ab795d6a4..03f7319e7cd0 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts +++ b/packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts @@ -1,11 +1,11 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { OrderByDirection } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; -import { FilterComparators } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; -import { Conjunctions } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; -import { DEFAULT_ORDER_DIRECTION } from 'src/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; -import { DEFAULT_CONJUNCTION } from 'src/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; +import { FilterComparators } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; +import { Conjunctions } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; +import { DEFAULT_ORDER_DIRECTION } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; +import { DEFAULT_CONJUNCTION } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/add-default-conjunction.utils'; export const computeLimitParameters = (): OpenAPIV3_1.ParameterObject => { return { diff --git a/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts b/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts index a508adc24d9e..e56c2e2f069d 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts +++ b/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { CompanyInteface } from 'src/engine/modules/quick-actions/interfaces/company.interface'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class IntelligenceService { diff --git a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts b/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts index 03a58166ac11..14e4bc82a1c3 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts +++ b/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts @@ -3,7 +3,7 @@ import { HttpModule } from '@nestjs/axios'; import { IntelligenceService } from 'src/engine/modules/quick-actions/intelligence.service'; import { QuickActionsService } from 'src/engine/modules/quick-actions/quick-actions.service'; -import { WorkspaceQueryRunnerModule } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.module'; +import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module'; @Module({ imports: [WorkspaceQueryRunnerModule, HttpModule], diff --git a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts b/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts index c2b55d17bf35..6ec86bb1cd62 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts +++ b/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts @@ -2,12 +2,12 @@ import { Injectable } from '@nestjs/common'; import { v4 as uuidv4 } from 'uuid'; -import { Record as IRecord } from 'src/engine/graphql/workspace-query-builder/interfaces/record.interface'; +import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { isWorkEmail } from 'src/utils/is-work-email'; -import { stringifyWithoutKeyQuote } from 'src/engine/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; -import { WorkspaceQueryRunnerService } from 'src/engine/graphql/workspace-query-runner/workspace-query-runner.service'; +import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; +import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; import { IntelligenceService } from 'src/engine/modules/quick-actions/intelligence.service'; import { capitalize } from 'src/utils/capitalize'; diff --git a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts b/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts index 269a75c7691d..e6cacc139a64 100644 --- a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts +++ b/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts @@ -9,8 +9,8 @@ import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { User } from 'src/engine/modules/user/user.entity'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { assert } from 'src/utils/assert'; export class UserWorkspaceService extends TypeOrmQueryService { diff --git a/packages/twenty-server/src/engine/modules/user/user.resolver.ts b/packages/twenty-server/src/engine/modules/user/user.resolver.ts index 8f0096b2f949..a909829f2f4a 100644 --- a/packages/twenty-server/src/engine/modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/modules/user/user.resolver.ts @@ -14,11 +14,11 @@ import crypto from 'crypto'; import { FileUpload, GraphQLUpload } from 'graphql-upload'; import { Repository } from 'typeorm'; -import { SupportDriver } from 'src/integrations/environment/interfaces/support.interface'; +import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; import { assert } from 'src/utils/assert'; diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts index 266b7e502288..b83cad9f2e8d 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts @@ -18,7 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { assert } from 'src/utils/assert'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { UpdateWorkspaceInput } from 'src/engine/modules/workspace/dtos/update-workspace-input'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/modules/user/user.entity'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; diff --git a/packages/twenty-server/src/engine-workspace/utils/__tests__/deduce-relation-direction.spec.ts b/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts similarity index 98% rename from packages/twenty-server/src/engine-workspace/utils/__tests__/deduce-relation-direction.spec.ts rename to packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts index 764320b49118..fb8261818e5b 100644 --- a/packages/twenty-server/src/engine-workspace/utils/__tests__/deduce-relation-direction.spec.ts +++ b/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts @@ -6,7 +6,7 @@ import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/rela import { deduceRelationDirection, RelationDirection, -} from 'src/engine-workspace/utils/deduce-relation-direction.util'; +} from 'src/engine/utils/deduce-relation-direction.util'; describe('deduceRelationDirection', () => { it('should return FROM when the current object Metadata ID matches fromObjectMetadataId and id matches fromFieldMetadataId', () => { diff --git a/packages/twenty-server/src/engine-workspace/utils/__tests__/get-resolver-name.spec.ts b/packages/twenty-server/src/engine/utils/__tests__/get-resolver-name.spec.ts similarity index 84% rename from packages/twenty-server/src/engine-workspace/utils/__tests__/get-resolver-name.spec.ts rename to packages/twenty-server/src/engine/utils/__tests__/get-resolver-name.spec.ts index ebb8d7f76347..16560a4e63d2 100644 --- a/packages/twenty-server/src/engine-workspace/utils/__tests__/get-resolver-name.spec.ts +++ b/packages/twenty-server/src/engine/utils/__tests__/get-resolver-name.spec.ts @@ -1,6 +1,6 @@ -import { WorkspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { getResolverName } from 'src/engine-workspace/utils/get-resolver-name.util'; +import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; describe('getResolverName', () => { const metadata = { diff --git a/packages/twenty-server/src/engine-workspace/utils/compute-custom-name.util.ts b/packages/twenty-server/src/engine/utils/compute-custom-name.util.ts similarity index 100% rename from packages/twenty-server/src/engine-workspace/utils/compute-custom-name.util.ts rename to packages/twenty-server/src/engine/utils/compute-custom-name.util.ts diff --git a/packages/twenty-server/src/engine-workspace/utils/compute-object-target-table.util.ts b/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts similarity index 100% rename from packages/twenty-server/src/engine-workspace/utils/compute-object-target-table.util.ts rename to packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts diff --git a/packages/twenty-server/src/engine-workspace/utils/deduce-relation-direction.util.ts b/packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts similarity index 100% rename from packages/twenty-server/src/engine-workspace/utils/deduce-relation-direction.util.ts rename to packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts diff --git a/packages/twenty-server/src/engine-workspace/utils/get-resolver-name.util.ts b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts similarity index 94% rename from packages/twenty-server/src/engine-workspace/utils/get-resolver-name.util.ts rename to packages/twenty-server/src/engine/utils/get-resolver-name.util.ts index 6440fbceb6e7..25ac725369b8 100644 --- a/packages/twenty-server/src/engine-workspace/utils/get-resolver-name.util.ts +++ b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts @@ -1,4 +1,4 @@ -import { WorkspaceResolverBuilderMethodNames } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; import { camelCase } from 'src/utils/camel-case'; diff --git a/packages/twenty-server/src/engine-workspace/utils/is-relation-field-metadata-type.util.ts b/packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts similarity index 100% rename from packages/twenty-server/src/engine-workspace/utils/is-relation-field-metadata-type.util.ts rename to packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts diff --git a/packages/twenty-server/src/engine-workspace/utils/render-apollo-playground.util.ts b/packages/twenty-server/src/engine/utils/render-apollo-playground.util.ts similarity index 100% rename from packages/twenty-server/src/engine-workspace/utils/render-apollo-playground.util.ts rename to packages/twenty-server/src/engine/utils/render-apollo-playground.util.ts diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command.ts index 1c08a9adf59b..822fd2e94fd1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command.ts @@ -2,8 +2,8 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; export type CleanInactiveWorkspacesCommandOptions = { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/start-clean-inactive-workspaces.cron.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/start-clean-inactive-workspaces.cron.command.ts index e17beb2ebd3d..6188b7faf00d 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/start-clean-inactive-workspaces.cron.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/start-clean-inactive-workspaces.cron.command.ts @@ -2,8 +2,8 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { cleanInactiveWorkspaceCronPattern } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.cron.pattern'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/stop-clean-inactive-workspaces.cron.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/stop-clean-inactive-workspaces.cron.command.ts index 8c61a5a3789d..1dd6dd85e650 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/stop-clean-inactive-workspaces.cron.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/stop-clean-inactive-workspaces.cron.command.ts @@ -2,8 +2,8 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { cleanInactiveWorkspaceCronPattern } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.cron.pattern'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts index 4c9f71eddb33..af75e69bb239 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts @@ -7,17 +7,17 @@ import { DeleteInactiveWorkspaceEmail, } from 'twenty-emails'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; import { UserService } from 'src/engine/modules/user/services/user.service'; -import { EmailService } from 'src/integrations/email/email.service'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EmailService } from 'src/engine/integrations/email/email.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { CleanInactiveWorkspacesCommandOptions } from 'src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command'; import { getDryRunLogHeader } from 'src/utils/get-dry-run-log-header'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/commands/workspace-health.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/commands/workspace-health.command.ts index 6d9bc0fcf6fe..a54366e6bdab 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/commands/workspace-health.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/commands/workspace-health.command.ts @@ -7,7 +7,7 @@ import { WorkspaceHealthMode } from 'src/engine/workspace-manager/workspace-heal import { WorkspaceHealthFixKind } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-fix-kind.interface'; import { WorkspaceHealthService } from 'src/engine/workspace-manager/workspace-health/workspace-health.service'; -import { CommandLogger } from 'src/commands/command-logger'; +import { CommandLogger } from 'src/command/command-logger'; interface WorkspaceHealthCommandOptions { workspaceId: string; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts index 649df369efb7..57286171af19 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts @@ -13,7 +13,7 @@ import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts index 44e0b472be17..65a2971c7a1e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts @@ -17,7 +17,7 @@ import { import { fieldMetadataTypeToColumnType } from 'src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util'; import { serializeTypeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-type-default-value.util'; import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; @Injectable() export class DatabaseStructureService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts index 1b4d45009970..098aac67a466 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts @@ -27,8 +27,8 @@ import { validateOptionsForType } from 'src/engine-metadata/field-metadata/utils import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; import { computeCompositeFieldMetadata } from 'src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util'; import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; -import { customNamePrefix } from 'src/engine-workspace/utils/compute-custom-name.util'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { customNamePrefix } from 'src/engine/utils/compute-custom-name.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; @Injectable() export class FieldMetadataHealthService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts index 921b10e8bae3..2d730b1ab4f8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts @@ -9,7 +9,7 @@ import { WorkspaceHealthOptions } from 'src/engine/workspace-manager/workspace-h import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; import { validName } from 'src/engine/workspace-manager/workspace-health/utils/valid-name.util'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; @Injectable() export class ObjectMetadataHealthService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts index 73597592a17a..8433cc2e5417 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts @@ -18,11 +18,11 @@ import { import { RelationDirection, deduceRelationDirection, -} from 'src/engine-workspace/utils/deduce-relation-direction.util'; +} from 'src/engine/utils/deduce-relation-direction.util'; import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; import { createRelationForeignKeyColumnName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util'; import { createRelationForeignKeyFieldMetadataName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util'; -import { isRelationFieldMetadataType } from 'src/engine-workspace/utils/is-relation-field-metadata-type.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util'; @Injectable() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts index 896d71560e36..70c3cd316a16 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts @@ -18,7 +18,7 @@ import { ObjectMetadataHealthService } from 'src/engine/workspace-manager/worksp import { FieldMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/field-metadata-health.service'; import { RelationMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; import { WorkspaceFixService } from 'src/engine/workspace-manager/workspace-health/services/workspace-fix.service'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts index 2ea64c3844f3..7608cbb862b1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts @@ -12,7 +12,7 @@ import { WorkspaceMigrationEntity, WorkspaceMigrationTableAction, } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts index 4ea31bbd38a6..e4118ddac006 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts @@ -9,7 +9,7 @@ import { WorkspaceMigrationEntity, WorkspaceMigrationTableAction, } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts index dc0136aaa870..980d9172346e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts @@ -8,7 +8,7 @@ import { WorkspaceMigrationEntity, WorkspaceMigrationTableAction, } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { computeObjectTargetTable } from 'src/engine-workspace/utils/compute-object-target-table.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { RelationMetadataEntity, RelationMetadataType, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts index 4ac081335a4e..397834ff623a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { CommandLogger } from 'src/commands/command-logger'; +import { CommandLogger } from 'src/command/command-logger'; @Injectable() export class SyncWorkspaceLoggerService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts index 86d727c1417f..d1baad13c787 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts @@ -8,10 +8,10 @@ import { RelationMetadataType, RelationOnDeleteAction, } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { customObjectStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; @BaseCustomObjectMetadata() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts index e1ff8a4b257a..0c3cfe2e024e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts @@ -1,30 +1,30 @@ -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; -import { ActivityObjectMetadata } from 'src/business/modules/activity/activity.object-metadata'; -import { ApiKeyObjectMetadata } from 'src/business/modules/api-key/api-key.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; -import { BlocklistObjectMetadata } from 'src/business/modules/calendar/blocklist.object-metadata'; -import { CalendarEventObjectMetadata } from 'src/business/modules/calendar/calendar-event.object-metadata'; -import { CalendarChannelObjectMetadata } from 'src/business/modules/calendar/calendar-channel.object-metadata'; -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; -import { CommentObjectMetadata } from 'src/business/modules/comment/comment.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { MessageChannelMessageAssociationObjectMetadata } from 'src/business/modules/message/message-channel-message-association.object-metadata'; -import { MessageChannelObjectMetadata } from 'src/business/modules/message/message-channel.object-metadata'; -import { MessageParticipantObjectMetadata } from 'src/business/modules/message/message-participant.object-metadata'; -import { MessageThreadObjectMetadata } from 'src/business/modules/message/message-thread.object-metadata'; -import { MessageObjectMetadata } from 'src/business/modules/message/message.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { PipelineStepObjectMetadata } from 'src/business/modules/pipeline-step/pipeline-step.object-metadata'; -import { ViewFieldObjectMetadata } from 'src/business/modules/view/view-field.object-metadata'; -import { ViewFilterObjectMetadata } from 'src/business/modules/view/view-filter.object-metadata'; -import { ViewSortObjectMetadata } from 'src/business/modules/view/view-sort.object-metadata'; -import { ViewObjectMetadata } from 'src/business/modules/view/view.object-metadata'; -import { WebhookObjectMetadata } from 'src/business/modules/webhook/webhook.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; -import { CalendarChannelEventAssociationObjectMetadata } from 'src/business/modules/calendar/calendar-channel-event-association.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; +import { ActivityObjectMetadata } from 'src/modules/activity/standard-objects/activity.object-metadata'; +import { ApiKeyObjectMetadata } from 'src/modules/api-key/standard-objects/api-key.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; +import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { CommentObjectMetadata } from 'src/modules/activity/standard-objects/comment.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { PipelineStepObjectMetadata } from 'src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata'; +import { ViewFieldObjectMetadata } from 'src/modules/view/standard-objects/view-field.object-metadata'; +import { ViewFilterObjectMetadata } from 'src/modules/view/standard-objects/view-filter.object-metadata'; +import { ViewSortObjectMetadata } from 'src/modules/view/standard-objects/view-sort.object-metadata'; +import { ViewObjectMetadata } from 'src/modules/view/standard-objects/view.object-metadata'; +import { WebhookObjectMetadata } from 'src/modules/webhook/standard-objects/webhook.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; export const standardObjectMetadataDefinitions = [ ActivityTargetObjectMetadata, diff --git a/packages/twenty-server/src/main.ts b/packages/twenty-server/src/main.ts index 7beec44acd5e..80b0543e481c 100644 --- a/packages/twenty-server/src/main.ts +++ b/packages/twenty-server/src/main.ts @@ -11,8 +11,8 @@ import '@sentry/tracing'; import { AppModule } from './app.module'; import { settings } from './engine/constants/settings'; -import { LoggerService } from './integrations/logger/logger.service'; -import { EnvironmentService } from './integrations/environment/environment.service'; +import { LoggerService } from './engine/integrations/logger/logger.service'; +import { EnvironmentService } from './engine/integrations/environment/environment.service'; const bootstrap = async () => { const app = await NestFactory.create(AppModule, { diff --git a/packages/twenty-server/src/business/modules/activity/activity-target.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts similarity index 88% rename from packages/twenty-server/src/business/modules/activity/activity-target.object-metadata.ts rename to packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts index 7bae811c4744..1a39445b047a 100644 --- a/packages/twenty-server/src/business/modules/activity/activity-target.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts @@ -7,11 +7,11 @@ import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metad import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; -import { ActivityObjectMetadata } from 'src/business/modules/activity/activity.object-metadata'; +import { ActivityObjectMetadata } from 'src/modules/activity/standard-objects/activity.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.activityTarget, diff --git a/packages/twenty-server/src/business/modules/activity/activity.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts similarity index 90% rename from packages/twenty-server/src/business/modules/activity/activity.object-metadata.ts rename to packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts index 78f26dcad7bf..d22cc6d267d5 100644 --- a/packages/twenty-server/src/business/modules/activity/activity.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts @@ -7,11 +7,11 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CommentObjectMetadata } from 'src/business/modules/comment/comment.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { CommentObjectMetadata } from 'src/modules/activity/standard-objects/comment.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.activity, diff --git a/packages/twenty-server/src/business/modules/comment/comment.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts similarity index 88% rename from packages/twenty-server/src/business/modules/comment/comment.object-metadata.ts rename to packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts index a0b964416b28..7fdb4595da78 100644 --- a/packages/twenty-server/src/business/modules/comment/comment.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts @@ -4,9 +4,9 @@ import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-m import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; -import { ActivityObjectMetadata } from 'src/business/modules/activity/activity.object-metadata'; +import { ActivityObjectMetadata } from 'src/modules/activity/standard-objects/activity.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.comment, diff --git a/packages/twenty-server/src/business/modules/api-key/api-key.object-metadata.ts b/packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts similarity index 100% rename from packages/twenty-server/src/business/modules/api-key/api-key.object-metadata.ts rename to packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts diff --git a/packages/twenty-server/src/business/modules/attachment/attachment.object-metadata.ts b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts similarity index 87% rename from packages/twenty-server/src/business/modules/attachment/attachment.object-metadata.ts rename to packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts index d86d03c47352..470abe7a5c78 100644 --- a/packages/twenty-server/src/business/modules/attachment/attachment.object-metadata.ts +++ b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts @@ -7,12 +7,12 @@ import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metad import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; -import { ActivityObjectMetadata } from 'src/business/modules/activity/activity.object-metadata'; +import { ActivityObjectMetadata } from 'src/modules/activity/standard-objects/activity.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.attachment, diff --git a/packages/twenty-server/src/modules/calendar/calendar.module.ts b/packages/twenty-server/src/modules/calendar/calendar.module.ts new file mode 100644 index 000000000000..6d688c6c8614 --- /dev/null +++ b/packages/twenty-server/src/modules/calendar/calendar.module.ts @@ -0,0 +1,41 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; +import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; +import { BlocklistModule } from 'src/modules/connected-account/repositories/blocklist/blocklist.module'; +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { CalendarChannelEventAssociationModule } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module'; +import { CalendarChannelModule } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.module'; +import { CalendarEventAttendeeModule } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module'; +import { CalendarEventModule } from 'src/modules/calendar/repositories/calendar-event/calendar-event.module'; +import { CalendarEventCleanerModule } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; +import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; +import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; +import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; +import { PersonModule } from 'src/modules/person/repositories/person/person.module'; +import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; + +@Module({ + imports: [ + EnvironmentModule, + WorkspaceDataSourceModule, + ConnectedAccountModule, + CalendarChannelModule, + CalendarChannelEventAssociationModule, + CalendarEventModule, + CalendarEventAttendeeModule, + CreateCompaniesAndContactsModule, + WorkspaceMemberModule, + TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), + CompanyModule, + PersonModule, + BlocklistModule, + CalendarEventCleanerModule, + ], + providers: [GoogleCalendarFullSyncService, GoogleCalendarClientProvider], + exports: [GoogleCalendarFullSyncService], +}) +export class CalendarModule {} diff --git a/packages/twenty-server/src/business/modules/calendar/commands/google-calendar-full-sync.command.ts b/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts similarity index 79% rename from packages/twenty-server/src/business/modules/calendar/commands/google-calendar-full-sync.command.ts rename to packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts index 0ef73ee8fd0f..4401d58f2ff8 100644 --- a/packages/twenty-server/src/business/modules/calendar/commands/google-calendar-full-sync.command.ts +++ b/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts @@ -2,13 +2,13 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; import { GoogleCalendarFullSyncJobData, GoogleCalendarFullSyncJob, -} from 'src/business/modules/calendar/jobs/google-calendar-full-sync.job'; +} from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; interface GoogleCalendarFullSyncOptions { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/calendar/commands/workspace-calendar-sync-commands.module.ts b/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts similarity index 69% rename from packages/twenty-server/src/business/modules/calendar/commands/workspace-calendar-sync-commands.module.ts rename to packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts index a4ca0fc3a31e..bcaa654bb3d8 100644 --- a/packages/twenty-server/src/business/modules/calendar/commands/workspace-calendar-sync-commands.module.ts +++ b/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts @@ -4,8 +4,8 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { GoogleCalendarFullSyncCommand } from 'src/business/modules/calendar/commands/google-calendar-full-sync.command'; +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { GoogleCalendarFullSyncCommand } from 'src/modules/calendar/commands/google-calendar-full-sync.command'; @Module({ imports: [ diff --git a/packages/twenty-server/src/business/modules/calendar/jobs/google-calendar-full-sync.job.ts b/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts similarity index 78% rename from packages/twenty-server/src/business/modules/calendar/jobs/google-calendar-full-sync.job.ts rename to packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts index 66066db5571b..9759bbf6b77d 100644 --- a/packages/twenty-server/src/business/modules/calendar/jobs/google-calendar-full-sync.job.ts +++ b/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts @@ -1,9 +1,9 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service'; -import { GoogleCalendarFullSyncService } from 'src/business/modules/calendar/services/google-calendar-full-sync.service'; +import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; +import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; export type GoogleCalendarFullSyncJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts similarity index 66% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts index 7c71211912ba..2b044c87f6de 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CalendarChannelEventAssociationService } from 'src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; +import { CalendarChannelEventAssociationService } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts similarity index 96% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts index af8050d45c02..8ea4b89806c2 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts @@ -4,8 +4,8 @@ import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { CalendarChannelEventAssociationObjectMetadata } from 'src/business/modules/calendar/calendar-channel-event-association.object-metadata'; -import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/business/modules/calendar-and-messaging/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; +import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; @Injectable() export class CalendarChannelEventAssociationService { diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts similarity index 71% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts index be0468f0604a..3640b0984000 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CalendarChannelService } from 'src/business/modules/calendar/repositories/calendar-channel/calendar-channel.service'; +import { CalendarChannelService } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts similarity index 95% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts index 152e8c345eb3..85921f68c545 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { CalendarChannelObjectMetadata } from 'src/business/modules/calendar/calendar-channel.object-metadata'; +import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts similarity index 69% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts index 95ee36ceb89d..64e015520cd5 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CalendarEventAttendeeService } from 'src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; +import { CalendarEventAttendeeService } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts similarity index 93% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts index b5d168b90890..737604d66846 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts @@ -4,9 +4,9 @@ import { EntityManager } from 'typeorm'; 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/business/modules/calendar/calendar-event-attendee.object-metadata'; -import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/business/modules/calendar-and-messaging/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; -import { CalendarEventAttendee } from 'src/business/modules/calendar/types/calendar-event'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; +import { CalendarEventAttendee } from 'src/modules/calendar/types/calendar-event'; @Injectable() export class CalendarEventAttendeeService { diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts similarity index 71% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.module.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts index 5285bfb0443f..7d501958f867 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.module.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CalendarEventService } from 'src/business/modules/calendar/repositories/calendar-event/calendar-event.service'; +import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts similarity index 93% rename from packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts index 3316d12e98b9..2a0d81014637 100644 --- a/packages/twenty-server/src/business/modules/calendar/repositories/calendar-event/calendar-event.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts @@ -4,10 +4,10 @@ import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { CalendarEventObjectMetadata } from 'src/business/modules/calendar/calendar-event.object-metadata'; -import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/business/modules/calendar-and-messaging/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; -import { CalendarEvent } from 'src/business/modules/calendar/types/calendar-event'; -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; +import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; +import { CalendarEvent } from 'src/modules/calendar/types/calendar-event'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; @Injectable() export class CalendarEventService { diff --git a/packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts similarity index 61% rename from packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts rename to packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts index b76f322d5dcc..98c1df1fb18d 100644 --- a/packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts @@ -2,8 +2,8 @@ import { Module } from '@nestjs/common'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { CalendarEventModule } from 'src/business/modules/calendar/repositories/calendar-event/calendar-event.module'; -import { CalendarEventCleanerService } from 'src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service'; +import { CalendarEventModule } from 'src/modules/calendar/repositories/calendar-event/calendar-event.module'; +import { CalendarEventCleanerService } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service'; @Module({ imports: [DataSourceModule, TypeORMModule, CalendarEventModule], diff --git a/packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts similarity index 67% rename from packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts rename to packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts index 12a299541fcb..c3128a326e5e 100644 --- a/packages/twenty-server/src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; -import { CalendarEventService } from 'src/business/modules/calendar/repositories/calendar-event/calendar-event.service'; -import { deleteUsingPagination } from 'src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util'; +import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; +import { deleteUsingPagination } from 'src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util'; @Injectable() export class CalendarEventCleanerService { diff --git a/packages/twenty-server/src/business/modules/calendar/services/google-calendar-full-sync.service.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts similarity index 84% rename from packages/twenty-server/src/business/modules/calendar/services/google-calendar-full-sync.service.ts rename to packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts index 714dc8f35134..a5f10af877e1 100644 --- a/packages/twenty-server/src/business/modules/calendar/services/google-calendar-full-sync.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts @@ -3,23 +3,23 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; -import { BlocklistService } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; import { FeatureFlagEntity, FeatureFlagKeys, } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { GoogleCalendarClientProvider } from 'src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider'; -import { googleCalendarSearchFilterExcludeEmails } from 'src/business/modules/calendar/utils/google-calendar-search-filter.util'; -import { CalendarChannelEventAssociationService } from 'src/business/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; -import { CalendarChannelService } from 'src/business/modules/calendar/repositories/calendar-channel/calendar-channel.service'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; +import { googleCalendarSearchFilterExcludeEmails } from 'src/modules/calendar/utils/google-calendar-search-filter.util'; +import { CalendarChannelEventAssociationService } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; +import { CalendarChannelService } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { CalendarEventService } from 'src/business/modules/calendar/repositories/calendar-event/calendar-event.service'; -import { formatGoogleCalendarEvent } from 'src/business/modules/calendar/utils/format-google-calendar-event.util'; -import { GoogleCalendarFullSyncJobData } from 'src/business/modules/calendar/jobs/google-calendar-full-sync.job'; -import { CalendarEventAttendeeService } from 'src/business/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; +import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; +import { formatGoogleCalendarEvent } from 'src/modules/calendar/utils/format-google-calendar-event.util'; +import { GoogleCalendarFullSyncJobData } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; +import { CalendarEventAttendeeService } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; @Injectable() export class GoogleCalendarFullSyncService { diff --git a/packages/twenty-server/src/modules/calendar/services/providers/calendar-providers.module.ts b/packages/twenty-server/src/modules/calendar/services/providers/calendar-providers.module.ts new file mode 100644 index 000000000000..67f8064f7adf --- /dev/null +++ b/packages/twenty-server/src/modules/calendar/services/providers/calendar-providers.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; +import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; + +@Module({ + imports: [EnvironmentModule], + providers: [GoogleCalendarClientProvider], + exports: [GoogleCalendarClientProvider], +}) +export class CalendarProvidersModule {} diff --git a/packages/twenty-server/src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts b/packages/twenty-server/src/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts similarity index 92% rename from packages/twenty-server/src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts rename to packages/twenty-server/src/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts index d93f7e9f8690..6e2faa04e613 100644 --- a/packages/twenty-server/src/business/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts +++ b/packages/twenty-server/src/modules/calendar/services/providers/google-calendar/google-calendar.provider.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { OAuth2Client } from 'google-auth-library'; import { calendar_v3 as calendarV3, google } from 'googleapis'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class GoogleCalendarClientProvider { diff --git a/packages/twenty-server/src/business/modules/calendar/calendar-channel-event-association.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts similarity index 95% rename from packages/twenty-server/src/business/modules/calendar/calendar-channel-event-association.object-metadata.ts rename to packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts index 2aa9fefcb7b6..01557560ebac 100644 --- a/packages/twenty-server/src/business/modules/calendar/calendar-channel-event-association.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts @@ -7,7 +7,7 @@ import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decor import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CalendarEventObjectMetadata } from 'src/business/modules/calendar/calendar-event.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.calendarChannelEventAssociation, diff --git a/packages/twenty-server/src/business/modules/calendar/calendar-channel.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts similarity index 95% rename from packages/twenty-server/src/business/modules/calendar/calendar-channel.object-metadata.ts rename to packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts index dbbc8529f06b..dfeb0a2b5229 100644 --- a/packages/twenty-server/src/business/modules/calendar/calendar-channel.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts @@ -11,8 +11,8 @@ import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decor import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; -import { CalendarChannelEventAssociationObjectMetadata } from 'src/business/modules/calendar/calendar-channel-event-association.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; export enum CalendarChannelVisibility { diff --git a/packages/twenty-server/src/business/modules/calendar/calendar-event-attendee.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts similarity index 92% rename from packages/twenty-server/src/business/modules/calendar/calendar-event-attendee.object-metadata.ts rename to packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts index 8507d5c3b942..2ba5c28789aa 100644 --- a/packages/twenty-server/src/business/modules/calendar/calendar-event-attendee.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts @@ -7,9 +7,9 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CalendarEventObjectMetadata } from 'src/business/modules/calendar/calendar-event.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; export enum CalendarEventAttendeeResponseStatus { NEEDS_ACTION = 'NEEDS_ACTION', diff --git a/packages/twenty-server/src/business/modules/calendar/calendar-event.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts similarity index 96% rename from packages/twenty-server/src/business/modules/calendar/calendar-event.object-metadata.ts rename to packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts index 8eb6a7467a7a..968c83c3cb5e 100644 --- a/packages/twenty-server/src/business/modules/calendar/calendar-event.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts @@ -10,8 +10,8 @@ import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decor import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CalendarChannelEventAssociationObjectMetadata } from 'src/business/modules/calendar/calendar-channel-event-association.object-metadata'; -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { calendarEventStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; diff --git a/packages/twenty-server/src/business/modules/calendar/types/calendar-event.ts b/packages/twenty-server/src/modules/calendar/types/calendar-event.ts similarity index 73% rename from packages/twenty-server/src/business/modules/calendar/types/calendar-event.ts rename to packages/twenty-server/src/modules/calendar/types/calendar-event.ts index e273ba67cb5f..83db8d0d8b9b 100644 --- a/packages/twenty-server/src/business/modules/calendar/types/calendar-event.ts +++ b/packages/twenty-server/src/modules/calendar/types/calendar-event.ts @@ -1,5 +1,5 @@ -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; -import { CalendarEventObjectMetadata } from 'src/business/modules/calendar/calendar-event.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; export type CalendarEvent = Omit< diff --git a/packages/twenty-server/src/business/modules/calendar/utils/format-google-calendar-event.util.ts b/packages/twenty-server/src/modules/calendar/utils/format-google-calendar-event.util.ts similarity index 88% rename from packages/twenty-server/src/business/modules/calendar/utils/format-google-calendar-event.util.ts rename to packages/twenty-server/src/modules/calendar/utils/format-google-calendar-event.util.ts index 795aad17e8d9..e99234263c21 100644 --- a/packages/twenty-server/src/business/modules/calendar/utils/format-google-calendar-event.util.ts +++ b/packages/twenty-server/src/modules/calendar/utils/format-google-calendar-event.util.ts @@ -1,8 +1,8 @@ import { calendar_v3 } from 'googleapis'; import { v4 } from 'uuid'; -import { CalendarEventWithAttendees } from 'src/business/modules/calendar/types/calendar-event'; -import { CalendarEventAttendeeResponseStatus } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; +import { CalendarEventWithAttendees } from 'src/modules/calendar/types/calendar-event'; +import { CalendarEventAttendeeResponseStatus } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; export const formatGoogleCalendarEvent = ( event: calendar_v3.Schema$Event, diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util.ts b/packages/twenty-server/src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util.ts rename to packages/twenty-server/src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util.ts diff --git a/packages/twenty-server/src/business/modules/calendar/utils/google-calendar-search-filter.util.ts b/packages/twenty-server/src/modules/calendar/utils/google-calendar-search-filter.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/calendar/utils/google-calendar-search-filter.util.ts rename to packages/twenty-server/src/modules/calendar/utils/google-calendar-search-filter.util.ts diff --git a/packages/twenty-server/src/business/modules/company/company.object-metadata.ts b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts similarity index 90% rename from packages/twenty-server/src/business/modules/company/company.object-metadata.ts rename to packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts index bd561c8e8e21..f951c066e72d 100644 --- a/packages/twenty-server/src/business/modules/company/company.object-metadata.ts +++ b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts @@ -12,13 +12,13 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.company, diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts new file mode 100644 index 000000000000..a6877df0fd9e --- /dev/null +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; + +import { PersonModule } from 'src/modules/person/repositories/person/person.module'; +import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; +import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; +import { CreateCompanyModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module'; +import { CreateContactModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; + +@Module({ + imports: [ + WorkspaceDataSourceModule, + CreateContactModule, + CreateCompanyModule, + WorkspaceMemberModule, + PersonModule, + ], + providers: [CreateCompanyAndContactService], + exports: [CreateCompanyAndContactService], +}) +export class CreateCompaniesAndContactsModule {} diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts similarity index 77% rename from packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts rename to packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts index db386ef7e53e..0462bc075646 100644 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts @@ -3,14 +3,14 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import compact from 'lodash/compact'; -import { Participant } from 'src/business/modules/message/types/gmail-message'; -import { getDomainNameFromHandle } from 'src/business/modules/message/utils/get-domain-name-from-handle.util'; -import { CreateCompanyService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service'; -import { CreateContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { PersonService } from 'src/engine-workspace/repositories/person/person.service'; -import { WorkspaceMemberService } from 'src/engine-workspace/repositories/workspace-member/workspace-member.service'; -import { getUniqueParticipantsAndHandles } from 'src/business/modules/message/utils/get-unique-participants-and-handles.util'; -import { filterOutParticipantsFromCompanyOrWorkspace } from 'src/business/modules/message/utils/filter-out-participants-from-company-or-workspace.util'; +import { Participant } from 'src/modules/messaging/types/gmail-message'; +import { getDomainNameFromHandle } from 'src/modules/messaging/utils/get-domain-name-from-handle.util'; +import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; +import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; +import { PersonService } from 'src/modules/person/repositories/person/person.service'; +import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; +import { getUniqueParticipantsAndHandles } from 'src/modules/messaging/utils/get-unique-participants-and-handles.util'; +import { filterOutParticipantsFromCompanyOrWorkspace } from 'src/modules/messaging/utils/filter-out-participants-from-company-or-workspace.util'; import { isWorkEmail } from 'src/utils/is-work-email'; @Injectable() diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts similarity index 57% rename from packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.module.ts rename to packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts index e413edeadbbe..31e2e68c74d7 100644 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.module.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { CreateCompanyService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service'; -import { CompanyModule } from 'src/business/modules/message/repositories/company/company.module'; +import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; +import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; @Module({ imports: [WorkspaceDataSourceModule, CompanyModule], diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts similarity index 92% rename from packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service.ts rename to packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts index cc755090f3a7..4052b1cbea6a 100644 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-company/create-company.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts @@ -4,8 +4,8 @@ import { EntityManager } from 'typeorm'; import { v4 } from 'uuid'; import axios, { AxiosInstance } from 'axios'; -import { CompanyService } from 'src/business/modules/message/repositories/company/company.service'; -import { getCompanyNameFromDomainName } from 'src/business/modules/message/utils/get-company-name-from-domain-name.util'; +import { CompanyService } from 'src/modules/messaging/repositories/company/company.service'; +import { getCompanyNameFromDomainName } from 'src/modules/messaging/utils/get-company-name-from-domain-name.util'; @Injectable() export class CreateCompanyService { private readonly httpService: AxiosInstance; diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts similarity index 58% rename from packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts rename to packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts index 612877ec5789..faa9404258a5 100644 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { CreateContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { PersonModule } from 'src/engine-workspace/repositories/person/person.module'; +import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; +import { PersonModule } from 'src/modules/person/repositories/person/person.module'; @Module({ imports: [WorkspaceDataSourceModule, PersonModule], diff --git a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts similarity index 87% rename from packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts rename to packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts index 03e4dfe91fbb..c96bbc2fda81 100644 --- a/packages/twenty-server/src/engine-workspace/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts @@ -3,8 +3,8 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { v4 } from 'uuid'; -import { PersonService } from 'src/engine-workspace/repositories/person/person.service'; -import { getFirstNameAndLastNameFromHandleAndDisplayName } from 'src/business/modules/message/utils/get-first-name-and-last-name-from-handle-and-display-name.util'; +import { PersonService } from 'src/modules/person/repositories/person/person.service'; +import { getFirstNameAndLastNameFromHandleAndDisplayName } from 'src/modules/messaging/utils/get-first-name-and-last-name-from-handle-and-display-name.util'; type ContactToCreate = { handle: string; diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.module.ts b/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts similarity index 71% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.module.ts rename to packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts index 875ae2223420..08e623074685 100644 --- a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.module.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { BlocklistService } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service'; +import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service.ts b/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts similarity index 89% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service.ts rename to packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts index 433f02da6d44..f8ff607e83cf 100644 --- a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts @@ -4,7 +4,7 @@ import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { BlocklistObjectMetadata } from 'src/business/modules/calendar/blocklist.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; @Injectable() export class BlocklistService { diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module.ts b/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts similarity index 68% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module.ts rename to packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts index 36b9514843d4..736d2e303c31 100644 --- a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service.ts b/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts similarity index 97% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service.ts rename to packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts index e6f766cb21ae..739da879afc8 100644 --- a/packages/twenty-server/src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts @@ -3,7 +3,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service.ts b/packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts similarity index 87% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service.ts rename to packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts index 6ae56784cb9d..88ba8c3d7ee3 100644 --- a/packages/twenty-server/src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service.ts +++ b/packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts @@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common'; import axios from 'axios'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; @Injectable() export class GoogleAPIsRefreshAccessTokenService { diff --git a/packages/twenty-server/src/business/modules/calendar/blocklist.object-metadata.ts b/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts similarity index 92% rename from packages/twenty-server/src/business/modules/calendar/blocklist.object-metadata.ts rename to packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts index 16bce3ff814b..fb47bddfa8e4 100644 --- a/packages/twenty-server/src/business/modules/calendar/blocklist.object-metadata.ts +++ b/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts @@ -5,7 +5,7 @@ import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metad import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.blocklist, diff --git a/packages/twenty-server/src/business/modules/connected-account/connected-account.object-metadata.ts b/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts similarity index 91% rename from packages/twenty-server/src/business/modules/connected-account/connected-account.object-metadata.ts rename to packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts index 68ca1cd67cdd..1044708e4ea5 100644 --- a/packages/twenty-server/src/business/modules/connected-account/connected-account.object-metadata.ts +++ b/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts @@ -12,9 +12,9 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CalendarChannelObjectMetadata } from 'src/business/modules/calendar/calendar-channel.object-metadata'; -import { MessageChannelObjectMetadata } from 'src/business/modules/message/message-channel.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.connectedAccount, diff --git a/packages/twenty-server/src/business/modules/favorite/favorite.object-metadata.ts b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts similarity index 88% rename from packages/twenty-server/src/business/modules/favorite/favorite.object-metadata.ts rename to packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts index b3712e90017b..3081099b96a3 100644 --- a/packages/twenty-server/src/business/modules/favorite/favorite.object-metadata.ts +++ b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts @@ -8,10 +8,10 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.favorite, diff --git a/packages/twenty-server/src/business/modules/message/commands/crons/fetch-all-workspaces-messages.cron.pattern.ts b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/commands/crons/fetch-all-workspaces-messages.cron.pattern.ts rename to packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern.ts diff --git a/packages/twenty-server/src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job.ts b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts similarity index 81% rename from packages/twenty-server/src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job.ts rename to packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts index 15363abdc278..2867fa1b09d4 100644 --- a/packages/twenty-server/src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job.ts +++ b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts @@ -3,16 +3,16 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository, In } from 'typeorm'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { GmailPartialSyncJobData, GmailPartialSyncJob, -} from 'src/business/modules/message/jobs/gmail-partial-sync.job'; +} from 'src/modules/messaging/jobs/gmail-partial-sync.job'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/message/commands/fetch-workspace-messages-commands.module.ts b/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts similarity index 57% rename from packages/twenty-server/src/business/modules/message/commands/fetch-workspace-messages-commands.module.ts rename to packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts index 59708b47265e..cd0936e1b6fa 100644 --- a/packages/twenty-server/src/business/modules/message/commands/fetch-workspace-messages-commands.module.ts +++ b/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts @@ -4,11 +4,11 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { GmailFullSyncCommand } from 'src/business/modules/message/commands/gmail-full-sync.command'; -import { GmailPartialSyncCommand } from 'src/business/modules/message/commands/gmail-partial-sync.command'; -import { ConnectedAccountModule } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.module'; -import { StartFetchAllWorkspacesMessagesCronCommand } from 'src/business/modules/message/commands/start-fetch-all-workspaces-messages.cron.command'; -import { StopFetchAllWorkspacesMessagesCronCommand } from 'src/business/modules/message/commands/stop-fetch-all-workspaces-messages.cron.command'; +import { GmailFullSyncCommand } from 'src/modules/messaging/commands/gmail-full-sync.command'; +import { GmailPartialSyncCommand } from 'src/modules/messaging/commands/gmail-partial-sync.command'; +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { StartFetchAllWorkspacesMessagesCronCommand } from 'src/modules/messaging/commands/start-fetch-all-workspaces-messages.cron.command'; +import { StopFetchAllWorkspacesMessagesCronCommand } from 'src/modules/messaging/commands/stop-fetch-all-workspaces-messages.cron.command'; @Module({ imports: [ diff --git a/packages/twenty-server/src/business/modules/message/commands/gmail-full-sync.command.ts b/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts similarity index 78% rename from packages/twenty-server/src/business/modules/message/commands/gmail-full-sync.command.ts rename to packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts index b3632a4a56a2..375986cb13c0 100644 --- a/packages/twenty-server/src/business/modules/message/commands/gmail-full-sync.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts @@ -2,13 +2,13 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { GmailFullSyncJobData, GmailFullSyncJob, -} from 'src/business/modules/message/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +} from 'src/modules/messaging/jobs/gmail-full-sync.job'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; interface GmailFullSyncOptions { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/commands/gmail-partial-sync.command.ts b/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts similarity index 78% rename from packages/twenty-server/src/business/modules/message/commands/gmail-partial-sync.command.ts rename to packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts index a819c5a97d6b..0511a9ad0b48 100644 --- a/packages/twenty-server/src/business/modules/message/commands/gmail-partial-sync.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts @@ -2,13 +2,13 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { GmailPartialSyncJob, GmailPartialSyncJobData, -} from 'src/business/modules/message/jobs/gmail-partial-sync.job'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; +} from 'src/modules/messaging/jobs/gmail-partial-sync.job'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; interface GmailPartialSyncOptions { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/commands/start-fetch-all-workspaces-messages.cron.command.ts b/packages/twenty-server/src/modules/messaging/commands/start-fetch-all-workspaces-messages.cron.command.ts similarity index 58% rename from packages/twenty-server/src/business/modules/message/commands/start-fetch-all-workspaces-messages.cron.command.ts rename to packages/twenty-server/src/modules/messaging/commands/start-fetch-all-workspaces-messages.cron.command.ts index 994403f7d5c0..4da6824a23fe 100644 --- a/packages/twenty-server/src/business/modules/message/commands/start-fetch-all-workspaces-messages.cron.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/start-fetch-all-workspaces-messages.cron.command.ts @@ -2,10 +2,10 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { fetchAllWorkspacesMessagesCronPattern } from 'src/business/modules/message/commands/crons/fetch-all-workspaces-messages.cron.pattern'; -import { FetchAllWorkspacesMessagesJob } from 'src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { fetchAllWorkspacesMessagesCronPattern } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern'; +import { FetchAllWorkspacesMessagesJob } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job'; @Command({ name: 'fetch-all-workspaces-messages:cron:start', diff --git a/packages/twenty-server/src/business/modules/message/commands/stop-fetch-all-workspaces-messages.cron.command.ts b/packages/twenty-server/src/modules/messaging/commands/stop-fetch-all-workspaces-messages.cron.command.ts similarity index 57% rename from packages/twenty-server/src/business/modules/message/commands/stop-fetch-all-workspaces-messages.cron.command.ts rename to packages/twenty-server/src/modules/messaging/commands/stop-fetch-all-workspaces-messages.cron.command.ts index 825b96ed69f8..3b87c84d3b3e 100644 --- a/packages/twenty-server/src/business/modules/message/commands/stop-fetch-all-workspaces-messages.cron.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/stop-fetch-all-workspaces-messages.cron.command.ts @@ -2,10 +2,10 @@ import { Inject } from '@nestjs/common'; import { Command, CommandRunner } from 'nest-commander'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { fetchAllWorkspacesMessagesCronPattern } from 'src/business/modules/message/commands/crons/fetch-all-workspaces-messages.cron.pattern'; -import { FetchAllWorkspacesMessagesJob } from 'src/business/modules/message/commands/crons/fetch-all-workspaces-messages.job'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { fetchAllWorkspacesMessagesCronPattern } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern'; +import { FetchAllWorkspacesMessagesJob } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job'; @Command({ name: 'fetch-all-workspaces-messages:cron:stop', diff --git a/packages/twenty-server/src/business/modules/message/jobs/create-companies-and-contacts-after-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts similarity index 78% rename from packages/twenty-server/src/business/modules/message/jobs/create-companies-and-contacts-after-sync.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts index 2658a28f387d..650828b45fe0 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/create-companies-and-contacts-after-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts @@ -1,10 +1,10 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { CreateCompanyAndContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; -import { MessageParticipantService } from 'src/business/modules/message/repositories/message-participant/message-participant.service'; +import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; export type CreateCompaniesAndContactsAfterSyncJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-calendar-data.job.ts b/packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job.ts similarity index 81% rename from packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-calendar-data.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job.ts index 606e13f20847..2d41ada2fa43 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-calendar-data.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job.ts @@ -1,8 +1,8 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { CalendarEventCleanerService } from 'src/business/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service'; +import { CalendarEventCleanerService } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service'; export type DeleteConnectedAccountAssociatedCalendarDataJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-messaging-data.job.ts b/packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job.ts similarity index 82% rename from packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-messaging-data.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job.ts index f5dc33ab7d13..eacef905ba18 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/delete-connected-account-associated-messaging-data.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job.ts @@ -1,8 +1,8 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { ThreadCleanerService } from 'src/business/modules/message/services/thread-cleaner/thread-cleaner.service'; +import { ThreadCleanerService } from 'src/modules/messaging/services/thread-cleaner/thread-cleaner.service'; export type DeleteConnectedAccountAssociatedMessagingDataJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/jobs/gmail-full-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts similarity index 78% rename from packages/twenty-server/src/business/modules/message/jobs/gmail-full-sync.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts index 82a92a13a8d7..c721f1752d0a 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/gmail-full-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts @@ -1,9 +1,9 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service'; -import { GmailFullSyncService } from 'src/business/modules/message/services/gmail-full-sync.service'; +import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; +import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync.service'; export type GmailFullSyncJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/jobs/gmail-partial-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts similarity index 76% rename from packages/twenty-server/src/business/modules/message/jobs/gmail-partial-sync.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts index 0b045de1de2a..b96ca955f101 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/gmail-partial-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts @@ -1,9 +1,9 @@ import { Injectable, Logger } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/business/modules/calendar-and-messaging/services/google-apis-refresh-access-token.service'; -import { GmailPartialSyncService } from 'src/business/modules/message/services/gmail-partial-sync.service'; +import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; +import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync.service'; export type GmailPartialSyncJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/jobs/match-message-participant.job.ts b/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts similarity index 83% rename from packages/twenty-server/src/business/modules/message/jobs/match-message-participant.job.ts rename to packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts index fb6f77286584..2b058b7e55de 100644 --- a/packages/twenty-server/src/business/modules/message/jobs/match-message-participant.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; -import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { MessageParticipantService } from 'src/business/modules/message/repositories/message-participant/message-participant.service'; +import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; export type MatchMessageParticipantsJobData = { workspaceId: string; diff --git a/packages/twenty-server/src/business/modules/message/listeners/messaging-connected-account.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts similarity index 67% rename from packages/twenty-server/src/business/modules/message/listeners/messaging-connected-account.listener.ts rename to packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts index 9ad45b96966e..bb352d612155 100644 --- a/packages/twenty-server/src/business/modules/message/listeners/messaging-connected-account.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts @@ -1,18 +1,18 @@ import { Injectable, Inject } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { ObjectRecordDeleteEvent } from 'src/integrations/event-emitter/types/object-record-delete.event'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { DeleteConnectedAccountAssociatedCalendarDataJobData, DeleteConnectedAccountAssociatedCalendarDataJob, -} from 'src/business/modules/message/jobs/delete-connected-account-associated-calendar-data.job'; +} from 'src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job'; import { DeleteConnectedAccountAssociatedMessagingDataJobData, DeleteConnectedAccountAssociatedMessagingDataJob, -} from 'src/business/modules/message/jobs/delete-connected-account-associated-messaging-data.job'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; +} from 'src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; @Injectable() export class MessagingConnectedAccountListener { diff --git a/packages/twenty-server/src/business/modules/message/listeners/messaging-message-channel.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts similarity index 61% rename from packages/twenty-server/src/business/modules/message/listeners/messaging-message-channel.listener.ts rename to packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts index acc25f3accad..3176e245b84f 100644 --- a/packages/twenty-server/src/business/modules/message/listeners/messaging-message-channel.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts @@ -1,15 +1,15 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event'; -import { objectRecordChangedProperties } from 'src/integrations/event-emitter/utils/object-record-changed-properties.util'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; +import { objectRecordChangedProperties } from 'src/engine/integrations/event-emitter/utils/object-record-changed-properties.util'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { CreateCompaniesAndContactsAfterSyncJobData, CreateCompaniesAndContactsAfterSyncJob, -} from 'src/business/modules/message/jobs/create-companies-and-contacts-after-sync.job'; -import { MessageChannelObjectMetadata } from 'src/business/modules/message/message-channel.object-metadata'; +} from 'src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; @Injectable() export class MessagingMessageChannelListener { diff --git a/packages/twenty-server/src/business/modules/message/listeners/messaging-person.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts similarity index 67% rename from packages/twenty-server/src/business/modules/message/listeners/messaging-person.listener.ts rename to packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts index d12582eeeedd..fa45120a1cf7 100644 --- a/packages/twenty-server/src/business/modules/message/listeners/messaging-person.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts @@ -1,16 +1,16 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event'; -import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event'; -import { objectRecordChangedProperties as objectRecordUpdateEventChangedProperties } from 'src/integrations/event-emitter/utils/object-record-changed-properties.util'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; +import { objectRecordChangedProperties as objectRecordUpdateEventChangedProperties } from 'src/engine/integrations/event-emitter/utils/object-record-changed-properties.util'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { MatchMessageParticipantJob, MatchMessageParticipantsJobData, -} from 'src/business/modules/message/jobs/match-message-participant.job'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; +} from 'src/modules/messaging/jobs/match-message-participant.job'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; @Injectable() export class MessagingPersonListener { diff --git a/packages/twenty-server/src/business/modules/message/listeners/messaging-workspace-member.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts similarity index 67% rename from packages/twenty-server/src/business/modules/message/listeners/messaging-workspace-member.listener.ts rename to packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts index 7ebb028252cd..d220f35abc6e 100644 --- a/packages/twenty-server/src/business/modules/message/listeners/messaging-workspace-member.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts @@ -1,16 +1,16 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event'; -import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event'; -import { objectRecordChangedProperties as objectRecordUpdateEventChangedProperties } from 'src/integrations/event-emitter/utils/object-record-changed-properties.util'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; +import { objectRecordChangedProperties as objectRecordUpdateEventChangedProperties } from 'src/engine/integrations/event-emitter/utils/object-record-changed-properties.util'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { MatchMessageParticipantJob, MatchMessageParticipantsJobData, -} from 'src/business/modules/message/jobs/match-message-participant.job'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +} from 'src/modules/messaging/jobs/match-message-participant.job'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @Injectable() export class MessagingWorkspaceMemberListener { diff --git a/packages/twenty-server/src/modules/messaging/messaging.module.ts b/packages/twenty-server/src/modules/messaging/messaging.module.ts new file mode 100644 index 000000000000..d2da63b31d84 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/messaging.module.ts @@ -0,0 +1,76 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { HttpModule } from '@nestjs/axios'; + +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; +import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; +import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; +import { MessagingPersonListener } from 'src/modules/messaging/listeners/messaging-person.listener'; +import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; +import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; +import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; +import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; +import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync.service'; +import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync.service'; +import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; +import { MessagingWorkspaceMemberListener } from 'src/modules/messaging/listeners/messaging-workspace-member.listener'; +import { MessagingMessageChannelListener } from 'src/modules/messaging/listeners/messaging-message-channel.listener'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; +import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; +import { PersonModule } from 'src/modules/person/repositories/person/person.module'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; +import { MessagingConnectedAccountListener } from 'src/modules/messaging/listeners/messaging-connected-account.listener'; +import { BlocklistModule } from 'src/modules/connected-account/repositories/blocklist/blocklist.module'; +import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch.service'; +@Module({ + imports: [ + EnvironmentModule, + WorkspaceDataSourceModule, + ConnectedAccountModule, + MessageChannelModule, + MessageChannelMessageAssociationModule, + MessageModule, + MessageThreadModule, + MessageParticipantModule, + CreateCompaniesAndContactsModule, + WorkspaceMemberModule, + TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), + CompanyModule, + PersonModule, + BlocklistModule, + HttpModule.register({ + baseURL: 'https://www.googleapis.com/batch/gmail/v1', + }), + ], + providers: [ + GmailFullSyncService, + GmailPartialSyncService, + FetchMessagesByBatchesService, + GoogleAPIsRefreshAccessTokenService, + GmailClientProvider, + CreateContactService, + CreateCompanyService, + MessagingPersonListener, + MessagingWorkspaceMemberListener, + MessagingMessageChannelListener, + MessageService, + SaveMessagesAndCreateContactsService, + MessagingConnectedAccountListener, + FetchByBatchesService, + ], + exports: [ + GmailPartialSyncService, + GmailFullSyncService, + GoogleAPIsRefreshAccessTokenService, + FetchByBatchesService, + ], +}) +export class MessagingModule {} diff --git a/packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-many.pre-query.hook.ts b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts similarity index 73% rename from packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-many.pre-query.hook.ts rename to packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts index 14de89bc537e..b5fb45c3f869 100644 --- a/packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-many.pre-query.hook.ts +++ b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts @@ -7,13 +7,13 @@ import { import { groupBy } from 'lodash'; -import { WorkspacePreQueryHook } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; -import { FindManyResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; +import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { MessageChannelMessageAssociationService } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; -import { WorkspaceMemberService } from 'src/engine-workspace/repositories/workspace-member/workspace-member.service'; +import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; @Injectable() export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook { diff --git a/packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-one.pre-query-hook.ts b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook.ts similarity index 57% rename from packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-one.pre-query-hook.ts rename to packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook.ts index a23663404f52..fb8585815d7c 100644 --- a/packages/twenty-server/src/business/modules/message/query-hooks/message/message-find-one.pre-query-hook.ts +++ b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { BadRequestException, Injectable } from '@nestjs/common'; -import { WorkspacePreQueryHook } from 'src/engine/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; -import { FindOneResolverArgs } from 'src/engine/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; +import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; +import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; @Injectable() export class MessageFindOnePreQueryHook implements WorkspacePreQueryHook { diff --git a/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts b/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts new file mode 100644 index 000000000000..0b47c48ff9f2 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts @@ -0,0 +1,28 @@ +import { Module } from '@nestjs/common'; + +import { MessageFindManyPreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook'; +import { MessageFindOnePreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook'; +import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; +import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; +import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; +import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; + +@Module({ + imports: [ + MessageChannelMessageAssociationModule, + MessageChannelModule, + ConnectedAccountModule, + WorkspaceMemberModule, + ], + providers: [ + { + provide: MessageFindOnePreQueryHook.name, + useClass: MessageFindOnePreQueryHook, + }, + { + provide: MessageFindManyPreQueryHook.name, + useClass: MessageFindManyPreQueryHook, + }, + ], +}) +export class MessagingQueryHookModule {} diff --git a/packages/twenty-server/src/business/modules/message/repositories/company/company.module.ts b/packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts similarity index 77% rename from packages/twenty-server/src/business/modules/message/repositories/company/company.module.ts rename to packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts index eb82ec64f29b..61460d6bf876 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/company/company.module.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { CompanyService } from 'src/business/modules/message/repositories/company/company.service'; +import { CompanyService } from 'src/modules/messaging/repositories/company/company.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; // TODO: Move outside of the messaging module diff --git a/packages/twenty-server/src/business/modules/message/repositories/company/company.service.ts b/packages/twenty-server/src/modules/messaging/repositories/company/company.service.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/repositories/company/company.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/company/company.service.ts diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts similarity index 66% rename from packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts index 9019827de82e..7c9f4de8f5a4 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { MessageChannelMessageAssociationService } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service'; +import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts similarity index 98% rename from packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts index 83aefc1717ed..17454e6027bb 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageChannelMessageAssociationObjectMetadata } from 'src/business/modules/message/message-channel-message-association.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts similarity index 71% rename from packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.module.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts index 9524ca822878..90661ee6b506 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.module.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts similarity index 95% rename from packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts index 9723f52cd782..71712ea67887 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-channel/message-channel.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageChannelObjectMetadata } from 'src/business/modules/message/message-channel.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts similarity index 60% rename from packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.module.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts index eab29afbf1c8..e8754fe547b1 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.module.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; -import { MessageParticipantService } from 'src/business/modules/message/repositories/message-participant/message-participant.service'; +import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { PersonModule } from 'src/engine-workspace/repositories/person/person.module'; +import { PersonModule } from 'src/modules/person/repositories/person/person.module'; @Module({ imports: [WorkspaceDataSourceModule, PersonModule], diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts similarity index 96% rename from packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts index 0c4d093ae45a..71b9635f6481 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-participant/message-participant.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts @@ -3,13 +3,13 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageParticipantObjectMetadata } from 'src/business/modules/message/message-participant.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; import { ParticipantWithId, ParticipantWithMessageId, -} from 'src/business/modules/message/types/gmail-message'; -import { PersonService } from 'src/engine-workspace/repositories/person/person.service'; +} from 'src/modules/messaging/types/gmail-message'; +import { PersonService } from 'src/modules/person/repositories/person/person.service'; @Injectable() export class MessageParticipantService { diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts similarity index 50% rename from packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.module.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts index 6502cbfe5d9f..d08c2358bacc 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.module.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts @@ -1,8 +1,8 @@ import { Module, forwardRef } from '@nestjs/common'; -import { MessageChannelMessageAssociationModule } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageThreadService } from 'src/business/modules/message/repositories/message-thread/message-thread.service'; -import { MessageModule } from 'src/business/modules/message/repositories/message/message.module'; +import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; +import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; +import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts similarity index 92% rename from packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts index 823fc74ceb82..b4196940964c 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message-thread/message-thread.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts @@ -5,8 +5,8 @@ import { v4 } from 'uuid'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { MessageChannelMessageAssociationService } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; +import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; @Injectable() export class MessageThreadService { diff --git a/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts new file mode 100644 index 000000000000..d6cbaab6d81b --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts @@ -0,0 +1,23 @@ +import { Module, forwardRef } from '@nestjs/common'; + +import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; +import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; +import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; +import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; + +@Module({ + imports: [ + WorkspaceDataSourceModule, + forwardRef(() => MessageThreadModule), + MessageParticipantModule, + MessageChannelMessageAssociationModule, + MessageChannelModule, + CreateCompaniesAndContactsModule, + ], + providers: [MessageService], + exports: [MessageService], +}) +export class MessageModule {} diff --git a/packages/twenty-server/src/business/modules/message/repositories/message/message.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts similarity index 93% rename from packages/twenty-server/src/business/modules/message/repositories/message/message.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts index 405076cd2792..1dd039ac146f 100644 --- a/packages/twenty-server/src/business/modules/message/repositories/message/message.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts @@ -4,14 +4,14 @@ import { DataSource, EntityManager } from 'typeorm'; import { v4 } from 'uuid'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageObjectMetadata } from 'src/business/modules/message/message.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { GmailMessage } from 'src/business/modules/message/types/gmail-message'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; -import { MessageChannelMessageAssociationService } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageThreadService } from 'src/business/modules/message/repositories/message-thread/message-thread.service'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; +import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; +import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; @Injectable() export class MessageService { diff --git a/packages/twenty-server/src/business/modules/message/services/fetch-by-batch.service.ts b/packages/twenty-server/src/modules/messaging/services/fetch-by-batch.service.ts similarity index 93% rename from packages/twenty-server/src/business/modules/message/services/fetch-by-batch.service.ts rename to packages/twenty-server/src/modules/messaging/services/fetch-by-batch.service.ts index 0e1af2b8e749..4d12b306b01d 100644 --- a/packages/twenty-server/src/business/modules/message/services/fetch-by-batch.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/fetch-by-batch.service.ts @@ -3,8 +3,8 @@ import { Injectable } from '@nestjs/common'; import { AxiosResponse } from 'axios'; -import { BatchQueries } from 'src/business/modules/calendar-and-messaging/types/batch-queries'; -import { GmailMessageParsedResponse } from 'src/business/modules/message/types/gmail-message-parsed-response'; +import { BatchQueries } from 'src/modules/messaging/types/batch-queries'; +import { GmailMessageParsedResponse } from 'src/modules/messaging/types/gmail-message-parsed-response'; @Injectable() export class FetchByBatchesService { diff --git a/packages/twenty-server/src/business/modules/message/services/fetch-messages-by-batches.service.ts b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts similarity index 89% rename from packages/twenty-server/src/business/modules/message/services/fetch-messages-by-batches.service.ts rename to packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts index 9ba6ce853cfa..9fb5badbf3bd 100644 --- a/packages/twenty-server/src/business/modules/message/services/fetch-messages-by-batches.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts @@ -4,11 +4,11 @@ import { AxiosResponse } from 'axios'; import { simpleParser } from 'mailparser'; import planer from 'planer'; -import { GmailMessage } from 'src/business/modules/message/types/gmail-message'; -import { MessageQuery } from 'src/business/modules/message/types/message-or-thread-query'; -import { GmailMessageParsedResponse } from 'src/business/modules/message/types/gmail-message-parsed-response'; -import { FetchByBatchesService } from 'src/business/modules/message/services/fetch-by-batch.service'; -import { formatAddressObjectAsParticipants } from 'src/business/modules/message/services/utils/format-address-object-as-participants.util'; +import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { MessageQuery } from 'src/modules/messaging/types/message-or-thread-query'; +import { GmailMessageParsedResponse } from 'src/modules/messaging/types/gmail-message-parsed-response'; +import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch.service'; +import { formatAddressObjectAsParticipants } from 'src/modules/messaging/services/utils/format-address-object-as-participants.util'; @Injectable() export class FetchMessagesByBatchesService { diff --git a/packages/twenty-server/src/business/modules/message/services/gmail-full-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts similarity index 83% rename from packages/twenty-server/src/business/modules/message/services/gmail-full-sync.service.ts rename to packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts index a3d67f4d4581..cfcfe9171ff6 100644 --- a/packages/twenty-server/src/business/modules/message/services/gmail-full-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts @@ -3,21 +3,21 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { FetchMessagesByBatchesService } from 'src/business/modules/message/services/fetch-messages-by-batches.service'; -import { GmailClientProvider } from 'src/business/modules/message/services/providers/gmail/gmail-client.provider'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; +import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { GmailFullSyncJobData, GmailFullSyncJob, -} from 'src/business/modules/message/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; -import { MessageChannelMessageAssociationService } from 'src/business/modules/message/repositories/message-channel-message-association/message-channel-message-association.service'; -import { createQueriesFromMessageIds } from 'src/business/modules/message/utils/create-queries-from-message-ids.util'; -import { gmailSearchFilterExcludeEmails } from 'src/business/modules/message/utils/gmail-search-filter.util'; -import { BlocklistService } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service'; -import { SaveMessagesAndCreateContactsService } from 'src/business/modules/message/services/save-messages-and-create-contacts.service'; +} from 'src/modules/messaging/jobs/gmail-full-sync.job'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; +import { createQueriesFromMessageIds } from 'src/modules/messaging/utils/create-queries-from-message-ids.util'; +import { gmailSearchFilterExcludeEmails } from 'src/modules/messaging/utils/gmail-search-filter.util'; +import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; import { FeatureFlagEntity, FeatureFlagKeys, diff --git a/packages/twenty-server/src/business/modules/message/services/gmail-partial-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts similarity index 89% rename from packages/twenty-server/src/business/modules/message/services/gmail-partial-sync.service.ts rename to packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts index 0649b0ee522c..a9698b63cee8 100644 --- a/packages/twenty-server/src/business/modules/message/services/gmail-partial-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts @@ -4,22 +4,22 @@ import { InjectRepository } from '@nestjs/typeorm'; import { gmail_v1 } from 'googleapis'; import { Repository } from 'typeorm'; -import { FetchMessagesByBatchesService } from 'src/business/modules/message/services/fetch-messages-by-batches.service'; -import { GmailClientProvider } from 'src/business/modules/message/services/providers/gmail/gmail-client.provider'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; +import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { GmailFullSyncJob, GmailFullSyncJobData, -} from 'src/business/modules/message/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/business/modules/calendar-and-messaging/repositories/connected-account/connected-account.service'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; -import { createQueriesFromMessageIds } from 'src/business/modules/message/utils/create-queries-from-message-ids.util'; -import { GmailMessage } from 'src/business/modules/message/types/gmail-message'; -import { isPersonEmail } from 'src/business/modules/message/utils/is-person-email.util'; -import { BlocklistService } from 'src/business/modules/calendar-and-messaging/repositories/blocklist/blocklist.service'; -import { SaveMessagesAndCreateContactsService } from 'src/business/modules/message/services/save-messages-and-create-contacts.service'; +} from 'src/modules/messaging/jobs/gmail-full-sync.job'; +import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { createQueriesFromMessageIds } from 'src/modules/messaging/utils/create-queries-from-message-ids.util'; +import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { isPersonEmail } from 'src/modules/messaging/utils/is-person-email.util'; +import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; import { FeatureFlagEntity, FeatureFlagKeys, diff --git a/packages/twenty-server/src/business/modules/message/services/providers/gmail/gmail-client.provider.ts b/packages/twenty-server/src/modules/messaging/services/providers/gmail/gmail-client.provider.ts similarity index 91% rename from packages/twenty-server/src/business/modules/message/services/providers/gmail/gmail-client.provider.ts rename to packages/twenty-server/src/modules/messaging/services/providers/gmail/gmail-client.provider.ts index a8e397d349f7..3b5e591ac546 100644 --- a/packages/twenty-server/src/business/modules/message/services/providers/gmail/gmail-client.provider.ts +++ b/packages/twenty-server/src/modules/messaging/services/providers/gmail/gmail-client.provider.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { OAuth2Client } from 'google-auth-library'; import { gmail_v1, google } from 'googleapis'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() export class GmailClientProvider { diff --git a/packages/twenty-server/src/modules/messaging/services/providers/messaging-providers.module.ts b/packages/twenty-server/src/modules/messaging/services/providers/messaging-providers.module.ts new file mode 100644 index 000000000000..fc0cb1c178d9 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/providers/messaging-providers.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; +import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; + +@Module({ + imports: [EnvironmentModule], + providers: [GmailClientProvider], + exports: [GmailClientProvider], +}) +export class MessagingProvidersModule {} diff --git a/packages/twenty-server/src/business/modules/message/services/save-messages-and-create-contacts.service.ts b/packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts similarity index 88% rename from packages/twenty-server/src/business/modules/message/services/save-messages-and-create-contacts.service.ts rename to packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts index 138c3932cf04..87669c8cfe9b 100644 --- a/packages/twenty-server/src/business/modules/message/services/save-messages-and-create-contacts.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts @@ -2,16 +2,16 @@ import { Injectable, Logger } from '@nestjs/common'; import { EntityManager } from 'typeorm'; -import { MessageChannelService } from 'src/business/modules/message/repositories/message-channel/message-channel.service'; -import { MessageParticipantService } from 'src/business/modules/message/repositories/message-participant/message-participant.service'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; -import { CreateCompanyAndContactService } from 'src/engine-workspace/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; +import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; import { GmailMessage, ParticipantWithMessageId, -} from 'src/business/modules/message/types/gmail-message'; +} from 'src/modules/messaging/types/gmail-message'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() diff --git a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.module.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts similarity index 56% rename from packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.module.ts rename to packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts index 80b969eabf1a..722c3b0092bd 100644 --- a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts @@ -2,9 +2,9 @@ import { Module } from '@nestjs/common'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { MessageThreadModule } from 'src/business/modules/message/repositories/message-thread/message-thread.module'; -import { MessageModule } from 'src/business/modules/message/repositories/message/message.module'; -import { ThreadCleanerService } from 'src/business/modules/message/services/thread-cleaner/thread-cleaner.service'; +import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; +import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; +import { ThreadCleanerService } from 'src/modules/messaging/services/thread-cleaner/thread-cleaner.service'; @Module({ imports: [ diff --git a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.service.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts similarity index 75% rename from packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.service.ts rename to packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts index 8219e5b9c6b1..3374882b634c 100644 --- a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/thread-cleaner.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts @@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { MessageThreadService } from 'src/business/modules/message/repositories/message-thread/message-thread.service'; -import { MessageService } from 'src/business/modules/message/repositories/message/message.service'; -import { deleteUsingPagination } from 'src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util'; +import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; +import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { deleteUsingPagination } from 'src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util'; @Injectable() export class ThreadCleanerService { diff --git a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util.spec.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util.spec.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util.spec.ts rename to packages/twenty-server/src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util.spec.ts diff --git a/packages/twenty-server/src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/services/thread-cleaner/utils/delete-using-pagination.util.ts rename to packages/twenty-server/src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util.ts diff --git a/packages/twenty-server/src/business/modules/message/services/utils/__tests__/format-address-object-as-participants.util.spec.ts b/packages/twenty-server/src/modules/messaging/services/utils/__tests__/format-address-object-as-participants.util.spec.ts similarity index 86% rename from packages/twenty-server/src/business/modules/message/services/utils/__tests__/format-address-object-as-participants.util.spec.ts rename to packages/twenty-server/src/modules/messaging/services/utils/__tests__/format-address-object-as-participants.util.spec.ts index cb1ffd495702..03d52b91d03a 100644 --- a/packages/twenty-server/src/business/modules/message/services/utils/__tests__/format-address-object-as-participants.util.spec.ts +++ b/packages/twenty-server/src/modules/messaging/services/utils/__tests__/format-address-object-as-participants.util.spec.ts @@ -1,4 +1,4 @@ -import { formatAddressObjectAsParticipants } from 'src/business/modules/message/services/utils/format-address-object-as-participants.util'; +import { formatAddressObjectAsParticipants } from 'src/modules/messaging/services/utils/format-address-object-as-participants.util'; describe('formatAddressObjectAsParticipants', () => { it('should format address object as participants', () => { diff --git a/packages/twenty-server/src/business/modules/message/services/utils/format-address-object-as-participants.util.ts b/packages/twenty-server/src/modules/messaging/services/utils/format-address-object-as-participants.util.ts similarity index 92% rename from packages/twenty-server/src/business/modules/message/services/utils/format-address-object-as-participants.util.ts rename to packages/twenty-server/src/modules/messaging/services/utils/format-address-object-as-participants.util.ts index c9baa38ca917..674bfa2c7d44 100644 --- a/packages/twenty-server/src/business/modules/message/services/utils/format-address-object-as-participants.util.ts +++ b/packages/twenty-server/src/modules/messaging/services/utils/format-address-object-as-participants.util.ts @@ -1,6 +1,6 @@ import { AddressObject } from 'mailparser'; -import { Participant } from 'src/business/modules/message/types/gmail-message'; +import { Participant } from 'src/modules/messaging/types/gmail-message'; const formatAddressObjectAsArray = ( addressObject: AddressObject | AddressObject[], diff --git a/packages/twenty-server/src/business/modules/message/message-channel-message-association.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts similarity index 89% rename from packages/twenty-server/src/business/modules/message/message-channel-message-association.object-metadata.ts rename to packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts index 290de139a0c3..47e6169020ef 100644 --- a/packages/twenty-server/src/business/modules/message/message-channel-message-association.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts @@ -6,9 +6,9 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { MessageChannelObjectMetadata } from 'src/business/modules/message/message-channel.object-metadata'; -import { MessageThreadObjectMetadata } from 'src/business/modules/message/message-thread.object-metadata'; -import { MessageObjectMetadata } from 'src/business/modules/message/message.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.messageChannelMessageAssociation, diff --git a/packages/twenty-server/src/business/modules/message/message-channel.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts similarity index 94% rename from packages/twenty-server/src/business/modules/message/message-channel.object-metadata.ts rename to packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts index ac6f880a9a4f..39ee80fa6056 100644 --- a/packages/twenty-server/src/business/modules/message/message-channel.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts @@ -11,8 +11,8 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; -import { MessageChannelMessageAssociationObjectMetadata } from 'src/business/modules/message/message-channel-message-association.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.messageChannel, diff --git a/packages/twenty-server/src/business/modules/message/message-participant.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts similarity index 90% rename from packages/twenty-server/src/business/modules/message/message-participant.object-metadata.ts rename to packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts index b0b917f60c0f..49fdaf291b5f 100644 --- a/packages/twenty-server/src/business/modules/message/message-participant.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts @@ -6,9 +6,9 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { MessageObjectMetadata } from 'src/business/modules/message/message.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.messageParticipant, diff --git a/packages/twenty-server/src/business/modules/message/message-thread.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts similarity index 92% rename from packages/twenty-server/src/business/modules/message/message-thread.object-metadata.ts rename to packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts index a6d03242a048..d35b3aff8626 100644 --- a/packages/twenty-server/src/business/modules/message/message-thread.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts @@ -11,8 +11,8 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { MessageChannelMessageAssociationObjectMetadata } from 'src/business/modules/message/message-channel-message-association.object-metadata'; -import { MessageObjectMetadata } from 'src/business/modules/message/message.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.messageThread, diff --git a/packages/twenty-server/src/business/modules/message/message.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts similarity index 92% rename from packages/twenty-server/src/business/modules/message/message.object-metadata.ts rename to packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts index 2fb054a29533..1c2aa129abe5 100644 --- a/packages/twenty-server/src/business/modules/message/message.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts @@ -11,9 +11,9 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { MessageChannelMessageAssociationObjectMetadata } from 'src/business/modules/message/message-channel-message-association.object-metadata'; -import { MessageParticipantObjectMetadata } from 'src/business/modules/message/message-participant.object-metadata'; -import { MessageThreadObjectMetadata } from 'src/business/modules/message/message-thread.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.message, diff --git a/packages/twenty-server/src/business/modules/calendar-and-messaging/types/batch-queries.ts b/packages/twenty-server/src/modules/messaging/types/batch-queries.ts similarity index 100% rename from packages/twenty-server/src/business/modules/calendar-and-messaging/types/batch-queries.ts rename to packages/twenty-server/src/modules/messaging/types/batch-queries.ts diff --git a/packages/twenty-server/src/business/modules/message/types/gmail-message-parsed-response.ts b/packages/twenty-server/src/modules/messaging/types/gmail-message-parsed-response.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/types/gmail-message-parsed-response.ts rename to packages/twenty-server/src/modules/messaging/types/gmail-message-parsed-response.ts diff --git a/packages/twenty-server/src/business/modules/message/types/gmail-message.ts b/packages/twenty-server/src/modules/messaging/types/gmail-message.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/types/gmail-message.ts rename to packages/twenty-server/src/modules/messaging/types/gmail-message.ts diff --git a/packages/twenty-server/src/business/modules/message/types/gmail-thread.ts b/packages/twenty-server/src/modules/messaging/types/gmail-thread.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/types/gmail-thread.ts rename to packages/twenty-server/src/modules/messaging/types/gmail-thread.ts diff --git a/packages/twenty-server/src/business/modules/message/types/message-or-thread-query.ts b/packages/twenty-server/src/modules/messaging/types/message-or-thread-query.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/types/message-or-thread-query.ts rename to packages/twenty-server/src/modules/messaging/types/message-or-thread-query.ts diff --git a/packages/twenty-server/src/business/modules/message/utils/create-queries-from-message-ids.util.ts b/packages/twenty-server/src/modules/messaging/utils/create-queries-from-message-ids.util.ts similarity index 71% rename from packages/twenty-server/src/business/modules/message/utils/create-queries-from-message-ids.util.ts rename to packages/twenty-server/src/modules/messaging/utils/create-queries-from-message-ids.util.ts index 936ee7873224..304454488f15 100644 --- a/packages/twenty-server/src/business/modules/message/utils/create-queries-from-message-ids.util.ts +++ b/packages/twenty-server/src/modules/messaging/utils/create-queries-from-message-ids.util.ts @@ -1,4 +1,4 @@ -import { MessageQuery } from 'src/business/modules/message/types/message-or-thread-query'; +import { MessageQuery } from 'src/modules/messaging/types/message-or-thread-query'; export const createQueriesFromMessageIds = ( messageExternalIds: string[], diff --git a/packages/twenty-server/src/business/modules/message/utils/filter-out-participants-from-company-or-workspace.util.ts b/packages/twenty-server/src/modules/messaging/utils/filter-out-participants-from-company-or-workspace.util.ts similarity index 70% rename from packages/twenty-server/src/business/modules/message/utils/filter-out-participants-from-company-or-workspace.util.ts rename to packages/twenty-server/src/modules/messaging/utils/filter-out-participants-from-company-or-workspace.util.ts index 076efa26b295..ec569804ef02 100644 --- a/packages/twenty-server/src/business/modules/message/utils/filter-out-participants-from-company-or-workspace.util.ts +++ b/packages/twenty-server/src/modules/messaging/utils/filter-out-participants-from-company-or-workspace.util.ts @@ -1,6 +1,6 @@ -import { Participant } from 'src/business/modules/message/types/gmail-message'; -import { getDomainNameFromHandle } from 'src/business/modules/message/utils/get-domain-name-from-handle.util'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { Participant } from 'src/modules/messaging/types/gmail-message'; +import { getDomainNameFromHandle } from 'src/modules/messaging/utils/get-domain-name-from-handle.util'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; export function filterOutParticipantsFromCompanyOrWorkspace( diff --git a/packages/twenty-server/src/business/modules/message/utils/get-company-name-from-domain-name.util.ts b/packages/twenty-server/src/modules/messaging/utils/get-company-name-from-domain-name.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/utils/get-company-name-from-domain-name.util.ts rename to packages/twenty-server/src/modules/messaging/utils/get-company-name-from-domain-name.util.ts diff --git a/packages/twenty-server/src/business/modules/message/utils/get-domain-name-from-handle.util.ts b/packages/twenty-server/src/modules/messaging/utils/get-domain-name-from-handle.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/utils/get-domain-name-from-handle.util.ts rename to packages/twenty-server/src/modules/messaging/utils/get-domain-name-from-handle.util.ts diff --git a/packages/twenty-server/src/business/modules/message/utils/get-first-name-and-last-name-from-handle-and-display-name.util.ts b/packages/twenty-server/src/modules/messaging/utils/get-first-name-and-last-name-from-handle-and-display-name.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/utils/get-first-name-and-last-name-from-handle-and-display-name.util.ts rename to packages/twenty-server/src/modules/messaging/utils/get-first-name-and-last-name-from-handle-and-display-name.util.ts diff --git a/packages/twenty-server/src/business/modules/message/utils/get-unique-participants-and-handles.util.ts b/packages/twenty-server/src/modules/messaging/utils/get-unique-participants-and-handles.util.ts similarity index 86% rename from packages/twenty-server/src/business/modules/message/utils/get-unique-participants-and-handles.util.ts rename to packages/twenty-server/src/modules/messaging/utils/get-unique-participants-and-handles.util.ts index 340839badc2a..78e7587ed457 100644 --- a/packages/twenty-server/src/business/modules/message/utils/get-unique-participants-and-handles.util.ts +++ b/packages/twenty-server/src/modules/messaging/utils/get-unique-participants-and-handles.util.ts @@ -1,6 +1,6 @@ import { uniq, uniqBy } from 'lodash'; -import { Participant } from 'src/business/modules/message/types/gmail-message'; +import { Participant } from 'src/modules/messaging/types/gmail-message'; export function getUniqueParticipantsAndHandles(participants: Participant[]): { uniqueParticipants: Participant[]; uniqueHandles: string[]; diff --git a/packages/twenty-server/src/business/modules/message/utils/gmail-search-filter.util.ts b/packages/twenty-server/src/modules/messaging/utils/gmail-search-filter.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/utils/gmail-search-filter.util.ts rename to packages/twenty-server/src/modules/messaging/utils/gmail-search-filter.util.ts diff --git a/packages/twenty-server/src/business/modules/message/utils/is-person-email.util.ts b/packages/twenty-server/src/modules/messaging/utils/is-person-email.util.ts similarity index 100% rename from packages/twenty-server/src/business/modules/message/utils/is-person-email.util.ts rename to packages/twenty-server/src/modules/messaging/utils/is-person-email.util.ts diff --git a/packages/twenty-server/src/modules/modules.module.ts b/packages/twenty-server/src/modules/modules.module.ts new file mode 100644 index 000000000000..2d966e073296 --- /dev/null +++ b/packages/twenty-server/src/modules/modules.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { CalendarModule } from 'src/modules/calendar/calendar.module'; +import { MessagingModule } from 'src/modules/messaging/messaging.module'; + +@Module({ + imports: [MessagingModule, CalendarModule], + providers: [], + exports: [], +}) +export class ModulesModule {} diff --git a/packages/twenty-server/src/business/modules/opportunity/opportunity.object-metadata.ts b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts similarity index 89% rename from packages/twenty-server/src/business/modules/opportunity/opportunity.object-metadata.ts rename to packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts index 070bd1e45f83..13ac4f326b23 100644 --- a/packages/twenty-server/src/business/modules/opportunity/opportunity.object-metadata.ts +++ b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts @@ -11,13 +11,13 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; -import { PipelineStepObjectMetadata } from 'src/business/modules/pipeline-step/pipeline-step.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { PipelineStepObjectMetadata } from 'src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.opportunity, diff --git a/packages/twenty-server/src/engine-workspace/repositories/person/person.module.ts b/packages/twenty-server/src/modules/person/repositories/person/person.module.ts similarity index 76% rename from packages/twenty-server/src/engine-workspace/repositories/person/person.module.ts rename to packages/twenty-server/src/modules/person/repositories/person/person.module.ts index fc501bab62fa..adf359cf792c 100644 --- a/packages/twenty-server/src/engine-workspace/repositories/person/person.module.ts +++ b/packages/twenty-server/src/modules/person/repositories/person/person.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { PersonService } from 'src/engine-workspace/repositories/person/person.service'; +import { PersonService } from 'src/modules/person/repositories/person/person.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/engine-workspace/repositories/person/person.service.ts b/packages/twenty-server/src/modules/person/repositories/person/person.service.ts similarity index 95% rename from packages/twenty-server/src/engine-workspace/repositories/person/person.service.ts rename to packages/twenty-server/src/modules/person/repositories/person/person.service.ts index 1438d3a77403..502b12f654b9 100644 --- a/packages/twenty-server/src/engine-workspace/repositories/person/person.service.ts +++ b/packages/twenty-server/src/modules/person/repositories/person/person.service.ts @@ -4,7 +4,7 @@ import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { PersonObjectMetadata } from 'src/business/modules/person/person.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; // TODO: Move outside of the messaging module @Injectable() diff --git a/packages/twenty-server/src/business/modules/person/person.object-metadata.ts b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts similarity index 89% rename from packages/twenty-server/src/business/modules/person/person.object-metadata.ts rename to packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts index e499e6fe7189..3e84b9f961c8 100644 --- a/packages/twenty-server/src/business/modules/person/person.object-metadata.ts +++ b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts @@ -13,14 +13,14 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { ActivityTargetObjectMetadata } from 'src/business/modules/activity/activity-target.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { MessageParticipantObjectMetadata } from 'src/business/modules/message/message-participant.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.person, diff --git a/packages/twenty-server/src/business/modules/pipeline-step/pipeline-step.object-metadata.ts b/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts similarity index 95% rename from packages/twenty-server/src/business/modules/pipeline-step/pipeline-step.object-metadata.ts rename to packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts index 1794961f690c..b1a6ea25330f 100644 --- a/packages/twenty-server/src/business/modules/pipeline-step/pipeline-step.object-metadata.ts +++ b/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts @@ -8,7 +8,7 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { OpportunityObjectMetadata } from 'src/business/modules/opportunity/opportunity.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.pipelineStep, diff --git a/packages/twenty-server/src/business/modules/view/view-field.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts similarity index 96% rename from packages/twenty-server/src/business/modules/view/view-field.object-metadata.ts rename to packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts index 6a96954fe142..e2771474c031 100644 --- a/packages/twenty-server/src/business/modules/view/view-field.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts @@ -6,7 +6,7 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ViewObjectMetadata } from 'src/business/modules/view/view.object-metadata'; +import { ViewObjectMetadata } from 'src/modules/view/standard-objects/view.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.viewField, diff --git a/packages/twenty-server/src/business/modules/view/view-filter.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts similarity index 96% rename from packages/twenty-server/src/business/modules/view/view-filter.object-metadata.ts rename to packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts index bf68a32fc659..8f8479893b6e 100644 --- a/packages/twenty-server/src/business/modules/view/view-filter.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts @@ -6,7 +6,7 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ViewObjectMetadata } from 'src/business/modules/view/view.object-metadata'; +import { ViewObjectMetadata } from 'src/modules/view/standard-objects/view.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.viewFilter, diff --git a/packages/twenty-server/src/business/modules/view/view-sort.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts similarity index 95% rename from packages/twenty-server/src/business/modules/view/view-sort.object-metadata.ts rename to packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts index 7aea069db74f..8380ff7ac377 100644 --- a/packages/twenty-server/src/business/modules/view/view-sort.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts @@ -6,7 +6,7 @@ import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ViewObjectMetadata } from 'src/business/modules/view/view.object-metadata'; +import { ViewObjectMetadata } from 'src/modules/view/standard-objects/view.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.viewSort, diff --git a/packages/twenty-server/src/business/modules/view/view.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts similarity index 92% rename from packages/twenty-server/src/business/modules/view/view.object-metadata.ts rename to packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts index 514ccdf6a063..b1055cda4192 100644 --- a/packages/twenty-server/src/business/modules/view/view.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts @@ -8,9 +8,9 @@ import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/d import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { ViewFieldObjectMetadata } from 'src/business/modules/view/view-field.object-metadata'; -import { ViewFilterObjectMetadata } from 'src/business/modules/view/view-filter.object-metadata'; -import { ViewSortObjectMetadata } from 'src/business/modules/view/view-sort.object-metadata'; +import { ViewFieldObjectMetadata } from 'src/modules/view/standard-objects/view-field.object-metadata'; +import { ViewFilterObjectMetadata } from 'src/modules/view/standard-objects/view-filter.object-metadata'; +import { ViewSortObjectMetadata } from 'src/modules/view/standard-objects/view-sort.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.view, diff --git a/packages/twenty-server/src/business/modules/webhook/webhook.object-metadata.ts b/packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts similarity index 100% rename from packages/twenty-server/src/business/modules/webhook/webhook.object-metadata.ts rename to packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts diff --git a/packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.module.ts b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts similarity index 71% rename from packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.module.ts rename to packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts index 587f62c9dc4b..54465e4132f5 100644 --- a/packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.module.ts +++ b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { WorkspaceMemberService } from 'src/engine-workspace/repositories/workspace-member/workspace-member.service'; +import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.service.ts b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts similarity index 94% rename from packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.service.ts rename to packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts index 65a338467ae8..c5d097285925 100644 --- a/packages/twenty-server/src/engine-workspace/repositories/workspace-member/workspace-member.service.ts +++ b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts @@ -3,7 +3,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { WorkspaceMemberObjectMetadata } from 'src/business/modules/workspace/workspace-member.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; // TODO: Move outside of the messaging module diff --git a/packages/twenty-server/src/business/modules/workspace/workspace-member.object-metadata.ts b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts similarity index 88% rename from packages/twenty-server/src/business/modules/workspace/workspace-member.object-metadata.ts rename to packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts index c1de6e5e6a2d..4db6b22618e6 100644 --- a/packages/twenty-server/src/business/modules/workspace/workspace-member.object-metadata.ts +++ b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts @@ -11,16 +11,16 @@ import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decor import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { ActivityObjectMetadata } from 'src/business/modules/activity/activity.object-metadata'; -import { AttachmentObjectMetadata } from 'src/business/modules/attachment/attachment.object-metadata'; +import { ActivityObjectMetadata } from 'src/modules/activity/standard-objects/activity.object-metadata'; +import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { BlocklistObjectMetadata } from 'src/business/modules/calendar/blocklist.object-metadata'; -import { CalendarEventAttendeeObjectMetadata } from 'src/business/modules/calendar/calendar-event-attendee.object-metadata'; -import { CommentObjectMetadata } from 'src/business/modules/comment/comment.object-metadata'; -import { CompanyObjectMetadata } from 'src/business/modules/company/company.object-metadata'; -import { ConnectedAccountObjectMetadata } from 'src/business/modules/connected-account/connected-account.object-metadata'; -import { FavoriteObjectMetadata } from 'src/business/modules/favorite/favorite.object-metadata'; -import { MessageParticipantObjectMetadata } from 'src/business/modules/message/message-participant.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { CommentObjectMetadata } from 'src/modules/activity/standard-objects/comment.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.workspaceMember, diff --git a/packages/twenty-server/src/queue-worker.module.ts b/packages/twenty-server/src/queue-worker.module.ts deleted file mode 100644 index 50d93ea62514..000000000000 --- a/packages/twenty-server/src/queue-worker.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { JobsModule } from 'src/integrations/message-queue/jobs.module'; -import { IntegrationsModule } from 'src/integrations/integrations.module'; - -@Module({ - imports: [IntegrationsModule, JobsModule], -}) -export class QueueWorkerModule {} diff --git a/packages/twenty-server/src/queue-worker/queue-worker.module.ts b/packages/twenty-server/src/queue-worker/queue-worker.module.ts new file mode 100644 index 000000000000..d6c87b882383 --- /dev/null +++ b/packages/twenty-server/src/queue-worker/queue-worker.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; + +import { JobsModule } from 'src/engine/integrations/message-queue/jobs.module'; +import { IntegrationsModule } from 'src/engine/integrations/integrations.module'; + +@Module({ + imports: [IntegrationsModule, JobsModule], +}) +export class QueueWorkerModule {} diff --git a/packages/twenty-server/src/queue-worker.ts b/packages/twenty-server/src/queue-worker/queue-worker.ts similarity index 64% rename from packages/twenty-server/src/queue-worker.ts rename to packages/twenty-server/src/queue-worker/queue-worker.ts index 326ac9ce88fc..6218a488e786 100644 --- a/packages/twenty-server/src/queue-worker.ts +++ b/packages/twenty-server/src/queue-worker/queue-worker.ts @@ -3,17 +3,16 @@ import { NestFactory } from '@nestjs/core'; import { MessageQueueJob, MessageQueueJobData, -} from 'src/integrations/message-queue/interfaces/message-queue-job.interface'; +} from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { JobsModule } from 'src/integrations/message-queue/jobs.module'; -import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants'; -import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service'; -import { getJobClassName } from 'src/integrations/message-queue/utils/get-job-class-name.util'; -import { QueueWorkerModule } from 'src/queue-worker.module'; - -import { LoggerService } from './integrations/logger/logger.service'; -import { ExceptionHandlerService } from './integrations/exception-handler/exception-handler.service'; -import { filterException } from './engine/filters/utils/global-exception-handler.util'; +import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; +import { LoggerService } from 'src/engine/integrations/logger/logger.service'; +import { JobsModule } from 'src/engine/integrations/message-queue/jobs.module'; +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { getJobClassName } from 'src/engine/integrations/message-queue/utils/get-job-class-name.util'; +import { QueueWorkerModule } from 'src/queue-worker/queue-worker.module'; async function bootstrap() { let exceptionHandlerService: ExceptionHandlerService | undefined; diff --git a/packages/twenty-server/src/utils/pagination/find-many-cursor-connection.ts b/packages/twenty-server/src/utils/pagination/find-many-cursor-connection.ts deleted file mode 100644 index d11e9b6b7c18..000000000000 --- a/packages/twenty-server/src/utils/pagination/find-many-cursor-connection.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { - LessThanOrEqual, - MoreThanOrEqual, - ObjectLiteral, - SelectQueryBuilder, -} from 'typeorm'; - -import { IEdge } from './interfaces/edge.interface'; -import { IConnectionArguments } from './interfaces/connection-arguments.interface'; -import { IOptions } from './interfaces/options.interface'; -import { IConnection } from './interfaces/connection.interface'; -import { validateArgs } from './utils/validate-args'; -import { mergeDefaultOptions } from './utils/default-options'; -import { - isBackwardPagination, - isForwardPagination, -} from './utils/pagination-direction'; -import { encodeCursor, extractCursorKeyValue } from './utils/cursor'; - -/** - * Override cursors options - */ -export async function findManyCursorConnection< - Entity extends ObjectLiteral, - Record = Entity, - Cursor = { id: string }, - Node = Record, - CustomEdge extends IEdge = IEdge, ->( - query: SelectQueryBuilder, - args: IConnectionArguments = {}, - initialOptions?: IOptions, -): Promise> { - if (!validateArgs(args)) { - throw new Error('Should never happen'); - } - - const options = mergeDefaultOptions(initialOptions); - const totalCountQuery = query.clone(); - const totalCount = await totalCountQuery.getCount(); - // Only to extract cursor shape - const cursorKeys = Object.keys(options.getCursor(undefined) as any); - - let records: Array; - let hasNextPage: boolean; - let hasPreviousPage: boolean; - - // Add order by based on the cursor keys - for (const key of cursorKeys) { - query.addOrderBy(key, 'ASC'); - } - - if (isForwardPagination(args)) { - // Fetch one additional record to determine if there is a next page - const take = args.first + 1; - - // Extract cursor map based on the encoded cursor - const cursorMap = extractCursorKeyValue(args.after, options); - const skip = cursorMap ? 1 : undefined; - - if (cursorMap) { - const [keys, values] = cursorMap; - - // Add `cursor` filter in where condition - query.andWhere( - keys.reduce((acc, key, index) => { - return { - ...acc, - [key]: MoreThanOrEqual(values[index]), - }; - }, {}), - ); - } - - // Add `take` and `skip` to the query - query.take(take).skip(skip); - - // Fetch records - records = await options.getRecords(query); - - // See if we are "after" another record, indicating a previous page - hasPreviousPage = !!args.after; - - // See if we have an additional record, indicating a next page - hasNextPage = records.length > args.first; - - // Remove the extra record (last element) from the results - if (hasNextPage) records.pop(); - } else if (isBackwardPagination(args)) { - // Fetch one additional record to determine if there is a previous page - const take = -1 * (args.last + 1); - - // Extract cursor map based on the encoded cursor - const cursorMap = extractCursorKeyValue(args.before, options); - const skip = cursorMap ? 1 : undefined; - - if (cursorMap) { - const [keys, values] = cursorMap; - - // Add `cursor` filter in where condition - query.andWhere( - keys.reduce((acc, key, index) => { - return { - ...acc, - [key]: LessThanOrEqual(values[index]), - }; - }, {}), - ); - } - - // Add `take` and `skip` to the query - query.take(take).skip(skip); - - // Fetch records - records = await options.getRecords(query); - - // See if we are "before" another record, indicating a next page - hasNextPage = !!args.before; - - // See if we have an additional record, indicating a previous page - hasPreviousPage = records.length > args.last; - - // Remove the extra record (first element) from the results - if (hasPreviousPage) records.shift(); - } else { - // Fetch records - records = await options.getRecords(query); - - hasNextPage = false; - hasPreviousPage = false; - } - - // The cursors are always the first & last elements of the result set - const startCursor = - records.length > 0 ? encodeCursor(records[0], options) : undefined; - const endCursor = - records.length > 0 - ? encodeCursor(records[records.length - 1], options) - : undefined; - - // Allow the recordToEdge function to return a custom edge type which will be inferred - type EdgeExtended = typeof options.recordToEdge extends ( - record: Record, - ) => infer X - ? X extends CustomEdge - ? X & { cursor: string } - : CustomEdge - : CustomEdge; - - const edges = records.map((record) => { - return { - ...options.recordToEdge(record), - cursor: encodeCursor(record, options), - } as EdgeExtended; - }); - - return { - edges, - pageInfo: { hasNextPage, hasPreviousPage, startCursor, endCursor }, - totalCount, - }; -} diff --git a/packages/twenty-server/src/utils/pagination/index.ts b/packages/twenty-server/src/utils/pagination/index.ts deleted file mode 100644 index 7708d25c7d6a..000000000000 --- a/packages/twenty-server/src/utils/pagination/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { ConnectionCursor, ConnectionArgs, Paginated } from './paginated'; -export { findManyCursorConnection } from './find-many-cursor-connection'; diff --git a/packages/twenty-server/src/utils/pagination/interfaces/connection-arguments.interface.ts b/packages/twenty-server/src/utils/pagination/interfaces/connection-arguments.interface.ts deleted file mode 100644 index 45b24052364e..000000000000 --- a/packages/twenty-server/src/utils/pagination/interfaces/connection-arguments.interface.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface IConnectionArguments { - first?: number | null; - after?: string | null; - last?: number | null; - before?: string | null; -} - -export type ConnectionArgumentsUnion = - | ForwardPaginationArguments - | BackwardPaginationArguments - | NoPaginationArguments; - -export type ForwardPaginationArguments = { first: number; after?: string }; -export type BackwardPaginationArguments = { last: number; before?: string }; -export type NoPaginationArguments = Record; diff --git a/packages/twenty-server/src/utils/pagination/interfaces/connection-cursor.type.ts b/packages/twenty-server/src/utils/pagination/interfaces/connection-cursor.type.ts deleted file mode 100644 index 91e8cffc7148..000000000000 --- a/packages/twenty-server/src/utils/pagination/interfaces/connection-cursor.type.ts +++ /dev/null @@ -1 +0,0 @@ -export type ConnectionCursor = string; diff --git a/packages/twenty-server/src/utils/pagination/interfaces/find-many-aguments.interface.ts b/packages/twenty-server/src/utils/pagination/interfaces/find-many-aguments.interface.ts deleted file mode 100644 index 66063d8541da..000000000000 --- a/packages/twenty-server/src/utils/pagination/interfaces/find-many-aguments.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IFindManyArguments { - cursor?: Cursor; - take?: number; - skip?: number; -} diff --git a/packages/twenty-server/src/utils/pagination/interfaces/options.interface.ts b/packages/twenty-server/src/utils/pagination/interfaces/options.interface.ts deleted file mode 100644 index 24b430e792bc..000000000000 --- a/packages/twenty-server/src/utils/pagination/interfaces/options.interface.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { GraphQLResolveInfo } from 'graphql'; -import { ObjectLiteral, SelectQueryBuilder } from 'typeorm'; - -import { IEdge } from './edge.interface'; - -export interface IOptions< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, -> { - getRecords?: (args: SelectQueryBuilder) => Promise; - getCursor?: (record: Record | undefined) => Cursor; - encodeCursor?: (cursor: Cursor) => string; - decodeCursor?: (cursorString: string) => Cursor; - recordToEdge?: (record: Record) => Omit; - resolveInfo?: GraphQLResolveInfo | null; -} diff --git a/packages/twenty-server/src/utils/pagination/page-info.ts b/packages/twenty-server/src/utils/pagination/page-info.ts deleted file mode 100644 index 0b9f35e88373..000000000000 --- a/packages/twenty-server/src/utils/pagination/page-info.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Field, ObjectType } from '@nestjs/graphql'; - -import { IPageInfo } from './interfaces/page-info.interface'; -import { ConnectionCursor } from './interfaces/connection-cursor.type'; - -@ObjectType({ isAbstract: true }) -export class PageInfo implements IPageInfo { - @Field({ nullable: true }) - public startCursor!: ConnectionCursor; - - @Field({ nullable: true }) - public endCursor!: ConnectionCursor; - - @Field(() => Boolean) - public hasPreviousPage!: boolean; - - @Field(() => Boolean) - public hasNextPage!: boolean; -} diff --git a/packages/twenty-server/src/utils/pagination/paginated.ts b/packages/twenty-server/src/utils/pagination/paginated.ts deleted file mode 100644 index 5124ad99a619..000000000000 --- a/packages/twenty-server/src/utils/pagination/paginated.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Type } from '@nestjs/common'; -import { ArgsType, Field, ObjectType } from '@nestjs/graphql'; - -import { IsNumber, IsOptional, IsString } from 'class-validator'; - -import { PageInfo } from './page-info'; - -import { IConnectionArguments } from './interfaces/connection-arguments.interface'; -import { IConnection } from './interfaces/connection.interface'; -import { IEdge } from './interfaces/edge.interface'; -import { IPageInfo } from './interfaces/page-info.interface'; - -export type ConnectionCursor = string; - -/** - * ConnectionArguments - */ -@ArgsType() -export class ConnectionArgs implements IConnectionArguments { - @Field({ nullable: true, description: 'Paginate before opaque cursor' }) - @IsString() - @IsOptional() - public before?: ConnectionCursor; - - @Field({ nullable: true, description: 'Paginate after opaque cursor' }) - @IsString() - @IsOptional() - public after?: ConnectionCursor; - - @Field({ nullable: true, description: 'Paginate first' }) - @IsNumber() - @IsOptional() - public first?: number; - - @Field({ nullable: true, description: 'Paginate last' }) - @IsNumber() - @IsOptional() - public last?: number; -} - -/** - * Paginated graphQL class inheritance - */ -export function Paginated(classRef: Type): Type> { - @ObjectType(`${classRef.name}Edge`, { isAbstract: true }) - class Edge implements IEdge { - public name = `${classRef.name}Edge`; - - @Field({ nullable: true }) - public cursor!: ConnectionCursor; - - @Field(() => classRef, { nullable: true }) - public node!: T; - } - - @ObjectType(`${classRef.name}Connection`, { isAbstract: true }) - class Connection implements IConnection { - public name = `${classRef.name}Connection`; - - @Field(() => [Edge], { nullable: true }) - public edges!: IEdge[]; - - @Field(() => PageInfo, { nullable: true }) - public pageInfo!: IPageInfo; - - @Field() - totalCount: number; - } - - return Connection as Type>; -} - -// export const encodeCursor = (cursor: Cursor) => -// Buffer.from(JSON.stringify(cursor)).toString('base64'); - -// export const decodeCursor = (cursor: string) => -// JSON.parse(Buffer.from(cursor, 'base64').toString('ascii')) as Cursor; diff --git a/packages/twenty-server/src/utils/pagination/utils/cursor.ts b/packages/twenty-server/src/utils/pagination/utils/cursor.ts deleted file mode 100644 index 30f4d61a057c..000000000000 --- a/packages/twenty-server/src/utils/pagination/utils/cursor.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ObjectLiteral } from 'typeorm'; - -import { IEdge } from 'src/utils/pagination/interfaces/edge.interface'; - -import { MergedOptions } from './default-options'; - -export function decodeCursor< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, ->( - connectionCursor: string | undefined, - options: MergedOptions, -): Cursor | undefined { - if (!connectionCursor) { - return undefined; - } - - return options.decodeCursor(connectionCursor); -} - -export function encodeCursor< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, ->( - record: Record, - options: MergedOptions, -): string { - return options.encodeCursor(options.getCursor(record)); -} - -export function extractCursorKeyValue< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, ->( - connectionCursor: string | undefined, - options: MergedOptions, -): [string[], unknown[]] | undefined { - const cursor = decodeCursor(connectionCursor, options); - - if (!cursor) { - return undefined; - } - - return [Object.keys(cursor), Object.values(cursor)]; -} diff --git a/packages/twenty-server/src/utils/pagination/utils/default-options.ts b/packages/twenty-server/src/utils/pagination/utils/default-options.ts deleted file mode 100644 index eefea206a03e..000000000000 --- a/packages/twenty-server/src/utils/pagination/utils/default-options.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ObjectLiteral } from 'typeorm'; - -import { IEdge } from 'src/utils/pagination/interfaces/edge.interface'; -import { IOptions } from 'src/utils/pagination/interfaces/options.interface'; - -export type MergedOptions< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, -> = Required>; - -export function mergeDefaultOptions< - Entity extends ObjectLiteral, - Record, - Cursor, - Node, - CustomEdge extends IEdge, ->( - pOptions?: IOptions, -): MergedOptions { - return { - getRecords: async (query) => { - return query.getRawMany(); - }, - getCursor: (record: Record | undefined) => - ({ id: (record as unknown as { id: string })?.id }) as unknown as Cursor, - encodeCursor: (cursor: Cursor) => - Buffer.from((cursor as unknown as { id: string }).id.toString()).toString( - 'base64', - ), - decodeCursor: (cursorString: string) => - ({ - id: Buffer.from(cursorString, 'base64').toString(), - }) as unknown as Cursor, - recordToEdge: (record: Record) => - ({ node: record }) as unknown as Omit, - resolveInfo: null, - ...pOptions, - }; -} diff --git a/packages/twenty-server/src/utils/pagination/utils/pagination-direction.ts b/packages/twenty-server/src/utils/pagination/utils/pagination-direction.ts deleted file mode 100644 index e602342b8d35..000000000000 --- a/packages/twenty-server/src/utils/pagination/utils/pagination-direction.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - BackwardPaginationArguments, - ConnectionArgumentsUnion, - ForwardPaginationArguments, -} from 'src/utils/pagination/interfaces/connection-arguments.interface'; - -export function isForwardPagination( - args: ConnectionArgumentsUnion, -): args is ForwardPaginationArguments { - return 'first' in args && args.first != null; -} - -export function isBackwardPagination( - args: ConnectionArgumentsUnion, -): args is BackwardPaginationArguments { - return 'last' in args && args.last != null; -} diff --git a/packages/twenty-server/src/utils/pagination/utils/validate-args.ts b/packages/twenty-server/src/utils/pagination/utils/validate-args.ts deleted file mode 100644 index 213c452d25c1..000000000000 --- a/packages/twenty-server/src/utils/pagination/utils/validate-args.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { - ConnectionArgumentsUnion, - IConnectionArguments, -} from 'src/utils/pagination/interfaces/connection-arguments.interface'; - -export function validateArgs( - args: IConnectionArguments, -): args is ConnectionArgumentsUnion { - // Only one of `first` and `last` / `after` and `before` can be set - if (args.first != null && args.last != null) { - throw new Error('Only one of "first" and "last" can be set'); - } - - if (args.after != null && args.before != null) { - throw new Error('Only one of "after" and "before" can be set'); - } - - // If `after` is set, `first` has to be set - if (args.after != null && args.first == null) { - throw new Error('"after" needs to be used with "first"'); - } - - // If `before` is set, `last` has to be set - if (args.before != null && args.last == null) { - throw new Error('"before" needs to be used with "last"'); - } - - // `first` and `last` have to be positive - if (args.first != null && args.first <= 0) { - throw new Error('"first" has to be positive'); - } - - if (args.last != null && args.last <= 0) { - throw new Error('"last" has to be positive'); - } - - return true; -} From 1cc8edd01694a789669f174365b6ff9cee05ce98 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 19:14:57 +0100 Subject: [PATCH 06/44] Fix tests and linter --- .../hooks/__tests__/useEmailThread.test.ts | 38 --------- .../hooks/__tests__/useActivityById.test.ts | 38 --------- .../hooks/__tests__/useCompleteTask.test.ts | 47 ---------- ...njectIntoTimelineActivitiesQueries.test.ts | 85 ------------------- 4 files changed, 208 deletions(-) delete mode 100644 packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.ts delete mode 100644 packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityById.test.ts delete mode 100644 packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useInjectIntoTimelineActivitiesQueries.test.ts diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.ts b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.ts deleted file mode 100644 index a3bccb817dcd..000000000000 --- a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { act, renderHook } from '@testing-library/react'; - -import { useEmailThread } from '../useEmailThread'; - -const mockSetViewableEmailThreadId = jest.fn(); -const mockUseOpenEmailThreadRightDrawer = jest.fn(); - -jest.mock('recoil', () => ({ - useSetRecoilState: () => mockSetViewableEmailThreadId, -})); - -jest.mock( - '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer', - () => ({ - useOpenEmailThreadRightDrawer: () => mockUseOpenEmailThreadRightDrawer, - }), -); - -jest.mock('@/activities/emails/state/viewableEmailThreadIdState', () => ({ - viewableEmailThreadIdState: () => 'mockViewableEmailThreadIdState', -})); - -describe('useEmailThread hook', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('openEmailThread function', () => { - const { result } = renderHook(() => useEmailThread()); - - act(() => { - result.current.openEmailThread('mockThreadId'); - }); - - expect(mockSetViewableEmailThreadId).toHaveBeenCalledWith('mockThreadId'); - expect(mockUseOpenEmailThreadRightDrawer).toHaveBeenCalled(); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityById.test.ts b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityById.test.ts deleted file mode 100644 index 40f4521a9b33..000000000000 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityById.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import { RecoilRoot } from 'recoil'; - -import { useActivityById } from '../useActivityById'; - -jest.mock('@/object-record/hooks/useFindOneRecord', () => ({ - useFindOneRecord: jest.fn(() => ({ - record: { - activity: { - id: 'test-activity-id', - name: 'Test Activity', - description: 'This is a test activity', - }, - }, - loading: false, - })), -})); - -describe('useActivityById', () => { - it('fetches activity by id and returns the activity and loading state', async () => { - const activityId = 'test-activity-id'; - const { result } = renderHook(() => useActivityById({ activityId }), { - wrapper: RecoilRoot, - }); - - expect(result.current.loading).toBe(false); - - expect(result.current.activity).toEqual({ - activity: { - id: 'test-activity-id', - name: 'Test Activity', - description: 'This is a test activity', - }, - activityTargets: [], - comments: [], - }); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.ts deleted file mode 100644 index e74a741b16f4..000000000000 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { renderHook } from '@testing-library/react'; - -import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask'; - -const mockUpdateOneRecord = jest.fn(); -jest.mock('@/object-record/hooks/useUpdateOneRecord', () => ({ - useUpdateOneRecord: () => ({ - updateOneRecord: mockUpdateOneRecord, - }), -})); - -describe('useCompleteTask', () => { - it('should complete the task when called with true', async () => { - const taskId = 'test-task-id'; - const { result } = renderHook(() => - useCompleteTask({ id: taskId, completedAt: null }), - ); - - const { completeTask } = result.current; - completeTask(true); - - expect(mockUpdateOneRecord).toHaveBeenCalledWith({ - idToUpdate: taskId, - updateOneRecordInput: { - completedAt: expect.any(String), - }, - }); - }); - - it('should uncomplete the task when called with false', async () => { - const taskId = 'test-task-id'; - const { result } = renderHook(() => - useCompleteTask({ id: taskId, completedAt: '2021-01-01T00:00:00' }), - ); - - const { completeTask } = result.current; - - completeTask(false); - - expect(mockUpdateOneRecord).toHaveBeenCalledWith({ - idToUpdate: taskId, - updateOneRecordInput: { - completedAt: null, - }, - }); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useInjectIntoTimelineActivitiesQueries.test.ts b/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useInjectIntoTimelineActivitiesQueries.test.ts deleted file mode 100644 index 7b033859e1ba..000000000000 --- a/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useInjectIntoTimelineActivitiesQueries.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { renderHook } from '@testing-library/react'; - -import { useInjectIntoActivitiesQueries } from '@/activities/hooks/useInjectIntoActivitiesQueries'; -import { useInjectIntoTimelineActivitiesQueries } from '@/activities/timeline/hooks/useInjectIntoTimelineActivitiesQueries'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; - -jest.mock('@/activities/hooks/useInjectIntoActivitiesQueries', () => ({ - useInjectIntoActivitiesQueries: jest.fn(() => ({ - injectActivitiesQueries: jest.fn(), - })), -})); - -describe('useInjectIntoTimelineActivitiesQueries', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should inject activities into timeline activities queries correctly', () => { - const mockActivityToInject: Activity = { - id: 'activity1', - createdAt: '2022-01-01T00:00:00', - updatedAt: '2022-01-01T00:00:00', - completedAt: '2022-01-01T00:00:00', - __typename: 'Activity', - reminderAt: '2022-01-01T00:00:00', - dueAt: '2022-01-01T00:00:00', - type: 'Task', - activityTargets: [], - title: 'Activity 1', - body: 'Activity 1 body', - author: { - id: 'author1', - name: { - firstName: 'John', - lastName: 'Doe', - }, - avatarUrl: 'https://example.com/avatar1.jpg', - }, - authorId: 'author1', - assignee: null, - assigneeId: null, - comments: [], - }; - const mockActivityTargetsToInject: ActivityTarget[] = [ - { - id: 'target1', - updatedAt: '2022-01-01T00:00:00', - createdAt: '2022-01-01T00:00:00', - activity: { - id: 'activity1', - createdAt: '2022-01-01T00:00:00', - updatedAt: '2022-01-01T00:00:00', - }, - }, - { - id: 'target2', - updatedAt: '2022-01-01T00:00:00', - createdAt: '2022-01-01T00:00:00', - activity: { - id: 'activity1', - createdAt: '2022-01-01T00:00:00', - updatedAt: '2022-01-01T00:00:00', - }, - }, - ]; - const mockTimelineTargetableObject: ActivityTargetableObject = { - id: 'timelineTarget1', - targetObjectNameSingular: 'Timeline', - }; - - const { result } = renderHook(() => - useInjectIntoTimelineActivitiesQueries(), - ); - - result.current.injectIntoTimelineActivitiesQueries({ - activityToInject: mockActivityToInject, - activityTargetsToInject: mockActivityTargetsToInject, - timelineTargetableObject: mockTimelineTargetableObject, - }); - - expect(useInjectIntoActivitiesQueries).toHaveBeenCalledTimes(1); - }); -}); From 8980cc576ce5bc9df75a2972dcccbbc91ebe0396 Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Fri, 15 Mar 2024 19:15:22 +0100 Subject: [PATCH 07/44] Prevent file upload in demo workspaces (#4503) * Build demo env guard * Put guard for auth * Add todo --------- Co-authored-by: Thomas Trompette --- .../src/engine/guards/demo.env.guard.ts | 36 +++++++++++++++++++ .../google-apis-auth.controller.ts | 9 ++--- .../google-gmail-auth.controller.ts | 26 ++++++-------- .../src/engine/modules/file/file.module.ts | 9 ++++- .../file/resolvers/file-upload.resolver.ts | 3 +- .../src/engine/modules/user/user.resolver.ts | 18 +++------- .../modules/workspace/workspace.resolver.ts | 13 ++----- 7 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 packages/twenty-server/src/engine/guards/demo.env.guard.ts diff --git a/packages/twenty-server/src/engine/guards/demo.env.guard.ts b/packages/twenty-server/src/engine/guards/demo.env.guard.ts new file mode 100644 index 000000000000..49fe9ae479dc --- /dev/null +++ b/packages/twenty-server/src/engine/guards/demo.env.guard.ts @@ -0,0 +1,36 @@ +import { + Injectable, + ExecutionContext, + UnauthorizedException, +} from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; + +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { getRequest } from 'src/utils/extract-request'; + +@Injectable() +export class DemoEnvGuard extends AuthGuard(['jwt']) { + constructor(private readonly environmentService: EnvironmentService) { + super(); + } + + getRequest(context: ExecutionContext) { + return getRequest(context); + } + + // TODO: input should be typed + handleRequest(err: any, user: any) { + const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); + const currentUserWorkspaceId = user?.workspace?.id; + + if (!currentUserWorkspaceId) { + throw new UnauthorizedException('Unauthorized for not logged in user'); + } + + if (demoWorkspaceIds.includes(currentUserWorkspaceId)) { + throw new UnauthorizedException('Unauthorized for demo workspace'); + } + + return user; + } +} diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts index 7cdb6279e814..1001cb07301a 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts @@ -8,6 +8,7 @@ import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-api import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; @Controller('auth/google-apis') export class GoogleAPIsAuthController { @@ -25,7 +26,7 @@ export class GoogleAPIsAuthController { } @Get('get-access-token') - @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard) + @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard) async googleAuthGetAccessToken( @Req() req: GoogleAPIsRequest, @Res() res: Response, @@ -37,12 +38,6 @@ export class GoogleAPIsAuthController { const { workspaceMemberId, workspaceId } = await this.tokenService.verifyTransientToken(transientToken); - const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); - - if (demoWorkspaceIds.includes(workspaceId)) { - throw new Error('Cannot connect Google account to demo workspace'); - } - if (!workspaceId) { throw new Error('Workspace not found'); } diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts index 18e15db3739a..96262fe243bf 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts @@ -2,6 +2,7 @@ import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis-oauth.guard'; import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-apis-provider-enabled.guard'; import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; @@ -25,7 +26,7 @@ export class GoogleGmailAuthController { } @Get('get-access-token') - @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard) + @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard) async googleAuthGetAccessToken( @Req() req: GoogleAPIsRequest, @Res() res: Response, @@ -37,25 +38,18 @@ export class GoogleGmailAuthController { const { workspaceMemberId, workspaceId } = await this.tokenService.verifyTransientToken(transientToken); - const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); - - if (demoWorkspaceIds.includes(workspaceId)) { - throw new Error('Cannot connect Gmail account to demo workspace'); - } - if (!workspaceId) { throw new Error('Workspace not found'); } - if (workspaceId) - await this.googleGmailService.saveConnectedAccount({ - handle: email, - workspaceMemberId: workspaceMemberId, - workspaceId: workspaceId, - provider: 'gmail', - accessToken, - refreshToken, - }); + await this.googleGmailService.saveConnectedAccount({ + handle: email, + workspaceMemberId: workspaceMemberId, + workspaceId: workspaceId, + provider: 'gmail', + accessToken, + refreshToken, + }); return res.redirect( `${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`, diff --git a/packages/twenty-server/src/engine/modules/file/file.module.ts b/packages/twenty-server/src/engine/modules/file/file.module.ts index 7d68ad3ceb7d..76d145d78b66 100644 --- a/packages/twenty-server/src/engine/modules/file/file.module.ts +++ b/packages/twenty-server/src/engine/modules/file/file.module.ts @@ -1,12 +1,19 @@ import { Module } from '@nestjs/common'; +import { EnvironmentService } from 'src/integrations/environment/environment.service'; + import { FileService } from './services/file.service'; import { FileUploadService } from './services/file-upload.service'; import { FileUploadResolver } from './resolvers/file-upload.resolver'; import { FileController } from './controllers/file.controller'; @Module({ - providers: [FileService, FileUploadService, FileUploadResolver], + providers: [ + FileService, + FileUploadService, + FileUploadResolver, + EnvironmentService, + ], exports: [FileService, FileUploadService], controllers: [FileController], }) diff --git a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts b/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts index 23b459d57fe9..fc7312371414 100644 --- a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts +++ b/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts @@ -8,8 +8,9 @@ import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.inter import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; -@UseGuards(JwtAuthGuard) +@UseGuards(JwtAuthGuard, DemoEnvGuard) @Resolver() export class FileUploadResolver { constructor(private readonly fileUploadService: FileUploadService) {} diff --git a/packages/twenty-server/src/engine/modules/user/user.resolver.ts b/packages/twenty-server/src/engine/modules/user/user.resolver.ts index a909829f2f4a..b9b051edd694 100644 --- a/packages/twenty-server/src/engine/modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/modules/user/user.resolver.ts @@ -6,7 +6,7 @@ import { ResolveField, Mutation, } from '@nestjs/graphql'; -import { ForbiddenException, UseGuards } from '@nestjs/common'; +import { UseGuards } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import crypto from 'crypto'; @@ -22,6 +22,7 @@ import { EnvironmentService } from 'src/engine/integrations/environment/environm import { streamToBuffer } from 'src/utils/stream-to-buffer'; import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; import { assert } from 'src/utils/assert'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { User } from 'src/engine/modules/user/user.entity'; import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; @@ -108,20 +109,9 @@ export class UserResolver { return paths[0]; } + @UseGuards(DemoEnvGuard) @Mutation(() => User) - async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) { - // Get the list of demo workspace IDs - const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); - - const currentUserWorkspaceId = defaultWorkspace.id; - - // Check if the user's default workspace ID is in the list of demo workspace IDs - if (demoWorkspaceIds.includes(currentUserWorkspaceId)) { - throw new ForbiddenException( - 'Deletion of users with a default demo workspace is not allowed.', - ); - } - + async deleteUser(@AuthUser() { id: userId }: User) { // Proceed with user deletion return this.userService.deleteUser(userId); } diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts index b83cad9f2e8d..061f4a8bdd58 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts @@ -6,7 +6,7 @@ import { ResolveField, Parent, } from '@nestjs/graphql'; -import { ForbiddenException, UseGuards } from '@nestjs/common'; +import { UseGuards } from '@nestjs/common'; import { FileUpload, GraphQLUpload } from 'graphql-upload'; @@ -18,12 +18,12 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { assert } from 'src/utils/assert'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { UpdateWorkspaceInput } from 'src/engine/modules/workspace/dtos/update-workspace-input'; -import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/modules/user/user.entity'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; import { BillingService } from 'src/engine/modules/billing/billing.service'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { Workspace } from './workspace.entity'; @@ -35,7 +35,6 @@ export class WorkspaceResolver { constructor( private readonly workspaceService: WorkspaceService, private readonly fileUploadService: FileUploadService, - private readonly environmentService: EnvironmentService, private readonly billingService: BillingService, ) {} @@ -89,15 +88,9 @@ export class WorkspaceResolver { return paths[0]; } + @UseGuards(DemoEnvGuard) @Mutation(() => Workspace) async deleteCurrentWorkspace(@AuthWorkspace() { id }: Workspace) { - const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); - - // Check if the id is in the list of demo workspaceIds - if (demoWorkspaceIds.includes(id)) { - throw new ForbiddenException('Demo workspaces cannot be deleted.'); - } - return this.workspaceService.deleteWorkspace(id); } From cd9f402bc25be41600d349095e71e82464d74391 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 19:39:01 +0100 Subject: [PATCH 08/44] Fix calendar broken tests --- .../__stories__/Calendar.stories.tsx | 5 +- .../utils/getObjectMetadataItemsMock.ts | 17 + .../src/testing/mock-data/metadata.ts | 477 ++++++++++++++++++ 3 files changed, 498 insertions(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/activities/calendar/components/__stories__/Calendar.stories.tsx b/packages/twenty-front/src/modules/activities/calendar/components/__stories__/Calendar.stories.tsx index 26c9083c2f00..65b8e0b17bc7 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/__stories__/Calendar.stories.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/__stories__/Calendar.stories.tsx @@ -2,13 +2,16 @@ import { Meta, StoryObj } from '@storybook/react'; import { Calendar } from '@/activities/calendar/components/Calendar'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; +import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; const meta: Meta = { title: 'Modules/Activities/Calendar/Calendar', component: Calendar, - decorators: [ComponentDecorator], + decorators: [ComponentDecorator, SnackBarDecorator], parameters: { container: { width: 728 }, + msw: graphqlMocks, }, }; diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts index 69202da6b0e0..d6711dc0b76c 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts @@ -19,6 +19,23 @@ export const getObjectMetadataItemsMock = () => { updatedAt: '2023-11-30T11:13:15.206Z', fields: [], }, + { + __typename: 'object', + id: '20202020-ddee-40de-9c9b-5f82a3503361', + dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', + nameSingular: 'calendarEvent', + namePlural: 'calendarEvents', + labelSingular: 'Calendar Event', + labelPlural: 'Calendar Events', + description: 'A calendar event', + icon: 'IconCalendarEvent', + isCustom: false, + isActive: true, + isSystem: true, + createdAt: '2023-11-30T11:13:15.206Z', + updatedAt: '2023-11-30T11:13:15.206Z', + fields: [], + }, { __typename: 'object', id: '20202020-d8d0-4c2d-a370-5499b2181d02', diff --git a/packages/twenty-front/src/testing/mock-data/metadata.ts b/packages/twenty-front/src/testing/mock-data/metadata.ts index 8a6371bed94d..768608ccfcd3 100644 --- a/packages/twenty-front/src/testing/mock-data/metadata.ts +++ b/packages/twenty-front/src/testing/mock-data/metadata.ts @@ -1398,6 +1398,482 @@ export const mockedPipelineStepsMetadata = { }, }; +const mockedCalendarEventsMetadata = { + __typename: 'objectEdge', + node: { + __typename: 'object', + id: 'dd77da2e-bc12-4443-b323-097656d720fc', + dataSourceId: 'fa94b810-e848-490c-a5f7-24a1ee5bfaa6', + nameSingular: 'calendarEvent', + namePlural: 'calendarEvents', + labelSingular: 'Calendar event', + labelPlural: 'Calendar events', + description: 'Calendar events', + icon: 'IconCalendar', + isCustom: false, + isActive: true, + isSystem: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + labelIdentifierFieldMetadataId: null, + imageIdentifierFieldMetadataId: null, + fields: { + __typename: 'ObjectFieldsConnection', + pageInfo: { + __typename: 'PageInfo', + hasNextPage: false, + hasPreviousPage: false, + startCursor: 'YXJyYXljb25uZWN0aW9uOjA=', + endCursor: 'YXJyYXljb25uZWN0aW9uOjE3', + }, + edges: [ + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '6fee09b1-a964-4b34-b239-a38d91b137f1', + type: 'DATE_TIME', + name: 'endsAt', + label: 'End DateTime', + description: 'End DateTime', + icon: 'IconCalendarClock', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '071d3b2a-9168-45bb-9a83-e840eb707d14', + type: 'TEXT', + name: 'conferenceUri', + label: 'Conference URI', + description: 'Conference URI', + icon: 'IconLink', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'dce09597-dde3-462b-8a8b-d0bae238df2b', + type: 'RELATION', + name: 'calendarChannelEventAssociations', + label: 'Calendar Channel Event Associations', + description: 'Calendar Channel Event Associations', + icon: 'IconCalendar', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + toRelationMetadata: null, + fromRelationMetadata: { + __typename: 'relation', + id: 'f4950160-aabd-44a3-b369-37b03b8f9ac6', + relationType: 'ONE_TO_MANY', + toFieldMetadataId: '8b4cd1d9-cd30-40c5-a01c-0d468443a704', + toObjectMetadata: { + __typename: 'object', + id: '7dd1f608-7696-43d1-8b5e-c95ea78b1e7a', + dataSourceId: 'fa94b810-e848-490c-a5f7-24a1ee5bfaa6', + nameSingular: 'calendarChannelEventAssociation', + namePlural: 'calendarChannelEventAssociations', + isSystem: true, + }, + }, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'ad4c78c7-1353-4f31-b2bf-57d97c528d4a', + type: 'TEXT', + name: 'iCalUID', + label: 'iCal UID', + description: 'iCal UID', + icon: 'IconKey', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '65a99333-4cd9-44af-94cc-e19a479ecc1e', + type: 'TEXT', + name: 'title', + label: 'Title', + description: 'Title', + icon: 'IconH1', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'd9cd21f2-7401-4873-b19c-3c9d7ed8bee2', + type: 'TEXT', + name: 'recurringEventExternalId', + label: 'Recurring Event ID', + description: 'Recurring Event ID', + icon: 'IconHistory', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '38f3297b-fe2e-434f-867b-963ed2c75ee0', + type: 'DATE_TIME', + name: 'externalCreatedAt', + label: 'Creation DateTime', + description: 'Creation DateTime', + icon: 'IconCalendarPlus', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '5232193e-6016-4f13-bdcd-95478dfe8e4a', + type: 'TEXT', + name: 'location', + label: 'Location', + description: 'Location', + icon: 'IconMapPin', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'bb49e0cc-72e6-4bc5-8bae-75e7b4f6cd53', + type: 'DATE_TIME', + name: 'startsAt', + label: 'Start DateTime', + description: 'Start DateTime', + icon: 'IconCalendarClock', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '07880d2d-4f08-458f-be0b-876402d2a769', + type: 'RELATION', + name: 'eventAttendees', + label: 'Event Attendees', + description: 'Event Attendees', + icon: 'IconUserCircle', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + toRelationMetadata: null, + fromRelationMetadata: { + __typename: 'relation', + id: '6ca76ccc-bdb1-4357-809e-66149e54474b', + relationType: 'ONE_TO_MANY', + toFieldMetadataId: '2ad8bb23-68f5-4a77-b23f-cac8db34a5f0', + toObjectMetadata: { + __typename: 'object', + id: '4adb1b1a-9643-4d1c-a2a0-b1b02ae192ad', + dataSourceId: 'fa94b810-e848-490c-a5f7-24a1ee5bfaa6', + nameSingular: 'calendarEventAttendee', + namePlural: 'calendarEventAttendees', + isSystem: true, + }, + }, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '0d348548-f8a8-4669-872e-43ef01e3d93b', + type: 'DATE_TIME', + name: 'externalUpdatedAt', + label: 'Update DateTime', + description: 'Update DateTime', + icon: 'IconCalendarCog', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: true, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '37d357eb-fc04-4b5c-a633-345b677d2c87', + type: 'TEXT', + name: 'description', + label: 'Description', + description: 'Description', + icon: 'IconFileDescription', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '3d14da78-db95-403e-bb2f-06ed076574cb', + type: 'TEXT', + name: 'conferenceSolution', + label: 'Conference Solution', + description: 'Conference Solution', + icon: 'IconScreenShare', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + value: '', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '847a63f7-0614-4491-b445-c67269868c93', + type: 'UUID', + name: 'id', + label: 'Id', + description: 'Id', + icon: 'Icon123', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + type: 'uuid', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '1d7a9a99-b6ef-4fae-abcd-60bba4d4cf5b', + type: 'BOOLEAN', + name: 'isFullDay', + label: 'Is Full Day', + description: 'Is Full Day', + icon: 'Icon24Hours', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '91058295-2974-4924-937a-2e6dec4b3b01', + type: 'BOOLEAN', + name: 'isCanceled', + label: 'Is canceled', + description: 'Is canceled', + icon: 'IconCalendarCancel', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: null, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'b93abe19-6228-4971-9ef0-4e38ef5ed314', + type: 'DATE_TIME', + name: 'createdAt', + label: 'Creation date', + description: 'Creation date', + icon: 'IconCalendar', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + type: 'now', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + { + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: 'f8b1abe7-8d26-4502-ac15-6f49c5112bb0', + type: 'DATE_TIME', + name: 'updatedAt', + label: 'Update date', + description: 'Update date', + icon: 'IconCalendar', + isCustom: false, + isActive: true, + isSystem: true, + isNullable: false, + createdAt: '2024-03-15T13:39:09.965Z', + updatedAt: '2024-03-15T13:39:09.965Z', + defaultValue: { + type: 'now', + }, + options: null, + fromRelationMetadata: null, + toRelationMetadata: null, + }, + }, + ], + }, + }, +} as ObjectEdge; + export const mockedActivityTargetsMetadata = { __typename: 'objectEdge', node: { @@ -7035,6 +7511,7 @@ export const mockedObjectMetadataItems = { mockedConnectedAccountsMetadata, mockedMessageChannelsMetadata, mockedWebhooksMetadata, + mockedCalendarEventsMetadata, mockedAttachmentsMetadata, mockedMessageParticipantsMetadata, mockedCustomMetadata, From dc9b84114a991d5d743a6a1ce633b96eecaf32e7 Mon Sep 17 00:00:00 2001 From: Abdullah <125115953+mabdullahabaid@users.noreply.github.com> Date: Sat, 16 Mar 2024 00:05:35 +0500 Subject: [PATCH 09/44] Server fix: Update EnvironmentService import path in File Module. (#4508) fix: update the import path for environment service inside the file.module.ts file to get the server up again --- packages/twenty-server/src/engine/modules/file/file.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-server/src/engine/modules/file/file.module.ts b/packages/twenty-server/src/engine/modules/file/file.module.ts index 76d145d78b66..0c0a42f15334 100644 --- a/packages/twenty-server/src/engine/modules/file/file.module.ts +++ b/packages/twenty-server/src/engine/modules/file/file.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { FileService } from './services/file.service'; import { FileUploadService } from './services/file-upload.service'; From e0ae12ffa12befd0a365ab43ea43edda64c6fc90 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 21:15:14 +0100 Subject: [PATCH 10/44] Fix server deploy (#4509) * Fix server deployment broken by nx * Fix server deployment broken by nx * Fix server deployment broken by nx * Fix * Fix * Fix * Fix --- .../prod/twenty-server/Dockerfile | 1 - .../utils/getObjectMetadataItemsMock.ts | 34 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/twenty-docker/prod/twenty-server/Dockerfile b/packages/twenty-docker/prod/twenty-server/Dockerfile index 954e1c39779e..84a9b695809d 100644 --- a/packages/twenty-docker/prod/twenty-server/Dockerfile +++ b/packages/twenty-docker/prod/twenty-server/Dockerfile @@ -6,7 +6,6 @@ COPY ./package.json . COPY ./yarn.lock . COPY ./.yarnrc.yml . COPY ./tsconfig.base.json . -COPY ./nx.json . COPY ./.yarn/releases /app/.yarn/releases COPY ./packages/twenty-emails /app/packages/twenty-emails COPY ./packages/twenty-server /app/packages/twenty-server diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts index d6711dc0b76c..f14d5607e409 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts @@ -19,23 +19,6 @@ export const getObjectMetadataItemsMock = () => { updatedAt: '2023-11-30T11:13:15.206Z', fields: [], }, - { - __typename: 'object', - id: '20202020-ddee-40de-9c9b-5f82a3503361', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'calendarEvent', - namePlural: 'calendarEvents', - labelSingular: 'Calendar Event', - labelPlural: 'Calendar Events', - description: 'A calendar event', - icon: 'IconCalendarEvent', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, { __typename: 'object', id: '20202020-d8d0-4c2d-a370-5499b2181d02', @@ -288,6 +271,23 @@ export const getObjectMetadataItemsMock = () => { }, ], }, + { + __typename: 'object', + id: '20202020-ddee-40de-9c9b-5f82a3503361', + dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', + nameSingular: 'calendarEvent', + namePlural: 'calendarEvents', + labelSingular: 'Calendar Event', + labelPlural: 'Calendar Events', + description: 'A calendar event', + icon: 'IconCalendarEvent', + isCustom: false, + isActive: true, + isSystem: true, + createdAt: '2023-11-30T11:13:15.206Z', + updatedAt: '2023-11-30T11:13:15.206Z', + fields: [], + }, { __typename: 'object', id: '20202020-cae9-4ff4-9579-f7d9fe44c937', From 5e5ae0b2ca4a94b1d2e5c4abceacb89af9bf3484 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 21:30:02 +0100 Subject: [PATCH 11/44] Fix server container build --- .../twenty-docker/prod/twenty-front/Dockerfile | 1 + .../twenty-docker/prod/twenty-server/Dockerfile | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/twenty-docker/prod/twenty-front/Dockerfile b/packages/twenty-docker/prod/twenty-front/Dockerfile index d3edf786d3e6..9b8c200c3b25 100644 --- a/packages/twenty-docker/prod/twenty-front/Dockerfile +++ b/packages/twenty-docker/prod/twenty-front/Dockerfile @@ -9,6 +9,7 @@ WORKDIR /app COPY ./package.json . COPY ./yarn.lock . COPY ./.yarnrc.yml . +COPY ./nx.json . COPY ./tsconfig.base.json . COPY ./.yarn/releases /app/.yarn/releases COPY ./tools/eslint-rules /app/tools/eslint-rules diff --git a/packages/twenty-docker/prod/twenty-server/Dockerfile b/packages/twenty-docker/prod/twenty-server/Dockerfile index 84a9b695809d..62d157631291 100644 --- a/packages/twenty-docker/prod/twenty-server/Dockerfile +++ b/packages/twenty-docker/prod/twenty-server/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.16.0-alpine as twenty-server +FROM node:18.16.0-alpine as twenty-server-build WORKDIR /app @@ -6,15 +6,24 @@ COPY ./package.json . COPY ./yarn.lock . COPY ./.yarnrc.yml . COPY ./tsconfig.base.json . +COPY ./nx.json . COPY ./.yarn/releases /app/.yarn/releases COPY ./packages/twenty-emails /app/packages/twenty-emails COPY ./packages/twenty-server /app/packages/twenty-server -RUN yarn workspaces focus twenty-emails twenty-server +RUN yarn + RUN npx nx reset RUN npx nx run twenty-server:build:packageJson RUN mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json -RUN yarn workspaces focus twenty-emails twenty-server RUN npx nx run twenty-server:build +RUN rm -rf /app/node_modules + +FROM node:18.17.1-alpine as twenty-server + +COPY --from=twenty-server-build /app /app +WORKDIR /app + +RUN yarn workspaces focus twenty-emails twenty-server WORKDIR /app/packages/twenty-server From feebc45d317ebbf27a3928e52f0cbf6d0db5924d Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 21:47:07 +0100 Subject: [PATCH 12/44] Fix storybook tests on IconPicker (#4510) --- packages/twenty-docker/prod/twenty-server/Dockerfile | 5 +---- .../ui/input/components/__stories__/IconPicker.stories.tsx | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/twenty-docker/prod/twenty-server/Dockerfile b/packages/twenty-docker/prod/twenty-server/Dockerfile index 62d157631291..fe952b31ac5d 100644 --- a/packages/twenty-docker/prod/twenty-server/Dockerfile +++ b/packages/twenty-docker/prod/twenty-server/Dockerfile @@ -16,14 +16,11 @@ RUN npx nx reset RUN npx nx run twenty-server:build:packageJson RUN mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json RUN npx nx run twenty-server:build -RUN rm -rf /app/node_modules +RUN yarn workspaces focus twenty-emails twenty-server FROM node:18.17.1-alpine as twenty-server COPY --from=twenty-server-build /app /app -WORKDIR /app - -RUN yarn workspaces focus twenty-emails twenty-server WORKDIR /app/packages/twenty-server diff --git a/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx b/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx index 95b433dfa1de..8167a00cb5ed 100644 --- a/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/__stories__/IconPicker.stories.tsx @@ -58,7 +58,7 @@ export const WithSearch: Story = { await sleep(100); - const searchedIcon = canvas.getByRole('button', { + const searchedIcon = await canvas.findByRole('button', { name: 'Icon Building Skyscraper', }); @@ -81,7 +81,7 @@ export const WithSearchAndClose: Story = { await sleep(100); - const searchedIcon = canvas.getByRole('button', { + const searchedIcon = await canvas.findByRole('button', { name: 'Icon Building Skyscraper', }); From eb07b373a71a1045131bd3adbf0604a8e0379fd6 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 23:08:30 +0100 Subject: [PATCH 13/44] Fix storage s3 endpoint not being optional --- packages/twenty-docker/prod/twenty-server/Dockerfile | 9 +++++++-- .../integrations/environment/environment-variables.ts | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/twenty-docker/prod/twenty-server/Dockerfile b/packages/twenty-docker/prod/twenty-server/Dockerfile index fe952b31ac5d..12d281538860 100644 --- a/packages/twenty-docker/prod/twenty-server/Dockerfile +++ b/packages/twenty-docker/prod/twenty-server/Dockerfile @@ -13,10 +13,15 @@ COPY ./packages/twenty-server /app/packages/twenty-server RUN yarn RUN npx nx reset +RUN npx nx run twenty-server:build +RUN mv /app/packages/twenty-server/dist /app/packages/twenty-server/build RUN npx nx run twenty-server:build:packageJson RUN mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json -RUN npx nx run twenty-server:build -RUN yarn workspaces focus twenty-emails twenty-server +RUN rm -rf /app/packages/twenty-server/dist +RUN mv /app/packages/twenty-server/build /app/packages/twenty-server/dist + +WORKDIR /app +RUN yarn workspaces focus --production twenty-emails twenty-server FROM node:18.17.1-alpine as twenty-server diff --git a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts index 62cc97c896a9..028e8a319bfb 100644 --- a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts @@ -165,6 +165,7 @@ export class EnvironmentVariables { @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3) @IsString() + @IsOptional() STORAGE_S3_ENDPOINT: string; @IsString() From 7294d5aedc3a6b405eaf8af30ffb85ca8a958ced Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 15 Mar 2024 23:33:25 +0100 Subject: [PATCH 14/44] Add migrate prod command --- packages/twenty-server/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 5330a9569bc3..b5c913daee80 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -29,7 +29,8 @@ "database:seed:demo": "npx nx command -- workspace:seed:demo", "database:reset": "npx nx database:truncate && npx nx database:init", "command": "node dist/src/command/command", - "queue:work": "node dist/src/queue-worker/queue-worker" + "queue:work": "node dist/src/queue-worker/queue-worker", + "database:migrate:prod": "npx -y typeorm migration:run -d dist/src/database/typeorm/metadata/metadata.datasource && npx -y typeorm migration:run -d dist/src/database/typeorm/core/core.datasource" }, "dependencies": { "@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga+nestjs+2.1.0.patch", From 411aac5efcfcb47d26945f200dde61f3883a35e7 Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Mon, 18 Mar 2024 14:05:35 +0100 Subject: [PATCH 15/44] Remove demo guard for mail api (#4527) Co-authored-by: Thomas Trompette --- .../auth/controllers/google-apis-auth.controller.ts | 9 +++++++-- .../auth/controllers/google-gmail-auth.controller.ts | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts index 1001cb07301a..7cdb6279e814 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts @@ -8,7 +8,6 @@ import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-api import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; @Controller('auth/google-apis') export class GoogleAPIsAuthController { @@ -26,7 +25,7 @@ export class GoogleAPIsAuthController { } @Get('get-access-token') - @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard) + @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard) async googleAuthGetAccessToken( @Req() req: GoogleAPIsRequest, @Res() res: Response, @@ -38,6 +37,12 @@ export class GoogleAPIsAuthController { const { workspaceMemberId, workspaceId } = await this.tokenService.verifyTransientToken(transientToken); + const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); + + if (demoWorkspaceIds.includes(workspaceId)) { + throw new Error('Cannot connect Google account to demo workspace'); + } + if (!workspaceId) { throw new Error('Workspace not found'); } diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts index 96262fe243bf..a5cc294aa20c 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts +++ b/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts @@ -2,7 +2,6 @@ import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; -import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis-oauth.guard'; import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-apis-provider-enabled.guard'; import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; @@ -26,7 +25,7 @@ export class GoogleGmailAuthController { } @Get('get-access-token') - @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard) + @UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard) async googleAuthGetAccessToken( @Req() req: GoogleAPIsRequest, @Res() res: Response, @@ -38,6 +37,12 @@ export class GoogleGmailAuthController { const { workspaceMemberId, workspaceId } = await this.tokenService.verifyTransientToken(transientToken); + const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS'); + + if (demoWorkspaceIds.includes(workspaceId)) { + throw new Error('Cannot connect Gmail account to demo workspace'); + } + if (!workspaceId) { throw new Error('Workspace not found'); } From 2aa6bcdb70e4f719bda27cd461c8cce1b3568c6a Mon Sep 17 00:00:00 2001 From: brendanlaschke Date: Mon, 18 Mar 2024 16:11:02 +0100 Subject: [PATCH 16/44] Action bar add delete count (#4470) Co-authored-by: Lucas Bordeau --- .../record-action-bar/hooks/useRecordActionBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx index 98ae1ee541da..7ee44441afc6 100644 --- a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx @@ -106,7 +106,7 @@ export const useRecordActionBar = ({ const baseActions: ContextMenuEntry[] = useMemo( () => [ { - label: 'Delete', + label: `Delete (${selectedRecordIds.length})`, Icon: IconTrash, accent: 'danger', onClick: () => handleDeleteClick(), @@ -118,7 +118,7 @@ export const useRecordActionBar = ({ onClick: () => download(), }, ], - [handleDeleteClick, download, progress], + [handleDeleteClick, download, progress, selectedRecordIds], ); const dataExecuteQuickActionOnmentEnabled = useIsFeatureEnabled( From 8fb1ab8933b93c034534829d3eb518c48d4c459f Mon Sep 17 00:00:00 2001 From: Weiko Date: Mon, 18 Mar 2024 16:26:23 +0100 Subject: [PATCH 17/44] [backend] rename repository services and replace repository modules by dynamicModule (#4536) * rename database services to repository * refactor more repositories * more refactoring * followup * remove unused imports * fix * fix * Fix calendar listener being called when flag is off * remove folders --- .../integrations/message-queue/jobs.module.ts | 29 ++- .../metadata-to-repository.mapping.ts | 33 +++ .../object-metadata-repository.decorator.ts | 12 + .../object-metadata-repository.module.ts | 40 ++++ .../src/modules/calendar/calendar.module.ts | 39 +--- .../google-calendar-full-sync.command.ts | 9 +- ...workspace-calendar-sync-commands.module.ts | 12 +- .../jobs/google-calendar-full-sync.job.ts | 4 +- ...r-channel-event-association.repository.ts} | 2 +- ...alendar-channel-event-assocation.module.ts | 11 - ...vice.ts => calendar-channel.repository.ts} | 2 +- .../calendar-channel.module.ts | 11 - ... => calendar-event-attendee.repository.ts} | 2 +- .../calendar-event-attendee.module.ts | 11 - ...ervice.ts => calendar-event.repository.ts} | 2 +- .../calendar-event/calendar-event.module.ts | 11 - .../calendar-event-cleaner.module.ts | 9 +- .../calendar-event-cleaner.service.ts | 17 +- .../google-calendar-full-sync.module.ts | 37 ++++ .../google-calendar-full-sync.service.ts | 59 +++-- .../repositories/company.repository.ts} | 3 +- .../create-company-and-contact.module.ts | 13 +- .../create-company-and-contact.service.ts | 17 +- .../create-company/create-company.module.ts | 6 +- .../create-company/create-company.service.ts | 13 +- .../create-contact/create-contact.module.ts | 6 +- .../create-contact/create-contact.service.ts | 11 +- ...ist.service.ts => blocklist.repository.ts} | 2 +- .../blocklist/blocklist.module.ts | 11 - ...ice.ts => connected-account.repository.ts} | 2 +- .../connected-account.module.ts | 11 - .../google-api-refresh-access-token.module.ts | 14 ++ ...oogle-api-refresh-access-token.service.ts} | 13 +- .../fetch-all-workspaces-messages.job.ts | 9 +- ...etch-workspace-messages-commands.module.ts | 12 +- .../commands/gmail-full-sync.command.ts | 9 +- .../commands/gmail-partial-sync.command.ts | 7 +- ...e-companies-and-contacts-after-sync.job.ts | 15 +- .../messaging/jobs/gmail-full-sync.job.ts | 6 +- .../messaging/jobs/gmail-partial-sync.job.ts | 6 +- .../jobs/match-message-participant.job.ts | 16 +- .../messaging-connected-account.listener.ts | 33 ++- .../src/modules/messaging/messaging.module.ts | 63 +----- .../message-find-many.pre-query.hook.ts | 29 ++- .../messaging-query-hook.module.ts | 19 +- .../repositories/company/company.module.ts | 12 - ...channel-message-association.repository.ts} | 28 ++- ...ssage-channel-message-assocation.module.ts | 11 - ...rvice.ts => message-channel.repository.ts} | 2 +- .../message-channel/message-channel.module.ts | 11 - ...e.ts => message-participant.repository.ts} | 45 +--- .../message-participant.module.ts | 12 - .../repositories/message-thread.repository.ts | 67 ++++++ .../message-thread/message-thread.module.ts | 17 -- .../message-thread/message-thread.service.ts | 105 --------- .../repositories/message.repository.ts | 138 ++++++++++++ .../repositories/message/message.module.ts | 23 -- .../fetch-by-batch/fetch-by-batch.module.ts | 15 ++ .../fetch-by-batch.service.ts | 0 .../fetch-messages-by-batches.module.ts | 11 + .../fetch-messages-by-batches.service.ts | 2 +- .../gmail-full-sync/gmail-full-sync.module.ts | 31 +++ .../gmail-full-sync.service.ts | 41 ++-- .../gmail-partial-sync.module.ts | 31 +++ .../gmail-partial-sync.service.ts | 35 +-- .../message-participant.module.ts | 16 ++ .../message-participant.service.ts | 59 +++++ .../message-thread/message-thread.module.ts | 20 ++ .../message-thread/message-thread.service.ts | 73 +++++++ .../services/message/message.module.ts | 26 +++ .../message/message.service.ts | 206 ++++++------------ ...save-message-and-create-contacts.module.ts | 26 +++ ...ve-messages-and-create-contacts.service.ts | 21 +- .../thread-cleaner/thread-cleaner.module.ts | 15 +- .../thread-cleaner/thread-cleaner.service.ts | 31 +-- ...person.service.ts => person.repository.ts} | 3 +- .../repositories/person/person.module.ts | 11 - ...vice.ts => workspace-member.repository.ts} | 3 +- .../workspace-member.module.ts | 11 - 79 files changed, 1080 insertions(+), 776 deletions(-) create mode 100644 packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts create mode 100644 packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.decorator.ts create mode 100644 packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.module.ts rename packages/twenty-server/src/modules/calendar/repositories/{calendar-channel-event-association/calendar-channel-event-association.service.ts => calendar-channel-event-association.repository.ts} (98%) delete mode 100644 packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts rename packages/twenty-server/src/modules/calendar/repositories/{calendar-channel/calendar-channel.service.ts => calendar-channel.repository.ts} (98%) delete mode 100644 packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts rename packages/twenty-server/src/modules/calendar/repositories/{calendar-event-attendee/calendar-event-attendee.service.ts => calendar-event-attendee.repository.ts} (99%) delete mode 100644 packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts rename packages/twenty-server/src/modules/calendar/repositories/{calendar-event/calendar-event.service.ts => calendar-event.repository.ts} (99%) delete mode 100644 packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts create mode 100644 packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts rename packages/twenty-server/src/modules/{messaging/repositories/company/company.service.ts => company/repositories/company.repository.ts} (95%) rename packages/twenty-server/src/modules/connected-account/repositories/{blocklist/blocklist.service.ts => blocklist.repository.ts} (96%) delete mode 100644 packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts rename packages/twenty-server/src/modules/connected-account/repositories/{connected-account/connected-account.service.ts => connected-account.repository.ts} (99%) delete mode 100644 packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts create mode 100644 packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.module.ts rename packages/twenty-server/src/modules/connected-account/services/{google-apis-refresh-access-token.service.ts => google-api-refresh-access-token/google-api-refresh-access-token.service.ts} (68%) delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts rename packages/twenty-server/src/modules/messaging/repositories/{message-channel-message-association/message-channel-message-association.service.ts => message-channel-message-association.repository.ts} (88%) delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts rename packages/twenty-server/src/modules/messaging/repositories/{message-channel/message-channel.service.ts => message-channel.repository.ts} (98%) delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts rename packages/twenty-server/src/modules/messaging/repositories/{message-participant/message-participant.service.ts => message-participant.repository.ts} (82%) delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts create mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-thread.repository.ts delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts create mode 100644 packages/twenty-server/src/modules/messaging/repositories/message.repository.ts delete mode 100644 packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts create mode 100644 packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.module.ts rename packages/twenty-server/src/modules/messaging/services/{ => fetch-by-batch}/fetch-by-batch.service.ts (100%) create mode 100644 packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module.ts rename packages/twenty-server/src/modules/messaging/services/{ => fetch-messages-by-batches}/fetch-messages-by-batches.service.ts (99%) create mode 100644 packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts rename packages/twenty-server/src/modules/messaging/services/{ => gmail-full-sync}/gmail-full-sync.service.ts (76%) create mode 100644 packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts rename packages/twenty-server/src/modules/messaging/services/{ => gmail-partial-sync}/gmail-partial-sync.service.ts (86%) create mode 100644 packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts create mode 100644 packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts create mode 100644 packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.module.ts create mode 100644 packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.service.ts create mode 100644 packages/twenty-server/src/modules/messaging/services/message/message.module.ts rename packages/twenty-server/src/modules/messaging/{repositories => services}/message/message.service.ts (56%) create mode 100644 packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts rename packages/twenty-server/src/modules/messaging/services/{ => save-message-and-create-contact}/save-messages-and-create-contacts.service.ts (81%) rename packages/twenty-server/src/modules/person/repositories/{person/person.service.ts => person.repository.ts} (96%) delete mode 100644 packages/twenty-server/src/modules/person/repositories/person/person.module.ts rename packages/twenty-server/src/modules/workspace-member/repositories/{workspace-member/workspace-member.service.ts => workspace-member.repository.ts} (96%) delete mode 100644 packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts diff --git a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts index f0dfa9a1efa9..4bec99690bc9 100644 --- a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts @@ -11,18 +11,14 @@ import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { MessagingModule } from 'src/modules/messaging/messaging.module'; import { GmailPartialSyncJob } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; import { EmailSenderJob } from 'src/engine/integrations/email/email-sender.job'; import { UserModule } from 'src/engine/modules/user/user.module'; import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; import { FetchAllWorkspacesMessagesJob } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; import { MatchMessageParticipantJob } from 'src/modules/messaging/jobs/match-message-participant.job'; import { CreateCompaniesAndContactsAfterSyncJob } from 'src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job'; import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; -import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module'; import { DataSeedDemoWorkspaceJob } from 'src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job'; import { DeleteConnectedAccountAssociatedMessagingDataJob } from 'src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job'; @@ -33,27 +29,31 @@ import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-work import { StripeModule } from 'src/engine/modules/billing/stripe/stripe.module'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { CalendarModule } from 'src/modules/calendar/calendar.module'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; import { GoogleCalendarFullSyncJob } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; import { CalendarEventCleanerModule } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; import { RecordPositionBackfillJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job'; import { RecordPositionBackfillModule } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-module'; import { DeleteConnectedAccountAssociatedCalendarDataJob } from 'src/modules/messaging/jobs/delete-connected-account-associated-calendar-data.job'; +import { GoogleCalendarFullSyncModule } from 'src/modules/calendar/services/google-calendar-full-sync.module'; +import { GoogleAPIRefreshAccessTokenModule } from 'src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.module'; +import { GmailFullSyncModule } from 'src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module'; +import { GmailPartialSyncModule } from 'src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module'; +import { MessageParticipantModule } from 'src/modules/messaging/services/message-participant/message-participant.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; @Module({ imports: [ BillingModule, DataSourceModule, - ConnectedAccountModule, CreateCompaniesAndContactsModule, DataSeedDemoWorkspaceModule, EnvironmentModule, HttpModule, - MessagingModule, - MessageParticipantModule, - MessageChannelModule, - CalendarModule, + GoogleCalendarFullSyncModule, ObjectMetadataModule, StripeModule, ThreadCleanerModule, @@ -65,6 +65,15 @@ import { DeleteConnectedAccountAssociatedCalendarDataJob } from 'src/modules/mes UserWorkspaceModule, WorkspaceDataSourceModule, RecordPositionBackfillModule, + GoogleAPIRefreshAccessTokenModule, + GmailFullSyncModule, + GmailPartialSyncModule, + MessageParticipantModule, + ObjectMetadataRepositoryModule.forFeature([ + ConnectedAccountObjectMetadata, + MessageParticipantObjectMetadata, + MessageChannelObjectMetadata, + ]), ], providers: [ { diff --git a/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts b/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts new file mode 100644 index 000000000000..593bde6e5ddf --- /dev/null +++ b/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts @@ -0,0 +1,33 @@ +import { CalendarChannelEventAssociationRepository } from 'src/modules/calendar/repositories/calendar-channel-event-association.repository'; +import { CalendarChannelRepository } from 'src/modules/calendar/repositories/calendar-channel.repository'; +import { CalendarEventAttendeeRepository } from 'src/modules/calendar/repositories/calendar-event-attendee.repository'; +import { CalendarEventRepository } from 'src/modules/calendar/repositories/calendar-event.repository'; +import { CompanyRepository } from 'src/modules/company/repositories/company.repository'; +import { BlocklistRepository } from 'src/modules/connected-account/repositories/blocklist.repository'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; +import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; +import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; +import { PersonRepository } from 'src/modules/person/repositories/person.repository'; +import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; + +export const metadataToRepositoryMapping = { + BlocklistObjectMetadata: BlocklistRepository, + CalendarChannelEventAssociationObjectMetadata: + CalendarChannelEventAssociationRepository, + CalendarChannelObjectMetadata: CalendarChannelRepository, + CalendarEventAttendeeObjectMetadata: CalendarEventAttendeeRepository, + CalendarEventObjectMetadata: CalendarEventRepository, + CompanyObjectMetadata: CompanyRepository, + ConnectedAccountObjectMetadata: ConnectedAccountRepository, + MessageChannelMessageAssociationObjectMetadata: + MessageChannelMessageAssociationRepository, + MessageChannelObjectMetadata: MessageChannelRepository, + MessageObjectMetadata: MessageRepository, + MessageParticipantObjectMetadata: MessageParticipantRepository, + MessageThreadObjectMetadata: MessageThreadRepository, + PersonObjectMetadata: PersonRepository, + WorkspaceMemberObjectMetadata: WorkspaceMemberRepository, +}; diff --git a/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.decorator.ts b/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.decorator.ts new file mode 100644 index 000000000000..d8e35a705e30 --- /dev/null +++ b/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.decorator.ts @@ -0,0 +1,12 @@ +import { Inject } from '@nestjs/common'; + +import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util'; +import { capitalize } from 'src/utils/capitalize'; + +export const InjectObjectMetadataRepository = (objectMetadata: any) => { + const token = `${capitalize( + convertClassNameToObjectMetadataName(objectMetadata.name), + )}Repository`; + + return Inject(token); +}; diff --git a/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.module.ts b/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.module.ts new file mode 100644 index 000000000000..624269b0bf8c --- /dev/null +++ b/packages/twenty-server/src/engine/object-metadata-repository/object-metadata-repository.module.ts @@ -0,0 +1,40 @@ +import { Global, Module, DynamicModule, Provider } from '@nestjs/common'; + +import { metadataToRepositoryMapping } from 'src/engine/object-metadata-repository/metadata-to-repository.mapping'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util'; +import { capitalize } from 'src/utils/capitalize'; + +@Global() +@Module({}) +export class ObjectMetadataRepositoryModule { + static forFeature(objectMetadatas): DynamicModule { + const providers: Provider[] = objectMetadatas.map((objectMetadata) => { + const repositoryClass = metadataToRepositoryMapping[objectMetadata.name]; + + if (!repositoryClass) { + throw new Error(`No repository found for ${objectMetadata.name}`); + } + + return { + provide: `${capitalize( + convertClassNameToObjectMetadataName(objectMetadata.name), + )}Repository`, + useFactory: ( + workspaceDataSourceService: WorkspaceDataSourceService, + ) => { + return new repositoryClass(workspaceDataSourceService); + }, + inject: [WorkspaceDataSourceService], + }; + }); + + return { + module: ObjectMetadataRepositoryModule, + imports: [WorkspaceDataSourceModule], + providers: [...providers], + exports: providers, + }; + } +} diff --git a/packages/twenty-server/src/modules/calendar/calendar.module.ts b/packages/twenty-server/src/modules/calendar/calendar.module.ts index 6d688c6c8614..b2aa06eff050 100644 --- a/packages/twenty-server/src/modules/calendar/calendar.module.ts +++ b/packages/twenty-server/src/modules/calendar/calendar.module.ts @@ -1,41 +1,8 @@ import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; -import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { BlocklistModule } from 'src/modules/connected-account/repositories/blocklist/blocklist.module'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; -import { CalendarChannelEventAssociationModule } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module'; -import { CalendarChannelModule } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.module'; -import { CalendarEventAttendeeModule } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module'; -import { CalendarEventModule } from 'src/modules/calendar/repositories/calendar-event/calendar-event.module'; -import { CalendarEventCleanerModule } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; -import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; -import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; -import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; -import { PersonModule } from 'src/modules/person/repositories/person/person.module'; -import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ - imports: [ - EnvironmentModule, - WorkspaceDataSourceModule, - ConnectedAccountModule, - CalendarChannelModule, - CalendarChannelEventAssociationModule, - CalendarEventModule, - CalendarEventAttendeeModule, - CreateCompaniesAndContactsModule, - WorkspaceMemberModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - CompanyModule, - PersonModule, - BlocklistModule, - CalendarEventCleanerModule, - ], - providers: [GoogleCalendarFullSyncService, GoogleCalendarClientProvider], - exports: [GoogleCalendarFullSyncService], + imports: [], + providers: [], + exports: [], }) export class CalendarModule {} diff --git a/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts b/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts index 4401d58f2ff8..bd3f04de748f 100644 --- a/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts +++ b/packages/twenty-server/src/modules/calendar/commands/google-calendar-full-sync.command.ts @@ -4,11 +4,13 @@ import { Command, CommandRunner, Option } from 'nest-commander'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; import { GoogleCalendarFullSyncJobData, GoogleCalendarFullSyncJob, } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; interface GoogleCalendarFullSyncOptions { workspaceId: string; @@ -23,7 +25,8 @@ export class GoogleCalendarFullSyncCommand extends CommandRunner { constructor( @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, ) { super(); } @@ -48,7 +51,7 @@ export class GoogleCalendarFullSyncCommand extends CommandRunner { private async fetchWorkspaceCalendars(workspaceId: string): Promise { const connectedAccounts = - await this.connectedAccountService.getAll(workspaceId); + await this.connectedAccountRepository.getAll(workspaceId); for (const connectedAccount of connectedAccounts) { await this.messageQueueService.add( diff --git a/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts b/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts index bcaa654bb3d8..18e1b88691ca 100644 --- a/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts +++ b/packages/twenty-server/src/modules/calendar/commands/workspace-calendar-sync-commands.module.ts @@ -1,18 +1,12 @@ import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; import { GoogleCalendarFullSyncCommand } from 'src/modules/calendar/commands/google-calendar-full-sync.command'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; @Module({ imports: [ - DataSourceModule, - TypeORMModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - ConnectedAccountModule, + ObjectMetadataRepositoryModule.forFeature([ConnectedAccountObjectMetadata]), ], providers: [GoogleCalendarFullSyncCommand], }) diff --git a/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts b/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts index 9759bbf6b77d..6408e72b6dba 100644 --- a/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts +++ b/packages/twenty-server/src/modules/calendar/jobs/google-calendar-full-sync.job.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; +import { GoogleAPIRefreshAccessTokenService } from 'src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service'; import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; export type GoogleCalendarFullSyncJobData = { @@ -18,7 +18,7 @@ export class GoogleCalendarFullSyncJob private readonly logger = new Logger(GoogleCalendarFullSyncJob.name); constructor( - private readonly googleAPIsRefreshAccessTokenService: GoogleAPIsRefreshAccessTokenService, + private readonly googleAPIsRefreshAccessTokenService: GoogleAPIRefreshAccessTokenService, private readonly googleCalendarFullSyncService: GoogleCalendarFullSyncService, ) {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association.repository.ts similarity index 98% rename from packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association.repository.ts index 8ea4b89806c2..5162c37bfe28 100644 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association.repository.ts @@ -8,7 +8,7 @@ import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calen import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; @Injectable() -export class CalendarChannelEventAssociationService { +export class CalendarChannelEventAssociationRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts deleted file mode 100644 index 2b044c87f6de..000000000000 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-assocation.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CalendarChannelEventAssociationService } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [CalendarChannelEventAssociationService], - exports: [CalendarChannelEventAssociationService], -}) -export class CalendarChannelEventAssociationModule {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel.repository.ts similarity index 98% rename from packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-channel.repository.ts index 85921f68c545..6273362d5ca6 100644 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel.repository.ts @@ -7,7 +7,7 @@ import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-obj import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() -export class CalendarChannelService { +export class CalendarChannelRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts deleted file mode 100644 index 3640b0984000..000000000000 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-channel/calendar-channel.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CalendarChannelService } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [CalendarChannelService], - exports: [CalendarChannelService], -}) -export class CalendarChannelModule {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts similarity index 99% rename from packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts index 737604d66846..39a556d8ea20 100644 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts @@ -9,7 +9,7 @@ import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/c import { CalendarEventAttendee } from 'src/modules/calendar/types/calendar-event'; @Injectable() -export class CalendarEventAttendeeService { +export class CalendarEventAttendeeRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts deleted file mode 100644 index 64e015520cd5..000000000000 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CalendarEventAttendeeService } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [CalendarEventAttendeeService], - exports: [CalendarEventAttendeeService], -}) -export class CalendarEventAttendeeModule {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event.repository.ts similarity index 99% rename from packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts rename to packages/twenty-server/src/modules/calendar/repositories/calendar-event.repository.ts index 2a0d81014637..2f23fc1d4040 100644 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.service.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event.repository.ts @@ -10,7 +10,7 @@ import { CalendarEvent } from 'src/modules/calendar/types/calendar-event'; import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; @Injectable() -export class CalendarEventService { +export class CalendarEventRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts deleted file mode 100644 index 7d501958f867..000000000000 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-event/calendar-event.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [CalendarEventService], - exports: [CalendarEventService], -}) -export class CalendarEventModule {} diff --git a/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts index 98c1df1fb18d..2f0d4977aa6d 100644 --- a/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module.ts @@ -1,12 +1,13 @@ import { Module } from '@nestjs/common'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { CalendarEventModule } from 'src/modules/calendar/repositories/calendar-event/calendar-event.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { CalendarEventCleanerService } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; @Module({ - imports: [DataSourceModule, TypeORMModule, CalendarEventModule], + imports: [ + ObjectMetadataRepositoryModule.forFeature([CalendarEventObjectMetadata]), + ], providers: [CalendarEventCleanerService], exports: [CalendarEventCleanerService], }) diff --git a/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts index c3128a326e5e..c56e046a7f12 100644 --- a/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.service.ts @@ -1,20 +1,27 @@ import { Injectable } from '@nestjs/common'; -import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { CalendarEventRepository } from 'src/modules/calendar/repositories/calendar-event.repository'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; import { deleteUsingPagination } from 'src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util'; @Injectable() export class CalendarEventCleanerService { - constructor(private readonly calendarEventService: CalendarEventService) {} + constructor( + @InjectObjectMetadataRepository(CalendarEventObjectMetadata) + private readonly calendarEventRepository: CalendarEventRepository, + ) {} public async cleanWorkspaceCalendarEvents(workspaceId: string) { await deleteUsingPagination( workspaceId, 500, - this.calendarEventService.getNonAssociatedCalendarEventIdsPaginated.bind( - this.calendarEventService, + this.calendarEventRepository.getNonAssociatedCalendarEventIdsPaginated.bind( + this.calendarEventRepository, + ), + this.calendarEventRepository.deleteByIds.bind( + this.calendarEventRepository, ), - this.calendarEventService.deleteByIds.bind(this.calendarEventService), ); } } diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts new file mode 100644 index 000000000000..e744f62b8b6a --- /dev/null +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts @@ -0,0 +1,37 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; +import { CalendarProvidersModule } from 'src/modules/calendar/services/providers/calendar-providers.module'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; +import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; + +@Module({ + imports: [ + CalendarProvidersModule, + ObjectMetadataRepositoryModule.forFeature([ + ConnectedAccountObjectMetadata, + CalendarEventObjectMetadata, + CalendarChannelObjectMetadata, + CalendarChannelEventAssociationObjectMetadata, + CalendarEventAttendeeObjectMetadata, + BlocklistObjectMetadata, + PersonObjectMetadata, + WorkspaceMemberObjectMetadata, + ]), + TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), + WorkspaceDataSourceModule, + ], + providers: [GoogleCalendarFullSyncService], + exports: [GoogleCalendarFullSyncService], +}) +export class GoogleCalendarFullSyncModule {} diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts index a5f10af877e1..d7a7a3abfd51 100644 --- a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts @@ -3,23 +3,30 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; -import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { BlocklistRepository } from 'src/modules/connected-account/repositories/blocklist.repository'; import { FeatureFlagEntity, FeatureFlagKeys, } from 'src/engine/modules/feature-flag/feature-flag.entity'; import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; import { googleCalendarSearchFilterExcludeEmails } from 'src/modules/calendar/utils/google-calendar-search-filter.util'; -import { CalendarChannelEventAssociationService } from 'src/modules/calendar/repositories/calendar-channel-event-association/calendar-channel-event-association.service'; -import { CalendarChannelService } from 'src/modules/calendar/repositories/calendar-channel/calendar-channel.service'; +import { CalendarChannelEventAssociationRepository } from 'src/modules/calendar/repositories/calendar-channel-event-association.repository'; +import { CalendarChannelRepository } from 'src/modules/calendar/repositories/calendar-channel.repository'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { CalendarEventService } from 'src/modules/calendar/repositories/calendar-event/calendar-event.service'; +import { CalendarEventRepository } from 'src/modules/calendar/repositories/calendar-event.repository'; import { formatGoogleCalendarEvent } from 'src/modules/calendar/utils/format-google-calendar-event.util'; import { GoogleCalendarFullSyncJobData } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; -import { CalendarEventAttendeeService } from 'src/modules/calendar/repositories/calendar-event-attendee/calendar-event-attendee.service'; +import { CalendarEventAttendeeRepository } from 'src/modules/calendar/repositories/calendar-event-attendee.repository'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { CalendarEventObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event.object-metadata'; +import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel.object-metadata'; +import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; +import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; @Injectable() export class GoogleCalendarFullSyncService { @@ -29,12 +36,20 @@ export class GoogleCalendarFullSyncService { private readonly googleCalendarClientProvider: GoogleCalendarClientProvider, @Inject(MessageQueue.calendarQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, - private readonly calendarEventService: CalendarEventService, - private readonly calendarChannelService: CalendarChannelService, - private readonly calendarChannelEventAssociationService: CalendarChannelEventAssociationService, - private readonly calendarEventAttendeesService: CalendarEventAttendeeService, - private readonly blocklistService: BlocklistService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, + @InjectObjectMetadataRepository(CalendarEventObjectMetadata) + private readonly calendarEventRepository: CalendarEventRepository, + @InjectObjectMetadataRepository(CalendarChannelObjectMetadata) + private readonly calendarChannelRepository: CalendarChannelRepository, + @InjectObjectMetadataRepository( + CalendarChannelEventAssociationObjectMetadata, + ) + private readonly calendarChannelEventAssociationRepository: CalendarChannelEventAssociationRepository, + @InjectObjectMetadataRepository(CalendarEventAttendeeObjectMetadata) + private readonly calendarEventAttendeesRepository: CalendarEventAttendeeRepository, + @InjectObjectMetadataRepository(BlocklistObjectMetadata) + private readonly blocklistRepository: BlocklistRepository, @InjectRepository(FeatureFlagEntity, 'core') private readonly featureFlagRepository: Repository, private readonly workspaceDataSourceService: WorkspaceDataSourceService, @@ -45,7 +60,7 @@ export class GoogleCalendarFullSyncService { connectedAccountId: string, pageToken?: string, ): Promise { - const connectedAccount = await this.connectedAccountService.getById( + const connectedAccount = await this.connectedAccountRepository.getById( connectedAccountId, workspaceId, ); @@ -64,7 +79,7 @@ export class GoogleCalendarFullSyncService { } const calendarChannel = - await this.calendarChannelService.getFirstByConnectedAccountIdOrFail( + await this.calendarChannelRepository.getFirstByConnectedAccountIdOrFail( connectedAccountId, workspaceId, ); @@ -87,7 +102,7 @@ export class GoogleCalendarFullSyncService { isBlocklistEnabledFeatureFlag && isBlocklistEnabledFeatureFlag.value; const blocklist = isBlocklistEnabled - ? await this.blocklistService.getByWorkspaceMemberId( + ? await this.blocklistRepository.getByWorkspaceMemberId( workspaceMemberId, workspaceId, ) @@ -130,7 +145,7 @@ export class GoogleCalendarFullSyncService { startTime = Date.now(); const existingCalendarChannelEventAssociations = - await this.calendarChannelEventAssociationService.getByEventExternalIdsAndCalendarChannelId( + await this.calendarChannelEventAssociationRepository.getByEventExternalIdsAndCalendarChannelId( eventExternalIds, calendarChannelId, workspaceId, @@ -180,7 +195,7 @@ export class GoogleCalendarFullSyncService { ); const iCalUIDCalendarEventIdMap = - await this.calendarEventService.getICalUIDCalendarEventIdMap( + await this.calendarEventRepository.getICalUIDCalendarEventIdMap( eventsToUpdate.map((event) => event.iCalUID), workspaceId, ); @@ -192,31 +207,31 @@ export class GoogleCalendarFullSyncService { ); dataSourceMetadata?.transaction(async (transactionManager) => { - this.calendarEventService.saveCalendarEvents( + this.calendarEventRepository.saveCalendarEvents( eventsToSave, workspaceId, transactionManager, ); - this.calendarEventService.updateCalendarEvents( + this.calendarEventRepository.updateCalendarEvents( eventsToUpdate, workspaceId, transactionManager, ); - this.calendarChannelEventAssociationService.saveCalendarChannelEventAssociations( + this.calendarChannelEventAssociationRepository.saveCalendarChannelEventAssociations( calendarChannelEventAssociationsToSave, workspaceId, transactionManager, ); - this.calendarEventAttendeesService.saveCalendarEventAttendees( + this.calendarEventAttendeesRepository.saveCalendarEventAttendees( attendeesToSave, workspaceId, transactionManager, ); - this.calendarEventAttendeesService.updateCalendarEventAttendees( + this.calendarEventAttendeesRepository.updateCalendarEventAttendees( attendeesToUpdate, iCalUIDCalendarEventIdMap, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/repositories/company/company.service.ts b/packages/twenty-server/src/modules/company/repositories/company.repository.ts similarity index 95% rename from packages/twenty-server/src/modules/messaging/repositories/company/company.service.ts rename to packages/twenty-server/src/modules/company/repositories/company.repository.ts index d4aa7c8a2a00..162ee88c84ee 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/company/company.service.ts +++ b/packages/twenty-server/src/modules/company/repositories/company.repository.ts @@ -11,9 +11,8 @@ export type CompanyToCreate = { city?: string; }; -// TODO: Move outside of the messaging module @Injectable() -export class CompanyService { +export class CompanyRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts index a6877df0fd9e..3c0f8e2624e2 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module.ts @@ -1,19 +1,20 @@ import { Module } from '@nestjs/common'; -import { PersonModule } from 'src/modules/person/repositories/person/person.module'; -import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; import { CreateCompanyModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module'; import { CreateContactModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @Module({ imports: [ - WorkspaceDataSourceModule, CreateContactModule, CreateCompanyModule, - WorkspaceMemberModule, - PersonModule, + ObjectMetadataRepositoryModule.forFeature([ + PersonObjectMetadata, + WorkspaceMemberObjectMetadata, + ]), ], providers: [CreateCompanyAndContactService], exports: [CreateCompanyAndContactService], diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts index 0462bc075646..cf1227048f06 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service.ts @@ -7,19 +7,24 @@ import { Participant } from 'src/modules/messaging/types/gmail-message'; import { getDomainNameFromHandle } from 'src/modules/messaging/utils/get-domain-name-from-handle.util'; import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { PersonService } from 'src/modules/person/repositories/person/person.service'; -import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; +import { PersonRepository } from 'src/modules/person/repositories/person.repository'; +import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; import { getUniqueParticipantsAndHandles } from 'src/modules/messaging/utils/get-unique-participants-and-handles.util'; import { filterOutParticipantsFromCompanyOrWorkspace } from 'src/modules/messaging/utils/filter-out-participants-from-company-or-workspace.util'; import { isWorkEmail } from 'src/utils/is-work-email'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @Injectable() export class CreateCompanyAndContactService { constructor( - private readonly personService: PersonService, private readonly createContactService: CreateContactService, private readonly createCompaniesService: CreateCompanyService, - private readonly workspaceMemberService: WorkspaceMemberService, + @InjectObjectMetadataRepository(PersonObjectMetadata) + private readonly personRepository: PersonRepository, + @InjectObjectMetadataRepository(WorkspaceMemberObjectMetadata) + private readonly workspaceMemberRepository: WorkspaceMemberRepository, ) {} async createCompaniesAndContacts( @@ -36,7 +41,7 @@ export class CreateCompanyAndContactService { const isContactAutoCreationForNonWorkEmailsEnabled = false; const workspaceMembers = - await this.workspaceMemberService.getAllByWorkspaceId( + await this.workspaceMemberRepository.getAllByWorkspaceId( workspaceId, transactionManager, ); @@ -55,7 +60,7 @@ export class CreateCompanyAndContactService { return; } - const alreadyCreatedContacts = await this.personService.getByEmails( + const alreadyCreatedContacts = await this.personRepository.getByEmails( uniqueHandles, workspaceId, ); diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts index 31e2e68c74d7..c353146d8dcb 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.module.ts @@ -1,11 +1,11 @@ import { Module } from '@nestjs/common'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; -import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; @Module({ - imports: [WorkspaceDataSourceModule, CompanyModule], + imports: [ObjectMetadataRepositoryModule.forFeature([CompanyObjectMetadata])], providers: [CreateCompanyService], exports: [CreateCompanyService], }) diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts index 4052b1cbea6a..57397208702d 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service.ts @@ -4,13 +4,18 @@ import { EntityManager } from 'typeorm'; import { v4 } from 'uuid'; import axios, { AxiosInstance } from 'axios'; -import { CompanyService } from 'src/modules/messaging/repositories/company/company.service'; +import { CompanyRepository } from 'src/modules/company/repositories/company.repository'; import { getCompanyNameFromDomainName } from 'src/modules/messaging/utils/get-company-name-from-domain-name.util'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; @Injectable() export class CreateCompanyService { private readonly httpService: AxiosInstance; - constructor(private readonly companyService: CompanyService) { + constructor( + @InjectObjectMetadataRepository(CompanyObjectMetadata) + private readonly companyRepository: CompanyRepository, + ) { this.httpService = axios.create({ baseURL: 'https://companies.twenty.com', }); @@ -30,7 +35,7 @@ export class CreateCompanyService { const uniqueDomainNames = [...new Set(domainNames)]; const existingCompanies = - await this.companyService.getExistingCompaniesByDomainNames( + await this.companyRepository.getExistingCompaniesByDomainNames( uniqueDomainNames, workspaceId, transactionManager, @@ -80,7 +85,7 @@ export class CreateCompanyService { const { name, city } = await this.getCompanyInfoFromDomainName(domainName); - this.companyService.createCompany( + this.companyRepository.createCompany( workspaceId, { id: companyId, diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts index faa9404258a5..bd3eaa1bde6f 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.module.ts @@ -1,11 +1,11 @@ import { Module } from '@nestjs/common'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { PersonModule } from 'src/modules/person/repositories/person/person.module'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; @Module({ - imports: [WorkspaceDataSourceModule, PersonModule], + imports: [ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata])], providers: [CreateContactService], exports: [CreateContactService], }) diff --git a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts index c96bbc2fda81..be3db3574917 100644 --- a/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts +++ b/packages/twenty-server/src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service.ts @@ -3,8 +3,10 @@ import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { v4 } from 'uuid'; -import { PersonService } from 'src/modules/person/repositories/person/person.service'; +import { PersonRepository } from 'src/modules/person/repositories/person.repository'; import { getFirstNameAndLastNameFromHandleAndDisplayName } from 'src/modules/messaging/utils/get-first-name-and-last-name-from-handle-and-display-name.util'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; type ContactToCreate = { handle: string; @@ -22,7 +24,10 @@ type FormattedContactToCreate = { @Injectable() export class CreateContactService { - constructor(private readonly personService: PersonService) {} + constructor( + @InjectObjectMetadataRepository(PersonObjectMetadata) + private readonly personRepository: PersonRepository, + ) {} public formatContacts( contactsToCreate: ContactToCreate[], @@ -54,7 +59,7 @@ export class CreateContactService { const formattedContacts = this.formatContacts(contactsToCreate); - await this.personService.createPeople( + await this.personRepository.createPeople( formattedContacts, workspaceId, transactionManager, diff --git a/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts b/packages/twenty-server/src/modules/connected-account/repositories/blocklist.repository.ts similarity index 96% rename from packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts rename to packages/twenty-server/src/modules/connected-account/repositories/blocklist.repository.ts index f8ff607e83cf..5b7fa2f1f608 100644 --- a/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.service.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/blocklist.repository.ts @@ -7,7 +7,7 @@ import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metada import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; @Injectable() -export class BlocklistService { +export class BlocklistRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts b/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts deleted file mode 100644 index 08e623074685..000000000000 --- a/packages/twenty-server/src/modules/connected-account/repositories/blocklist/blocklist.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [BlocklistService], - exports: [BlocklistService], -}) -export class BlocklistModule {} diff --git a/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts b/packages/twenty-server/src/modules/connected-account/repositories/connected-account.repository.ts similarity index 99% rename from packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts rename to packages/twenty-server/src/modules/connected-account/repositories/connected-account.repository.ts index 739da879afc8..5a46a1a8e5f5 100644 --- a/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.service.ts +++ b/packages/twenty-server/src/modules/connected-account/repositories/connected-account.repository.ts @@ -7,7 +7,7 @@ import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/st import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() -export class ConnectedAccountService { +export class ConnectedAccountRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts b/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts deleted file mode 100644 index 736d2e303c31..000000000000 --- a/packages/twenty-server/src/modules/connected-account/repositories/connected-account/connected-account.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [ConnectedAccountService], - exports: [ConnectedAccountService], -}) -export class ConnectedAccountModule {} diff --git a/packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.module.ts b/packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.module.ts new file mode 100644 index 000000000000..29db89400d02 --- /dev/null +++ b/packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; + +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { GoogleAPIRefreshAccessTokenService } from 'src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; + +@Module({ + imports: [ + ObjectMetadataRepositoryModule.forFeature([ConnectedAccountObjectMetadata]), + ], + providers: [GoogleAPIRefreshAccessTokenService], + exports: [GoogleAPIRefreshAccessTokenService], +}) +export class GoogleAPIRefreshAccessTokenModule {} diff --git a/packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts b/packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service.ts similarity index 68% rename from packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts rename to packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service.ts index 88ba8c3d7ee3..284f5b185b3f 100644 --- a/packages/twenty-server/src/modules/connected-account/services/google-apis-refresh-access-token.service.ts +++ b/packages/twenty-server/src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service.ts @@ -3,20 +3,23 @@ import { Injectable } from '@nestjs/common'; import axios from 'axios'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; @Injectable() -export class GoogleAPIsRefreshAccessTokenService { +export class GoogleAPIRefreshAccessTokenService { constructor( private readonly environmentService: EnvironmentService, - private readonly connectedAccountService: ConnectedAccountService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, ) {} async refreshAndSaveAccessToken( workspaceId: string, connectedAccountId: string, ): Promise { - const connectedAccount = await this.connectedAccountService.getById( + const connectedAccount = await this.connectedAccountRepository.getById( connectedAccountId, workspaceId, ); @@ -37,7 +40,7 @@ export class GoogleAPIsRefreshAccessTokenService { const accessToken = await this.refreshAccessToken(refreshToken); - await this.connectedAccountService.updateAccessToken( + await this.connectedAccountRepository.updateAccessToken( accessToken, connectedAccountId, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts index 2867fa1b09d4..d6756626ee45 100644 --- a/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts +++ b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts @@ -7,13 +7,15 @@ import { MessageQueueJob } from 'src/engine/integrations/message-queue/interface import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { GmailPartialSyncJobData, GmailPartialSyncJob, } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; @Injectable() export class FetchAllWorkspacesMessagesJob @@ -28,7 +30,8 @@ export class FetchAllWorkspacesMessagesJob private readonly dataSourceRepository: Repository, @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, ) {} async handle(): Promise { @@ -59,7 +62,7 @@ export class FetchAllWorkspacesMessagesJob private async fetchWorkspaceMessages(workspaceId: string): Promise { try { const connectedAccounts = - await this.connectedAccountService.getAll(workspaceId); + await this.connectedAccountRepository.getAll(workspaceId); for (const connectedAccount of connectedAccounts) { await this.messageQueueService.add( diff --git a/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts b/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts index cd0936e1b6fa..c285a6235ecf 100644 --- a/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts +++ b/packages/twenty-server/src/modules/messaging/commands/fetch-workspace-messages-commands.module.ts @@ -1,21 +1,15 @@ import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { GmailFullSyncCommand } from 'src/modules/messaging/commands/gmail-full-sync.command'; import { GmailPartialSyncCommand } from 'src/modules/messaging/commands/gmail-partial-sync.command'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; import { StartFetchAllWorkspacesMessagesCronCommand } from 'src/modules/messaging/commands/start-fetch-all-workspaces-messages.cron.command'; import { StopFetchAllWorkspacesMessagesCronCommand } from 'src/modules/messaging/commands/stop-fetch-all-workspaces-messages.cron.command'; @Module({ imports: [ - DataSourceModule, - TypeORMModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - ConnectedAccountModule, + ObjectMetadataRepositoryModule.forFeature([ConnectedAccountObjectMetadata]), ], providers: [ GmailFullSyncCommand, diff --git a/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts b/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts index 375986cb13c0..da47d33266b1 100644 --- a/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/gmail-full-sync.command.ts @@ -8,7 +8,9 @@ import { GmailFullSyncJobData, GmailFullSyncJob, } from 'src/modules/messaging/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; interface GmailFullSyncOptions { workspaceId: string; @@ -22,7 +24,8 @@ export class GmailFullSyncCommand extends CommandRunner { constructor( @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, ) { super(); } @@ -47,7 +50,7 @@ export class GmailFullSyncCommand extends CommandRunner { private async fetchWorkspaceMessages(workspaceId: string): Promise { const connectedAccounts = - await this.connectedAccountService.getAll(workspaceId); + await this.connectedAccountRepository.getAll(workspaceId); for (const connectedAccount of connectedAccounts) { await this.messageQueueService.add( diff --git a/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts b/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts index 0511a9ad0b48..36c4dd57c6ea 100644 --- a/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts +++ b/packages/twenty-server/src/modules/messaging/commands/gmail-partial-sync.command.ts @@ -8,7 +8,9 @@ import { GmailPartialSyncJob, GmailPartialSyncJobData, } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; interface GmailPartialSyncOptions { workspaceId: string; @@ -22,7 +24,8 @@ export class GmailPartialSyncCommand extends CommandRunner { constructor( @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountService: ConnectedAccountRepository, ) { super(); } diff --git a/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts index 650828b45fe0..4908da0a3272 100644 --- a/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/create-companies-and-contacts-after-sync.job.ts @@ -2,9 +2,13 @@ import { Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; +import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; export type CreateCompaniesAndContactsAfterSyncJobData = { workspaceId: string; @@ -20,8 +24,11 @@ export class CreateCompaniesAndContactsAfterSyncJob ); constructor( private readonly createCompaniesAndContactsService: CreateCompanyAndContactService, - private readonly messageChannelService: MessageChannelService, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelService: MessageChannelRepository, private readonly messageParticipantService: MessageParticipantService, + @InjectObjectMetadataRepository(MessageParticipantObjectMetadata) + private readonly messageParticipantRepository: MessageParticipantRepository, ) {} async handle( @@ -44,7 +51,7 @@ export class CreateCompaniesAndContactsAfterSyncJob } const messageParticipantsWithoutPersonIdAndWorkspaceMemberId = - await this.messageParticipantService.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing( + await this.messageParticipantRepository.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing( messageChannelId, workspaceId, ); diff --git a/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts index c721f1752d0a..7011ded5b50d 100644 --- a/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/gmail-full-sync.job.ts @@ -2,8 +2,8 @@ import { Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; -import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync.service'; +import { GoogleAPIRefreshAccessTokenService } from 'src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service'; +import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service'; export type GmailFullSyncJobData = { workspaceId: string; @@ -16,7 +16,7 @@ export class GmailFullSyncJob implements MessageQueueJob { private readonly logger = new Logger(GmailFullSyncJob.name); constructor( - private readonly googleAPIsRefreshAccessTokenService: GoogleAPIsRefreshAccessTokenService, + private readonly googleAPIsRefreshAccessTokenService: GoogleAPIRefreshAccessTokenService, private readonly gmailFullSyncService: GmailFullSyncService, ) {} diff --git a/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts b/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts index b96ca955f101..478bb33345fc 100644 --- a/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/gmail-partial-sync.job.ts @@ -2,8 +2,8 @@ import { Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; -import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync.service'; +import { GoogleAPIRefreshAccessTokenService } from 'src/modules/connected-account/services/google-api-refresh-access-token/google-api-refresh-access-token.service'; +import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service'; export type GmailPartialSyncJobData = { workspaceId: string; @@ -17,7 +17,7 @@ export class GmailPartialSyncJob private readonly logger = new Logger(GmailPartialSyncJob.name); constructor( - private readonly googleAPIsRefreshAccessTokenService: GoogleAPIsRefreshAccessTokenService, + private readonly googleAPIsRefreshAccessTokenService: GoogleAPIRefreshAccessTokenService, private readonly gmailPartialSyncService: GmailPartialSyncService, ) {} diff --git a/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts b/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts index 2b058b7e55de..9eadb5898907 100644 --- a/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts +++ b/packages/twenty-server/src/modules/messaging/jobs/match-message-participant.job.ts @@ -2,7 +2,9 @@ import { Injectable } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; export type MatchMessageParticipantsJobData = { workspaceId: string; @@ -16,28 +18,32 @@ export class MatchMessageParticipantJob implements MessageQueueJob { constructor( - private readonly messageParticipantService: MessageParticipantService, + @InjectObjectMetadataRepository(MessageParticipantObjectMetadata) + private readonly messageParticipantRepository: MessageParticipantRepository, ) {} async handle(data: MatchMessageParticipantsJobData): Promise { const { workspaceId, personId, workspaceMemberId, email } = data; const messageParticipantsToUpdate = - await this.messageParticipantService.getByHandles([email], workspaceId); + await this.messageParticipantRepository.getByHandles( + [email], + workspaceId, + ); const messageParticipantIdsToUpdate = messageParticipantsToUpdate.map( (participant) => participant.id, ); if (personId) { - await this.messageParticipantService.updateParticipantsPersonId( + await this.messageParticipantRepository.updateParticipantsPersonId( messageParticipantIdsToUpdate, personId, workspaceId, ); } if (workspaceMemberId) { - await this.messageParticipantService.updateParticipantsWorkspaceMemberId( + await this.messageParticipantRepository.updateParticipantsWorkspaceMemberId( messageParticipantIdsToUpdate, workspaceMemberId, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts index bb352d612155..f0f2ee0a096c 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts @@ -1,5 +1,8 @@ import { Injectable, Inject } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; @@ -13,6 +16,10 @@ import { DeleteConnectedAccountAssociatedMessagingDataJob, } from 'src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { + FeatureFlagEntity, + FeatureFlagKeys, +} from 'src/engine/modules/feature-flag/feature-flag.entity'; @Injectable() export class MessagingConnectedAccountListener { @@ -21,12 +28,20 @@ export class MessagingConnectedAccountListener { private readonly messageQueueService: MessageQueueService, @Inject(MessageQueue.calendarQueue) private readonly calendarQueueService: MessageQueueService, + @InjectRepository(FeatureFlagEntity, 'core') + private readonly featureFlagRepository: Repository, ) {} @OnEvent('connectedAccount.deleted') - handleDeletedEvent( + async handleDeletedEvent( payload: ObjectRecordDeleteEvent, ) { + const isCalendarEnabled = await this.featureFlagRepository.findOneBy({ + workspaceId: payload.workspaceId, + key: FeatureFlagKeys.IsCalendarEnabled, + value: true, + }); + this.messageQueueService.add( DeleteConnectedAccountAssociatedMessagingDataJob.name, { @@ -35,12 +50,14 @@ export class MessagingConnectedAccountListener { }, ); - this.calendarQueueService.add( - DeleteConnectedAccountAssociatedCalendarDataJob.name, - { - workspaceId: payload.workspaceId, - connectedAccountId: payload.deletedRecord.id, - }, - ); + if (isCalendarEnabled) { + this.calendarQueueService.add( + DeleteConnectedAccountAssociatedCalendarDataJob.name, + { + workspaceId: payload.workspaceId, + connectedAccountId: payload.deletedRecord.id, + }, + ); + } } } diff --git a/packages/twenty-server/src/modules/messaging/messaging.module.ts b/packages/twenty-server/src/modules/messaging/messaging.module.ts index d2da63b31d84..9dd275e9f3d9 100644 --- a/packages/twenty-server/src/modules/messaging/messaging.module.ts +++ b/packages/twenty-server/src/modules/messaging/messaging.module.ts @@ -1,76 +1,19 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { HttpModule } from '@nestjs/axios'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; -import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; -import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; -import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; import { MessagingPersonListener } from 'src/modules/messaging/listeners/messaging-person.listener'; -import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; -import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; -import { CreateContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-contact/create-contact.service'; -import { CreateCompanyService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company/create-company.service'; -import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; -import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync.service'; -import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync.service'; -import { GoogleAPIsRefreshAccessTokenService } from 'src/modules/connected-account/services/google-apis-refresh-access-token.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; import { MessagingWorkspaceMemberListener } from 'src/modules/messaging/listeners/messaging-workspace-member.listener'; import { MessagingMessageChannelListener } from 'src/modules/messaging/listeners/messaging-message-channel.listener'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; -import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; -import { CompanyModule } from 'src/modules/messaging/repositories/company/company.module'; -import { PersonModule } from 'src/modules/person/repositories/person/person.module'; -import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; import { MessagingConnectedAccountListener } from 'src/modules/messaging/listeners/messaging-connected-account.listener'; -import { BlocklistModule } from 'src/modules/connected-account/repositories/blocklist/blocklist.module'; -import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch.service'; +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; @Module({ - imports: [ - EnvironmentModule, - WorkspaceDataSourceModule, - ConnectedAccountModule, - MessageChannelModule, - MessageChannelMessageAssociationModule, - MessageModule, - MessageThreadModule, - MessageParticipantModule, - CreateCompaniesAndContactsModule, - WorkspaceMemberModule, - TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), - CompanyModule, - PersonModule, - BlocklistModule, - HttpModule.register({ - baseURL: 'https://www.googleapis.com/batch/gmail/v1', - }), - ], + imports: [TypeOrmModule.forFeature([FeatureFlagEntity], 'core')], providers: [ - GmailFullSyncService, - GmailPartialSyncService, - FetchMessagesByBatchesService, - GoogleAPIsRefreshAccessTokenService, - GmailClientProvider, - CreateContactService, - CreateCompanyService, MessagingPersonListener, MessagingWorkspaceMemberListener, MessagingMessageChannelListener, - MessageService, - SaveMessagesAndCreateContactsService, MessagingConnectedAccountListener, - FetchByBatchesService, - ], - exports: [ - GmailPartialSyncService, - GmailFullSyncService, - GoogleAPIsRefreshAccessTokenService, - FetchByBatchesService, ], + exports: [], }) export class MessagingModule {} diff --git a/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts index b5fb45c3f869..5824e536b6cf 100644 --- a/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts +++ b/packages/twenty-server/src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook.ts @@ -10,18 +10,29 @@ import { groupBy } from 'lodash'; import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; -import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; +import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; @Injectable() export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook { constructor( - private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, - private readonly messageChannelService: MessageChannelService, - private readonly connectedAccountService: ConnectedAccountService, - private readonly workspaceMemberService: WorkspaceMemberService, + @InjectObjectMetadataRepository( + MessageChannelMessageAssociationObjectMetadata, + ) + private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationRepository, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelService: MessageChannelRepository, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, + @InjectObjectMetadataRepository(WorkspaceMemberObjectMetadata) + private readonly workspaceMemberService: WorkspaceMemberRepository, ) {} async execute( @@ -75,7 +86,7 @@ export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook { await this.workspaceMemberService.getByIdOrFail(userId, workspaceId); const messageChannelsConnectedAccounts = - await this.connectedAccountService.getByIds( + await this.connectedAccountRepository.getByIds( messageChannels.map((channel) => channel.connectedAccountId), workspaceId, ); diff --git a/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts b/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts index 0b47c48ff9f2..2570a7f2bc63 100644 --- a/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts +++ b/packages/twenty-server/src/modules/messaging/query-hooks/messaging-query-hook.module.ts @@ -2,17 +2,20 @@ import { Module } from '@nestjs/common'; import { MessageFindManyPreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-many.pre-query.hook'; import { MessageFindOnePreQueryHook } from 'src/modules/messaging/query-hooks/message/message-find-one.pre-query-hook'; -import { ConnectedAccountModule } from 'src/modules/connected-account/repositories/connected-account/connected-account.module'; -import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; -import { WorkspaceMemberModule } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; @Module({ imports: [ - MessageChannelMessageAssociationModule, - MessageChannelModule, - ConnectedAccountModule, - WorkspaceMemberModule, + ObjectMetadataRepositoryModule.forFeature([ + MessageChannelMessageAssociationObjectMetadata, + MessageChannelObjectMetadata, + ConnectedAccountObjectMetadata, + WorkspaceMemberObjectMetadata, + ]), ], providers: [ { diff --git a/packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts b/packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts deleted file mode 100644 index 61460d6bf876..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/company/company.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { CompanyService } from 'src/modules/messaging/repositories/company/company.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -// TODO: Move outside of the messaging module -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [CompanyService], - exports: [CompanyService], -}) -export class CompanyModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association.repository.ts similarity index 88% rename from packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association.repository.ts index 17454e6027bb..eb5f283e2d07 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association.repository.ts @@ -7,7 +7,7 @@ import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/mess import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() -export class MessageChannelMessageAssociationService { +export class MessageChannelMessageAssociationRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} @@ -192,4 +192,30 @@ export class MessageChannelMessageAssociationService { transactionManager, ); } + + public async insert( + messageChannelId: string, + messageId: string, + messageExternalId: string, + messageThreadId: string, + messageThreadExternalId: string, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."messageChannelMessageAssociation" ("messageChannelId", "messageId", "messageExternalId", "messageThreadId", "messageThreadExternalId") VALUES ($1, $2, $3, $4, $5)`, + [ + messageChannelId, + messageId, + messageExternalId, + messageThreadId, + messageThreadExternalId, + ], + workspaceId, + transactionManager, + ); + } } diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts deleted file mode 100644 index 7c9f4de8f5a4..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [MessageChannelMessageAssociationService], - exports: [MessageChannelMessageAssociationService], -}) -export class MessageChannelMessageAssociationModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel.repository.ts similarity index 98% rename from packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-channel.repository.ts index 71712ea67887..59c0ddab7b87 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-channel.repository.ts @@ -7,7 +7,7 @@ import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-obj import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; @Injectable() -export class MessageChannelService { +export class MessageChannelRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts deleted file mode 100644 index 90661ee6b506..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message-channel/message-channel.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [MessageChannelService], - exports: [MessageChannelService], -}) -export class MessageChannelModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts similarity index 82% rename from packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts rename to packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts index 71b9635f6481..839cf63ca295 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.service.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts @@ -9,13 +9,11 @@ import { ParticipantWithId, ParticipantWithMessageId, } from 'src/modules/messaging/types/gmail-message'; -import { PersonService } from 'src/modules/person/repositories/person/person.service'; @Injectable() -export class MessageParticipantService { +export class MessageParticipantRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, - private readonly personService: PersonService, ) {} public async getByHandles( @@ -195,45 +193,4 @@ export class MessageParticipantService { transactionManager, ); } - - public async updateMessageParticipantsAfterPeopleCreation( - participants: ParticipantWithId[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - if (!participants) return; - - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const handles = participants.map((participant) => participant.handle); - - const participantPersonIds = await this.personService.getByEmails( - handles, - workspaceId, - transactionManager, - ); - - const messageParticipantsToUpdate = participants.map((participant) => [ - participant.id, - participantPersonIds.find( - (e: { id: string; email: string }) => e.email === participant.handle, - )?.id, - ]); - - if (messageParticipantsToUpdate.length === 0) return; - - const valuesString = messageParticipantsToUpdate - .map((_, index) => `($${index * 2 + 1}::uuid, $${index * 2 + 2}::uuid)`) - .join(', '); - - await this.workspaceDataSourceService.executeRawQuery( - `UPDATE ${dataSourceSchema}."messageParticipant" AS "messageParticipant" SET "personId" = "data"."personId" - FROM (VALUES ${valuesString}) AS "data"("id", "personId") - WHERE "messageParticipant"."id" = "data"."id"`, - messageParticipantsToUpdate.flat(), - workspaceId, - transactionManager, - ); - } } diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts deleted file mode 100644 index e8754fe547b1..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message-participant/message-participant.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { PersonModule } from 'src/modules/person/repositories/person/person.module'; - -@Module({ - imports: [WorkspaceDataSourceModule, PersonModule], - providers: [MessageParticipantService], - exports: [MessageParticipantService], -}) -export class MessageParticipantModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-thread.repository.ts b/packages/twenty-server/src/modules/messaging/repositories/message-thread.repository.ts new file mode 100644 index 000000000000..bf0e9d7c90af --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/repositories/message-thread.repository.ts @@ -0,0 +1,67 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; + +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; + +@Injectable() +export class MessageThreadRepository { + constructor( + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + ) {} + + public async getOrphanThreadIdsPaginated( + limit: number, + offset: number, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const orphanThreads = await this.workspaceDataSourceService.executeRawQuery( + `SELECT mt.id + FROM ${dataSourceSchema}."messageThread" mt + LEFT JOIN ${dataSourceSchema}."message" m ON mt.id = m."messageThreadId" + WHERE m."messageThreadId" IS NULL + LIMIT $1 OFFSET $2`, + [limit, offset], + workspaceId, + transactionManager, + ); + + return orphanThreads.map(({ id }) => id); + } + + public async deleteByIds( + messageThreadIds: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `DELETE FROM ${dataSourceSchema}."messageThread" WHERE id = ANY($1)`, + [messageThreadIds], + workspaceId, + transactionManager, + ); + } + + public async insert( + messageThreadId: string, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."messageThread" (id) VALUES ($1)`, + [messageThreadId], + workspaceId, + transactionManager, + ); + } +} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts deleted file mode 100644 index d08c2358bacc..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Module, forwardRef } from '@nestjs/common'; - -import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; -import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [ - WorkspaceDataSourceModule, - MessageChannelMessageAssociationModule, - forwardRef(() => MessageModule), - ], - providers: [MessageThreadService], - exports: [MessageThreadService], -}) -export class MessageThreadModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts b/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts deleted file mode 100644 index b4196940964c..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message-thread/message-thread.service.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Inject, Injectable, forwardRef } from '@nestjs/common'; - -import { EntityManager } from 'typeorm'; -import { v4 } from 'uuid'; - -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; - -@Injectable() -export class MessageThreadService { - constructor( - private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, - private readonly workspaceDataSourceService: WorkspaceDataSourceService, - @Inject(forwardRef(() => MessageService)) - private readonly messageService: MessageService, - ) {} - - public async getOrphanThreadIdsPaginated( - limit: number, - offset: number, - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const orphanThreads = await this.workspaceDataSourceService.executeRawQuery( - `SELECT mt.id - FROM ${dataSourceSchema}."messageThread" mt - LEFT JOIN ${dataSourceSchema}."message" m ON mt.id = m."messageThreadId" - WHERE m."messageThreadId" IS NULL - LIMIT $1 OFFSET $2`, - [limit, offset], - workspaceId, - transactionManager, - ); - - return orphanThreads.map(({ id }) => id); - } - - public async deleteByIds( - messageThreadIds: string[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - await this.workspaceDataSourceService.executeRawQuery( - `DELETE FROM ${dataSourceSchema}."messageThread" WHERE id = ANY($1)`, - [messageThreadIds], - workspaceId, - transactionManager, - ); - } - - public async saveMessageThreadOrReturnExistingMessageThread( - headerMessageId: string, - messageThreadExternalId: string, - dataSourceMetadata: DataSourceEntity, - workspaceId: string, - manager: EntityManager, - ) { - // Check if message thread already exists via threadExternalId - const existingMessageChannelMessageAssociationByMessageThreadExternalId = - await this.messageChannelMessageAssociationService.getFirstByMessageThreadExternalId( - messageThreadExternalId, - workspaceId, - manager, - ); - - const existingMessageThread = - existingMessageChannelMessageAssociationByMessageThreadExternalId?.messageThreadId; - - if (existingMessageThread) { - return Promise.resolve(existingMessageThread); - } - - // Check if message thread already exists via existing message headerMessageId - const existingMessageWithSameHeaderMessageId = - await this.messageService.getFirstOrNullByHeaderMessageId( - headerMessageId, - workspaceId, - manager, - ); - - if (existingMessageWithSameHeaderMessageId) { - return Promise.resolve( - existingMessageWithSameHeaderMessageId.messageThreadId, - ); - } - - // If message thread does not exist, create new message thread - const newMessageThreadId = v4(); - - await manager.query( - `INSERT INTO ${dataSourceMetadata.schema}."messageThread" ("id") VALUES ($1)`, - [newMessageThreadId], - ); - - return Promise.resolve(newMessageThreadId); - } -} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message.repository.ts b/packages/twenty-server/src/modules/messaging/repositories/message.repository.ts new file mode 100644 index 000000000000..b884f4458ee0 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/repositories/message.repository.ts @@ -0,0 +1,138 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; + +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; +import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; + +@Injectable() +export class MessageRepository { + constructor( + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + ) {} + + public async getNonAssociatedMessageIdsPaginated( + limit: number, + offset: number, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const nonAssociatedMessages = + await this.workspaceDataSourceService.executeRawQuery( + `SELECT m.id FROM ${dataSourceSchema}."message" m + LEFT JOIN ${dataSourceSchema}."messageChannelMessageAssociation" mcma + ON m.id = mcma."messageId" + WHERE mcma.id IS NULL + LIMIT $1 OFFSET $2`, + [limit, offset], + workspaceId, + transactionManager, + ); + + return nonAssociatedMessages.map(({ id }) => id); + } + + public async getFirstOrNullByHeaderMessageId( + headerMessageId: string, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise | null> { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const messages = await this.workspaceDataSourceService.executeRawQuery( + `SELECT * FROM ${dataSourceSchema}."message" WHERE "headerMessageId" = $1 LIMIT 1`, + [headerMessageId], + workspaceId, + transactionManager, + ); + + if (!messages || messages.length === 0) { + return null; + } + + return messages[0]; + } + + public async getByIds( + messageIds: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise[]> { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + return await this.workspaceDataSourceService.executeRawQuery( + `SELECT * FROM ${dataSourceSchema}."message" WHERE "id" = ANY($1)`, + [messageIds], + workspaceId, + transactionManager, + ); + } + + public async deleteByIds( + messageIds: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `DELETE FROM ${dataSourceSchema}."message" WHERE "id" = ANY($1)`, + [messageIds], + workspaceId, + transactionManager, + ); + } + + public async getByMessageThreadIds( + messageThreadIds: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise[]> { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + return await this.workspaceDataSourceService.executeRawQuery( + `SELECT * FROM ${dataSourceSchema}."message" WHERE "messageThreadId" = ANY($1)`, + [messageThreadIds], + workspaceId, + transactionManager, + ); + } + + public async insert( + id: string, + headerMessageId: string, + subject: string, + receivedAt: Date, + messageDirection: string, + messageThreadId: string, + text: string, + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."message" ("id", "headerMessageId", "subject", "receivedAt", "direction", "messageThreadId", "text") VALUES ($1, $2, $3, $4, $5, $6, $7)`, + [ + id, + headerMessageId, + subject, + receivedAt, + messageDirection, + messageThreadId, + text, + ], + workspaceId, + transactionManager, + ); + } +} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts b/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts deleted file mode 100644 index d6cbaab6d81b..000000000000 --- a/packages/twenty-server/src/modules/messaging/repositories/message/message.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Module, forwardRef } from '@nestjs/common'; - -import { MessageChannelModule } from 'src/modules/messaging/repositories/message-channel/message-channel.module'; -import { MessageChannelMessageAssociationModule } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module'; -import { MessageParticipantModule } from 'src/modules/messaging/repositories/message-participant/message-participant.module'; -import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; - -@Module({ - imports: [ - WorkspaceDataSourceModule, - forwardRef(() => MessageThreadModule), - MessageParticipantModule, - MessageChannelMessageAssociationModule, - MessageChannelModule, - CreateCompaniesAndContactsModule, - ], - providers: [MessageService], - exports: [MessageService], -}) -export class MessageModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.module.ts b/packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.module.ts new file mode 100644 index 000000000000..0535c95caf87 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.module.ts @@ -0,0 +1,15 @@ +import { HttpModule } from '@nestjs/axios'; +import { Module } from '@nestjs/common'; + +import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch/fetch-by-batch.service'; + +@Module({ + imports: [ + HttpModule.register({ + baseURL: 'https://www.googleapis.com/batch/gmail/v1', + }), + ], + providers: [FetchByBatchesService], + exports: [FetchByBatchesService], +}) +export class FetchByBatchModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/fetch-by-batch.service.ts b/packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.service.ts similarity index 100% rename from packages/twenty-server/src/modules/messaging/services/fetch-by-batch.service.ts rename to packages/twenty-server/src/modules/messaging/services/fetch-by-batch/fetch-by-batch.service.ts diff --git a/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module.ts b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module.ts new file mode 100644 index 000000000000..9bcb913718b6 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { FetchByBatchModule } from 'src/modules/messaging/services/fetch-by-batch/fetch-by-batch.module'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service'; + +@Module({ + imports: [FetchByBatchModule], + providers: [FetchMessagesByBatchesService], + exports: [FetchMessagesByBatchesService], +}) +export class FetchMessagesByBatchesModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service.ts similarity index 99% rename from packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts rename to packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service.ts index 9fb5badbf3bd..63b2b2e0d7bb 100644 --- a/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service.ts @@ -7,7 +7,7 @@ import planer from 'planer'; import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; import { MessageQuery } from 'src/modules/messaging/types/message-or-thread-query'; import { GmailMessageParsedResponse } from 'src/modules/messaging/types/gmail-message-parsed-response'; -import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch.service'; +import { FetchByBatchesService } from 'src/modules/messaging/services/fetch-by-batch/fetch-by-batch.service'; import { formatAddressObjectAsParticipants } from 'src/modules/messaging/services/utils/format-address-object-as-participants.util'; @Injectable() diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts new file mode 100644 index 000000000000..b9a12f9c2947 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts @@ -0,0 +1,31 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { FetchMessagesByBatchesModule } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module'; +import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service'; +import { MessagingProvidersModule } from 'src/modules/messaging/services/providers/messaging-providers.module'; +import { SaveMessagesAndCreateContactsModule } from 'src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; + +@Module({ + imports: [ + MessagingProvidersModule, + FetchMessagesByBatchesModule, + ObjectMetadataRepositoryModule.forFeature([ + ConnectedAccountObjectMetadata, + MessageChannelObjectMetadata, + MessageChannelMessageAssociationObjectMetadata, + BlocklistObjectMetadata, + ]), + SaveMessagesAndCreateContactsModule, + TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), + ], + providers: [GmailFullSyncService], + exports: [GmailFullSyncService], +}) +export class GmailFullSyncModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts similarity index 76% rename from packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts rename to packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts index cfcfe9171ff6..61cd34f11a9f 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts @@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service'; import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; @@ -11,17 +11,22 @@ import { GmailFullSyncJobData, GmailFullSyncJob, } from 'src/modules/messaging/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; import { createQueriesFromMessageIds } from 'src/modules/messaging/utils/create-queries-from-message-ids.util'; import { gmailSearchFilterExcludeEmails } from 'src/modules/messaging/utils/gmail-search-filter.util'; -import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; -import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; +import { BlocklistRepository } from 'src/modules/connected-account/repositories/blocklist.repository'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service'; import { FeatureFlagEntity, FeatureFlagKeys, } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; @Injectable() export class GmailFullSyncService { @@ -32,10 +37,16 @@ export class GmailFullSyncService { private readonly fetchMessagesByBatchesService: FetchMessagesByBatchesService, @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, - private readonly messageChannelService: MessageChannelService, - private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, - private readonly blocklistService: BlocklistService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelRepository: MessageChannelRepository, + @InjectObjectMetadataRepository( + MessageChannelMessageAssociationObjectMetadata, + ) + private readonly messageChannelMessageAssociationRepository: MessageChannelMessageAssociationRepository, + @InjectObjectMetadataRepository(BlocklistObjectMetadata) + private readonly blocklistRepository: BlocklistRepository, private readonly saveMessagesAndCreateContactsService: SaveMessagesAndCreateContactsService, @InjectRepository(FeatureFlagEntity, 'core') private readonly featureFlagRepository: Repository, @@ -46,7 +57,7 @@ export class GmailFullSyncService { connectedAccountId: string, nextPageToken?: string, ): Promise { - const connectedAccount = await this.connectedAccountService.getById( + const connectedAccount = await this.connectedAccountRepository.getById( connectedAccountId, workspaceId, ); @@ -70,7 +81,7 @@ export class GmailFullSyncService { } const gmailMessageChannel = - await this.messageChannelService.getFirstByConnectedAccountId( + await this.messageChannelRepository.getFirstByConnectedAccountId( connectedAccountId, workspaceId, ); @@ -99,7 +110,7 @@ export class GmailFullSyncService { isBlocklistEnabledFeatureFlag && isBlocklistEnabledFeatureFlag.value; const blocklist = isBlocklistEnabled - ? await this.blocklistService.getByWorkspaceMemberId( + ? await this.blocklistRepository.getByWorkspaceMemberId( workspaceMemberId, workspaceId, ) @@ -140,7 +151,7 @@ export class GmailFullSyncService { startTime = Date.now(); const existingMessageChannelMessageAssociations = - await this.messageChannelMessageAssociationService.getByMessageExternalIdsAndMessageChannelId( + await this.messageChannelMessageAssociationRepository.getByMessageExternalIdsAndMessageChannelId( messageExternalIds, gmailMessageChannelId, workspaceId, @@ -221,7 +232,7 @@ export class GmailFullSyncService { startTime = Date.now(); - await this.connectedAccountService.updateLastSyncHistoryIdIfHigher( + await this.connectedAccountRepository.updateLastSyncHistoryIdIfHigher( historyId, connectedAccount.id, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts new file mode 100644 index 000000000000..744e70295bf4 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts @@ -0,0 +1,31 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { FetchMessagesByBatchesModule } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module'; +import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service'; +import { MessageModule } from 'src/modules/messaging/services/message/message.module'; +import { MessagingProvidersModule } from 'src/modules/messaging/services/providers/messaging-providers.module'; +import { SaveMessagesAndCreateContactsModule } from 'src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; + +@Module({ + imports: [ + MessagingProvidersModule, + FetchMessagesByBatchesModule, + ObjectMetadataRepositoryModule.forFeature([ + ConnectedAccountObjectMetadata, + MessageChannelObjectMetadata, + BlocklistObjectMetadata, + ]), + MessageModule, + SaveMessagesAndCreateContactsModule, + TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), + ], + providers: [GmailPartialSyncService], + exports: [GmailPartialSyncService], +}) +export class GmailPartialSyncModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts similarity index 86% rename from packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts rename to packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts index a9698b63cee8..e202fb820d4e 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts @@ -4,7 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { gmail_v1 } from 'googleapis'; import { Repository } from 'typeorm'; -import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches.service'; +import { FetchMessagesByBatchesService } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.service'; import { GmailClientProvider } from 'src/modules/messaging/services/providers/gmail/gmail-client.provider'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; @@ -12,18 +12,22 @@ import { GmailFullSyncJob, GmailFullSyncJobData, } from 'src/modules/messaging/jobs/gmail-full-sync.job'; -import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; import { createQueriesFromMessageIds } from 'src/modules/messaging/utils/create-queries-from-message-ids.util'; import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; import { isPersonEmail } from 'src/modules/messaging/utils/is-person-email.util'; -import { BlocklistService } from 'src/modules/connected-account/repositories/blocklist/blocklist.service'; -import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-messages-and-create-contacts.service'; +import { BlocklistRepository } from 'src/modules/connected-account/repositories/blocklist.repository'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service'; import { FeatureFlagEntity, FeatureFlagKeys, } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { MessageService } from 'src/modules/messaging/services/message/message.service'; @Injectable() export class GmailPartialSyncService { @@ -34,10 +38,13 @@ export class GmailPartialSyncService { private readonly fetchMessagesByBatchesService: FetchMessagesByBatchesService, @Inject(MessageQueue.messagingQueue) private readonly messageQueueService: MessageQueueService, - private readonly connectedAccountService: ConnectedAccountService, - private readonly messageChannelService: MessageChannelService, + @InjectObjectMetadataRepository(ConnectedAccountObjectMetadata) + private readonly connectedAccountRepository: ConnectedAccountRepository, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelRepository: MessageChannelRepository, private readonly messageService: MessageService, - private readonly blocklistService: BlocklistService, + @InjectObjectMetadataRepository(BlocklistObjectMetadata) + private readonly blocklistRepository: BlocklistRepository, private readonly saveMessagesAndCreateContactsService: SaveMessagesAndCreateContactsService, @InjectRepository(FeatureFlagEntity, 'core') private readonly featureFlagRepository: Repository, @@ -48,7 +55,7 @@ export class GmailPartialSyncService { connectedAccountId: string, maxResults = 500, ): Promise { - const connectedAccount = await this.connectedAccountService.getById( + const connectedAccount = await this.connectedAccountRepository.getById( connectedAccountId, workspaceId, ); @@ -103,7 +110,7 @@ export class GmailPartialSyncService { `gmail partial-sync for workspace ${workspaceId} and account ${connectedAccountId}: invalid lastSyncHistoryId, falling back to full sync.`, ); - await this.connectedAccountService.deleteHistoryId( + await this.connectedAccountRepository.deleteHistoryId( connectedAccountId, workspaceId, ); @@ -143,7 +150,7 @@ export class GmailPartialSyncService { } const gmailMessageChannel = - await this.messageChannelService.getFirstByConnectedAccountId( + await this.messageChannelRepository.getFirstByConnectedAccountId( connectedAccountId, workspaceId, ); @@ -183,7 +190,7 @@ export class GmailPartialSyncService { isBlocklistEnabledFeatureFlag && isBlocklistEnabledFeatureFlag.value; const blocklist = isBlocklistEnabled - ? await this.blocklistService.getByWorkspaceMemberId( + ? await this.blocklistRepository.getByWorkspaceMemberId( connectedAccount.accountOwnerId, workspaceId, ) @@ -251,7 +258,7 @@ export class GmailPartialSyncService { } startTime = Date.now(); - await this.connectedAccountService.updateLastSyncHistoryId( + await this.connectedAccountRepository.updateLastSyncHistoryId( historyId, connectedAccount.id, workspaceId, diff --git a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts new file mode 100644 index 000000000000..9491cb305961 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; + +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; + +@Module({ + imports: [ + WorkspaceDataSourceModule, + ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]), + ], + providers: [MessageParticipantService], + exports: [MessageParticipantService], +}) +export class MessageParticipantModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts new file mode 100644 index 000000000000..7219051817e1 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; + +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ParticipantWithId } from 'src/modules/messaging/types/gmail-message'; +import { PersonRepository } from 'src/modules/person/repositories/person.repository'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; + +@Injectable() +export class MessageParticipantService { + constructor( + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + @InjectObjectMetadataRepository(PersonObjectMetadata) + private readonly personRepository: PersonRepository, + ) {} + + public async updateMessageParticipantsAfterPeopleCreation( + participants: ParticipantWithId[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + if (!participants) return; + + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const handles = participants.map((participant) => participant.handle); + + const participantPersonIds = await this.personRepository.getByEmails( + handles, + workspaceId, + transactionManager, + ); + + const messageParticipantsToUpdate = participants.map((participant) => [ + participant.id, + participantPersonIds.find( + (e: { id: string; email: string }) => e.email === participant.handle, + )?.id, + ]); + + if (messageParticipantsToUpdate.length === 0) return; + + const valuesString = messageParticipantsToUpdate + .map((_, index) => `($${index * 2 + 1}::uuid, $${index * 2 + 2}::uuid)`) + .join(', '); + + await this.workspaceDataSourceService.executeRawQuery( + `UPDATE ${dataSourceSchema}."messageParticipant" AS "messageParticipant" SET "personId" = "data"."personId" + FROM (VALUES ${valuesString}) AS "data"("id", "personId") + WHERE "messageParticipant"."id" = "data"."id"`, + messageParticipantsToUpdate.flat(), + workspaceId, + transactionManager, + ); + } +} diff --git a/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.module.ts b/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.module.ts new file mode 100644 index 000000000000..c06f474db6b8 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.module.ts @@ -0,0 +1,20 @@ +import { Module } from '@nestjs/common'; + +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { MessageThreadService } from 'src/modules/messaging/services/message-thread/message-thread.service'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; + +@Module({ + imports: [ + ObjectMetadataRepositoryModule.forFeature([ + MessageChannelMessageAssociationObjectMetadata, + MessageObjectMetadata, + MessageThreadObjectMetadata, + ]), + ], + providers: [MessageThreadService], + exports: [MessageThreadService], +}) +export class MessageThreadModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.service.ts b/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.service.ts new file mode 100644 index 000000000000..01fa411a3f99 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/message-thread/message-thread.service.ts @@ -0,0 +1,73 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; +import { v4 } from 'uuid'; + +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; +import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; + +@Injectable() +export class MessageThreadService { + constructor( + @InjectObjectMetadataRepository( + MessageChannelMessageAssociationObjectMetadata, + ) + private readonly messageChannelMessageAssociationRepository: MessageChannelMessageAssociationRepository, + @InjectObjectMetadataRepository(MessageObjectMetadata) + private readonly messageRepository: MessageRepository, + @InjectObjectMetadataRepository(MessageThreadObjectMetadata) + private readonly messageThreadRepository: MessageThreadRepository, + ) {} + + public async saveMessageThreadOrReturnExistingMessageThread( + headerMessageId: string, + messageThreadExternalId: string, + workspaceId: string, + manager: EntityManager, + ) { + // Check if message thread already exists via threadExternalId + const existingMessageChannelMessageAssociationByMessageThreadExternalId = + await this.messageChannelMessageAssociationRepository.getFirstByMessageThreadExternalId( + messageThreadExternalId, + workspaceId, + manager, + ); + + const existingMessageThread = + existingMessageChannelMessageAssociationByMessageThreadExternalId?.messageThreadId; + + if (existingMessageThread) { + return Promise.resolve(existingMessageThread); + } + + // Check if message thread already exists via existing message headerMessageId + const existingMessageWithSameHeaderMessageId = + await this.messageRepository.getFirstOrNullByHeaderMessageId( + headerMessageId, + workspaceId, + manager, + ); + + if (existingMessageWithSameHeaderMessageId) { + return Promise.resolve( + existingMessageWithSameHeaderMessageId.messageThreadId, + ); + } + + // If message thread does not exist, create new message thread + const newMessageThreadId = v4(); + + await this.messageThreadRepository.insert( + newMessageThreadId, + workspaceId, + manager, + ); + + return Promise.resolve(newMessageThreadId); + } +} diff --git a/packages/twenty-server/src/modules/messaging/services/message/message.module.ts b/packages/twenty-server/src/modules/messaging/services/message/message.module.ts new file mode 100644 index 000000000000..9a2bb8abd7e4 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/message/message.module.ts @@ -0,0 +1,26 @@ +import { Module } from '@nestjs/common'; + +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { MessageThreadModule } from 'src/modules/messaging/services/message-thread/message-thread.module'; +import { MessageService } from 'src/modules/messaging/services/message/message.service'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; + +@Module({ + imports: [ + WorkspaceDataSourceModule, + ObjectMetadataRepositoryModule.forFeature([ + MessageChannelMessageAssociationObjectMetadata, + MessageObjectMetadata, + MessageChannelObjectMetadata, + MessageThreadObjectMetadata, + ]), + MessageThreadModule, + ], + providers: [MessageService], + exports: [MessageService], +}) +export class MessageModule {} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts similarity index 56% rename from packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts rename to packages/twenty-server/src/modules/messaging/services/message/message.service.ts index 1dd039ac146f..7832ecefe17e 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/message/message.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts @@ -1,17 +1,23 @@ -import { Inject, Injectable, Logger, forwardRef } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { DataSource, EntityManager } from 'typeorm'; import { v4 } from 'uuid'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; -import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; -import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; -import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; +import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; +import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; +import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; +import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { MessageThreadService } from 'src/modules/messaging/services/message-thread/message-thread.service'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; @Injectable() export class MessageService { @@ -19,106 +25,19 @@ export class MessageService { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, - private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, - @Inject(forwardRef(() => MessageThreadService)) + @InjectObjectMetadataRepository( + MessageChannelMessageAssociationObjectMetadata, + ) + private readonly messageChannelMessageAssociationRepository: MessageChannelMessageAssociationRepository, + @InjectObjectMetadataRepository(MessageObjectMetadata) + private readonly messageRepository: MessageRepository, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelRepository: MessageChannelRepository, + @InjectObjectMetadataRepository(MessageThreadObjectMetadata) + private readonly messageThreadRepository: MessageThreadRepository, private readonly messageThreadService: MessageThreadService, - private readonly messageChannelService: MessageChannelService, ) {} - public async getNonAssociatedMessageIdsPaginated( - limit: number, - offset: number, - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const nonAssociatedMessages = - await this.workspaceDataSourceService.executeRawQuery( - `SELECT m.id FROM ${dataSourceSchema}."message" m - LEFT JOIN ${dataSourceSchema}."messageChannelMessageAssociation" mcma - ON m.id = mcma."messageId" - WHERE mcma.id IS NULL - LIMIT $1 OFFSET $2`, - [limit, offset], - workspaceId, - transactionManager, - ); - - return nonAssociatedMessages.map(({ id }) => id); - } - - public async getFirstOrNullByHeaderMessageId( - headerMessageId: string, - workspaceId: string, - transactionManager?: EntityManager, - ): Promise | null> { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const messages = await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."message" WHERE "headerMessageId" = $1 LIMIT 1`, - [headerMessageId], - workspaceId, - transactionManager, - ); - - if (!messages || messages.length === 0) { - return null; - } - - return messages[0]; - } - - public async getByIds( - messageIds: string[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise[]> { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - return await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."message" WHERE "id" = ANY($1)`, - [messageIds], - workspaceId, - transactionManager, - ); - } - - public async deleteByIds( - messageIds: string[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - await this.workspaceDataSourceService.executeRawQuery( - `DELETE FROM ${dataSourceSchema}."message" WHERE "id" = ANY($1)`, - [messageIds], - workspaceId, - transactionManager, - ); - } - - public async getByMessageThreadIds( - messageThreadIds: string[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise[]> { - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - return await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."message" WHERE "messageThreadId" = ANY($1)`, - [messageThreadIds], - workspaceId, - transactionManager, - ); - } - public async saveMessages( messages: GmailMessage[], dataSourceMetadata: DataSourceEntity, @@ -140,7 +59,7 @@ export class MessageService { await workspaceDataSource?.transaction( async (manager: EntityManager) => { const gmailMessageChannel = - await this.messageChannelService.getByIds( + await this.messageChannelRepository.getByIds( [gmailMessageChannelId], workspaceId, manager, @@ -157,7 +76,7 @@ export class MessageService { } const existingMessageChannelMessageAssociationsCount = - await this.messageChannelMessageAssociationService.countByMessageExternalIdsAndMessageChannelId( + await this.messageChannelMessageAssociationRepository.countByMessageExternalIdsAndMessageChannelId( [message.externalId], gmailMessageChannelId, workspaceId, @@ -173,7 +92,6 @@ export class MessageService { await this.messageThreadService.saveMessageThreadOrReturnExistingMessageThread( message.headerMessageId, message.messageThreadExternalId, - dataSourceMetadata, workspaceId, manager, ); @@ -193,15 +111,14 @@ export class MessageService { savedOrExistingMessageId, ); - await manager.query( - `INSERT INTO ${dataSourceMetadata.schema}."messageChannelMessageAssociation" ("messageChannelId", "messageId", "messageExternalId", "messageThreadId", "messageThreadExternalId") VALUES ($1, $2, $3, $4, $5)`, - [ - gmailMessageChannelId, - savedOrExistingMessageId, - message.externalId, - savedOrExistingMessageThreadId, - message.messageThreadExternalId, - ], + await this.messageChannelMessageAssociationRepository.insert( + gmailMessageChannelId, + savedOrExistingMessageId, + message.externalId, + savedOrExistingMessageThreadId, + message.messageThreadExternalId, + workspaceId, + manager, ); }, ); @@ -223,10 +140,11 @@ export class MessageService { workspaceId: string, manager: EntityManager, ): Promise { - const existingMessage = await this.getFirstOrNullByHeaderMessageId( - message.headerMessageId, - workspaceId, - ); + const existingMessage = + await this.messageRepository.getFirstOrNullByHeaderMessageId( + message.headerMessageId, + workspaceId, + ); const existingMessageId = existingMessage?.id; if (existingMessageId) { @@ -240,17 +158,16 @@ export class MessageService { const receivedAt = new Date(parseInt(message.internalDate)); - await manager.query( - `INSERT INTO ${dataSourceMetadata.schema}."message" ("id", "headerMessageId", "subject", "receivedAt", "direction", "messageThreadId", "text") VALUES ($1, $2, $3, $4, $5, $6, $7)`, - [ - newMessageId, - message.headerMessageId, - message.subject, - receivedAt, - messageDirection, - messageThreadId, - message.text, - ], + await this.messageRepository.insert( + newMessageId, + message.headerMessageId, + message.subject, + receivedAt, + messageDirection, + messageThreadId, + message.text, + workspaceId, + manager, ); return Promise.resolve(newMessageId); @@ -268,7 +185,7 @@ export class MessageService { await workspaceDataSource?.transaction(async (manager: EntityManager) => { const messageChannelMessageAssociationsToDelete = - await this.messageChannelMessageAssociationService.getByMessageExternalIdsAndMessageChannelId( + await this.messageChannelMessageAssociationRepository.getByMessageExternalIdsAndMessageChannelId( messagesDeletedMessageExternalIds, gmailMessageChannelId, workspaceId, @@ -281,7 +198,7 @@ export class MessageService { messageChannelMessageAssociationToDelete.id, ); - await this.messageChannelMessageAssociationService.deleteByIds( + await this.messageChannelMessageAssociationRepository.deleteByIds( messageChannelMessageAssociationIdsToDeleteIds, workspaceId, manager, @@ -294,7 +211,7 @@ export class MessageService { ); const messageChannelMessageAssociationByMessageIds = - await this.messageChannelMessageAssociationService.getByMessageIds( + await this.messageChannelMessageAssociationRepository.getByMessageIds( messageIdsFromMessageChannelMessageAssociationsToDelete, workspaceId, manager, @@ -314,7 +231,11 @@ export class MessageService { ), ); - await this.deleteByIds(messageIdsToDelete, workspaceId, manager); + await this.messageRepository.deleteByIds( + messageIdsToDelete, + workspaceId, + manager, + ); const messageThreadIdsFromMessageChannelMessageAssociationsToDelete = messageChannelMessageAssociationsToDelete.map( @@ -322,11 +243,12 @@ export class MessageService { messageChannelMessageAssociationToDelete.messageThreadId, ); - const messagesByThreadIds = await this.getByMessageThreadIds( - messageThreadIdsFromMessageChannelMessageAssociationsToDelete, - workspaceId, - manager, - ); + const messagesByThreadIds = + await this.messageRepository.getByMessageThreadIds( + messageThreadIdsFromMessageChannelMessageAssociationsToDelete, + workspaceId, + manager, + ); const threadIdsToDelete = messageThreadIdsFromMessageChannelMessageAssociationsToDelete.filter( @@ -336,7 +258,7 @@ export class MessageService { ), ); - await this.messageThreadService.deleteByIds( + await this.messageThreadRepository.deleteByIds( threadIdsToDelete, workspaceId, manager, diff --git a/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts new file mode 100644 index 000000000000..6f727a3f4fec --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts @@ -0,0 +1,26 @@ +import { Module } from '@nestjs/common'; + +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { CreateCompaniesAndContactsModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.module'; +import { MessageParticipantModule } from 'src/modules/messaging/services/message-participant/message-participant.module'; +import { MessageModule } from 'src/modules/messaging/services/message/message.module'; +import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; + +@Module({ + imports: [ + MessageModule, + ObjectMetadataRepositoryModule.forFeature([ + MessageChannelObjectMetadata, + MessageParticipantObjectMetadata, + ]), + CreateCompaniesAndContactsModule, + MessageParticipantModule, + WorkspaceDataSourceModule, + ], + providers: [SaveMessagesAndCreateContactsService], + exports: [SaveMessagesAndCreateContactsService], +}) +export class SaveMessagesAndCreateContactsModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts similarity index 81% rename from packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts rename to packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts index 87669c8cfe9b..cd18e83aaee1 100644 --- a/packages/twenty-server/src/modules/messaging/services/save-messages-and-create-contacts.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts @@ -2,9 +2,8 @@ import { Injectable, Logger } from '@nestjs/common'; import { EntityManager } from 'typeorm'; -import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; -import { MessageParticipantService } from 'src/modules/messaging/repositories/message-participant/message-participant.service'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; +import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/create-company-and-contact/create-company-and-contact.service'; import { GmailMessage, @@ -13,6 +12,11 @@ import { import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageService } from 'src/modules/messaging/services/message/message.service'; +import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; @Injectable() export class SaveMessagesAndCreateContactsService { @@ -22,7 +26,10 @@ export class SaveMessagesAndCreateContactsService { constructor( private readonly messageService: MessageService, - private readonly messageChannelService: MessageChannelService, + @InjectObjectMetadataRepository(MessageChannelObjectMetadata) + private readonly messageChannelRepository: MessageChannelRepository, + @InjectObjectMetadataRepository(MessageParticipantObjectMetadata) + private readonly messageParticipantRepository: MessageParticipantRepository, private readonly createCompaniesAndContactsService: CreateCompanyAndContactService, private readonly messageParticipantService: MessageParticipantService, private readonly workspaceDataSourceService: WorkspaceDataSourceService, @@ -60,7 +67,7 @@ export class SaveMessagesAndCreateContactsService { ); const gmailMessageChannel = - await this.messageChannelService.getFirstByConnectedAccountId( + await this.messageChannelRepository.getFirstByConnectedAccountId( connectedAccount.id, workspaceId, ); @@ -111,7 +118,7 @@ export class SaveMessagesAndCreateContactsService { ); const messageParticipantsWithoutPersonIdAndWorkspaceMemberId = - await this.messageParticipantService.getByHandlesWithoutPersonIdAndWorkspaceMemberId( + await this.messageParticipantRepository.getByHandlesWithoutPersonIdAndWorkspaceMemberId( handles, workspaceId, ); @@ -157,7 +164,7 @@ export class SaveMessagesAndCreateContactsService { jobName?: string, ) { try { - await this.messageParticipantService.saveMessageParticipants( + await this.messageParticipantRepository.saveMessageParticipants( participantsWithMessageId, workspaceId, ); diff --git a/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts index 722c3b0092bd..33b43ab4360e 100644 --- a/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.module.ts @@ -1,17 +1,16 @@ import { Module } from '@nestjs/common'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { MessageThreadModule } from 'src/modules/messaging/repositories/message-thread/message-thread.module'; -import { MessageModule } from 'src/modules/messaging/repositories/message/message.module'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { ThreadCleanerService } from 'src/modules/messaging/services/thread-cleaner/thread-cleaner.service'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; @Module({ imports: [ - DataSourceModule, - TypeORMModule, - MessageThreadModule, - MessageModule, + ObjectMetadataRepositoryModule.forFeature([ + MessageObjectMetadata, + MessageThreadObjectMetadata, + ]), ], providers: [ThreadCleanerService], exports: [ThreadCleanerService], diff --git a/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts index 3374882b634c..f370674dc762 100644 --- a/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/thread-cleaner/thread-cleaner.service.ts @@ -1,37 +1,40 @@ import { Injectable } from '@nestjs/common'; -import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { MessageThreadService } from 'src/modules/messaging/repositories/message-thread/message-thread.service'; -import { MessageService } from 'src/modules/messaging/repositories/message/message.service'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; +import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; import { deleteUsingPagination } from 'src/modules/messaging/services/thread-cleaner/utils/delete-using-pagination.util'; +import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; @Injectable() export class ThreadCleanerService { constructor( - private readonly dataSourceService: DataSourceService, - private readonly typeORMService: TypeORMService, - private readonly messageService: MessageService, - private readonly messageThreadService: MessageThreadService, + @InjectObjectMetadataRepository(MessageObjectMetadata) + private readonly messageRepository: MessageRepository, + @InjectObjectMetadataRepository(MessageThreadObjectMetadata) + private readonly messageThreadRepository: MessageThreadRepository, ) {} public async cleanWorkspaceThreads(workspaceId: string) { await deleteUsingPagination( workspaceId, 500, - this.messageService.getNonAssociatedMessageIdsPaginated.bind( - this.messageService, + this.messageRepository.getNonAssociatedMessageIdsPaginated.bind( + this.messageRepository, ), - this.messageService.deleteByIds.bind(this.messageService), + this.messageRepository.deleteByIds.bind(this.messageRepository), ); await deleteUsingPagination( workspaceId, 500, - this.messageThreadService.getOrphanThreadIdsPaginated.bind( - this.messageThreadService, + this.messageThreadRepository.getOrphanThreadIdsPaginated.bind( + this.messageThreadRepository, + ), + this.messageThreadRepository.deleteByIds.bind( + this.messageThreadRepository, ), - this.messageThreadService.deleteByIds.bind(this.messageThreadService), ); } } diff --git a/packages/twenty-server/src/modules/person/repositories/person/person.service.ts b/packages/twenty-server/src/modules/person/repositories/person.repository.ts similarity index 96% rename from packages/twenty-server/src/modules/person/repositories/person/person.service.ts rename to packages/twenty-server/src/modules/person/repositories/person.repository.ts index 502b12f654b9..656c524fac07 100644 --- a/packages/twenty-server/src/modules/person/repositories/person/person.service.ts +++ b/packages/twenty-server/src/modules/person/repositories/person.repository.ts @@ -6,9 +6,8 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; -// TODO: Move outside of the messaging module @Injectable() -export class PersonService { +export class PersonRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/person/repositories/person/person.module.ts b/packages/twenty-server/src/modules/person/repositories/person/person.module.ts deleted file mode 100644 index adf359cf792c..000000000000 --- a/packages/twenty-server/src/modules/person/repositories/person/person.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { PersonService } from 'src/modules/person/repositories/person/person.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [PersonService], - exports: [PersonService], -}) -export class PersonModule {} diff --git a/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member.repository.ts similarity index 96% rename from packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts rename to packages/twenty-server/src/modules/workspace-member/repositories/workspace-member.repository.ts index c5d097285925..f2605eb874b9 100644 --- a/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.service.ts +++ b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member.repository.ts @@ -6,9 +6,8 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -// TODO: Move outside of the messaging module @Injectable() -export class WorkspaceMemberService { +export class WorkspaceMemberRepository { constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} diff --git a/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts b/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts deleted file mode 100644 index 54465e4132f5..000000000000 --- a/packages/twenty-server/src/modules/workspace-member/repositories/workspace-member/workspace-member.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; - -@Module({ - imports: [WorkspaceDataSourceModule], - providers: [WorkspaceMemberService], - exports: [WorkspaceMemberService], -}) -export class WorkspaceMemberModule {} From 1cc8bdd3e90b07b4434096e081d1447937ecce85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20HOUZET?= Date: Mon, 18 Mar 2024 16:30:26 +0100 Subject: [PATCH 18/44] Update docker-compose.mdx (#4545) The name of docker instance now use - and not _ for the name. --- packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx index 754cb99dc7a6..928f74cafecc 100644 --- a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx @@ -24,7 +24,7 @@ REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh ### Not able to login -If you encounter errors, (not able to log into the application after inputting an email) after the inital setup, try running `docker exec -it twenty_backend_1 yarn database:reset` and see if that solves your issue. +If you encounter errors, (not able to log into the application after inputting an email) after the inital setup, try running `docker exec -it twenty-backend-1 yarn database:reset` and see if that solves your issue. ### Cannot connect to server, running behind a reverse proxy From bdbd77c696e7947d7b33273d6eebbfc5c7669ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Mon, 18 Mar 2024 17:09:39 +0100 Subject: [PATCH 19/44] Cleanup default values and leftover methods in environmentService (#4550) * Cleanup default values and leftover methods in environmentService * Adress remainings configService calls --- packages/twenty-server/scripts/utils.ts | 8 +- packages/twenty-server/src/command/command.ts | 7 +- .../database/typeorm/core/core.datasource.ts | 2 +- .../typeorm/metadata/metadata.datasource.ts | 2 +- .../src/engine/api/rest/api-rest.service.ts | 6 +- .../engine/api/rest/metadata-rest.service.ts | 6 +- .../environment/environment-variables.ts | 88 ++++++++++--------- .../environment/environment.default.ts | 77 ---------------- .../environment/environment.service.ts | 39 +------- .../modules/auth/services/token.service.ts | 4 +- .../client-config/client-config.entity.ts | 10 +-- .../modules/open-api/open-api.service.ts | 11 ++- packages/twenty-server/src/main.ts | 5 +- .../src/queue-worker/queue-worker.ts | 6 +- .../twenty-server/src/utils/get-server-url.ts | 11 +++ 15 files changed, 110 insertions(+), 172 deletions(-) delete mode 100644 packages/twenty-server/src/engine/integrations/environment/environment.default.ts create mode 100644 packages/twenty-server/src/utils/get-server-url.ts diff --git a/packages/twenty-server/scripts/utils.ts b/packages/twenty-server/scripts/utils.ts index f944c423102a..3b2bea525912 100644 --- a/packages/twenty-server/scripts/utils.ts +++ b/packages/twenty-server/scripts/utils.ts @@ -2,16 +2,16 @@ import { ConfigService } from '@nestjs/config'; import console from 'console'; -import { config } from 'dotenv'; import { DataSource } from 'typeorm'; -config(); -const configService = new ConfigService(); +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; + +const environmentService = new EnvironmentService(new ConfigService()); export const connectionSource = new DataSource({ type: 'postgres', logging: false, - url: configService.get('PG_DATABASE_URL'), + url: environmentService.get('PG_DATABASE_URL'), }); export const camelToSnakeCase = (str) => diff --git a/packages/twenty-server/src/command/command.ts b/packages/twenty-server/src/command/command.ts index bf1774bbe3e1..b73377d6bd54 100644 --- a/packages/twenty-server/src/command/command.ts +++ b/packages/twenty-server/src/command/command.ts @@ -1,8 +1,11 @@ +import { ConfigService } from '@nestjs/config'; + import { CommandFactory } from 'nest-commander'; import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { LoggerService } from 'src/engine/integrations/logger/logger.service'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { CommandModule } from './command.module'; @@ -17,8 +20,10 @@ async function bootstrap() { exceptionHandlerService.captureExceptions([err]); }; + const environmentService = new EnvironmentService(new ConfigService()); + const app = await CommandFactory.createWithoutRunning(CommandModule, { - bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', + bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), errorHandler, serviceErrorHandler: errorHandler, }); diff --git a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts index c3187df96cf7..0d2bbbcddb32 100644 --- a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts +++ b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts @@ -7,7 +7,7 @@ config(); const configService = new ConfigService(); export const typeORMCoreModuleOptions: TypeOrmModuleOptions = { - url: configService.get('PG_DATABASE_URL'), + url: configService.get('PG_DATABASE_URL'), type: 'postgres', logging: ['error'], schema: 'core', diff --git a/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts b/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts index 94a65ab877a2..408f047bea24 100644 --- a/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts +++ b/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts @@ -7,7 +7,7 @@ config(); const configService = new ConfigService(); export const typeORMMetadataModuleOptions: TypeOrmModuleOptions = { - url: configService.get('PG_DATABASE_URL'), + url: configService.get('PG_DATABASE_URL'), type: 'postgres', logging: ['error'], schema: 'metadata', diff --git a/packages/twenty-server/src/engine/api/rest/api-rest.service.ts b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts index f5306b55ec1b..7d89c20f521c 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts @@ -8,6 +8,7 @@ import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-b import { TokenService } from 'src/engine/modules/auth/services/token.service'; import { ApiRestResponse } from 'src/engine/api/rest/types/api-rest-response.type'; import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; +import { getServerUrl } from 'src/utils/get-server-url'; @Injectable() export class ApiRestService { @@ -22,7 +23,10 @@ export class ApiRestService { request: Request, data: ApiRestQuery, ): Promise { - const baseUrl = this.environmentService.getBaseUrl(request); + const baseUrl = getServerUrl( + request, + this.environmentService.get('SERVER_URL'), + ); try { return await this.httpService.axiosRef.post(`${baseUrl}/graphql`, data, { diff --git a/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts index 4b460236d5be..8a4b61be5f96 100644 --- a/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts @@ -7,6 +7,7 @@ import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; import { TokenService } from 'src/engine/modules/auth/services/token.service'; import { parseMetadataPath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; import { capitalize } from 'src/utils/capitalize'; +import { getServerUrl } from 'src/utils/get-server-url'; @Injectable() export class ApiRestMetadataService { @@ -18,7 +19,10 @@ export class ApiRestMetadataService { ) {} async callMetadata(request, data: ApiRestQuery) { - const baseUrl = this.environmentService.getBaseUrl(request); + const baseUrl = getServerUrl( + request, + this.environmentService.get('SERVER_URL'), + ); try { return await this.httpService.axiosRef.post(`${baseUrl}/metadata`, data, { diff --git a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts index 028e8a319bfb..9280550fc489 100644 --- a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts @@ -21,6 +21,7 @@ import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handle import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; import { IsStrictlyLowerThan } from 'src/engine/integrations/environment/decorators/is-strictly-lower-than.decorator'; +import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; import { IsDuration } from './decorators/is-duration.decorator'; import { AwsRegion } from './interfaces/aws-region.interface'; @@ -35,17 +36,17 @@ export class EnvironmentVariables { @CastToBoolean() @IsOptional() @IsBoolean() - DEBUG_MODE: boolean; + DEBUG_MODE: boolean = false; @CastToBoolean() @IsOptional() @IsBoolean() - SIGN_IN_PREFILLED: boolean; + SIGN_IN_PREFILLED: boolean = false; @CastToBoolean() @IsOptional() @IsBoolean() - IS_BILLING_ENABLED: boolean; + IS_BILLING_ENABLED: boolean = false; @IsString() @ValidateIf((env) => env.IS_BILLING_ENABLED === true) @@ -59,7 +60,7 @@ export class EnvironmentVariables { @CastToPositiveNumber() @IsOptional() @ValidateIf((env) => env.IS_BILLING_ENABLED === true) - BILLING_FREE_TRIAL_DURATION_IN_DAYS: number; + BILLING_FREE_TRIAL_DURATION_IN_DAYS: number = 7; @IsString() @ValidateIf((env) => env.IS_BILLING_ENABLED === true) @@ -72,17 +73,17 @@ export class EnvironmentVariables { @CastToBoolean() @IsOptional() @IsBoolean() - TELEMETRY_ENABLED: boolean; + TELEMETRY_ENABLED: boolean = true; @CastToBoolean() @IsOptional() @IsBoolean() - TELEMETRY_ANONYMIZATION_ENABLED: boolean; + TELEMETRY_ANONYMIZATION_ENABLED: boolean = true; @CastToPositiveNumber() @IsNumber() @IsOptional() - PORT: number; + PORT: number = 3000; // Database @IsDefined() @@ -108,25 +109,25 @@ export class EnvironmentVariables { @IsDuration() @IsOptional() - ACCESS_TOKEN_EXPIRES_IN: string; + ACCESS_TOKEN_EXPIRES_IN: string = '30m'; @IsString() REFRESH_TOKEN_SECRET: string; @IsDuration() @IsOptional() - REFRESH_TOKEN_EXPIRES_IN: string; + REFRESH_TOKEN_EXPIRES_IN: string = '30m'; @IsDuration() @IsOptional() - REFRESH_TOKEN_COOL_DOWN: string; + REFRESH_TOKEN_COOL_DOWN: string = '1m'; @IsString() - LOGIN_TOKEN_SECRET: string; + LOGIN_TOKEN_SECRET: string = '30m'; @IsDuration() @IsOptional() - LOGIN_TOKEN_EXPIRES_IN: string; + LOGIN_TOKEN_EXPIRES_IN: string = '15m'; // Auth @IsUrl({ require_tld: false }) @@ -136,7 +137,7 @@ export class EnvironmentVariables { @CastToBoolean() @IsOptional() @IsBoolean() - AUTH_GOOGLE_ENABLED: boolean; + AUTH_GOOGLE_ENABLED: boolean = false; @IsString() @ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true) @@ -153,7 +154,7 @@ export class EnvironmentVariables { // Storage @IsEnum(StorageDriverType) @IsOptional() - STORAGE_TYPE: StorageDriverType; + STORAGE_TYPE: StorageDriverType = StorageDriverType.Local; @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3) @IsAWSRegion() @@ -170,12 +171,12 @@ export class EnvironmentVariables { @IsString() @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local) - STORAGE_LOCAL_PATH: string; + STORAGE_LOCAL_PATH: string = '.local-storage'; // Support @IsEnum(SupportDriver) @IsOptional() - SUPPORT_DRIVER: SupportDriver; + SUPPORT_DRIVER: SupportDriver = SupportDriver.None; @ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front) @IsString() @@ -187,19 +188,20 @@ export class EnvironmentVariables { @IsEnum(LoggerDriverType) @IsOptional() - LOGGER_DRIVER: LoggerDriverType; + LOGGER_DRIVER: LoggerDriverType = LoggerDriverType.Console; @IsEnum(ExceptionHandlerDriver) @IsOptional() - EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver; + EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver = + ExceptionHandlerDriver.Console; @CastToLogLevelArray() @IsOptional() - LOG_LEVELS: LogLevel[]; + LOG_LEVELS: LogLevel[] = ['log', 'error', 'warn']; @CastToStringArray() @IsOptional() - DEMO_WORKSPACE_IDS: string[]; + DEMO_WORKSPACE_IDS: string[] = []; @ValidateIf( (env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry, @@ -209,7 +211,7 @@ export class EnvironmentVariables { @IsDuration() @IsOptional() - PASSWORD_RESET_TOKEN_EXPIRES_IN: string; + PASSWORD_RESET_TOKEN_EXPIRES_IN: string = '5m'; @CastToPositiveNumber() @IsNumber() @@ -219,48 +221,48 @@ export class EnvironmentVariables { '"WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION" should be strictly lower that "WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION"', }) @ValidateIf((env) => env.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION > 0) - WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION: number; + WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION: number = 30; @CastToPositiveNumber() @IsNumber() @ValidateIf((env) => env.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION > 0) - WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION: number; + WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION: number = 60; @CastToBoolean() @IsOptional() @IsBoolean() - IS_SIGN_UP_DISABLED: boolean; + IS_SIGN_UP_DISABLED: boolean = false; @CastToPositiveNumber() @IsOptional() @IsNumber() - MUTATION_MAXIMUM_RECORD_AFFECTED: number; + MUTATION_MAXIMUM_RECORD_AFFECTED: number = 100; - REDIS_HOST: string; + REDIS_HOST: string = '127.0.0.1'; - REDIS_PORT: number; + REDIS_PORT: number = 6379; - API_TOKEN_EXPIRES_IN: string; + API_TOKEN_EXPIRES_IN: string = '100y'; - SHORT_TERM_TOKEN_EXPIRES_IN: string; + SHORT_TERM_TOKEN_EXPIRES_IN: string = '5m'; - MESSAGING_PROVIDER_GMAIL_ENABLED: boolean; + MESSAGING_PROVIDER_GMAIL_ENABLED: boolean = false; MESSAGING_PROVIDER_GMAIL_CALLBACK_URL: string; - MESSAGE_QUEUE_TYPE: string; + MESSAGE_QUEUE_TYPE: string = MessageQueueDriverType.Sync; - EMAIL_FROM_ADDRESS: string; + EMAIL_FROM_ADDRESS: string = 'noreply@yourdomain.com'; - EMAIL_SYSTEM_ADDRESS: string; + EMAIL_SYSTEM_ADDRESS: string = 'system@yourdomain.com'; - EMAIL_FROM_NAME: string; + EMAIL_FROM_NAME: string = 'Felix from Twenty'; - EMAIL_DRIVER: EmailDriver; + EMAIL_DRIVER: EmailDriver = EmailDriver.Logger; EMAIL_SMTP_HOST: string; - EMAIL_SMTP_PORT: number; + EMAIL_SMTP_PORT: number = 587; EMAIL_SMTP_USER: string; @@ -268,15 +270,19 @@ export class EnvironmentVariables { OPENROUTER_API_KEY: string; - API_RATE_LIMITING_TTL: number; + API_RATE_LIMITING_TTL: number = 100; - API_RATE_LIMITING_LIMIT: number; + API_RATE_LIMITING_LIMIT: number = 500; - CACHE_STORAGE_TYPE: string; + CACHE_STORAGE_TYPE: string = 'memory'; + + CACHE_STORAGE_TTL: number = 3600 * 24 * 7; + + CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean = false; - CACHE_STORAGE_TTL: number; - CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean; AUTH_GOOGLE_APIS_CALLBACK_URL: string; + + LOGGER_IS_BUFFER_ENABLED: boolean = true; } export const validate = (config: Record) => { diff --git a/packages/twenty-server/src/engine/integrations/environment/environment.default.ts b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts deleted file mode 100644 index 9c724584d2b5..000000000000 --- a/packages/twenty-server/src/engine/integrations/environment/environment.default.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; -import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; - -import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; -import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; -import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; -import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; -import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; - -const EnvironmentDefault = new EnvironmentVariables(); - -EnvironmentDefault.DEBUG_MODE = false; -EnvironmentDefault.SIGN_IN_PREFILLED = false; -EnvironmentDefault.IS_BILLING_ENABLED = false; -EnvironmentDefault.BILLING_PLAN_REQUIRED_LINK = ''; -EnvironmentDefault.BILLING_STRIPE_BASE_PLAN_PRODUCT_ID = ''; -EnvironmentDefault.BILLING_FREE_TRIAL_DURATION_IN_DAYS = 7; -EnvironmentDefault.BILLING_STRIPE_API_KEY = ''; -EnvironmentDefault.BILLING_STRIPE_WEBHOOK_SECRET = ''; -EnvironmentDefault.TELEMETRY_ENABLED = true; -EnvironmentDefault.TELEMETRY_ANONYMIZATION_ENABLED = true; -EnvironmentDefault.PORT = 3000; -EnvironmentDefault.REDIS_HOST = '127.0.0.1'; -EnvironmentDefault.REDIS_PORT = 6379; -EnvironmentDefault.PG_DATABASE_URL = ''; -EnvironmentDefault.FRONT_BASE_URL = ''; -EnvironmentDefault.SERVER_URL = ''; -EnvironmentDefault.ACCESS_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.ACCESS_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.REFRESH_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.REFRESH_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.REFRESH_TOKEN_COOL_DOWN = '1m'; -EnvironmentDefault.LOGIN_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.LOGIN_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.API_TOKEN_EXPIRES_IN = '100y'; -EnvironmentDefault.SHORT_TERM_TOKEN_EXPIRES_IN = '5m'; -EnvironmentDefault.FRONT_AUTH_CALLBACK_URL = ''; -EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_ENABLED = false; -EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_CALLBACK_URL = ''; -EnvironmentDefault.AUTH_GOOGLE_ENABLED = false; -EnvironmentDefault.AUTH_GOOGLE_CLIENT_ID = ''; -EnvironmentDefault.AUTH_GOOGLE_CLIENT_SECRET = ''; -EnvironmentDefault.AUTH_GOOGLE_CALLBACK_URL = ''; -EnvironmentDefault.STORAGE_TYPE = StorageDriverType.Local; -EnvironmentDefault.STORAGE_S3_REGION = 'aws-east-1'; -EnvironmentDefault.STORAGE_S3_NAME = ''; -EnvironmentDefault.STORAGE_S3_ENDPOINT = ''; -EnvironmentDefault.STORAGE_LOCAL_PATH = '.local-storage'; -EnvironmentDefault.MESSAGE_QUEUE_TYPE = MessageQueueDriverType.Sync; -EnvironmentDefault.EMAIL_FROM_ADDRESS = 'noreply@yourdomain.com'; -EnvironmentDefault.EMAIL_SYSTEM_ADDRESS = 'system@yourdomain.com'; -EnvironmentDefault.EMAIL_FROM_NAME = 'John from Twenty'; -EnvironmentDefault.EMAIL_DRIVER = EmailDriver.Logger; -EnvironmentDefault.EMAIL_SMTP_HOST = ''; -EnvironmentDefault.EMAIL_SMTP_PORT = 587; -EnvironmentDefault.EMAIL_SMTP_USER = ''; -EnvironmentDefault.EMAIL_SMTP_PASSWORD = ''; -EnvironmentDefault.SUPPORT_DRIVER = SupportDriver.None; -EnvironmentDefault.SUPPORT_FRONT_CHAT_ID = ''; -EnvironmentDefault.SUPPORT_FRONT_HMAC_KEY = ''; -EnvironmentDefault.LOGGER_DRIVER = LoggerDriverType.Console; -EnvironmentDefault.EXCEPTION_HANDLER_DRIVER = ExceptionHandlerDriver.Console; -EnvironmentDefault.LOG_LEVELS = ['log', 'error', 'warn']; -EnvironmentDefault.SENTRY_DSN = ''; -EnvironmentDefault.DEMO_WORKSPACE_IDS = []; -EnvironmentDefault.OPENROUTER_API_KEY = ''; -EnvironmentDefault.PASSWORD_RESET_TOKEN_EXPIRES_IN = '5m'; -EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION = 30; -EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION = 60; -EnvironmentDefault.IS_SIGN_UP_DISABLED = false; -EnvironmentDefault.API_RATE_LIMITING_TTL = 100; -EnvironmentDefault.API_RATE_LIMITING_LIMIT = 500; -EnvironmentDefault.MUTATION_MAXIMUM_RECORD_AFFECTED = 100; -EnvironmentDefault.CACHE_STORAGE_TYPE = 'memory'; -EnvironmentDefault.CACHE_STORAGE_TTL = 3600 * 24 * 7; - -export { EnvironmentDefault }; diff --git a/packages/twenty-server/src/engine/integrations/environment/environment.service.ts b/packages/twenty-server/src/engine/integrations/environment/environment.service.ts index 275671a054af..8440249551fa 100644 --- a/packages/twenty-server/src/engine/integrations/environment/environment.service.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment.service.ts @@ -2,47 +2,16 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { Request } from 'express'; - import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; -import { EnvironmentDefault } from 'src/engine/integrations/environment/environment.default'; @Injectable() export class EnvironmentService { - constructor(private configService: ConfigService) {} + constructor(private readonly configService: ConfigService) {} get(key: T): EnvironmentVariables[T] { - return ( - this.configService.get(key) ?? - EnvironmentDefault[key] + return this.configService.get( + key, + new EnvironmentVariables()[key], ); } - - getServerUrl(): string { - const url = this.configService.get('SERVER_URL')!; - - if (url?.endsWith('/')) { - return url.substring(0, url.length - 1); - } - - return url; - } - - getBaseUrl(request: Request): string { - return ( - this.getServerUrl() || `${request.protocol}://${request.get('host')}` - ); - } - - getFrontAuthCallbackUrl(): string { - return ( - this.configService.get('FRONT_AUTH_CALLBACK_URL') ?? - this.get('FRONT_BASE_URL') + '/verify' - ); - } - - // TODO: check because it isn't called - getLoggerIsBufferEnabled(): boolean | undefined { - return this.configService.get('LOGGER_IS_BUFFER_ENABLED') ?? true; - } } diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts index 30a573be4bf5..72aa8fc83c68 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts @@ -361,7 +361,9 @@ export class TokenService { } computeRedirectURI(loginToken: string): string { - return `${this.environmentService.getFrontAuthCallbackUrl()}?loginToken=${loginToken}`; + return `${this.environmentService.get( + 'FRONT_BASE_URL', + )}/verify?loginToken=${loginToken}`; } async verifyJwt(token: string, secret?: string) { diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts b/packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts index 57a719acc941..184c7004720c 100644 --- a/packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts +++ b/packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts @@ -26,11 +26,11 @@ class Billing { @Field(() => Boolean) isBillingEnabled: boolean; - @Field(() => String) - billingUrl: string; + @Field(() => String, { nullable: true }) + billingUrl?: string; @Field(() => Number, { nullable: true }) - billingFreeTrialDurationInDays: number | undefined; + billingFreeTrialDurationInDays?: number; } @ObjectType() @@ -39,13 +39,13 @@ class Support { supportDriver: string; @Field(() => String, { nullable: true }) - supportFrontChatId: string | undefined; + supportFrontChatId?: string; } @ObjectType() class Sentry { @Field(() => String, { nullable: true }) - dsn: string | undefined; + dsn?: string; } @ObjectType() diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts b/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts index 40f5378e804e..bc0b9d38872f 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts +++ b/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts @@ -26,6 +26,7 @@ import { } from 'src/engine/modules/open-api/utils/responses.utils'; import { getRequestBody } from 'src/engine/modules/open-api/utils/request-body.utils'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { getServerUrl } from 'src/utils/get-server-url'; @Injectable() export class OpenApiService { @@ -36,7 +37,10 @@ export class OpenApiService { ) {} async generateCoreSchema(request: Request): Promise { - const baseUrl = this.environmentService.getBaseUrl(request); + const baseUrl = getServerUrl( + request, + this.environmentService.get('SERVER_URL'), + ); const schema = baseSchema('core', baseUrl); @@ -93,7 +97,10 @@ export class OpenApiService { async generateMetaDataSchema( request: Request, ): Promise { - const baseUrl = this.environmentService.getBaseUrl(request); + const baseUrl = getServerUrl( + request, + this.environmentService.get('SERVER_URL'), + ); const schema = baseSchema('metadata', baseUrl); diff --git a/packages/twenty-server/src/main.ts b/packages/twenty-server/src/main.ts index 80b0543e481c..5e7913012264 100644 --- a/packages/twenty-server/src/main.ts +++ b/packages/twenty-server/src/main.ts @@ -1,6 +1,7 @@ import { NestFactory } from '@nestjs/core'; import { ValidationPipe } from '@nestjs/common'; import { NestExpressApplication } from '@nestjs/platform-express'; +import { ConfigService } from '@nestjs/config'; import * as Sentry from '@sentry/node'; import { graphqlUploadExpress } from 'graphql-upload'; @@ -15,9 +16,11 @@ import { LoggerService } from './engine/integrations/logger/logger.service'; import { EnvironmentService } from './engine/integrations/environment/environment.service'; const bootstrap = async () => { + const environmentService = new EnvironmentService(new ConfigService()); + const app = await NestFactory.create(AppModule, { cors: true, - bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', + bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), rawBody: true, }); const logger = app.get(LoggerService); diff --git a/packages/twenty-server/src/queue-worker/queue-worker.ts b/packages/twenty-server/src/queue-worker/queue-worker.ts index 6218a488e786..eae85670f7eb 100644 --- a/packages/twenty-server/src/queue-worker/queue-worker.ts +++ b/packages/twenty-server/src/queue-worker/queue-worker.ts @@ -1,4 +1,5 @@ import { NestFactory } from '@nestjs/core'; +import { ConfigService } from '@nestjs/config'; import { MessageQueueJob, @@ -13,14 +14,17 @@ import { MessageQueue } from 'src/engine/integrations/message-queue/message-queu import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { getJobClassName } from 'src/engine/integrations/message-queue/utils/get-job-class-name.util'; import { QueueWorkerModule } from 'src/queue-worker/queue-worker.module'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; async function bootstrap() { let exceptionHandlerService: ExceptionHandlerService | undefined; let loggerService: LoggerService | undefined; try { + const environmentService = new EnvironmentService(new ConfigService()); + const app = await NestFactory.createApplicationContext(QueueWorkerModule, { - bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', + bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), }); loggerService = app.get(LoggerService); diff --git a/packages/twenty-server/src/utils/get-server-url.ts b/packages/twenty-server/src/utils/get-server-url.ts new file mode 100644 index 000000000000..2ab7be3be2f3 --- /dev/null +++ b/packages/twenty-server/src/utils/get-server-url.ts @@ -0,0 +1,11 @@ +import { Request } from 'express'; + +export const getServerUrl = ( + request: Request, + serverUrlEnv: string, +): string => { + if (serverUrlEnv?.endsWith('/')) + return serverUrlEnv.substring(0, serverUrlEnv.length - 1); + + return serverUrlEnv || `${request.protocol}://${request.get('host')}`; +}; From 872fb2bd49623d558c3828809350227393913463 Mon Sep 17 00:00:00 2001 From: "gitstart-app[bot]" <57568882+gitstart-app[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:10:07 +0100 Subject: [PATCH 20/44] TWNTY-4450 - Add tests for `/modules/activities/emails` (#4520) * Add tests for `/modules/activities/emails` Co-authored-by: v1b3m Co-authored-by: Thiago Nascimbeni * Fix tests Co-authored-by: v1b3m Co-authored-by: Thiago Nascimbeni * Remove temporary changes Co-authored-by: v1b3m Co-authored-by: Thiago Nascimbeni --------- Co-authored-by: gitstart-twenty Co-authored-by: v1b3m Co-authored-by: Thiago Nascimbeni --- .../__tests__/useCalendarEvents.test.tsx | 53 ++++++++++ .../useOpenCalendarEventRightDrawer.test.tsx | 35 ++++++ .../emails/components/EmailThreadPreview.tsx | 2 +- .../hooks/__tests__/useEmailThread.test.tsx | 69 ++++++++++++ .../hooks/internal/useEmailThreadStates.ts | 2 +- .../activities/emails/hooks/useEmailThread.ts | 2 +- .../getTimelineThreadsFromCompanyId.test.ts | 16 +++ .../getTimelineThreadsFromPersonId.test.ts | 16 +++ .../components/RightDrawerEmailThread.tsx | 2 +- .../useRightDrawerEmailThread.test.tsx | 40 +++++++ .../hooks/useRightDrawerEmailThread.ts | 2 +- .../emailThreadsPageComponentState.ts | 0 .../lastViewableEmailThreadIdState.ts | 0 .../viewableEmailThreadIdState.ts | 0 .../getDisplayNameFromParticipant.test.ts | 100 ++++++++++++++++++ 15 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 packages/twenty-front/src/modules/activities/calendar/hooks/__tests__/useCalendarEvents.test.tsx create mode 100644 packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx create mode 100644 packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx create mode 100644 packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromCompanyId.test.ts create mode 100644 packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromPersonId.test.ts create mode 100644 packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/__tests__/useRightDrawerEmailThread.test.tsx rename packages/twenty-front/src/modules/activities/emails/{state => states}/emailThreadsPageComponentState.ts (100%) rename packages/twenty-front/src/modules/activities/emails/{state => states}/lastViewableEmailThreadIdState.ts (100%) rename packages/twenty-front/src/modules/activities/emails/{state => states}/viewableEmailThreadIdState.ts (100%) create mode 100644 packages/twenty-front/src/modules/activities/emails/utils/__tests__/getDisplayNameFromParticipant.test.ts diff --git a/packages/twenty-front/src/modules/activities/calendar/hooks/__tests__/useCalendarEvents.test.tsx b/packages/twenty-front/src/modules/activities/calendar/hooks/__tests__/useCalendarEvents.test.tsx new file mode 100644 index 000000000000..498cc5ff75af --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/hooks/__tests__/useCalendarEvents.test.tsx @@ -0,0 +1,53 @@ +import { act, renderHook } from '@testing-library/react'; + +import { useCalendarEvents } from '@/activities/calendar/hooks/useCalendarEvents'; +import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; + +const calendarEvents: CalendarEvent[] = [ + { + id: '1234', + externalCreatedAt: '2024-02-17T20:45:43.854Z', + isFullDay: false, + startsAt: '2024-02-17T21:45:27.822Z', + visibility: 'METADATA', + }, + { + id: '5678', + externalCreatedAt: '2024-02-18T19:43:37.854Z', + isFullDay: false, + startsAt: '2024-02-18T21:43:27.754Z', + visibility: 'SHARE_EVERYTHING', + }, + { + id: '91011', + externalCreatedAt: '2024-02-19T20:45:20.854Z', + isFullDay: true, + startsAt: '2024-02-19T22:05:27.653Z', + visibility: 'METADATA', + }, + { + id: '121314', + externalCreatedAt: '2024-02-20T20:45:12.854Z', + isFullDay: true, + startsAt: '2024-02-20T23:15:23.150Z', + visibility: 'SHARE_EVERYTHING', + }, +]; + +describe('useCalendar', () => { + it('returns calendar events', () => { + const { result } = renderHook(() => useCalendarEvents(calendarEvents)); + + expect(result.current.currentCalendarEvent).toBe(calendarEvents[0]); + + expect(result.current.getNextCalendarEvent(calendarEvents[1])).toBe( + calendarEvents[0], + ); + + act(() => { + result.current.updateCurrentCalendarEvent(); + }); + + expect(result.current.currentCalendarEvent).toBe(calendarEvents[0]); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx new file mode 100644 index 000000000000..04544ed53bc3 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx @@ -0,0 +1,35 @@ +import { act, renderHook } from '@testing-library/react'; +import { RecoilRoot, useRecoilValue } from 'recoil'; + +import { useOpenCalendarEventRightDrawer } from '@/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer'; +import { viewableCalendarEventIdState } from '@/activities/calendar/states/viewableCalendarEventIdState'; +import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState'; + +describe('useOpenCalendarEventRightDrawer', () => { + it('opens the right drawer with the calendar event', () => { + const { result } = renderHook( + () => { + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState()); + const viewableCalendarEventId = useRecoilValue( + viewableCalendarEventIdState(), + ); + return { + ...useOpenCalendarEventRightDrawer(), + isRightDrawerOpen, + viewableCalendarEventId, + }; + }, + { wrapper: RecoilRoot }, + ); + + expect(result.current.isRightDrawerOpen).toBe(false); + expect(result.current.viewableCalendarEventId).toBeNull(); + + act(() => { + result.current.openCalendarEventRightDrawer('1234'); + }); + + expect(result.current.isRightDrawerOpen).toBe(true); + expect(result.current.viewableCalendarEventId).toBe('1234'); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx index 98f5cf004a3d..8c7b10aae2ab 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx @@ -4,7 +4,7 @@ import { useRecoilCallback } from 'recoil'; import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared'; import { useEmailThread } from '@/activities/emails/hooks/useEmailThread'; -import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/state/lastViewableEmailThreadIdState'; +import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/states/lastViewableEmailThreadIdState'; import { CardContent } from '@/ui/layout/card/components/CardContent'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale'; diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx new file mode 100644 index 000000000000..c2a1fdf3a2eb --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx @@ -0,0 +1,69 @@ +import { act, renderHook } from '@testing-library/react'; +import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil'; + +import { useEmailThread } from '@/activities/emails/hooks/useEmailThread'; +import { viewableEmailThreadIdState } from '@/activities/emails/states/viewableEmailThreadIdState'; +import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState'; + +const viewableEmailThreadId = '1234'; + +describe('useEmailThread', () => { + it('should open email thread', () => { + const { result } = renderHook( + () => { + const emailThread = useEmailThread(); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState()); + const viewableEmailThreadId = useRecoilValue( + viewableEmailThreadIdState(), + ); + + return { ...emailThread, isRightDrawerOpen, viewableEmailThreadId }; + }, + { wrapper: RecoilRoot }, + ); + + expect(result.current.isRightDrawerOpen).toBe(false); + expect(result.current.viewableEmailThreadId).toBeNull(); + + act(() => { + result.current.openEmailThread(viewableEmailThreadId); + }); + + expect(result.current.isRightDrawerOpen).toBe(true); + expect(result.current.viewableEmailThreadId).toBe(viewableEmailThreadId); + }); + + it('should close email thread', () => { + const { result } = renderHook( + () => { + const emailThread = useEmailThread(); + const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState( + isRightDrawerOpenState(), + ); + const [viewableEmailThreadId, setViewableEmailThreadId] = + useRecoilState(viewableEmailThreadIdState()); + + return { + ...emailThread, + isRightDrawerOpen, + viewableEmailThreadId, + setIsRightDrawerOpen, + setViewableEmailThreadId, + }; + }, + { wrapper: RecoilRoot }, + ); + + act(() => { + result.current.setIsRightDrawerOpen(true); + result.current.setViewableEmailThreadId(viewableEmailThreadId); + }); + + act(() => { + result.current.openEmailThread(viewableEmailThreadId); + }); + + expect(result.current.isRightDrawerOpen).toBe(false); + expect(result.current.viewableEmailThreadId).toBeNull(); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts b/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts index 946a43e0f835..0162ee6d4feb 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts +++ b/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts @@ -1,4 +1,4 @@ -import { emailThreadsPageComponentState } from '@/activities/emails/state/emailThreadsPageComponentState'; +import { emailThreadsPageComponentState } from '@/activities/emails/states/emailThreadsPageComponentState'; import { TabListScopeInternalContext } from '@/ui/layout/tab/scopes/scope-internal-context/TabListScopeInternalContext'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts b/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts index a5fca6861b1d..5ca934b73852 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts +++ b/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts @@ -1,7 +1,7 @@ import { useRecoilCallback } from 'recoil'; import { useOpenEmailThreadRightDrawer } from '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer'; -import { viewableEmailThreadIdState } from '@/activities/emails/state/viewableEmailThreadIdState'; +import { viewableEmailThreadIdState } from '@/activities/emails/states/viewableEmailThreadIdState'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState'; diff --git a/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromCompanyId.test.ts b/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromCompanyId.test.ts new file mode 100644 index 000000000000..9b3c3ba70fde --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromCompanyId.test.ts @@ -0,0 +1,16 @@ +import { gql } from '@apollo/client'; + +import { getTimelineThreadsFromCompanyId } from '../getTimelineThreadsFromCompanyId'; + +jest.mock('@apollo/client', () => ({ + gql: jest.fn().mockImplementation((strings) => { + return strings.map((str: string) => str.trim()).join(' '); + }), +})); + +describe('getTimelineThreadsFromCompanyId query', () => { + test('should construct the query correctly', () => { + expect(gql).toHaveBeenCalled(); + expect(getTimelineThreadsFromCompanyId).toBeDefined(); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromPersonId.test.ts b/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromPersonId.test.ts new file mode 100644 index 000000000000..66862b7288ee --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/queries/__tests__/getTimelineThreadsFromPersonId.test.ts @@ -0,0 +1,16 @@ +import { gql } from '@apollo/client'; + +import { getTimelineThreadsFromPersonId } from '../getTimelineThreadsFromPersonId'; + +jest.mock('@apollo/client', () => ({ + gql: jest.fn().mockImplementation((strings) => { + return strings.map((str: string) => str.trim()).join(' '); + }), +})); + +describe('getTimelineThreadsFromPersonId query', () => { + test('should construct the query correctly', () => { + expect(gql).toHaveBeenCalled(); + expect(getTimelineThreadsFromPersonId).toBeDefined(); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx index c901644f6444..fc71fdfe3a0c 100644 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx @@ -6,7 +6,7 @@ import { EmailThreadFetchMoreLoader } from '@/activities/emails/components/Email import { EmailThreadHeader } from '@/activities/emails/components/EmailThreadHeader'; import { EmailThreadMessage } from '@/activities/emails/components/EmailThreadMessage'; import { useRightDrawerEmailThread } from '@/activities/emails/right-drawer/hooks/useRightDrawerEmailThread'; -import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/state/lastViewableEmailThreadIdState'; +import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/states/lastViewableEmailThreadIdState'; import { RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID } from '@/ui/layout/right-drawer/constants/RightDrawerClickOutsideListener'; import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/__tests__/useRightDrawerEmailThread.test.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/__tests__/useRightDrawerEmailThread.test.tsx new file mode 100644 index 000000000000..63f1b09b06de --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/__tests__/useRightDrawerEmailThread.test.tsx @@ -0,0 +1,40 @@ +import { MockedProvider } from '@apollo/client/testing'; +import { renderHook } from '@testing-library/react'; +import { RecoilRoot } from 'recoil'; + +import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; + +import { useRightDrawerEmailThread } from '../useRightDrawerEmailThread'; + +jest.mock('@/object-record/hooks/useFindManyRecords', () => ({ + __esModule: true, + useFindManyRecords: jest.fn(), +})); + +describe('useRightDrawerEmailThread', () => { + it('should return correct values', async () => { + const mockMessages = [ + { id: '1', text: 'Message 1' }, + { id: '2', text: 'Message 2' }, + ]; + const mockFetchMoreRecords = jest.fn(); + (useFindManyRecords as jest.Mock).mockReturnValue({ + records: mockMessages, + loading: false, + fetchMoreRecords: mockFetchMoreRecords, + }); + + const { result } = renderHook(() => useRightDrawerEmailThread(), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + expect(result.current.thread).toBeDefined(); + expect(result.current.messages).toEqual(mockMessages); + expect(result.current.loading).toBeFalsy(); + expect(result.current.fetchMoreMessages).toBeInstanceOf(Function); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts index 7415ba501f82..dac62986ff75 100644 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts @@ -3,7 +3,7 @@ import { useApolloClient } from '@apollo/client'; import gql from 'graphql-tag'; import { useRecoilValue } from 'recoil'; -import { viewableEmailThreadIdState } from '@/activities/emails/state/viewableEmailThreadIdState'; +import { viewableEmailThreadIdState } from '@/activities/emails/states/viewableEmailThreadIdState'; import { EmailThreadMessage as EmailThreadMessageType } from '@/activities/emails/types/EmailThreadMessage'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; diff --git a/packages/twenty-front/src/modules/activities/emails/state/emailThreadsPageComponentState.ts b/packages/twenty-front/src/modules/activities/emails/states/emailThreadsPageComponentState.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/emails/state/emailThreadsPageComponentState.ts rename to packages/twenty-front/src/modules/activities/emails/states/emailThreadsPageComponentState.ts diff --git a/packages/twenty-front/src/modules/activities/emails/state/lastViewableEmailThreadIdState.ts b/packages/twenty-front/src/modules/activities/emails/states/lastViewableEmailThreadIdState.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/emails/state/lastViewableEmailThreadIdState.ts rename to packages/twenty-front/src/modules/activities/emails/states/lastViewableEmailThreadIdState.ts diff --git a/packages/twenty-front/src/modules/activities/emails/state/viewableEmailThreadIdState.ts b/packages/twenty-front/src/modules/activities/emails/states/viewableEmailThreadIdState.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/emails/state/viewableEmailThreadIdState.ts rename to packages/twenty-front/src/modules/activities/emails/states/viewableEmailThreadIdState.ts diff --git a/packages/twenty-front/src/modules/activities/emails/utils/__tests__/getDisplayNameFromParticipant.test.ts b/packages/twenty-front/src/modules/activities/emails/utils/__tests__/getDisplayNameFromParticipant.test.ts new file mode 100644 index 000000000000..e7647d869483 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/emails/utils/__tests__/getDisplayNameFromParticipant.test.ts @@ -0,0 +1,100 @@ +import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; + +import { getDisplayNameFromParticipant } from '../getDisplayNameFromParticipant'; + +describe('getDisplayNameFromParticipant', () => { + const participantWithName: EmailThreadMessageParticipant = { + displayName: '', + handle: '', + role: 'from', + person: { + id: '1', + createdAt: '', + updatedAt: '', + deletedAt: null, + name: { + firstName: 'John', + lastName: 'Doe', + }, + avatarUrl: '', + jobTitle: '', + linkedinLink: { + url: '', + label: '', + }, + xLink: { + url: '', + label: '', + }, + city: '', + email: '', + phone: '', + companyId: '', + }, + workspaceMember: { + id: '1', + name: { + firstName: 'Jane', + lastName: 'Smith', + }, + locale: '', + createdAt: '', + updatedAt: '', + userEmail: '', + userId: '', + }, + }; + + const participantWithHandle: any = { + displayName: '', + handle: 'user_handle', + role: 'from', + }; + + const participantWithDisplayName: any = { + displayName: 'User123', + handle: '', + role: 'from', + }; + + const participantWithoutInfo: any = { + displayName: '', + handle: '', + role: 'from', + }; + + it('should return full name when shouldUseFullName is true', () => { + expect( + getDisplayNameFromParticipant({ + participant: participantWithName, + shouldUseFullName: true, + }), + ).toBe('John Doe'); + }); + + it('should return first name when shouldUseFullName is false', () => { + expect( + getDisplayNameFromParticipant({ participant: participantWithName }), + ).toBe('John'); + }); + + it('should return displayName if it is a non-empty string', () => { + expect( + getDisplayNameFromParticipant({ + participant: participantWithDisplayName, + }), + ).toBe('User123'); + }); + + it('should return handle if displayName is not available', () => { + expect( + getDisplayNameFromParticipant({ participant: participantWithHandle }), + ).toBe('user_handle'); + }); + + it('should return Unknown if no suitable information is available', () => { + expect( + getDisplayNameFromParticipant({ participant: participantWithoutInfo }), + ).toBe('Unknown'); + }); +}); From 9f6c578a46d768af4cd1fbdae5c7dda7036da7ec Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Mon, 18 Mar 2024 17:13:32 +0100 Subject: [PATCH 21/44] Added context (#4557) --- .../activities/emails/hooks/__tests__/useEmailThread.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx index c2a1fdf3a2eb..f68a8872085f 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx +++ b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx @@ -33,7 +33,7 @@ describe('useEmailThread', () => { expect(result.current.viewableEmailThreadId).toBe(viewableEmailThreadId); }); - it('should close email thread', () => { + it('should close email thread if trying to open the same thread id', () => { const { result } = renderHook( () => { const emailThread = useEmailThread(); From e579554d47965ffa28a92a759aa325dcd2b6bfba Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Tue, 19 Mar 2024 16:39:53 +0100 Subject: [PATCH 22/44] Add getters factory for attachements (#4567) * Add getter factory for attachements * Override guard in test * Add secret in env variables * Return custom message on expiration * Rename to signPayload --------- Co-authored-by: Thomas Trompette --- .../workspace-query-runner/factories/index.ts | 2 + .../factories/query-result-getters.factory.ts | 75 ++++++++++++++++++ .../workspace-query-runner.module.ts | 2 + .../workspace-query-runner.service.ts | 67 ++++++++++------ .../environment/environment-variables.ts | 7 ++ .../environment/environment.default.ts | 79 +++++++++++++++++++ .../src/engine/modules/auth/auth.module.ts | 4 +- .../auth/services/sign-up.service.spec.ts | 2 +- .../modules/auth/services/sign-up.service.ts | 2 +- .../auth/services/token.service.spec.ts | 5 -- .../modules/auth/services/token.service.ts | 10 ++- .../file/controllers/file.controller.spec.ts | 8 +- .../file/controllers/file.controller.ts | 4 +- .../file/file-upload/file-upload.module.ts | 11 +++ .../resolvers/file-upload.resolver.spec.ts | 2 +- .../resolvers/file-upload.resolver.ts | 2 +- .../services/file-upload.service.spec.ts | 0 .../services/file-upload.service.ts | 0 .../src/engine/modules/file/file.module.ts | 15 ++-- .../modules/file/guards/file-path-guard.ts | 52 ++++++++++++ .../src/engine/modules/user/user.module.ts | 4 +- .../src/engine/modules/user/user.resolver.ts | 2 +- .../modules/workspace/workspace.module.ts | 4 +- .../modules/workspace/workspace.resolver.ts | 2 +- 24 files changed, 306 insertions(+), 55 deletions(-) create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts create mode 100644 packages/twenty-server/src/engine/integrations/environment/environment.default.ts create mode 100644 packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts rename packages/twenty-server/src/engine/modules/file/{ => file-upload}/resolvers/file-upload.resolver.spec.ts (85%) rename packages/twenty-server/src/engine/modules/file/{ => file-upload}/resolvers/file-upload.resolver.ts (94%) rename packages/twenty-server/src/engine/modules/file/{ => file-upload}/services/file-upload.service.spec.ts (100%) rename packages/twenty-server/src/engine/modules/file/{ => file-upload}/services/file-upload.service.ts (100%) create mode 100644 packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts index c24cd552189d..d1e72fb1621c 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/index.ts @@ -1,7 +1,9 @@ +import { QueryResultGettersFactory } from './query-result-getters.factory'; import { RecordPositionFactory } from './record-position.factory'; import { QueryRunnerArgsFactory } from './query-runner-args.factory'; export const workspaceQueryRunnerFactories = [ QueryRunnerArgsFactory, RecordPositionFactory, + QueryResultGettersFactory, ]; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts new file mode 100644 index 000000000000..6ea3a300ea92 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@nestjs/common'; + +import { addMilliseconds } from 'date-fns'; +import ms from 'ms'; + +import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; + +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { TokenService } from 'src/engine/modules/auth/services/token.service'; + +@Injectable() +export class QueryResultGettersFactory { + constructor( + private readonly tokenService: TokenService, + private readonly environmentService: EnvironmentService, + ) {} + + async create( + result: Result, + objectMetadataItem: ObjectMetadataInterface, + ): Promise { + // TODO: look for file type once implemented + switch (objectMetadataItem.nameSingular) { + case 'attachment': + return this.applyAttachmentGetters(result); + default: + return result; + } + } + + private async applyAttachmentGetters( + attachments: any, + ): Promise { + if (!attachments || !attachments.edges) { + return attachments; + } + + const fileTokenExpiresIn = this.environmentService.get( + 'FILE_TOKEN_EXPIRES_IN', + ); + const secret = this.environmentService.get('FILE_TOKEN_SECRET'); + + const mappedEdges = await Promise.all( + attachments.edges.map(async (attachment: any) => { + if (!attachment.node.id || !attachment?.node?.fullPath) { + return attachment; + } + + const expirationDate = addMilliseconds( + new Date(), + ms(fileTokenExpiresIn), + ); + + const signedPayload = await this.tokenService.encodePayload( + { + expiration_date: expirationDate, + attachment_id: attachment.node.id, + }, + { + secret, + }, + ); + + attachment.node.fullPath = `${attachment.node.fullPath}?token=${signedPayload}`; + + return attachment; + }), + ); + + return { + ...attachments, + edges: mappedEdges, + } as Result; + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index 86384c7b1425..e96db3e364d2 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -5,11 +5,13 @@ import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/works import { WorkspacePreQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module'; import { workspaceQueryRunnerFactories } from 'src/engine/api/graphql/workspace-query-runner/factories'; import { RecordPositionListener } from 'src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener'; +import { AuthModule } from 'src/engine/modules/auth/auth.module'; import { WorkspaceQueryRunnerService } from './workspace-query-runner.service'; @Module({ imports: [ + AuthModule, WorkspaceQueryBuilderModule, WorkspaceDataSourceModule, WorkspacePreQueryHookModule, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index cc7573571488..620008a6a575 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -45,6 +45,7 @@ import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-q import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { NotFoundError } from 'src/engine/filters/utils/graphql-errors.util'; import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory'; +import { QueryResultGettersFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory'; import { WorkspaceQueryRunnerOptions } from './interfaces/query-runner-option.interface'; import { @@ -61,6 +62,7 @@ export class WorkspaceQueryRunnerService { private readonly workspaceQueryBuilderFactory: WorkspaceQueryBuilderFactory, private readonly workspaceDataSourceService: WorkspaceDataSourceService, private readonly queryRunnerArgsFactory: QueryRunnerArgsFactory, + private readonly queryResultGettersFactory: QueryResultGettersFactory, @Inject(MessageQueue.webhookQueue) private readonly messageQueueService: MessageQueueService, private readonly eventEmitter: EventEmitter2, @@ -133,7 +135,7 @@ export class WorkspaceQueryRunnerService { ); const result = await this.execute(query, workspaceId); - const parsedResult = this.parseResult>( + const parsedResult = await this.parseResult>( result, objectMetadataItem, '', @@ -174,7 +176,7 @@ export class WorkspaceQueryRunnerService { workspaceId, ); - const parsedResult = this.parseResult>( + const parsedResult = await this.parseResult>( existingRecordResult, objectMetadataItem, '', @@ -227,10 +229,12 @@ export class WorkspaceQueryRunnerService { const result = await this.execute(query, workspaceId); - const parsedResults = this.parseResult>( - result, - objectMetadataItem, - 'insertInto', + const parsedResults = ( + await this.parseResult>( + result, + objectMetadataItem, + 'insertInto', + ) )?.records; await this.triggerWebhooks( @@ -280,10 +284,12 @@ export class WorkspaceQueryRunnerService { const result = await this.execute(query, workspaceId); - const parsedResults = this.parseResult>( - result, - objectMetadataItem, - 'update', + const parsedResults = ( + await this.parseResult>( + result, + objectMetadataItem, + 'update', + ) )?.records; await this.triggerWebhooks( @@ -316,10 +322,12 @@ export class WorkspaceQueryRunnerService { const result = await this.execute(query, workspaceId); - const parsedResults = this.parseResult>( - result, - objectMetadataItem, - 'update', + const parsedResults = ( + await this.parseResult>( + result, + objectMetadataItem, + 'update', + ) )?.records; await this.triggerWebhooks( @@ -349,10 +357,12 @@ export class WorkspaceQueryRunnerService { const result = await this.execute(query, workspaceId); - const parsedResults = this.parseResult>( - result, - objectMetadataItem, - 'deleteFrom', + const parsedResults = ( + await this.parseResult>( + result, + objectMetadataItem, + 'deleteFrom', + ) )?.records; await this.triggerWebhooks( @@ -382,10 +392,12 @@ export class WorkspaceQueryRunnerService { ); const result = await this.execute(query, workspaceId); - const parsedResults = this.parseResult>( - result, - objectMetadataItem, - 'deleteFrom', + const parsedResults = ( + await this.parseResult>( + result, + objectMetadataItem, + 'deleteFrom', + ) )?.records; await this.triggerWebhooks( @@ -445,11 +457,11 @@ export class WorkspaceQueryRunnerService { return results; } - private parseResult( + private async parseResult( graphqlResult: PGGraphQLResult | undefined, objectMetadataItem: ObjectMetadataInterface, command: string, - ): Result { + ): Promise { const entityKey = `${command}${computeObjectTargetTable( objectMetadataItem, )}Collection`; @@ -481,7 +493,12 @@ export class WorkspaceQueryRunnerService { throw error; } - return parseResult(result); + const resultWithGetters = await this.queryResultGettersFactory.create( + result, + objectMetadataItem, + ); + + return parseResult(resultWithGetters); } async executeAndParse( diff --git a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts index 9280550fc489..1afb6e784e3b 100644 --- a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts @@ -129,6 +129,13 @@ export class EnvironmentVariables { @IsOptional() LOGIN_TOKEN_EXPIRES_IN: string = '15m'; + @IsString() + FILE_TOKEN_SECRET: string; + + @IsDuration() + @IsOptional() + FILE_TOKEN_EXPIRES_IN: string; + // Auth @IsUrl({ require_tld: false }) @IsOptional() diff --git a/packages/twenty-server/src/engine/integrations/environment/environment.default.ts b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts new file mode 100644 index 000000000000..3b3632d4fbb1 --- /dev/null +++ b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts @@ -0,0 +1,79 @@ +import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; +import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; + +import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; +import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; +import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; +import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; +import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; + +const EnvironmentDefault = new EnvironmentVariables(); + +EnvironmentDefault.DEBUG_MODE = false; +EnvironmentDefault.SIGN_IN_PREFILLED = false; +EnvironmentDefault.IS_BILLING_ENABLED = false; +EnvironmentDefault.BILLING_PLAN_REQUIRED_LINK = ''; +EnvironmentDefault.BILLING_STRIPE_BASE_PLAN_PRODUCT_ID = ''; +EnvironmentDefault.BILLING_FREE_TRIAL_DURATION_IN_DAYS = 7; +EnvironmentDefault.BILLING_STRIPE_API_KEY = ''; +EnvironmentDefault.BILLING_STRIPE_WEBHOOK_SECRET = ''; +EnvironmentDefault.TELEMETRY_ENABLED = true; +EnvironmentDefault.TELEMETRY_ANONYMIZATION_ENABLED = true; +EnvironmentDefault.PORT = 3000; +EnvironmentDefault.REDIS_HOST = '127.0.0.1'; +EnvironmentDefault.REDIS_PORT = 6379; +EnvironmentDefault.PG_DATABASE_URL = ''; +EnvironmentDefault.FRONT_BASE_URL = ''; +EnvironmentDefault.SERVER_URL = ''; +EnvironmentDefault.ACCESS_TOKEN_SECRET = 'random_string'; +EnvironmentDefault.ACCESS_TOKEN_EXPIRES_IN = '30m'; +EnvironmentDefault.REFRESH_TOKEN_SECRET = 'random_string'; +EnvironmentDefault.REFRESH_TOKEN_EXPIRES_IN = '30m'; +EnvironmentDefault.REFRESH_TOKEN_COOL_DOWN = '1m'; +EnvironmentDefault.LOGIN_TOKEN_SECRET = 'random_string'; +EnvironmentDefault.LOGIN_TOKEN_EXPIRES_IN = '30m'; +EnvironmentDefault.FILE_TOKEN_SECRET = 'random_string'; +EnvironmentDefault.FILE_TOKEN_EXPIRES_IN = '1d'; +EnvironmentDefault.API_TOKEN_EXPIRES_IN = '100y'; +EnvironmentDefault.SHORT_TERM_TOKEN_EXPIRES_IN = '5m'; +EnvironmentDefault.FRONT_AUTH_CALLBACK_URL = ''; +EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_ENABLED = false; +EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_CALLBACK_URL = ''; +EnvironmentDefault.AUTH_GOOGLE_ENABLED = false; +EnvironmentDefault.AUTH_GOOGLE_CLIENT_ID = ''; +EnvironmentDefault.AUTH_GOOGLE_CLIENT_SECRET = ''; +EnvironmentDefault.AUTH_GOOGLE_CALLBACK_URL = ''; +EnvironmentDefault.STORAGE_TYPE = StorageDriverType.Local; +EnvironmentDefault.STORAGE_S3_REGION = 'aws-east-1'; +EnvironmentDefault.STORAGE_S3_NAME = ''; +EnvironmentDefault.STORAGE_S3_ENDPOINT = ''; +EnvironmentDefault.STORAGE_LOCAL_PATH = '.local-storage'; +EnvironmentDefault.MESSAGE_QUEUE_TYPE = MessageQueueDriverType.Sync; +EnvironmentDefault.EMAIL_FROM_ADDRESS = 'noreply@yourdomain.com'; +EnvironmentDefault.EMAIL_SYSTEM_ADDRESS = 'system@yourdomain.com'; +EnvironmentDefault.EMAIL_FROM_NAME = 'John from Twenty'; +EnvironmentDefault.EMAIL_DRIVER = EmailDriver.Logger; +EnvironmentDefault.EMAIL_SMTP_HOST = ''; +EnvironmentDefault.EMAIL_SMTP_PORT = 587; +EnvironmentDefault.EMAIL_SMTP_USER = ''; +EnvironmentDefault.EMAIL_SMTP_PASSWORD = ''; +EnvironmentDefault.SUPPORT_DRIVER = SupportDriver.None; +EnvironmentDefault.SUPPORT_FRONT_CHAT_ID = ''; +EnvironmentDefault.SUPPORT_FRONT_HMAC_KEY = ''; +EnvironmentDefault.LOGGER_DRIVER = LoggerDriverType.Console; +EnvironmentDefault.EXCEPTION_HANDLER_DRIVER = ExceptionHandlerDriver.Console; +EnvironmentDefault.LOG_LEVELS = ['log', 'error', 'warn']; +EnvironmentDefault.SENTRY_DSN = ''; +EnvironmentDefault.DEMO_WORKSPACE_IDS = []; +EnvironmentDefault.OPENROUTER_API_KEY = ''; +EnvironmentDefault.PASSWORD_RESET_TOKEN_EXPIRES_IN = '5m'; +EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION = 30; +EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION = 60; +EnvironmentDefault.IS_SIGN_UP_DISABLED = false; +EnvironmentDefault.API_RATE_LIMITING_TTL = 100; +EnvironmentDefault.API_RATE_LIMITING_LIMIT = 500; +EnvironmentDefault.MUTATION_MAXIMUM_RECORD_AFFECTED = 100; +EnvironmentDefault.CACHE_STORAGE_TYPE = 'memory'; +EnvironmentDefault.CACHE_STORAGE_TTL = 3600 * 24 * 7; + +export { EnvironmentDefault }; diff --git a/packages/twenty-server/src/engine/modules/auth/auth.module.ts b/packages/twenty-server/src/engine/modules/auth/auth.module.ts index 5d7995fd316c..a33776122ba4 100644 --- a/packages/twenty-server/src/engine/modules/auth/auth.module.ts +++ b/packages/twenty-server/src/engine/modules/auth/auth.module.ts @@ -5,7 +5,6 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { HttpModule } from '@nestjs/axios'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { FileModule } from 'src/engine/modules/file/file.module'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; @@ -22,6 +21,7 @@ import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-work import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; import { GoogleGmailAuthController } from 'src/engine/modules/auth/controllers/google-gmail-auth.controller'; import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; import { AuthResolver } from './auth.resolver'; @@ -42,7 +42,7 @@ const jwtModule = JwtModule.registerAsync({ @Module({ imports: [ jwtModule, - FileModule, + FileUploadModule, DataSourceModule, UserModule, WorkspaceManagerModule, diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts index 2fe72ca96947..af3b2ea6cca9 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts @@ -6,7 +6,7 @@ import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; describe('SignUpService', () => { diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts index f19f5cadd95f..9c49e61be7b8 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts @@ -19,7 +19,7 @@ import { } from 'src/engine/modules/auth/auth.util'; import { User } from 'src/engine/modules/user/user.entity'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { getImageBufferFromUrl } from 'src/utils/image'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts b/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts index 5fc239cae1d7..697359de9afa 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts @@ -7,7 +7,6 @@ import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.ent import { User } from 'src/engine/modules/user/user.entity'; import { JwtAuthStrategy } from 'src/engine/modules/auth/strategies/jwt.auth.strategy'; import { EmailService } from 'src/engine/integrations/email/email.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { TokenService } from './token.service'; @@ -35,10 +34,6 @@ describe('TokenService', () => { provide: EmailService, useValue: {}, }, - { - provide: UserWorkspaceService, - useValue: {}, - }, { provide: getRepositoryToken(User, 'core'), useValue: {}, diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts index 72aa8fc83c68..76ac9e9d7001 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts +++ b/packages/twenty-server/src/engine/modules/auth/services/token.service.ts @@ -40,7 +40,6 @@ import { EmailService } from 'src/engine/integrations/email/email.service'; import { InvalidatePassword } from 'src/engine/modules/auth/dto/invalidate-password.entity'; import { EmailPasswordResetLink } from 'src/engine/modules/auth/dto/email-password-reset-link.entity'; import { JwtData } from 'src/engine/modules/auth/types/jwt-data.type'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; @Injectable() @@ -56,7 +55,6 @@ export class TokenService { @InjectRepository(Workspace, 'core') private readonly workspaceRepository: Repository, private readonly emailService: EmailService, - private readonly userWorkspaceService: UserWorkspaceService, ) {} async generateAccessToken( @@ -528,4 +526,12 @@ export class TokenService { return { success: true }; } + + async encodePayload(payload: any, options?: any): Promise { + return this.jwtService.sign(payload, options); + } + + async decodePayload(payload: any, options?: any): Promise { + return this.jwtService.decode(payload, options); + } } diff --git a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts b/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts index b7048b4166ea..7005425ab333 100644 --- a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts +++ b/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts @@ -1,11 +1,14 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { CanActivate } from '@nestjs/common'; import { FileService } from 'src/engine/modules/file/services/file.service'; +import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; import { FileController } from './file.controller'; describe('FileController', () => { let controller: FileController; + const mock_FilePathGuard: CanActivate = { canActivate: jest.fn(() => true) }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -16,7 +19,10 @@ describe('FileController', () => { useValue: {}, }, ], - }).compile(); + }) + .overrideGuard(FilePathGuard) + .useValue(mock_FilePathGuard) + .compile(); controller = module.get(FileController); }); diff --git a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts b/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts index 3e9d231445f2..ad3547de41d0 100644 --- a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts +++ b/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts @@ -1,7 +1,8 @@ -import { Controller, Get, Param, Res } from '@nestjs/common'; +import { Controller, Get, Param, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; +import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; import { checkFilePath, checkFilename, @@ -10,6 +11,7 @@ import { FileService } from 'src/engine/modules/file/services/file.service'; // TODO: Add cookie authentication @Controller('files') +@UseGuards(FilePathGuard) export class FileController { constructor(private readonly fileService: FileService) {} diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts b/packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts new file mode 100644 index 000000000000..4c27162db784 --- /dev/null +++ b/packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { FileUploadResolver } from 'src/engine/modules/file/file-upload/resolvers/file-upload.resolver'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; + +@Module({ + providers: [FileUploadService, FileUploadResolver, EnvironmentService], + exports: [FileUploadService, FileUploadResolver], +}) +export class FileUploadModule {} diff --git a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.spec.ts b/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts similarity index 85% rename from packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.spec.ts rename to packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts index b5ec1c02fae0..242907bee04d 100644 --- a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.spec.ts +++ b/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { FileUploadResolver } from './file-upload.resolver'; diff --git a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts b/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts similarity index 94% rename from packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts rename to packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts index fc7312371414..8b4a1f1a4553 100644 --- a/packages/twenty-server/src/engine/modules/file/resolvers/file-upload.resolver.ts +++ b/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts @@ -5,7 +5,7 @@ import { GraphQLUpload, FileUpload } from 'graphql-upload'; import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; diff --git a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts b/packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/services/file-upload.service.spec.ts rename to packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.spec.ts diff --git a/packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts b/packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/services/file-upload.service.ts rename to packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.ts diff --git a/packages/twenty-server/src/engine/modules/file/file.module.ts b/packages/twenty-server/src/engine/modules/file/file.module.ts index 0c0a42f15334..dfbed11bf12b 100644 --- a/packages/twenty-server/src/engine/modules/file/file.module.ts +++ b/packages/twenty-server/src/engine/modules/file/file.module.ts @@ -1,20 +1,17 @@ import { Module } from '@nestjs/common'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; +import { AuthModule } from 'src/engine/modules/auth/auth.module'; +import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; import { FileService } from './services/file.service'; -import { FileUploadService } from './services/file-upload.service'; -import { FileUploadResolver } from './resolvers/file-upload.resolver'; import { FileController } from './controllers/file.controller'; @Module({ - providers: [ - FileService, - FileUploadService, - FileUploadResolver, - EnvironmentService, - ], - exports: [FileService, FileUploadService], + imports: [FileUploadModule, AuthModule], + providers: [FileService, EnvironmentService, FilePathGuard], + exports: [FileService], controllers: [FileController], }) export class FileModule {} diff --git a/packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts b/packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts new file mode 100644 index 000000000000..93ede5dc7c9b --- /dev/null +++ b/packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts @@ -0,0 +1,52 @@ +import { + Injectable, + CanActivate, + ExecutionContext, + HttpException, + HttpStatus, +} from '@nestjs/common'; + +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { TokenService } from 'src/engine/modules/auth/services/token.service'; + +@Injectable() +export class FilePathGuard implements CanActivate { + constructor( + private readonly tokenService: TokenService, + private readonly environmentService: EnvironmentService, + ) {} + + async canActivate(context: ExecutionContext): Promise { + const query = context.switchToHttp().getRequest().query; + + if (query && query['token']) { + return !(await this.isExpired(query['token'])); + } + + return true; + } + + private async isExpired(signedExpirationDate: string): Promise { + const decodedPayload = await this.tokenService.decodePayload( + signedExpirationDate, + { + secret: this.environmentService.get('FILE_TOKEN_SECRET'), + }, + ); + + const expirationDate = decodedPayload?.['expiration_date']; + + if (!expirationDate) { + return true; + } + + if (new Date(expirationDate) < new Date()) { + throw new HttpException( + 'This url has expired. Please reload twenty page and open file again.', + HttpStatus.FORBIDDEN, + ); + } + + return false; + } +} diff --git a/packages/twenty-server/src/engine/modules/user/user.module.ts b/packages/twenty-server/src/engine/modules/user/user.module.ts index 3edc028e66b1..3265e620da6a 100644 --- a/packages/twenty-server/src/engine/modules/user/user.module.ts +++ b/packages/twenty-server/src/engine/modules/user/user.module.ts @@ -4,7 +4,6 @@ import { Module } from '@nestjs/common'; import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; -import { FileModule } from 'src/engine/modules/file/file.module'; import { User } from 'src/engine/modules/user/user.entity'; import { UserResolver } from 'src/engine/modules/user/user.resolver'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; @@ -12,6 +11,7 @@ import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.mo import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; import { userAutoResolverOpts } from './user.auto-resolver-opts'; @@ -27,7 +27,7 @@ import { UserService } from './services/user.service'; resolvers: userAutoResolverOpts, }), DataSourceModule, - FileModule, + FileUploadModule, UserWorkspaceModule, ], exports: [UserService], diff --git a/packages/twenty-server/src/engine/modules/user/user.resolver.ts b/packages/twenty-server/src/engine/modules/user/user.resolver.ts index b9b051edd694..9485875d4001 100644 --- a/packages/twenty-server/src/engine/modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/modules/user/user.resolver.ts @@ -20,7 +20,7 @@ import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.inter import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { assert } from 'src/utils/assert'; import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts b/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts index 65dc8e1430d0..a2fa95f2316d 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts +++ b/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts @@ -3,7 +3,6 @@ import { Module } from '@nestjs/common'; import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; -import { FileModule } from 'src/engine/modules/file/file.module'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { WorkspaceResolver } from 'src/engine/modules/workspace/workspace.resolver'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; @@ -12,6 +11,7 @@ import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace. import { User } from 'src/engine/modules/user/user.entity'; import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; import { BillingModule } from 'src/engine/modules/billing/billing.module'; +import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; import { Workspace } from './workspace.entity'; import { workspaceAutoResolverOpts } from './workspace.auto-resolver-opts'; @@ -24,7 +24,7 @@ import { WorkspaceService } from './services/workspace.service'; NestjsQueryGraphQLModule.forFeature({ imports: [ BillingModule, - FileModule, + FileUploadModule, NestjsQueryTypeOrmModule.forFeature( [User, Workspace, UserWorkspace, FeatureFlagEntity], 'core', diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts index 061f4a8bdd58..db02e138425e 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts @@ -13,7 +13,7 @@ import { FileUpload, GraphQLUpload } from 'graphql-upload'; import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; -import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service'; +import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { assert } from 'src/utils/assert'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; From 4ab426c52a33b29ec13d152b7cd76dfceef17d6a Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:34:00 +0100 Subject: [PATCH 23/44] 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 --- .../twenty-front/src/generated/graphql.tsx | 216 +++++++++++++- .../queries/fragments/attendeeFragment.ts | 13 + .../fragments/calendarEventFragment.ts | 19 ++ .../calendarEventFragmentWithTotalFragment.ts | 13 + .../queries/getCalendarEventsFromCompanyId.ts | 20 ++ .../queries/getCalendarEventsFromPersonId.ts | 20 ++ .../calendar/constants/calendar.constants.ts | 2 + .../timeline-calendar-event-attendee.dto.ts | 25 ++ .../dtos/timeline-calendar-event.dto.ts | 52 ++++ ...timeline-calendar-events-with-total.dto.ts | 12 + .../timeline-calendar-event.module.ts | 12 + .../timeline-calendar-event.resolver.ts | 108 +++++++ .../timeline-calendar-event.service.ts | 271 ++++++++++++++++++ .../engine/modules/engine-modules.module.ts | 3 + .../messaging/dtos/timeline-thread.dto.ts | 4 +- 15 files changed, 785 insertions(+), 5 deletions(-) create mode 100644 packages/twenty-front/src/modules/activities/calendar/queries/fragments/attendeeFragment.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragment.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromCompanyId.ts create mode 100644 packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromPersonId.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts create mode 100644 packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index c96373fe9276..973de1bd5bd7 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -61,7 +61,7 @@ export type AuthTokens = { export type Billing = { __typename?: 'Billing'; billingFreeTrialDurationInDays?: Maybe; - billingUrl: Scalars['String']; + billingUrl?: Maybe; isBillingEnabled: Scalars['Boolean']; }; @@ -417,6 +417,8 @@ export type Query = { currentWorkspace: Workspace; findWorkspaceFromInviteHash: Workspace; getProductPrices: ProductPricesEntity; + getTimelineCalendarEventsFromCompanyId: TimelineCalendarEventsWithTotal; + getTimelineCalendarEventsFromPersonId: TimelineCalendarEventsWithTotal; getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal; getTimelineThreadsFromPersonId: TimelineThreadsWithTotal; 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 = { companyId: Scalars['ID']; page: Scalars['Int']; @@ -492,6 +508,23 @@ export type RelationConnection = { 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 = { __typename?: 'RelationDeleteResponse'; createdAt?: Maybe; @@ -545,6 +578,45 @@ export type Telemetry = { enabled: Scalars['Boolean']; }; +export type TimelineCalendarEvent = { + __typename?: 'TimelineCalendarEvent'; + attendees: Array; + 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; + workspaceMemberId?: Maybe; +}; + +/** Visibility of the calendar event */ +export enum TimelineCalendarEventVisibility { + Metadata = 'METADATA', + ShareEverything = 'SHARE_EVERYTHING' +} + +export type TimelineCalendarEventsWithTotal = { + __typename?: 'TimelineCalendarEventsWithTotal'; + timelineCalendarEvents: Array; + totalNumberOfCalendarEvents: Scalars['Int']; +}; + export type TimelineThread = { __typename?: 'TimelineThread'; firstParticipant: TimelineThreadParticipant; @@ -716,6 +788,7 @@ export type Field = { label: Scalars['String']; name: Scalars['String']; options?: Maybe; + relationDefinition?: Maybe; toRelationMetadata?: Maybe; type: FieldMetadataType; updatedAt: Scalars['DateTime']; @@ -794,6 +867,30 @@ export type RelationEdge = { 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 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 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<{ 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 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` fragment ParticipantFragment on TimelineThreadParticipant { 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) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetTimelineCalendarEventsFromCompanyIdDocument, options); + } +export function useGetTimelineCalendarEventsFromCompanyIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetTimelineCalendarEventsFromCompanyIdDocument, options); + } +export type GetTimelineCalendarEventsFromCompanyIdQueryHookResult = ReturnType; +export type GetTimelineCalendarEventsFromCompanyIdLazyQueryHookResult = ReturnType; +export type GetTimelineCalendarEventsFromCompanyIdQueryResult = Apollo.QueryResult; +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) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetTimelineCalendarEventsFromPersonIdDocument, options); + } +export function useGetTimelineCalendarEventsFromPersonIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetTimelineCalendarEventsFromPersonIdDocument, options); + } +export type GetTimelineCalendarEventsFromPersonIdQueryHookResult = ReturnType; +export type GetTimelineCalendarEventsFromPersonIdLazyQueryHookResult = ReturnType; +export type GetTimelineCalendarEventsFromPersonIdQueryResult = Apollo.QueryResult; export const GetTimelineThreadsFromCompanyIdDocument = gql` query GetTimelineThreadsFromCompanyId($companyId: ID!, $page: Int!, $pageSize: Int!) { getTimelineThreadsFromCompanyId( diff --git a/packages/twenty-front/src/modules/activities/calendar/queries/fragments/attendeeFragment.ts b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/attendeeFragment.ts new file mode 100644 index 000000000000..fc6b600dd354 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/attendeeFragment.ts @@ -0,0 +1,13 @@ +import { gql } from '@apollo/client'; + +export const attendeeFragment = gql` + fragment AttendeeFragment on TimelineCalendarEventAttendee { + personId + workspaceMemberId + firstName + lastName + displayName + avatarUrl + handle + } +`; diff --git a/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragment.ts b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragment.ts new file mode 100644 index 000000000000..5188d3d77b94 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragment.ts @@ -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} +`; diff --git a/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment.ts b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment.ts new file mode 100644 index 000000000000..5788bb09c566 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/queries/fragments/calendarEventFragmentWithTotalFragment.ts @@ -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} +`; diff --git a/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromCompanyId.ts b/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromCompanyId.ts new file mode 100644 index 000000000000..1928fded25ac --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromCompanyId.ts @@ -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} +`; diff --git a/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromPersonId.ts b/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromPersonId.ts new file mode 100644 index 000000000000..764282a6be96 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/calendar/queries/getCalendarEventsFromPersonId.ts @@ -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} +`; diff --git a/packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts b/packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts new file mode 100644 index 000000000000..3a0d0be05fdc --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts @@ -0,0 +1,2 @@ +export const TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE = 20; +export const TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE = 50; diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts new file mode 100644 index 000000000000..1b5082b22cbd --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts @@ -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; +} diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts new file mode 100644 index 000000000000..3d276f72e15f --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts @@ -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; +} diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts new file mode 100644 index 000000000000..4b879c380df4 --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts @@ -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[]; +} diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts new file mode 100644 index 000000000000..7b658e1720e8 --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts @@ -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 {} diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts new file mode 100644 index 000000000000..1e9e176dc64c --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts @@ -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; + } +} diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts new file mode 100644 index 000000000000..37429daf75ab --- /dev/null +++ b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts @@ -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 & { + 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 { + const offset = (page - 1) * pageSize; + + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const calendarEvents: Omit[] = + 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 { + 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; + } +} diff --git a/packages/twenty-server/src/engine/modules/engine-modules.module.ts b/packages/twenty-server/src/engine/modules/engine-modules.module.ts index aa23a0f5221d..d0dd3097398b 100644 --- a/packages/twenty-server/src/engine/modules/engine-modules.module.ts +++ b/packages/twenty-server/src/engine/modules/engine-modules.module.ts @@ -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 { BillingModule } from 'src/engine/modules/billing/billing.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 { FileModule } from './file/file.module'; @@ -26,6 +27,7 @@ import { ClientConfigModule } from './client-config/client-config.module'; OpenApiModule, RefreshTokenModule, TimelineMessagingModule, + TimelineCalendarEventModule, UserModule, WorkspaceModule, ], @@ -34,6 +36,7 @@ import { ClientConfigModule } from './client-config/client-config.module'; AuthModule, FeatureFlagModule, TimelineMessagingModule, + TimelineCalendarEventModule, UserModule, WorkspaceModule, ], diff --git a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts b/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts index 86d540bd8eb4..811ea2b96479 100644 --- a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts +++ b/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts @@ -1,12 +1,10 @@ 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'; @ObjectType('TimelineThread') export class TimelineThread { - @IDField(() => ID) + @Field(() => ID) id: string; @Field() From 4bfb90657f26e65e22a7739e222027d1cc540e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Tue, 19 Mar 2024 21:54:08 +0100 Subject: [PATCH 24/44] Add JSON field type and Event object (#4566) * Add JSON field type and Event object * Simplify code * Adress PR comments and add featureFlag --- .../src/generated-metadata/graphql.ts | 65 +++++++++-- .../twenty-front/src/generated/graphql.tsx | 45 ++++---- .../analytics/graphql/queries/createEvent.ts | 9 -- .../analytics/graphql/queries/track.ts | 9 ++ .../hooks/__tests__/useEventTracker.test.tsx | 6 +- .../hooks/__tests__/useTrackEvent.test.tsx | 8 +- .../analytics/hooks/useEventTracker.ts | 4 +- .../hooks/__tests__/useApolloFactory.test.tsx | 4 +- .../services/__tests__/apollo.factory.test.ts | 4 +- .../modules/workspace/types/FeatureFlagKey.ts | 3 +- .../twenty-front/src/testing/graphqlMocks.ts | 6 +- .../typeorm-seeds/core/feature-flags.ts | 5 + .../dtos/default-value.input.ts | 7 ++ .../field-metadata/field-metadata.entity.ts | 1 + .../field-metadata-default-value.interface.ts | 2 + .../utils/generate-target-column-map.util.ts | 1 + .../validate-default-value-for-type.util.ts | 2 + ...field-metadata-type-to-column-type.util.ts | 2 + .../workspace-migration.factory.ts | 1 + .../jobs/save-event-to-db.job.ts | 54 +++++++++ .../listeners/entity-events-to-db.listener.ts | 67 ++++++++++++ .../listeners/record-position.listener.ts | 21 ++-- .../workspace-query-runner.module.ts | 7 ++ .../workspace-query-runner.service.ts | 34 ++++-- .../graphql-types/input/index.ts | 1 + .../input/json-filter.input-type.ts | 10 ++ .../services/type-mapper.service.ts | 5 + .../types/object-record-create.event.ts | 15 +-- .../types/object-record-delete.event.ts | 9 +- .../types/object-record-update.event.ts | 11 +- .../types/object-record.base.event.ts | 8 ++ .../integrations/message-queue/jobs.module.ts | 5 + .../message-queue/message-queue.constants.ts | 1 + .../modules/analytics/analytics.resolver.ts | 6 +- .../feature-flag/feature-flag.entity.ts | 1 + .../open-api/utils/components.utils.ts | 3 + .../user-workspace/user-workspace.service.ts | 6 +- ...p-field-metadata-type-to-data-type.util.ts | 2 + .../commands/add-standard-id.command.ts | 2 + .../constants/standard-field-ids.ts | 13 +++ .../constants/standard-object-ids.ts | 1 + .../standard-objects/index.ts | 2 + .../company.object-metadata.ts | 21 ++++ .../standard-objects/event.object-metadata.ts | 103 ++++++++++++++++++ .../messaging-connected-account.listener.ts | 4 +- .../messaging-message-channel.listener.ts | 8 +- .../listeners/messaging-person.listener.ts | 14 +-- .../messaging-workspace-member.listener.ts | 14 +-- .../opportunity.object-metadata.ts | 19 ++++ .../person.object-metadata.ts | 20 ++++ .../workspace-member.object-metadata.ts | 21 ++++ 51 files changed, 575 insertions(+), 117 deletions(-) delete mode 100644 packages/twenty-front/src/modules/analytics/graphql/queries/createEvent.ts create mode 100644 packages/twenty-front/src/modules/analytics/graphql/queries/track.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts create mode 100644 packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts create mode 100644 packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 5ae4a8999565..63d820235287 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -66,10 +66,32 @@ export type AuthTokens = { export type Billing = { __typename?: 'Billing'; billingFreeTrialDurationInDays?: Maybe; - billingUrl: Scalars['String']['output']; + billingUrl?: Maybe; isBillingEnabled: Scalars['Boolean']['output']; }; +export type BillingSubscription = { + __typename?: 'BillingSubscription'; + id: Scalars['ID']['output']; + status: Scalars['String']['output']; +}; + +export type BillingSubscriptionFilter = { + and?: InputMaybe>; + id?: InputMaybe; + or?: InputMaybe>; +}; + +export type BillingSubscriptionSort = { + direction: SortDirection; + field: BillingSubscriptionSortFields; + nulls?: InputMaybe; +}; + +export enum BillingSubscriptionSortFields { + Id = 'id' +} + export type BooleanFieldComparison = { is?: InputMaybe; isNot?: InputMaybe; @@ -241,6 +263,7 @@ export enum FieldMetadataType { DateTime = 'DATE_TIME', Email = 'EMAIL', FullName = 'FULL_NAME', + Json = 'JSON', Link = 'LINK', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', @@ -301,7 +324,6 @@ export type Mutation = { activateWorkspace: Workspace; challenge: LoginToken; checkoutSession: SessionEntity; - createEvent: Analytics; createOneField: Field; createOneObject: Object; createOneRefreshToken: RefreshToken; @@ -318,6 +340,7 @@ export type Mutation = { impersonate: Verify; renewToken: AuthTokens; signUp: LoginToken; + track: Analytics; updateOneField: Field; updateOneObject: Object; updatePasswordViaResetToken: InvalidatePassword; @@ -347,12 +370,6 @@ export type MutationCheckoutSessionArgs = { }; -export type MutationCreateEventArgs = { - data: Scalars['JSON']['input']; - type: Scalars['String']['input']; -}; - - export type MutationCreateOneFieldArgs = { input: CreateOneFieldMetadataInput; }; @@ -421,6 +438,12 @@ export type MutationSignUpArgs = { }; +export type MutationTrackArgs = { + data: Scalars['JSON']['input']; + type: Scalars['String']['input']; +}; + + export type MutationUpdateOneFieldArgs = { input: UpdateOneFieldMetadataInput; }; @@ -631,6 +654,23 @@ export type RelationConnection = { 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 = { __typename?: 'RelationDeleteResponse'; createdAt?: Maybe; @@ -831,7 +871,9 @@ export type Workspace = { __typename?: 'Workspace'; activationStatus: Scalars['String']['output']; allowImpersonation: Scalars['Boolean']['output']; + billingSubscriptions?: Maybe>; createdAt: Scalars['DateTime']['output']; + currentBillingSubscription?: Maybe; deletedAt?: Maybe; displayName?: Maybe; domainName?: Maybe; @@ -844,6 +886,12 @@ export type Workspace = { }; +export type WorkspaceBillingSubscriptionsArgs = { + filter?: BillingSubscriptionFilter; + sorting?: Array; +}; + + export type WorkspaceFeatureFlagsArgs = { filter?: FeatureFlagFilter; sorting?: Array; @@ -886,6 +934,7 @@ export type Field = { label: Scalars['String']['output']; name: Scalars['String']['output']; options?: Maybe; + relationDefinition?: Maybe; toRelationMetadata?: Maybe; type: FieldMetadataType; updatedAt: Scalars['DateTime']['output']; diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 973de1bd5bd7..abf8cb43f0d1 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -183,6 +183,7 @@ export enum FieldMetadataType { DateTime = 'DATE_TIME', Email = 'EMAIL', FullName = 'FULL_NAME', + Json = 'JSON', Link = 'LINK', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', @@ -243,7 +244,6 @@ export type Mutation = { activateWorkspace: Workspace; challenge: LoginToken; checkoutSession: SessionEntity; - createEvent: Analytics; createOneObject: Object; createOneRefreshToken: RefreshToken; deleteCurrentWorkspace: Workspace; @@ -256,6 +256,7 @@ export type Mutation = { impersonate: Verify; renewToken: AuthTokens; signUp: LoginToken; + track: Analytics; updateOneObject: Object; updatePasswordViaResetToken: InvalidatePassword; updateWorkspace: Workspace; @@ -284,12 +285,6 @@ export type MutationCheckoutSessionArgs = { }; -export type MutationCreateEventArgs = { - data: Scalars['JSON']; - type: Scalars['String']; -}; - - export type MutationDeleteOneObjectArgs = { input: DeleteOneObjectInput; }; @@ -328,6 +323,12 @@ export type MutationSignUpArgs = { }; +export type MutationTrackArgs = { + data: Scalars['JSON']; + type: Scalars['String']; +}; + + export type MutationUpdatePasswordViaResetTokenArgs = { newPassword: Scalars['String']; passwordResetToken: Scalars['String']; @@ -917,13 +918,13 @@ export type GetTimelineThreadsFromPersonIdQuery = { __typename?: 'Query', getTim export type TimelineThreadFragment = { __typename?: 'TimelineThread', id: string, subject: string, lastMessageReceivedAt: string }; -export type CreateEventMutationVariables = Exact<{ +export type TrackMutationVariables = Exact<{ type: Scalars['String']; data: Scalars['JSON']; }>; -export type CreateEventMutation = { __typename?: 'Mutation', createEvent: { __typename?: 'Analytics', success: boolean } }; +export type TrackMutation = { __typename?: 'Mutation', track: { __typename?: 'Analytics', success: boolean } }; export type AuthTokenFragmentFragment = { __typename?: 'AuthToken', token: string, expiresAt: string }; @@ -1397,40 +1398,40 @@ export function useGetTimelineThreadsFromPersonIdLazyQuery(baseOptions?: Apollo. export type GetTimelineThreadsFromPersonIdQueryHookResult = ReturnType; export type GetTimelineThreadsFromPersonIdLazyQueryHookResult = ReturnType; export type GetTimelineThreadsFromPersonIdQueryResult = Apollo.QueryResult; -export const CreateEventDocument = gql` - mutation CreateEvent($type: String!, $data: JSON!) { - createEvent(type: $type, data: $data) { +export const TrackDocument = gql` + mutation Track($type: String!, $data: JSON!) { + track(type: $type, data: $data) { success } } `; -export type CreateEventMutationFn = Apollo.MutationFunction; +export type TrackMutationFn = Apollo.MutationFunction; /** - * __useCreateEventMutation__ + * __useTrackMutation__ * - * To run a mutation, you first call `useCreateEventMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateEventMutation` returns a tuple that includes: + * To run a mutation, you first call `useTrackMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useTrackMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [createEventMutation, { data, loading, error }] = useCreateEventMutation({ + * const [trackMutation, { data, loading, error }] = useTrackMutation({ * variables: { * type: // value for 'type' * data: // value for 'data' * }, * }); */ -export function useCreateEventMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useTrackMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(CreateEventDocument, options); + return Apollo.useMutation(TrackDocument, options); } -export type CreateEventMutationHookResult = ReturnType; -export type CreateEventMutationResult = Apollo.MutationResult; -export type CreateEventMutationOptions = Apollo.BaseMutationOptions; +export type TrackMutationHookResult = ReturnType; +export type TrackMutationResult = Apollo.MutationResult; +export type TrackMutationOptions = Apollo.BaseMutationOptions; export const ChallengeDocument = gql` mutation Challenge($email: String!, $password: String!) { challenge(email: $email, password: $password) { diff --git a/packages/twenty-front/src/modules/analytics/graphql/queries/createEvent.ts b/packages/twenty-front/src/modules/analytics/graphql/queries/createEvent.ts deleted file mode 100644 index 6183b9107325..000000000000 --- a/packages/twenty-front/src/modules/analytics/graphql/queries/createEvent.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { gql } from '@apollo/client'; - -export const CREATE_EVENT = gql` - mutation CreateEvent($type: String!, $data: JSON!) { - createEvent(type: $type, data: $data) { - success - } - } -`; diff --git a/packages/twenty-front/src/modules/analytics/graphql/queries/track.ts b/packages/twenty-front/src/modules/analytics/graphql/queries/track.ts new file mode 100644 index 000000000000..3aa7bba0fcf4 --- /dev/null +++ b/packages/twenty-front/src/modules/analytics/graphql/queries/track.ts @@ -0,0 +1,9 @@ +import { gql } from '@apollo/client'; + +export const TRACK = gql` + mutation Track($type: String!, $data: JSON!) { + track(type: $type, data: $data) { + success + } + } +`; diff --git a/packages/twenty-front/src/modules/analytics/hooks/__tests__/useEventTracker.test.tsx b/packages/twenty-front/src/modules/analytics/hooks/__tests__/useEventTracker.test.tsx index 85d60977d7a9..9b60f1ffa646 100644 --- a/packages/twenty-front/src/modules/analytics/hooks/__tests__/useEventTracker.test.tsx +++ b/packages/twenty-front/src/modules/analytics/hooks/__tests__/useEventTracker.test.tsx @@ -11,8 +11,8 @@ const mocks: MockedResponse[] = [ { request: { query: gql` - mutation CreateEvent($type: String!, $data: JSON!) { - createEvent(type: $type, data: $data) { + mutation Track($type: String!, $data: JSON!) { + track(type: $type, data: $data) { success } } @@ -24,7 +24,7 @@ const mocks: MockedResponse[] = [ }, result: jest.fn(() => ({ data: { - createEvent: { + track: { success: true, }, }, diff --git a/packages/twenty-front/src/modules/analytics/hooks/__tests__/useTrackEvent.test.tsx b/packages/twenty-front/src/modules/analytics/hooks/__tests__/useTrackEvent.test.tsx index 69eeecdf1ca8..f82b7323a658 100644 --- a/packages/twenty-front/src/modules/analytics/hooks/__tests__/useTrackEvent.test.tsx +++ b/packages/twenty-front/src/modules/analytics/hooks/__tests__/useTrackEvent.test.tsx @@ -4,10 +4,10 @@ import { RecoilRoot } from 'recoil'; import { useTrackEvent } from '../useTrackEvent'; -const mockCreateEventMutation = jest.fn(); +const mockTrackMutation = jest.fn(); jest.mock('~/generated/graphql', () => ({ - useCreateEventMutation: () => [mockCreateEventMutation], + useTrackMutation: () => [mockTrackMutation], })); describe('useTrackEvent', () => { @@ -17,8 +17,8 @@ describe('useTrackEvent', () => { renderHook(() => useTrackEvent(eventType, eventData), { wrapper: RecoilRoot, }); - expect(mockCreateEventMutation).toHaveBeenCalledTimes(1); - expect(mockCreateEventMutation).toHaveBeenCalledWith({ + expect(mockTrackMutation).toHaveBeenCalledTimes(1); + expect(mockTrackMutation).toHaveBeenCalledWith({ variables: { type: eventType, data: eventData }, }); }); diff --git a/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts b/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts index 75f80b4ba7c0..d2c34d023075 100644 --- a/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts +++ b/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts @@ -2,7 +2,7 @@ import { useCallback } from 'react'; import { useRecoilValue } from 'recoil'; import { telemetryState } from '@/client-config/states/telemetryState'; -import { useCreateEventMutation } from '~/generated/graphql'; +import { useTrackMutation } from '~/generated/graphql'; interface EventLocation { pathname: string; @@ -14,7 +14,7 @@ export interface EventData { export const useEventTracker = () => { const telemetry = useRecoilValue(telemetryState()); - const [createEventMutation] = useCreateEventMutation(); + const [createEventMutation] = useTrackMutation(); return useCallback( (eventType: string, eventData: EventData) => { diff --git a/packages/twenty-front/src/modules/apollo/hooks/__tests__/useApolloFactory.test.tsx b/packages/twenty-front/src/modules/apollo/hooks/__tests__/useApolloFactory.test.tsx index bea66cc15c5f..d1608ab9308c 100644 --- a/packages/twenty-front/src/modules/apollo/hooks/__tests__/useApolloFactory.test.tsx +++ b/packages/twenty-front/src/modules/apollo/hooks/__tests__/useApolloFactory.test.tsx @@ -77,8 +77,8 @@ describe('useApolloFactory', () => { await act(async () => { await result.current.factory.mutate({ mutation: gql` - mutation CreateEvent($type: String!, $data: JSON!) { - createEvent(type: $type, data: $data) { + mutation Track($type: String!, $data: JSON!) { + track(type: $type, data: $data) { success } } diff --git a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts index 7bd43be26a84..d0ba37512438 100644 --- a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts +++ b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts @@ -41,8 +41,8 @@ const makeRequest = async () => { await client.mutate({ mutation: gql` - mutation CreateEvent($type: String!, $data: JSON!) { - createEvent(type: $type, data: $data) { + mutation Track($type: String!, $data: JSON!) { + track(type: $type, data: $data) { success } } diff --git a/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts b/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts index 6b679b7d9108..8c3fa5df92e5 100644 --- a/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts +++ b/packages/twenty-front/src/modules/workspace/types/FeatureFlagKey.ts @@ -1,4 +1,5 @@ export type FeatureFlagKey = | 'IS_BLOCKLIST_ENABLED' | 'IS_CALENDAR_ENABLED' - | 'IS_QUICK_ACTIONS_ENABLED'; + | 'IS_QUICK_ACTIONS_ENABLED' + | 'IS_EVENT_OBJECT_ENABLED'; diff --git a/packages/twenty-front/src/testing/graphqlMocks.ts b/packages/twenty-front/src/testing/graphqlMocks.ts index 9908092dbf91..7bca3dbc3642 100644 --- a/packages/twenty-front/src/testing/graphqlMocks.ts +++ b/packages/twenty-front/src/testing/graphqlMocks.ts @@ -1,7 +1,7 @@ import { getOperationName } from '@apollo/client/utilities'; import { graphql, HttpResponse } from 'msw'; -import { CREATE_EVENT } from '@/analytics/graphql/queries/createEvent'; +import { TRACK } from '@/analytics/graphql/queries/track'; import { GET_CLIENT_CONFIG } from '@/client-config/graphql/queries/getClientConfig'; import { FIND_MANY_OBJECT_METADATA_ITEMS } from '@/object-metadata/graphql/queries'; import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser'; @@ -31,10 +31,10 @@ export const graphqlMocks = { }, }); }), - graphql.mutation(getOperationName(CREATE_EVENT) ?? '', () => { + graphql.mutation(getOperationName(TRACK) ?? '', () => { return HttpResponse.json({ data: { - createEvent: { success: 1, __typename: 'Event' }, + track: { success: 1, __typename: 'TRACK' }, }, }); }), diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts index 7391c5a81f71..98a4ce34b491 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts @@ -25,6 +25,11 @@ export const seedFeatureFlags = async ( workspaceId: workspaceId, value: true, }, + { + key: FeatureFlagKeys.IsEventObjectEnabled, + workspaceId: workspaceId, + value: true, + }, ]) .execute(); }; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts index 812ff65910c7..89830525a159 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts @@ -2,6 +2,7 @@ import { IsArray, IsBoolean, IsDate, + IsJSON, IsNotEmpty, IsNumber, IsNumberString, @@ -16,6 +17,12 @@ export class FieldMetadataDefaultValueString { value: string | null; } +export class FieldMetadataDefaultValueJson { + @ValidateIf((_object, value) => value !== null) + @IsJSON() + value: JSON | null; +} + export class FieldMetadataDefaultValueNumber { @ValidateIf((_object, value) => value !== null) @IsNumber() diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts index f42446afa460..2ac194c4dabd 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts @@ -36,6 +36,7 @@ export enum FieldMetadataType { MULTI_SELECT = 'MULTI_SELECT', RELATION = 'RELATION', POSITION = 'POSITION', + JSON = 'JSON', } @Entity('fieldMetadata') diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts b/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts index cfe99ebf64f0..d08a8be1cf28 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts @@ -3,6 +3,7 @@ import { FieldMetadataDefaultValueCurrency, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, + FieldMetadataDefaultValueJson, FieldMetadataDefaultValueLink, FieldMetadataDefaultValueNumber, FieldMetadataDefaultValueString, @@ -50,6 +51,7 @@ type FieldMetadataDefaultValueMapping = { [FieldMetadataType.RATING]: FieldMetadataDefaultValueString; [FieldMetadataType.SELECT]: FieldMetadataDefaultValueString; [FieldMetadataType.MULTI_SELECT]: FieldMetadataDefaultValueStringArray; + [FieldMetadataType.JSON]: FieldMetadataDefaultValueJson; }; type DefaultValueByFieldMetadata = [ diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts b/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts index c44dffbfc09f..54161679cae3 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts @@ -35,6 +35,7 @@ export function generateTargetColumnMap( case FieldMetadataType.SELECT: case FieldMetadataType.MULTI_SELECT: case FieldMetadataType.POSITION: + case FieldMetadataType.JSON: return { value: columnName, }; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts index 3c936497de0a..9e9377e24020 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts +++ b/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts @@ -9,6 +9,7 @@ import { FieldMetadataDefaultValueCurrency, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, + FieldMetadataDefaultValueJson, FieldMetadataDefaultValueLink, FieldMetadataDefaultValueNumber, FieldMetadataDefaultValueString, @@ -39,6 +40,7 @@ export const defaultValueValidatorsMap = { [FieldMetadataType.RATING]: [FieldMetadataDefaultValueString], [FieldMetadataType.SELECT]: [FieldMetadataDefaultValueString], [FieldMetadataType.MULTI_SELECT]: [FieldMetadataDefaultValueStringArray], + [FieldMetadataType.JSON]: [FieldMetadataDefaultValueJson], }; export const validateDefaultValueForType = ( diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts index 848040f8b7ce..36bf8c30ac28 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts +++ b/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts @@ -29,6 +29,8 @@ export const fieldMetadataTypeToColumnType = ( case FieldMetadataType.SELECT: case FieldMetadataType.MULTI_SELECT: return 'enum'; + case FieldMetadataType.JSON: + return 'jsonb'; default: throw new Error(`Cannot convert ${fieldMetadataType} to column type.`); } diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts index c3709df5f170..55819d2d6f60 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts +++ b/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts @@ -67,6 +67,7 @@ export class WorkspaceMigrationFactory { [FieldMetadataType.NUMERIC, { factory: this.basicColumnActionFactory }], [FieldMetadataType.NUMBER, { factory: this.basicColumnActionFactory }], [FieldMetadataType.POSITION, { factory: this.basicColumnActionFactory }], + [FieldMetadataType.JSON, { factory: this.basicColumnActionFactory }], [ FieldMetadataType.PROBABILITY, { factory: this.basicColumnActionFactory }, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts new file mode 100644 index 000000000000..44fbad59c54d --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts @@ -0,0 +1,54 @@ +import { Injectable } from '@nestjs/common'; + +import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; + +import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; + +export type SaveEventToDbJobData = { + workspaceId: string; + recordId: string; + objectName: string; + operation: string; + details: any; +}; + +@Injectable() +export class SaveEventToDbJob implements MessageQueueJob { + constructor( + private readonly dataSourceService: DataSourceService, + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + ) {} + + async handle(data: SaveEventToDbJobData): Promise { + const dataSourceMetadata = + await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( + data.workspaceId, + ); + const workspaceDataSource = + await this.workspaceDataSourceService.connectToWorkspaceDataSource( + data.workspaceId, + ); + + const eventType = `${data.operation}.${data.objectName}`; + + // TODO: add "workspaceMember" (who performed the action, need to send it in the event) + // TODO: need to support objects others than "person", "company", "opportunities" + + if ( + data.objectName != 'person' && + data.objectName != 'company' && + data.objectName != 'opportunities' + ) { + return; + } + + await workspaceDataSource?.query( + `INSERT INTO ${dataSourceMetadata.schema}."event" + ("name", "properties", "${data.objectName}Id") + VALUES ('${eventType}', '${JSON.stringify(data.details)}', '${ + data.recordId + }') RETURNING *`, + ); + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts new file mode 100644 index 000000000000..6f6b25f8d699 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts @@ -0,0 +1,67 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; + +import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; +import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { + SaveEventToDbJobData, + SaveEventToDbJob, +} from 'src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job'; +import { + FeatureFlagEntity, + FeatureFlagKeys, +} from 'src/engine/modules/feature-flag/feature-flag.entity'; + +@Injectable() +export class EntityEventsToDbListener { + constructor( + @Inject(MessageQueue.entityEventsToDbQueue) + private readonly messageQueueService: MessageQueueService, + @InjectRepository(FeatureFlagEntity, 'core') + private readonly featureFlagRepository: Repository, + ) {} + + @OnEvent('*.created') + async handleCreate(payload: ObjectRecordCreateEvent) { + return this.handle(payload, 'created'); + } + + @OnEvent('*.updated') + async handleUpdate(payload: ObjectRecordCreateEvent) { + return this.handle(payload, 'updated'); + } + + // @OnEvent('*.deleted') - TODO: implement when we have soft deleted + // .... + + private async handle( + payload: ObjectRecordCreateEvent, + operation: string, + ) { + const isEventObjectEnabledFeatureFlag = + await this.featureFlagRepository.findOneBy({ + workspaceId: payload.workspaceId, + key: FeatureFlagKeys.IsEventObjectEnabled, + value: true, + }); + + if ( + !isEventObjectEnabledFeatureFlag || + !isEventObjectEnabledFeatureFlag.value + ) { + return; + } + + this.messageQueueService.add(SaveEventToDbJob.name, { + workspaceId: payload.workspaceId, + recordId: payload.recordId, + objectName: payload.objectMetadata.nameSingular, + operation: operation, + details: payload.details, + }); + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts index c3fc08c61e06..8e3a23916e02 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts @@ -1,10 +1,9 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { - CreatedObjectMetadata, - ObjectRecordCreateEvent, -} from 'src/engine/integrations/event-emitter/types/object-record-create.event'; +import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; + +import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { @@ -21,11 +20,11 @@ export class RecordPositionListener { @OnEvent('*.created') async handleAllCreate(payload: ObjectRecordCreateEvent) { - if (!hasPositionField(payload.createdObjectMetadata)) { + if (!hasPositionField(payload.objectMetadata)) { return; } - if (hasPositionSet(payload.createdRecord)) { + if (hasPositionSet(payload.details.after)) { return; } @@ -33,15 +32,19 @@ export class RecordPositionListener { RecordPositionBackfillJob.name, { workspaceId: payload.workspaceId, - recordId: payload.createdRecord.id, - objectMetadata: payload.createdObjectMetadata, + recordId: payload.recordId, + objectMetadata: { + nameSingular: payload.objectMetadata.nameSingular, + isCustom: payload.objectMetadata.isCustom, + }, }, ); } } +// TODO: use objectMetadata instead of hardcoded standard objects name const hasPositionField = ( - createdObjectMetadata: CreatedObjectMetadata, + createdObjectMetadata: ObjectMetadataInterface, ): boolean => { return ( createdObjectMetadata.isCustom || diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index e96db3e364d2..b9feb83faac8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -1,4 +1,5 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; import { WorkspaceQueryBuilderModule } from 'src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @@ -6,20 +7,26 @@ import { WorkspacePreQueryHookModule } from 'src/engine/api/graphql/workspace-qu import { workspaceQueryRunnerFactories } from 'src/engine/api/graphql/workspace-query-runner/factories'; import { RecordPositionListener } from 'src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener'; import { AuthModule } from 'src/engine/modules/auth/auth.module'; +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; import { WorkspaceQueryRunnerService } from './workspace-query-runner.service'; +import { EntityEventsToDbListener } from './listeners/entity-events-to-db.listener'; + @Module({ imports: [ AuthModule, WorkspaceQueryBuilderModule, WorkspaceDataSourceModule, WorkspacePreQueryHookModule, + TypeOrmModule.forFeature([Workspace, FeatureFlagEntity], 'core'), ], providers: [ WorkspaceQueryRunnerService, ...workspaceQueryRunnerFactories, RecordPositionListener, + EntityEventsToDbListener, ], exports: [WorkspaceQueryRunnerService], }) diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index 620008a6a575..1088f2ad7592 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -246,10 +246,10 @@ export class WorkspaceQueryRunnerService { parsedResults.forEach((record) => { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.created`, { workspaceId, - createdRecord: this.removeNestedProperties(record), - createdObjectMetadata: { - nameSingular: objectMetadataItem.nameSingular, - isCustom: objectMetadataItem.isCustom, + recordId: record.id, + objectMetadata: objectMetadataItem, + details: { + after: record, }, } satisfies ObjectRecordCreateEvent); }); @@ -300,8 +300,12 @@ export class WorkspaceQueryRunnerService { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.updated`, { workspaceId, - previousRecord: this.removeNestedProperties(existingRecord as Record), - updatedRecord: this.removeNestedProperties(parsedResults?.[0]), + recordId: (existingRecord as Record).id, + objectMetadata: objectMetadataItem, + details: { + before: this.removeNestedProperties(existingRecord as Record), + after: this.removeNestedProperties(parsedResults?.[0]), + }, } satisfies ObjectRecordUpdateEvent); return parsedResults?.[0]; @@ -336,6 +340,12 @@ export class WorkspaceQueryRunnerService { options, ); + // TODO: check - NO EVENT SENT? + // OK I spent 2 hours trying to implement before/after diff and + // figured out why it hasn't been implement + // Doing a findMany in that context is very hard as long as we don't + // have a proper ORM. Let's come back to this once we do (target end of April 24?) + return parsedResults; } @@ -374,7 +384,11 @@ export class WorkspaceQueryRunnerService { parsedResults.forEach((record) => { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.deleted`, { workspaceId, - deletedRecord: [this.removeNestedProperties(record)], + recordId: record.id, + objectMetadata: objectMetadataItem, + details: { + before: [this.removeNestedProperties(record)], + }, } satisfies ObjectRecordDeleteEvent); }); @@ -408,7 +422,11 @@ export class WorkspaceQueryRunnerService { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.deleted`, { workspaceId, - deletedRecord: this.removeNestedProperties(parsedResults?.[0]), + recordId: args.id, + objectMetadata: objectMetadataItem, + details: { + before: this.removeNestedProperties(parsedResults?.[0]), + }, } satisfies ObjectRecordDeleteEvent); return parsedResults?.[0]; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts index 31fea9680dd9..42ddc89099e3 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts @@ -8,3 +8,4 @@ export * from './string-filter.input-type'; export * from './time-filter.input-type'; export * from './uuid-filter.input-type'; export * from './boolean-filter.input-type'; +export * from './json-filter.input-type'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts new file mode 100644 index 000000000000..6161bd86ebea --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts @@ -0,0 +1,10 @@ +import { GraphQLInputObjectType } from 'graphql'; + +import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; + +export const JsonFilterType = new GraphQLInputObjectType({ + name: 'JsonFilter', + fields: { + is: { type: FilterIs }, + }, +}); diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index d2df890aaf81..32a8c0b7c6d9 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -15,6 +15,7 @@ import { GraphQLString, GraphQLType, } from 'graphql'; +import GraphQLJSON from 'graphql-type-json'; import { DateScalarMode, @@ -31,6 +32,7 @@ import { IntFilterType, BooleanFilterType, BigFloatFilterType, + JsonFilterType, } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input'; import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum'; import { BigFloatScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; @@ -68,6 +70,7 @@ export class TypeMapperService { [FieldMetadataType.PROBABILITY, GraphQLFloat], [FieldMetadataType.RELATION, GraphQLID], [FieldMetadataType.POSITION, PositionScalarType], + [FieldMetadataType.JSON, GraphQLJSON], ]); return typeScalarMapping.get(fieldMetadataType); @@ -99,6 +102,7 @@ export class TypeMapperService { [FieldMetadataType.PROBABILITY, FloatFilterType], [FieldMetadataType.RELATION, UUIDFilterType], [FieldMetadataType.POSITION, FloatFilterType], + [FieldMetadataType.JSON, JsonFilterType], ]); return typeFilterMapping.get(fieldMetadataType); @@ -122,6 +126,7 @@ export class TypeMapperService { [FieldMetadataType.SELECT, OrderByDirectionType], [FieldMetadataType.MULTI_SELECT, OrderByDirectionType], [FieldMetadataType.POSITION, OrderByDirectionType], + [FieldMetadataType.JSON, OrderByDirectionType], ]); return typeOrderByMapping.get(fieldMetadataType); diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts index fcfda8132320..3e72f4fa3151 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-create.event.ts @@ -1,12 +1,7 @@ -import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; +import { ObjectRecordBaseEvent } from 'src/engine/integrations/event-emitter/types/object-record.base.event'; -export type CreatedObjectMetadata = { - nameSingular: string; - isCustom: boolean; -}; - -export class ObjectRecordCreateEvent { - workspaceId: string; - createdRecord: T; - createdObjectMetadata: CreatedObjectMetadata; +export class ObjectRecordCreateEvent extends ObjectRecordBaseEvent { + details: { + after: T; + }; } diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts index 6e7c011a925b..b02f0a87b2c5 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-delete.event.ts @@ -1,6 +1,7 @@ -import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; +import { ObjectRecordBaseEvent } from 'src/engine/integrations/event-emitter/types/object-record.base.event'; -export declare class ObjectRecordDeleteEvent { - workspaceId: string; - deletedRecord: T; +export class ObjectRecordDeleteEvent extends ObjectRecordBaseEvent { + details: { + before: T; + }; } diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts index 6da59637df5a..ef6a6d387604 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts @@ -1,7 +1,8 @@ -import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; +import { ObjectRecordBaseEvent } from 'src/engine/integrations/event-emitter/types/object-record.base.event'; -export class ObjectRecordUpdateEvent { - workspaceId: string; - previousRecord: T; - updatedRecord: T; +export class ObjectRecordUpdateEvent extends ObjectRecordBaseEvent { + details: { + before: T; + after: T; + }; } diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts new file mode 100644 index 000000000000..d926f9efa8b7 --- /dev/null +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts @@ -0,0 +1,8 @@ +import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; + +export class ObjectRecordBaseEvent { + workspaceId: string; + recordId: string; + objectMetadata: ObjectMetadataInterface; + details: any; +} diff --git a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts index 4bec99690bc9..d2f056b721c2 100644 --- a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts @@ -44,6 +44,7 @@ import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repos import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { SaveEventToDbJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job'; @Module({ imports: [ @@ -130,6 +131,10 @@ import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-obj provide: RecordPositionBackfillJob.name, useClass: RecordPositionBackfillJob, }, + { + provide: SaveEventToDbJob.name, + useClass: SaveEventToDbJob, + }, ], }) export class JobsModule { diff --git a/packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts index 7cb1fae15733..e3a319e02988 100644 --- a/packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/message-queue.constants.ts @@ -9,4 +9,5 @@ export enum MessageQueue { calendarQueue = 'calendar-queue', billingQueue = 'billing-queue', recordPositionBackfillQueue = 'record-position-backfill-queue', + entityEventsToDbQueue = 'entity-events-to-db-queue', } diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts b/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts index 79e55563c13c..999b347dc029 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts +++ b/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts @@ -20,14 +20,14 @@ export class AnalyticsResolver { constructor(private readonly analyticsService: AnalyticsService) {} @Mutation(() => Analytics) - createEvent( - @Args() createEventInput: CreateAnalyticsInput, + track( + @Args() createAnalyticsInput: CreateAnalyticsInput, @AuthWorkspace() workspace: Workspace | undefined, @AuthUser({ allowUndefined: true }) user: User | undefined, @Context('req') request: Request, ) { return this.analyticsService.create( - createEventInput, + createAnalyticsInput, user, workspace, request, diff --git a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts b/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts index 9ed988fb80a0..a3ae8c2635e8 100644 --- a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts +++ b/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts @@ -16,6 +16,7 @@ import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; export enum FeatureFlagKeys { IsBlocklistEnabled = 'IS_BLOCKLIST_ENABLED', IsCalendarEnabled = 'IS_CALENDAR_ENABLED', + IsEventObjectEnabled = 'IS_EVENT_OBJECT_ENABLED', } @Entity({ name: 'featureFlag', schema: 'core' }) diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts index b3336e880bb7..7fc94e5233da 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts @@ -69,6 +69,9 @@ const getSchemaComponentsProperties = ( ), }; break; + case FieldMetadataType.JSON: + type: 'object'; + break; default: itemProperty.type = 'string'; break; diff --git a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts b/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts index e6cacc139a64..b43afb61f17d 100644 --- a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts +++ b/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts @@ -62,8 +62,10 @@ export class UserWorkspaceService extends TypeOrmQueryService { new ObjectRecordCreateEvent(); payload.workspaceId = workspaceId; - payload.createdRecord = new WorkspaceMemberObjectMetadata(); - payload.createdRecord = workspaceMember[0]; + payload.details = { + after: workspaceMember[0], + }; + payload.recordId = workspaceMember[0].id; this.eventEmitter.emit('workspaceMember.created', payload); } diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts index cf35064ce730..c219eeca6ab6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts @@ -22,6 +22,8 @@ export const mapFieldMetadataTypeToDataType = ( return 'boolean'; case FieldMetadataType.DATE_TIME: return 'timestamp'; + case FieldMetadataType.JSON: + return 'jsonb'; case FieldMetadataType.RATING: case FieldMetadataType.SELECT: case FieldMetadataType.MULTI_SELECT: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts index 548a0325742f..8c70d3ecf8dd 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts @@ -50,6 +50,7 @@ export class AddStandardIdCommand extends CommandRunner { { IS_BLOCKLIST_ENABLED: true, IS_CALENDAR_ENABLED: true, + IS_EVENT_OBJECT_ENABLED: true, }, ); const standardFieldMetadataCollection = this.standardFieldFactory.create( @@ -61,6 +62,7 @@ export class AddStandardIdCommand extends CommandRunner { { IS_BLOCKLIST_ENABLED: true, IS_CALENDAR_ENABLED: true, + IS_EVENT_OBJECT_ENABLED: true, }, ); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index ee05ed3a24e0..f3cf6d23c04f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -122,6 +122,7 @@ export const companyStandardFieldIds = { opportunities: '20202020-add3-4658-8e23-d70dccb6d0ec', favorites: '20202020-4d1d-41ac-b13b-621631298d55', attachments: '20202020-c1b5-4120-b0f0-987ca401ed53', + events: '20202020-0414-4daf-9c0d-64fe7b27f89f', }; export const connectedAccountStandardFieldIds = { @@ -135,6 +136,15 @@ export const connectedAccountStandardFieldIds = { calendarChannels: '20202020-af4a-47bb-99ec-51911c1d3977', }; +export const eventStandardFieldIds = { + properties: '20202020-f142-4b04-b91b-6a2b4af3bf10', + workspaceMember: '20202020-af23-4479-9a30-868edc474b35', + person: '20202020-c414-45b9-a60a-ac27aa96229e', + company: '20202020-04ad-4221-a744-7a8278a5ce20', + opportunity: '20202020-7664-4a35-a3df-580d389fd5f0', + custom: '20202020-4a71-41b0-9f83-9cdcca3f8b14', +}; + export const favoriteStandardFieldIds = { position: '20202020-dd26-42c6-8c3c-2a7598c204f6', workspaceMember: '20202020-ce63-49cb-9676-fdc0c45892cd', @@ -199,6 +209,7 @@ export const opportunityStandardFieldIds = { favorites: '20202020-a1c2-4500-aaae-83ba8a0e827a', activityTargets: '20202020-220a-42d6-8261-b2102d6eab35', attachments: '20202020-87c7-4118-83d6-2f4031005209', + events: '20202020-30e2-421f-96c7-19c69d1cf631', }; export const personStandardFieldIds = { @@ -218,6 +229,7 @@ export const personStandardFieldIds = { attachments: '20202020-cd97-451f-87fa-bcb789bdbf3a', messageParticipants: '20202020-498e-4c61-8158-fa04f0638334', calendarEventAttendees: '20202020-52ee-45e9-a702-b64b3753e3a9', + events: '20202020-a43e-4873-9c23-e522de906ce5', }; export const pipelineStepStandardFieldIds = { @@ -284,6 +296,7 @@ export const workspaceMemberStandardFieldIds = { messageParticipants: '20202020-8f99-48bc-a5eb-edd33dd54188', blocklist: '20202020-6cb2-4161-9f29-a4b7f1283859', calendarEventAttendees: '20202020-0dbc-4841-9ce1-3e793b5b3512', + events: '20202020-e15b-47b8-94fe-8200e3c66615', }; export const customObjectStandardFieldIds = { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts index 40711e9b1c27..e155df556982 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts @@ -18,6 +18,7 @@ export const standardObjectIds = { comment: '20202020-435f-4de9-89b5-97e32233bf5f', company: '20202020-b374-4779-a561-80086cb2e17f', connectedAccount: '20202020-977e-46b2-890b-c3002ddfd5c5', + event: '20202020-6736-4337-b5c4-8b39fae325a5', favorite: '20202020-ab56-4e05-92a3-e2414a499860', messageChannelMessageAssociation: '20202020-ad1e-4127-bccb-d83ae04d2ccb', messageChannel: '20202020-fe8c-40bc-a681-b80b771449b7', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts index 0c3cfe2e024e..dd53ab77b254 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts @@ -25,6 +25,7 @@ import { ViewObjectMetadata } from 'src/modules/view/standard-objects/view.objec import { WebhookObjectMetadata } from 'src/modules/webhook/standard-objects/webhook.object-metadata'; import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; export const standardObjectMetadataDefinitions = [ ActivityTargetObjectMetadata, @@ -35,6 +36,7 @@ export const standardObjectMetadataDefinitions = [ CommentObjectMetadata, CompanyObjectMetadata, ConnectedAccountObjectMetadata, + EventObjectMetadata, FavoriteObjectMetadata, OpportunityObjectMetadata, PersonObjectMetadata, diff --git a/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts index f951c066e72d..214e80439b41 100644 --- a/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts +++ b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts @@ -19,6 +19,8 @@ import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/fa import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; +import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator'; @ObjectMetadata({ standardId: standardObjectIds.company, @@ -206,4 +208,23 @@ export class CompanyObjectMetadata extends BaseObjectMetadata { }) @IsNullable() attachments: AttachmentObjectMetadata[]; + + @FieldMetadata({ + standardId: companyStandardFieldIds.events, + type: FieldMetadataType.RELATION, + label: 'Events', + description: 'Events linked to the company', + icon: 'IconIconTimelineEvent', + }) + @RelationMetadata({ + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => EventObjectMetadata, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @IsNullable() + @Gate({ + featureFlag: 'IS_EVENT_OBJECT_ENABLED', + }) + @IsSystem() + events: EventObjectMetadata[]; } diff --git a/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts new file mode 100644 index 000000000000..545370acfb56 --- /dev/null +++ b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts @@ -0,0 +1,103 @@ +import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { eventStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata'; +import { DynamicRelationFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface'; +import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; +import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator'; +import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; +import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; +import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; +import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; +import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; +import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; + +@ObjectMetadata({ + standardId: standardObjectIds.event, + namePlural: 'events', + labelSingular: 'Event', + labelPlural: 'Events', + description: 'An event', + icon: 'IconJson', +}) +@IsSystem() +@Gate({ + featureFlag: FeatureFlagKeys.IsEventObjectEnabled, +}) +export class EventObjectMetadata extends BaseObjectMetadata { + @FieldMetadata({ + standardId: eventStandardFieldIds.properties, + type: FieldMetadataType.TEXT, + label: 'Event name', + description: 'Event name/type', + icon: 'IconAbc', + }) + name: string; + + @FieldMetadata({ + standardId: eventStandardFieldIds.properties, + type: FieldMetadataType.JSON, + label: 'Event details', + description: 'Json value for event details', + icon: 'IconListDetails', + }) + @IsNullable() + properties: JSON; + + @FieldMetadata({ + standardId: eventStandardFieldIds.workspaceMember, + type: FieldMetadataType.RELATION, + label: 'Workspace Member', + description: 'Event workspace member', + icon: 'IconCircleUser', + joinColumn: 'workspaceMemberId', + }) + @IsNullable() + workspaceMember: WorkspaceMemberObjectMetadata; + + @FieldMetadata({ + standardId: eventStandardFieldIds.person, + type: FieldMetadataType.RELATION, + label: 'Person', + description: 'Event person', + icon: 'IconUser', + joinColumn: 'personId', + }) + @IsNullable() + person: PersonObjectMetadata; + + @FieldMetadata({ + standardId: eventStandardFieldIds.company, + type: FieldMetadataType.RELATION, + label: 'Company', + description: 'Event company', + icon: 'IconBuildingSkyscraper', + joinColumn: 'companyId', + }) + @IsNullable() + company: CompanyObjectMetadata; + + @FieldMetadata({ + standardId: eventStandardFieldIds.opportunity, + type: FieldMetadataType.RELATION, + label: 'Opportunity', + description: 'Events opportunity', + icon: 'IconTargetArrow', + joinColumn: 'opportunityId', + }) + @IsNullable() + opportunity: OpportunityObjectMetadata; + + @DynamicRelationFieldMetadata((oppositeObjectMetadata) => ({ + standardId: eventStandardFieldIds.custom, + name: oppositeObjectMetadata.nameSingular, + label: oppositeObjectMetadata.labelSingular, + description: `Favorite ${oppositeObjectMetadata.labelSingular}`, + joinColumn: `${oppositeObjectMetadata.nameSingular}Id`, + icon: 'IconBuildingSkyscraper', + })) + custom: CustomObjectMetadata; +} diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts index f0f2ee0a096c..d22bf5f36708 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts @@ -46,7 +46,7 @@ export class MessagingConnectedAccountListener { DeleteConnectedAccountAssociatedMessagingDataJob.name, { workspaceId: payload.workspaceId, - connectedAccountId: payload.deletedRecord.id, + connectedAccountId: payload.recordId, }, ); @@ -55,7 +55,7 @@ export class MessagingConnectedAccountListener { DeleteConnectedAccountAssociatedCalendarDataJob.name, { workspaceId: payload.workspaceId, - connectedAccountId: payload.deletedRecord.id, + connectedAccountId: payload.recordId, }, ); } diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts index 3176e245b84f..00a50a1c5973 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-message-channel.listener.ts @@ -24,16 +24,16 @@ export class MessagingMessageChannelListener { ) { if ( objectRecordChangedProperties( - payload.previousRecord, - payload.updatedRecord, + payload.details.before, + payload.details.after, ).includes('isContactAutoCreationEnabled') && - payload.updatedRecord.isContactAutoCreationEnabled + payload.details.after.isContactAutoCreationEnabled ) { this.messageQueueService.add( CreateCompaniesAndContactsAfterSyncJob.name, { workspaceId: payload.workspaceId, - messageChannelId: payload.updatedRecord.id, + messageChannelId: payload.recordId, }, ); } diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts index fa45120a1cf7..df748ecaf42d 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-person.listener.ts @@ -23,7 +23,7 @@ export class MessagingPersonListener { async handleCreatedEvent( payload: ObjectRecordCreateEvent, ) { - if (payload.createdRecord.email === null) { + if (payload.details.after.email === null) { return; } @@ -31,8 +31,8 @@ export class MessagingPersonListener { MatchMessageParticipantJob.name, { workspaceId: payload.workspaceId, - email: payload.createdRecord.email, - personId: payload.createdRecord.id, + email: payload.details.after.email, + personId: payload.recordId, }, ); } @@ -43,16 +43,16 @@ export class MessagingPersonListener { ) { if ( objectRecordUpdateEventChangedProperties( - payload.previousRecord, - payload.updatedRecord, + payload.details.before, + payload.details.after, ).includes('email') ) { this.messageQueueService.add( MatchMessageParticipantJob.name, { workspaceId: payload.workspaceId, - email: payload.updatedRecord.email, - personId: payload.updatedRecord.id, + email: payload.details.after.email, + personId: payload.recordId, }, ); } diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts index d220f35abc6e..366bdab7c05f 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-workspace-member.listener.ts @@ -23,7 +23,7 @@ export class MessagingWorkspaceMemberListener { async handleCreatedEvent( payload: ObjectRecordCreateEvent, ) { - if (payload.createdRecord.userEmail === null) { + if (payload.details.after.userEmail === null) { return; } @@ -31,8 +31,8 @@ export class MessagingWorkspaceMemberListener { MatchMessageParticipantJob.name, { workspaceId: payload.workspaceId, - email: payload.createdRecord.userEmail, - workspaceMemberId: payload.createdRecord.id, + email: payload.details.after.userEmail, + workspaceMemberId: payload.details.after.id, }, ); } @@ -43,16 +43,16 @@ export class MessagingWorkspaceMemberListener { ) { if ( objectRecordUpdateEventChangedProperties( - payload.previousRecord, - payload.updatedRecord, + payload.details.before, + payload.details.after, ).includes('userEmail') ) { await this.messageQueueService.add( MatchMessageParticipantJob.name, { workspaceId: payload.workspaceId, - email: payload.updatedRecord.userEmail, - workspaceMemberId: payload.updatedRecord.id, + email: payload.details.after.userEmail, + workspaceMemberId: payload.recordId, }, ); } diff --git a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts index 13ac4f326b23..73af78b73520 100644 --- a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts +++ b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts @@ -18,6 +18,8 @@ import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/comp import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; import { PipelineStepObjectMetadata } from 'src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; +import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator'; @ObjectMetadata({ standardId: standardObjectIds.opportunity, @@ -178,4 +180,21 @@ export class OpportunityObjectMetadata extends BaseObjectMetadata { }) @IsNullable() attachments: AttachmentObjectMetadata[]; + + @FieldMetadata({ + standardId: opportunityStandardFieldIds.events, + type: FieldMetadataType.RELATION, + label: 'Events', + description: 'Events linked to the opportunity.', + icon: 'IconTimelineEvent', + }) + @RelationMetadata({ + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => EventObjectMetadata, + }) + @Gate({ + featureFlag: 'IS_EVENT_OBJECT_ENABLED', + }) + @IsNullable() + events: EventObjectMetadata[]; } diff --git a/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts index 3e84b9f961c8..1461c49af6b1 100644 --- a/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts +++ b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts @@ -21,6 +21,7 @@ import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/comp import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.person, @@ -218,4 +219,23 @@ export class PersonObjectMetadata extends BaseObjectMetadata { }) @IsSystem() calendarEventAttendees: CalendarEventAttendeeObjectMetadata[]; + + @FieldMetadata({ + standardId: personStandardFieldIds.events, + type: FieldMetadataType.RELATION, + label: 'Events', + description: 'Events linked to the company', + icon: 'IconTimelineEvent', + }) + @RelationMetadata({ + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => EventObjectMetadata, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @IsNullable() + @Gate({ + featureFlag: 'IS_EVENT_OBJECT_ENABLED', + }) + @IsSystem() + events: EventObjectMetadata[]; } diff --git a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts index 4db6b22618e6..6c42fd51594e 100644 --- a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts +++ b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts @@ -21,6 +21,8 @@ import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/comp import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; +import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; @ObjectMetadata({ standardId: standardObjectIds.workspaceMember, @@ -231,4 +233,23 @@ export class WorkspaceMemberObjectMetadata extends BaseObjectMetadata { featureFlag: 'IS_CALENDAR_ENABLED', }) calendarEventAttendees: CalendarEventAttendeeObjectMetadata[]; + + @FieldMetadata({ + standardId: workspaceMemberStandardFieldIds.events, + type: FieldMetadataType.RELATION, + label: 'Events', + description: 'Events linked to the workspace member', + icon: 'IconTimelineEvent', + }) + @RelationMetadata({ + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => EventObjectMetadata, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @IsNullable() + @Gate({ + featureFlag: 'IS_EVENT_OBJECT_ENABLED', + }) + @IsSystem() + events: EventObjectMetadata[]; } From b6e8bb1a6cdc2a8e847a40a2be9af7bf383728cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Tue, 19 Mar 2024 22:19:40 +0100 Subject: [PATCH 25/44] Delete auth/file front variables (#4455) --- packages/twenty-docker/prod/twenty-front/Dockerfile | 2 -- .../docs/start/self-hosting/cloud-providers.mdx | 8 -------- .../docs/start/self-hosting/docker-compose.mdx | 2 -- .../docs/start/self-hosting/self-hosting.mdx | 2 -- packages/twenty-front/.env.example | 2 -- packages/twenty-front/src/config/index.ts | 12 +----------- .../twenty-front/src/modules/auth/hooks/useAuth.ts | 6 +++--- .../SettingsAccountsListEmptyStateCard.tsx | 6 +++--- .../users/utils/getProfilePictureAbsoluteURI.ts | 6 +++--- 9 files changed, 10 insertions(+), 36 deletions(-) diff --git a/packages/twenty-docker/prod/twenty-front/Dockerfile b/packages/twenty-docker/prod/twenty-front/Dockerfile index 9b8c200c3b25..7480b7e1c3a3 100644 --- a/packages/twenty-docker/prod/twenty-front/Dockerfile +++ b/packages/twenty-docker/prod/twenty-front/Dockerfile @@ -1,8 +1,6 @@ FROM node:18.17.1-alpine as twenty-front-build ARG REACT_APP_SERVER_BASE_URL -ARG REACT_APP_SERVER_AUTH_URL -ARG REACT_APP_SERVER_FILES_URL WORKDIR /app diff --git a/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx b/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx index 8250dfece6a8..0eae5ff1a405 100644 --- a/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx @@ -229,14 +229,6 @@ resource "azurerm_container_app" "twenty_front" { name = "REACT_APP_SERVER_BASE_URL" value = "https://${azurerm_container_app.twenty_server.ingress[0].fqdn}" } - env { - name = "REACT_APP_SERVER_AUTH_URL" - value = "https://${azurerm_container_app.twenty_server.ingress[0].fqdn}/auth" - } - env { - name = "REACT_APP_SERVER_FILES_URL" - value = "https://${azurerm_container_app.twenty_server.ingress[0].fqdn}/files" - } } } } diff --git a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx index 928f74cafecc..0204e30fb281 100644 --- a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx @@ -59,8 +59,6 @@ services: environment: - SIGN_IN_PREFILLED=${SIGN_IN_PREFILLED} - REACT_APP_SERVER_BASE_URL=${LOCAL_SERVER_URL} - - REACT_APP_SERVER_AUTH_URL=${LOCAL_SERVER_URL}/auth - - REACT_APP_SERVER_FILES_URL=${LOCAL_SERVER_URL}/files depends_on: - backend diff --git a/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx b/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx index 343c7aca0ed0..29044fa58588 100644 --- a/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx @@ -23,8 +23,6 @@ import TabItem from '@theme/TabItem'; diff --git a/packages/twenty-front/.env.example b/packages/twenty-front/.env.example index e39840f2f67c..423b00b0733b 100644 --- a/packages/twenty-front/.env.example +++ b/packages/twenty-front/.env.example @@ -2,6 +2,4 @@ REACT_APP_SERVER_BASE_URL=http://localhost:3000 GENERATE_SOURCEMAP=false # ———————— Optional ———————— -# REACT_APP_SERVER_AUTH_URL=http://localhost:3000/auth -# REACT_APP_SERVER_FILES_URL=http://localhost:3000/files # CHROMATIC_PROJECT_TOKEN= diff --git a/packages/twenty-front/src/config/index.ts b/packages/twenty-front/src/config/index.ts index f128fd760f79..1220a5b0a435 100644 --- a/packages/twenty-front/src/config/index.ts +++ b/packages/twenty-front/src/config/index.ts @@ -27,14 +27,4 @@ const getDefaultUrl = () => { export const REACT_APP_SERVER_BASE_URL = window._env_?.REACT_APP_SERVER_BASE_URL || process.env.REACT_APP_SERVER_BASE_URL || - getDefaultUrl(); - -export const REACT_APP_SERVER_AUTH_URL = - window._env_?.REACT_APP_SERVER_AUTH_URL || - process.env.REACT_APP_SERVER_AUTH_URL || - REACT_APP_SERVER_BASE_URL + '/auth'; - -export const REACT_APP_SERVER_FILES_URL = - window._env_?.REACT_APP_SERVER_FILES_URL || - process.env.REACT_APP_SERVER_FILES_URL || - REACT_APP_SERVER_BASE_URL + '/files'; + getDefaultUrl(); \ No newline at end of file diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index d598b69806a3..3ecd5271e5f4 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -19,7 +19,7 @@ import { supportChatState } from '@/client-config/states/supportChatState'; import { telemetryState } from '@/client-config/states/telemetryState'; import { iconsState } from '@/ui/display/icon/states/iconsState'; import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; -import { REACT_APP_SERVER_AUTH_URL } from '~/config'; +import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { useChallengeMutation, useCheckUserExistsLazyQuery, @@ -204,9 +204,9 @@ export const useAuth = () => { ); const handleGoogleLogin = useCallback((workspaceInviteHash?: string) => { - const authServerUrl = REACT_APP_SERVER_AUTH_URL; + const authServerUrl = REACT_APP_SERVER_BASE_URL; window.location.href = - `${authServerUrl}/google/${ + `${authServerUrl}/auth/google/${ workspaceInviteHash ? '?inviteHash=' + workspaceInviteHash : '' }` || ''; }, []); diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx index c8d807681439..9f891846bc88 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx @@ -6,7 +6,7 @@ import { Button } from '@/ui/input/button/components/Button'; import { Card } from '@/ui/layout/card/components/Card'; import { CardContent } from '@/ui/layout/card/components/CardContent'; import { CardHeader } from '@/ui/layout/card/components/CardHeader'; -import { REACT_APP_SERVER_AUTH_URL } from '~/config'; +import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { useGenerateTransientTokenMutation } from '~/generated/graphql'; const StyledHeader = styled(CardHeader)` @@ -30,14 +30,14 @@ export const SettingsAccountsListEmptyStateCard = ({ const [generateTransientToken] = useGenerateTransientTokenMutation(); const handleGmailLogin = useCallback(async () => { - const authServerUrl = REACT_APP_SERVER_AUTH_URL; + const authServerUrl = REACT_APP_SERVER_BASE_URL; const transientToken = await generateTransientToken(); const token = transientToken.data?.generateTransientToken.transientToken.token; - window.location.href = `${authServerUrl}/google-gmail?transientToken=${token}`; + window.location.href = `${authServerUrl}/auth/google-gmail?transientToken=${token}`; }, [generateTransientToken]); return ( diff --git a/packages/twenty-front/src/modules/users/utils/getProfilePictureAbsoluteURI.ts b/packages/twenty-front/src/modules/users/utils/getProfilePictureAbsoluteURI.ts index 86f97c1df47c..b38880af8fe0 100644 --- a/packages/twenty-front/src/modules/users/utils/getProfilePictureAbsoluteURI.ts +++ b/packages/twenty-front/src/modules/users/utils/getProfilePictureAbsoluteURI.ts @@ -1,4 +1,4 @@ -import { REACT_APP_SERVER_FILES_URL } from '~/config'; +import { REACT_APP_SERVER_BASE_URL } from '~/config'; export const getImageAbsoluteURIOrBase64 = (imageUrl?: string | null) => { if (!imageUrl) { @@ -13,7 +13,7 @@ export const getImageAbsoluteURIOrBase64 = (imageUrl?: string | null) => { return imageUrl; } - const serverFilesUrl = REACT_APP_SERVER_FILES_URL; + const serverFilesUrl = REACT_APP_SERVER_BASE_URL; - return `${serverFilesUrl}/${imageUrl}`; + return `${serverFilesUrl}/files/${imageUrl}`; }; From c90e379fc4dde68ffac7c4f336e642e4dfae507e Mon Sep 17 00:00:00 2001 From: Thomas des Francs Date: Tue, 19 Mar 2024 22:39:52 +0100 Subject: [PATCH 26/44] Release updates (#4571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding 0.3.0 first content & introducing the new images folder * adding changelog from 0.2.3 to 0.3.3 * tracking new files * removing unwanted file * Improving Copy & adding Gmail integration to 0.3.3 * micro fix --------- Co-authored-by: Félix Malfait --- .../images/releases/0.2.3_relations.png | Bin 0 -> 415009 bytes .../public/images/releases/0.2.3_webhooks.png | Bin 0 -> 400124 bytes .../public/images/releases/0.3.0_rating.png | Bin 0 -> 325990 bytes .../images/releases/0.3.1_contributors.png | Bin 0 -> 288277 bytes .../images/releases/0.3.2_new_layout.png | Bin 0 -> 282704 bytes .../public/images/releases/0.3.3_emails.png | Bin 0 -> 288970 bytes .../public/images/releases/0.3.3_kanban.png | Bin 0 -> 472841 bytes .../public/images/releases/0.3.3_sign_up.png | Bin 0 -> 290790 bytes .../src/content/releases/0.2.3.mdx | 16 ++++++++++++ .../src/content/releases/0.3.0.mdx | 10 ++++++++ .../src/content/releases/0.3.1.mdx | 11 +++++++++ .../src/content/releases/0.3.2.mdx | 10 ++++++++ .../src/content/releases/0.3.3.mdx | 23 ++++++++++++++++++ .../src/content/releases/CompactView.mdx | 11 --------- .../src/content/releases/Inbox.mdx | 10 -------- 15 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 packages/twenty-website/public/images/releases/0.2.3_relations.png create mode 100644 packages/twenty-website/public/images/releases/0.2.3_webhooks.png create mode 100644 packages/twenty-website/public/images/releases/0.3.0_rating.png create mode 100644 packages/twenty-website/public/images/releases/0.3.1_contributors.png create mode 100644 packages/twenty-website/public/images/releases/0.3.2_new_layout.png create mode 100644 packages/twenty-website/public/images/releases/0.3.3_emails.png create mode 100644 packages/twenty-website/public/images/releases/0.3.3_kanban.png create mode 100644 packages/twenty-website/public/images/releases/0.3.3_sign_up.png create mode 100644 packages/twenty-website/src/content/releases/0.2.3.mdx create mode 100644 packages/twenty-website/src/content/releases/0.3.0.mdx create mode 100644 packages/twenty-website/src/content/releases/0.3.1.mdx create mode 100644 packages/twenty-website/src/content/releases/0.3.2.mdx create mode 100644 packages/twenty-website/src/content/releases/0.3.3.mdx delete mode 100644 packages/twenty-website/src/content/releases/CompactView.mdx delete mode 100644 packages/twenty-website/src/content/releases/Inbox.mdx diff --git a/packages/twenty-website/public/images/releases/0.2.3_relations.png b/packages/twenty-website/public/images/releases/0.2.3_relations.png new file mode 100644 index 0000000000000000000000000000000000000000..dd0c2bd14ff0e233857b8c80ba0f31d758cb9b83 GIT binary patch literal 415009 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

~*S1k!JGTo*T95m^ zVvlWHF~s4%qSe)=paK}%0LhMf@kQbV-Qb$FG44Zf4kNyDovQe9t7odQ)A!a~ADc%0 zKcE*pG7w#AYSz%^`>23>DZiCC``GrYg0DG}{jGI^>&>%p$)`(WhbJykAo z{`IE{l91azN|dsOl*79MtryT)qxt%Z6S7yTPR0cCYkC9hm;-yhPmv1q18a)B;K?eY zR}7#X+cq+Z6@8#EL;#~b-QxT9y!gN^@}kzJ;wt7 zK3nUwWl=%%fUn)?Gish4njzd6g$<;Nzxp2Vqz+HEb&g<9Y0dCkf6LvlfDDz%7HedQ zs~HaRIa>2h=>f+ChpeE|(W;fF-|gZ4{8jsg3nRrKYJl{JoU&-v&VEy$=CpcBbcmvKll3Vs4x% zbzUFIold>xw9l`2_R*t4-E#TOl9ws24cD9;iDRV|FTZHMc8W$rv?j{VmH1=qV8zP5 z=YT;n4H(%{MUG4lqa8!_qmCbZ|_?a8F zboS5g5CPcaj?PpJJC#V%fS272Ag~4$H`*A>21FE?TtGOSei{coBkHkkaVH;S{AtAS}doW9+a>+x%PLb|p^oUcS{==!afin{!~xhFTT z^?YO%UpgC?ut^<ggByWXi78JoiSIp1TqHjJcdjnx9aSsGb}OEjyskAUmXd^8C_ zMX9x8zg!bsghByqe@<1z6(A9N_k~r zF7!mH$m#+4e+P!nf7l58VWNcV z8^2K_#!NIFKFjeACoi0Axdd>POaHpb`;Y=<{Z~ugHV6pM`?P6IQQ}Ch+;BZ*3{80w zGWsy2SLA;_0Ezmv+R+v_U5hA;)JuYZGE=Z9D7p9Q7;it#2No7zu%VgheEl9^VXV(K z%$^{RY<)663qcb9w#Lxtg1qlYwtT0v@w2uhz3o z>WIlOUn{|_o|#Da1JynQA29FrQ+xJ=m4x;s1JDvIa@Y{%!0Xq_RM!b;YAg%sC{r-^ zcS!}W)tK3{9YeP2y3%v3@SpkB5%M|)%X-+-G3r~(bXrYo6#RMFHA9C*fRskX)3@-J zbf}i7hv;cOnkLko0LW?mr%wzl1^WpJC5EWuSq){j)KcXN2b@&GPBxg+pIc>E7-?S4 zL_o4L$c=7nBs*BJ;a)!NY$<-5{U36oA#PXR40;ATX7%NrbWsG;&u#>lL@4F@sS4pa zqp@GGDVO8c)aN~{$AC?3)1@@Sc;1k%Hac1}zMN$F25-Gsnf-os$E<{cp#n;8`M+^b zUZ^nughU80Is@_g@NA1q~ZG!t4VbHSFx

hdajer5D_30`wszD{hg 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

i#bT7TC(~7p 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

*Rj`=-QPz3zbdHl11W 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੗JV|Tc7sHKU*-BYcUL-SC>Bd@4Ya2s{Wrj)NY?x%R%}q7h|?ocQ6$x~SL{u9r+G!MuL&r^;c9h>oNI z`jPCDTqTs$BQ!&Ix4VcHP61(4pty5ze!9bF^eL=g`?)5xK=Vx@l$JJ!m9e4t_<;Cl z{>LvJ_(gcQ|QLf1jt z1RuJ+T(%OfM$M^j4`fQ-=Tl6c755tpwGK|W3mWS;!?r$-xB3$Z*~c#@Bq6=t2+C{D ztS$oZ6i)P&?C4VG?a4Y0)U7$d7l|ZVSHWW<_Pr}rU$tY6*qW*_qcizQsWUploRe*Z z(gCXnr~gfDvWaw!i6~7{Ug$nGUkF?xi^F4vZUXGEpM|7!y9bc@Df#MUZ&chxQ}Z5l zzQ*>wHf)fYuK#65vWdUh$@!qZr|e%T{stP zrrxj~t2H~S6t)V1!(Am$;R;m3n2Aql5W^9|S2YSd(uzOSpqbuS+5=y}M zXe-0`T`-AhWs~wMDR1lApz~!3H#LTz_RO>R^qQq73W%Hto2~bOHc={4eEKTl@e1c} zTIdvnC%I!tPEzJnbGTYK^`eS?s9(;c(7Vw=TkOHu`>jmPLc>BDEf!}@*hJsXzV750 zjf#*yA#y^5CFBOYo$tfpwg5E$8#AU?zsBHqj%!fnH%wCst@L{*z%U@q9s^_D{S){X zrYkko2D;$&V)r+N^%ZKM(TTryZ#d6YZiIFp0bQTwJiKf2^&h;OWKNjW`q_MxUig`m z>$u}~!&R}1Y%v8!S7PhdJ2HHK9iN-+Fz5{{VtZpy|MAS8e+J{Da&}NuFoY}uHm^bX z&@E;7vNW;+2u^tBDIRDLmlr?h_=)2j5Pz?!15YfwL=!s)Wa-c<3oYbYigM|S5n}Z9 zCn~9xZJ--YG|u(k3DP4)F^{6CEIJ{TxmKoVDGYhfiAGRgo3H2}ai+WvC*oxSYzsk<3dMf__<|(qE1tZEp z%H9mSV&6Dl;n2;6Wz&ve9b>I6=f7p!d?WGn@81*)B5ai!KX{;xPXgi?5q6ACnIZvyGJ;fcuqP!1{!sL9r zaPru-*GZ2s#!abcebcNq+L~#2Vl)W~o6k+b(;!WB&BcnWb&E`^{Ez$klzNi=rg^4u z?MxyWF3{QQsiDcFKNXJ*G)w~uYQiMN97PysYJ5`L6EyXl2>I9b8&{Wc)TA{GS1BxV z3YXp?T{eLgFd=!KE8*B=u=USNh?md+x{m_oHndE>gDwYG**$*xj>Fznn~CJv^O?!2jAG%a(P#;puGK_qBUHXdl@>8Z48DqXO2{_$;aH#h!wvkQ(bz2Ez8&hV8-z6z zSitMx)jX}3J9!jJPw!Jgcz%?c&rM1=Dg;7R@pd3a?VVTUZQ7n6Rp-OkcTAJ0*;@>v zb5s(*4b0LNB_1DQmV4${@E4i098FIRj2cOP-s&%5>O~MT{4A0Qb*xU17`T!fY@#flnTNRdNSNV!|3CGJ;03qIcZ_Lx~WA3d7tZiB-DrmV4o&25g$k z786&Qx~y%|h&J+oF_#2Fj!w{i|6+{KsP`4&oh&yuhiomR*3TJp|CCj;4&B$t`wMT) zOSqYM&nBW7Lh%x4=8}Dqdf)iaJpQFrBK9g_F;vl)&qW;mJswZ2R(TtcfGcFhGtsVP z@C!~cNBu^jdbuu-4U=C_o>mDNp`c;dU3+F%h+&5-Q?9}7rRIp#B5)F}%6tVpg0Bwa z-uhDF${w=WiC>@gLGSzigMT^;^V*<)LH@aJAB_Rkr#&m{LW-w(+&(XIg>wVl&XH>J zCflV}-PIh*(sv%%Bcb$QfivM_rU_D{GqsnIkFoC|P2eY@l@{nox0W zshNc8s4J|dYJ<_I5j)}bgtZyDwbvp6DVD_JNzu~*y~+_^7O?+qB_c!~M-WJlx%4`x zjm<58m~GhcNS|7<8vuY%vy=?iUl6b|>gc$w2P*5_(-}2mJT6Lls1+Zt+MFrynKGTY zumNZFYiN=ui*UbAG)hudKD~h)-iRd}um(4e2KARx(MIloQ3BWei8GKG(alG)8}jPzWl9IH>jBs(H7+`qy!(9>QmltbD?-S?9a?2{wcZ7+ASJ3O!7HhOz|S1tZE(jFMK zFn0A`$=z8HxJ;SSzqF~lQ_ZrLTMU3kDe?>^e13kPs0hZ}2+G2{5c4*Kc}Y2(bC0VG+EcM)Sfs#Qutbn>%WmM>R@bw-Z z$62{Qevbw0TXM?^+_dK_LHWNzhEH_E)s38pl*rJjqgT0f6lH>SOQt@IH1$}02V+Oq z8S&0ROzrd$s!0%Uu!I?*O$qBTUU==<&wQbQu)?Z=FN{NcMu7!}WVcYY-nP~G(otiR z=0$3_*+mVLcUk?G{k6?(f8?ky7BA5Ik5cN`hdr6-YjMBgH@BVO_@z_f)<#nqw8~Z_ zP-HqAg4OCF9hMiCz4MC+&u@JR|1MpOmG}~DAz@(Ql2MJ&K%2Gn)a4z(j$hDGrHy}b zdAJDOZ?3wqV4`p!8>4=w>St9iL#5J+Mvvxn9PtX)#`u~f|H^T^pK$^uhxQ9jf3Y+D zXRwAet$HBXT%vvUGgfSt#BzWRihCe$(^ra1Dv!nuokjGC7oIQ;;E8(&I82SA*k(CY zy$J?$WIRil#3ph_#9YLPv-ga=9UCP6WxD6KyWP zv0ls<>EpUDBsf27xhyjY`Qk;S!EL5M>7t-bog7+Ed}OD|qezK36?yEd9Ic}8R~)|O zKKss&`q&ono7@Dijy)+G*yb6?-|dq0%?L@=`d*LODDG^rj~yEXIjQua*ZWqBW>gEe z4qcg0P?0DY67&r_7rZ0wnE5D`Q;}nHeRS!ff1!HBNlr$XY88-rPg#fLhj%u#Tzjwg z&8T}spKyvD+8O^fb0+G7Tmmhxk5CApPptL0S^n%Z!Yi)i_&T&18mCk&&_+wXKezT> z(4la&oJ;u`zEkir`Mw&V+f$-pp3_K}o_O2~;9Pf4)SiuC^1FoE&0@S8RCKG8uiYQ( z!)FD1|9f~E4Y;@=$w-KP=Fi(|Xgjhl%rri{pNl&|6+u^V8M)>gxx^CIB3c^_XRH|< zs~}zG-jR)K;*}t9HrwQSHNIsjb9OZG4d4mE%O_v~5D>3NLms!WJu~k0FCn zz!m?YyRl^#(Ytz~4?fDdT4Ch(7`SkJ!lIGk`6J=_C}Q|GHX;RG?Jw#a{R>~oZCM0s z6dXNCW|CkfyJU0EMSYP=?-0%;zJi|w&@_Kjkjl{e_W$Z9zm_Cc>480pJ(hj?!2Edg zmyAj<8dzqR7@{~%H2;7bkI}ZzsAdq>!f2^h(*o)iz|X_K07cI8f<{rK*tbS{JgNmH zdEW9JA)?hU(Uv)GwCX8pH=PmD$_*!7`OU$Jc*uYt*q&Dh-k~RU^m3_D2 z8;RMCjk2Eh=0E-{_sq#mkL)8Kn>qC9=d-6mTF(zF!ihQ?odNHOPWlmLKc2?81iizg zfFT8Oe{@|1A3r$m?`FQN;b|aoCAb zA@#1tcDPg4mF95mA)~`Pj*4EZD^Sw~w*ZkUA{=9a9vahj#TaEtu~iPxQg74Z6>xr+ zjF#EuoJwSJb~yHZXGjAYpRX>1D%MRdW+tC6%PHJtrb;Qyay;Y|S7g}g5V*q0|3EGP zBHBMyZ_{-T^65LnT}1MoN!BW~pyK0u346)yt$(TlMf;@3Z3u#sZUk*m{&D+V_iz(! z!s&YI{S`1>$RxQikP()y> z!Qd97{>?xHrpS{tqTqyf5@DY%O5(A_V!;~Y>H5jc4f|Lmd17(sbKCQ82Ogh5q(CIjG^j2YH2#Nbyt z;)5D?>guR20HV7}+;PXl$XUVC>3aGNYsNFv{*i}(VN<%)85P*Fmk2*H!!siULcE!V zA6civM<0dy_nFBAa<~Ql)0RRy(WtVfxR9FGJiENxr*P=Y<+XZR_#!-VaFqYygscg1rgX6OPDno1jvQfwcCa7 z*vw*9NIU}HLdeSySxm=5+W-~`VUxMtMn}ndKp)ZOGTxxR47zyi_+V`0kEm$$q^Y)z zPrf^{)@E~jwo$(N2@&gL`r`n59Qq7b@QG1IBy!~_(r~@6-qEZryAeKd}+p#Jb z8D~D*Z1 zZ1%SSA2g!ECdM$^3%aAACoP~;QORB0uWK8p3NO(G1mn02yx=dc;0l~DTtB@CRft?y z+vwTDQj0(PcgIbmNJ53?w%bVc}e*{dN8Nk}2Qp)xHt_ z*n6a*;TcfaQr|4bm>H5QSpsSmTP1V|<{USY*B$5(O^&osuPg4ub=5uX0>Nr03mqX7 zr9Y|h_EW61=S@dBv)0qkJq852AO{E-lqH9~>7x89A**|^Ui>5WsmS{SPn*Ip0kcB! zXbh(k8&Rw@;MF)R^I<+yw*?o?_%&hfCyXvA`0+r}dYrKHK=(Y`MkuPy$h{=$KQv8p zZ-ZbY7c3;I(NUoAjta37Vgsp&%jX|19c6cp;Osh*5c9^2srZ-UXURg~Iufzb7H5+J zAFQ)!ln4jqchMs$ImEzIK2GRCl<1NU=|>uOu`f8B&PbOHN0;9?;rIoD@;iU9uewW2 z|0ntNS$M@hSTw-!3>z7x3s73=#P9ZfW7n_j17;HHaxgUrO>(^bW#sfL&~+zzf$3ps z=6N>15nn6+I>!mH$aR8K2_Qm3I!>vTg!pEZH0l;CAT*xl&;Mczk-%y6gUce0G@ zGfUixf!pimx4ErM0U50lHi^u+D;|f#n`v(Un(eQ8I8Mu6EG{5Qps{NAFS|F#5wQ$H z^9_7=JC~-epqp6)W8F^8;+^NW@)uM()cmZ6b92B<+Bf=HpY?jHvCr`@0*e0j3m=L6 znapE?al0j*OjlPUWHZYl5}C1CocrL7)i)(>iF_$&JMEkF>bMD;jVXS7oyB&gxP4#C z#GG&pn8Z9qwdd4?a8N&<2#E>#Z{~};PVGDu5v}vTUi$etqae!5(b~Qsy$0w_R)lJo zj%_Tz!{ie1?Wc_S3YuGb(Ra{+iW|1XTg;f4cQEkqa#?Wq73G;N zzR^MRkDY|3zT}t=Ay_qUTN`-Y1N38}Qs$o2M$%6Gw1_N7HNVi}6GS6p#MvOZIc({O zTiS}IWYwf=_`dY(jKvGhw%Uog$-Zjt8LV6)a2cXSGYIIe-I2|k_)L{vbmYNmt`0k- zGjp#p7+?EJTt2m;-c$DzwVwq3Y4)R_n!`kK_=|W3&#dBquADh7JA46(`-f#4psDW) z{r||kozRjOqL;du9v@G&h<=RYyILyM!r*XudGvas6&9!J-B=X{?80cIf6c`T-5Yrv zTHZx4-9n7v9H)HV59G;sNjL(XL1-K@*)p#qwgTCpyaM|6ErFEd#4v3wnF+#q1kG`>{!#FPUJmzv(c1v>Zq6s$kO#%{!Tkj|cWA$Q^6;vNKH ziFoM@e+S8L7z;=gZ`NSY1uijpxSqdppP`ZPz!;{KFt>N>I6NxU))}?Mh$kGLBr5#Cl;jVbl`%;6SnYim{Y{&|NTUxVMu@9+Z>47 zCLM%&CjVW1zZOeGH`VYi9Tgf8LKPM*cRO9qU!%F)>^lUYablO3m*4-*E+K8oi57pE zsWBOjLafv57#Pa0D&3V^r8Tfp<1pFkNm<>VEsibtsd63Wyn`Ouri6?+fhD=4;JGmQ zei?M|JP-uT+#-~e@}2pR@iC2)5~d>8%HG#5$+2)XA!;o zE4(?kC-=h_$1cnr8GXeSDqFv1AreX7+z*ZrWtSDO9NY6BONd;yT#l50jP?VdF)lsW zdMhva&0=R&{bSUjtIL9b*b>g8=hKlk0!yrtQPtId7aG=nt~opV0a~r`wLC7C#MCR7fa`KREIBp5g7};9GesVos8%zP?vXcGQkCbZeR}3M zYl60i_y19@96S%fBlLmq-}OrqS%X>TLNGEz1P2ZY%UpQ|rGHr+>X`^0zr)$dQRNo$ z_XT3BFw<@Mn(#TNmLhDL4b5Ycs`z|r8KbbZ@(J~P9$JeUE_hD~jL~?TKUl(wx;U8c zXyzcl@WIqME?!sd65>%Kyy5+8UqEwyg!+8hhJ?KCF>_lI@r*;oJ?yYpx3m>}#L8K* zbgI4MGT*?(5#?g=ZB=_Xwr+@NoT)|FJ zH}?BUImOpSLDn4hDUho1Q;6T-9W84C1<%vS7Iw0KIM9biy<97n!6iz4?PK6fKQaBQFwy8EVo|8C} zjAuf{Zn^#NO}&Ikbltd`dz1G;Dk%_=CsE(C$WAnlJX4z1wtm6@S!aN zS+{65gApR!UOd2!sw%Mm>(i)$LJPdQe?rL{U8t1lkYQwBdvA5~fBlp(}-k68lGW9es?1Ee5BOvB%u0prHI63a?q+pPj0 zM8@LhO8aeyg5u($q>+4G316SU&?52QFz}w5zMA|i)Pb~*3wd{Vs4uMfuN;>_V22Y% zkY#sPX2_v~6zc%PN)Axdk9xo3)aSr^F{NC1N7QlsN60Xu-hO#qd>u#4#zyAaud<}3 zpL0DJpAkYl_PxeLKL>yr#$MJz`|Nn#0=iv_Rfum6-7zfM?Q9BJcKFa5x35*5g#%wZ%laqjFCHH+aLz6s zw6)*qSsv}ok9ywDTs&Uh9kyNaFIkq|>3ITw!Lr!XLW|X0p@jtcUs9LH|9e#tR_51t zhCY8=5+WiKW|JDB`s)1>ZrA*Yu-pC|esWIOaZdGMoLbD!03t%T2X`>e&@^+XK+f-* zw7oM?r-E0mBOF^Yn78>c0k!NbXtMvwc+1wdk%w z1oX+i91Nr%Oq0mCd?c`9rIVEw2Z~*g%S*@anB-|%Seqn6_G_jxrZ$Gp7HAZhu^NAh z*AvL^onLDWSQKX}r7Fk946$Y|+rrBt1{ek{f4vHyV4!9|MMzDXCFMA|Ug?T0miknC ze3({G@Oe+Csgr{EiNaxdbh8D;9kV`B%_bZzo~~B+ zs+ukci0Ax&Kh5!~=_->^qgjb z1M(iJ0QGWQzjc%=E;n4eO@V7=TJ%?@jg=cH&++x~Cj99ulI^8U`Ufd%mjMqIMP?P& z7H}#Xbvxl343`onwvFW9FFG}VH)Z!mnJtzK;jS~T%7hXpB)2;@DBYXiYIBgC88{Pu5R*H{LRcJ%ZC!8&vfEn9%||T zXum{%#}g&Ma9s3YbyM&S4mMlwBh6IUHh-nQxn4?sEf3ATd)?892nk|Alq4efqP=Yk z&P;l~z|>MOly2YbT}=Q9cw1{Ff9R&V2^t^b{yaE0N|^r;{bs<1%Ca!$MANh2F~=o~ zpgi}#mr=<^VQ?E--S6vfg`ij036cf$XIugfMSvRO9};AcbW|8$VRN%M3}f7PA|Bdm zD#)*xpBeH-M{sVbVQRwycd6UV*YtiuR6GEqp(}^_k2-$Zkm@T`p2FyXCF-JS62nZ~#ZWZC^F`DJjwY#I#v|0?m(DQr5J@ilk#ua;=5p?{RzrWs&)m6@-c%dAB3&D{>Fyf=CMrB;%QcXf7m>dHg^ zXG~GLgI2Cn4wq2-q26YaR{2NG(G1JhnT2xtSDN!P8A1^Wyi?FioiE*+!}~>X1%25* zf)w5bBJCyPdO7)T>28;{p&!qV_m~3??_f@ndnUDD>zLpuH*xi`ge4Lj7G2B(1K##? z(=tzDF(f$8za9X+C~#OaD%_0+CaPlf zKt?-}zpoBx|FD-Zu~7OO1s$4ah|O<-RdmG5HsP1P6Lpi#-q}zw!K)P~$)6M+hoxs4 z<4=`KWFy$0){FJHZzV;{SH#vC7*AOoyEc;z501%8T~1fbDL}{dzT0`RpULyb$^aewk_w z&ykIk94kw)g3@6E?ii8y9|_g;)M1Ruoik@S_TPN8yNwNrAmVi=ig|P4?G!*A^Gq2& zY&NX$0w>W-nY0?tsdrUxW3dpU-@C|Q^pW(7nKc=QR>6So`$^qL9{ESWVsX1XW5?_> z-4XQRuh)C^g~#ijpFd0a(pR94pQKeXUVd^Ft{A{@xZNwnxr4PF+wEotmtWKgj`Dx# zz01*DjlT(7`dHeB_h(iMLGiyU)vs*;X(K6zT!TAeVeR(=Ygic@?&-WU8hUB#>cEMg zYr)!>ck&n1?w=D9=w({M{F93DhWjv74SnYv`vY02_RT-2W6t^L-4cs-CIM!yjHkJ` zKL{uxe0-vd%m5kA5bz`)G~?Y6NFUv z@#^Iw145He?pKGFUXIJ#^F@cu_!tpW=k9hh6_@!fLf_+BL=Ri*tPiX>oa!mOdi{bH zgRaOfzZ?bLnGToerT)h`;5ZfREV7?4tqT6{)u+~_XN@$^pz%jEJCALio>UqfR&8C< zMfhU;PFAxZ=vhPwK_RK)eR}U7Q|$d*c$!c7(%L-b?NB^*3aIoRX^n_zm0hm%zEfxv z5d!?a4SYFI`C#8F+a}AE+5Cs7`~mtEt!aMPhT98ZRT2Yi>e*M0vLpdV&Wud1 zv(*+i5sK%^4z4Dj!wx-k>s!xVsFg+}LbtR$fBs3Pmie?AzkALfwn0ChIG*}J;ERj` z&an^ID+Rhi?SE>y;7KJDD;3vUz3v-N$tf3OuK10wg311>tEO;p|Gn`IYvA9mx}MZ{ z?H@r*X}y{ynUcE)XB|yv6&(;#%KC&z+S__#8Mlf}t3k#HWp&HS(cIB-+aGEX%FyIX z26g{V42LH_ z*1ny;Ga1jm1gw^Y|J+D8_GUFxMQalOjeZ-$@hN^Y*+G2ut~eYafj`IEX6n_T(5 z?|OjL>!=sUyftH!Vf7IqyB|ncb@qymr{pH#e*8;z*!{y>4W z_M`*dEro}YR2t;B`JND{1&GJa=O7c%Jl87A<*XJkFiEmkz4k$M*Sy0_EX#eJ=`9A)IwOBCc+~-{T+WWV)_UIP87*zSct_XKn24jKXc~7N= z4+oa;P8~WIBt6@%n{2d__?kR3Ui5!`hHf0xMj62#(x-4y)eEz6MiV`V`-dL~U?y#O zD_J|6i_g*_{gpGG|8xJ7aKj}2=(mOVcC*5N0f7Se<# zEMC9ytbKM0iyxrc3wQ@f1<@zjpOh~GrsQLvRhAy1)!Q*+b~=08uG_zVI^3InE85rC zN3cK0%9$lK!}#>5yA4PE72wp=dibZn^ELGOukDclQS;dHuy@>StUvb?o&k+UmOg$H zK{Px|2bzr(g6~Lw{U-eHBBl(rM_4f0%VHAb`HJI+*K=RaPxsQGT)u?q%!OZFMOkeP zvN3bRwJrNQ28T;w2r&dSlZ+oc>6)wK>$Brc_7*P$l*BC@h3<*l@jVXt)aUAz)fe*8 zCsyD5my!kA7tU@yvG;xV05I*o=Xr))w=ul`%lXC#ezPg|xLNOPw6IsXD(9CQ;T3bk z?ZQyd7IC7`R=UoxZ5n}PCQQS$Z7pAz>U^0K!A=2mjhseaul-&G*mFJ4;BS$sp{ZMd z<|gcO;*v?3pwX#O`E_>v`RNz>{9F256}I=TEAlpl$nc>6u^KB$-}$$0viH&^O^-%} zbAkwwdPe9nsuV(iC-fqpqg-Tl9mj(Vn@WD%@afVJcYwzG$kPu8Eg+QE?}i^7m|(W`CIF(N$JUw4qKUI!m!Nb8Eo3E&LV2 zv~7i<$@UZ-c}g1hqCfjT ztL4{hJD=enZBKwdnE%<{M*a@N0qB_x0nC&lQgT=jTrBCLpU*J59$7@UZ*@QHQGPgW z{CE?+c^FlZ8NJ`BQ#3&95BGd}rgY2~djb@C!HnDR+R5j#S{&+WSjxDM`SY9@dI%J# z_e^J8)fwYtJzWDdHSae61GP-S1Cs`V7DQ7H**cGNSrY~{Inh{lCK~z~2>Ss?D*0Z} zrKRKPWmag34VlK{Vb*d2sUU+gq6~{>z=Y>|sJAmEt9}@6kTp%@7#qpi2wR|7U+c- zgH3*DVlQqeW$+)C)rMR{pB^?vAUETl{oEnXHc9Wigg(UFwdZK}`tzD%&%NBnz~&}b z>@F9^w`nzQ!W0F@g$E`*QBiz?}oYHo2h5JzDmUaLnWr*o9@^+w% zT%3#~NQ_JjVMHFdTUYtvLzVEMs#U-HV0j6Sn5oJ}k305mdN@HsWs(LdbM zo9n<@$lv?zYgw9_mf*4t5%z@j=zVc=`%wN}Nxpz1acTMZ!I;M}L@lhDsSLstE?*sr z90}(S_z6tl8Rd0=D0m}21DZeScg;-+x0ar)6>~KjM;>nut)q!lYH{j{DpmFAH_f9e zNhqEoXZmnMN&dabI@tA@Lr*38u>T3yWdn_`smt+VQts3kK6nL>W}iBQXOG*zf*n`V zd$HNY_1%AbF_V)vy_?Ea3^6a|;#3_mlb?TYg@zpB9xwye%FR5b14SaUhXPSIl2v4#!(0sIUViHkV zea-w7|D?J!*_h#KW}Jp|ed=mzr?3TrPUa=-8I;T6*O>9R@t**v^l%fUKfFp%UsNX=aVZdE}2-T7AMjXn_H*@`#F|T{gmb} z12Iw~9+`&|MYqN3w|k*kr^=3ad7(U~TM}W+`!;`wOp#qRdhtpeQGMKv3iN+K=;P>_ zzE*10ad0>C8S&c|2T8nL$~xNC)Xw{9@x7B4_hTrfzgLVx6rm64Hg`~B)LaauL5`qH z(A0}JX`JkI-Dsb z+4GF@blawyRe&U=>J|I#YYt153%4I96J$=SSpOs~AC5m?Tx?q|xESv?hbQI#>{A(1 zd$pSH$*20LXIchi4P6U+OYPOR3^$p6PZHgFJiS~L+1n^5%9fK*}FX{ADW)ye+jO#C3^i@-D(6DN?3T z9nE5gZ535WnY`t}OkDJQ+lwSktMMCe6V-f=Y}d5ju%$C&@Ni6wTe2Jf)e#s~RSEn<6jugLZk@YkYsQ2Au!1Yx>7V z>8vkXd88J%4s+k`I#58AF@E5faBes}pl+K7Z?zp|dSZNJf*BV_lOkG0bpT5y4-+!z z_>jUqkDBM|Vbg1uyU(~X7EsJr)CG)H~h#g_)xNjquMl05=wi9Ov_% zzYEZRUng6p998tP9<9x4r@QQEr4f5$cCC?Y<_!{GKmHi$rf~*r5g1H86ms1`HFoQZ||5A1kQ_AKYzEfVn~TT zUxplCCt6vY!Ji4YKB2@$yn?=md5J9=(1;lrL{OPx7p^&yKx$NiRhdfjMPB5t(OT)q z7y-7u=B*G~Zz5WU^@`hn_{)ieX2JU~w28Z6?`6qQ3v+4Yk-ZdTrE#r-@AJz>Mr)c{ zS;#CRj<8ObruB^yyaE}9P)d`g_}&Bz-ac7P%>@S%kmYSF^uE>UuvEZl)aG-oHN42q z7ggFm&U?#n{glDO!$ta1^_=q7Dxvh_hvb*4z4be8_+A`Lb$UIYK6s~G6&2*E38chF zCkaGS^B+Cfd$j85(oWV+Q%uI)vSk;zMs4LWu8d?dr{9XI?J#L02*#}z zjk@uT$J{%$J^1{pXa*K+<3mkR(zx$79g$?Nx?{b32<5mYn zN?Z5zc560VXR=tn;TD)+@V{TY=GQ{-!AkWSWZQEIHu&)x zY=I+mR3$Q$_wfzZ^P zBgDej`{ItikAF(mOY+5S@__JbR-x~G2?@tDE&b~oOBDnEa0P3mJiNkchY=%j<|WHq zPrB4a?Y4hBd+!f%szde4sf2OPx_<%q=h#(-4%NS%q|f?-?n=RV-*Y``&J<*?;8&XWWk zuRadtys~YWM}CzktM`*qW8M#Gc#M$fx5v}0 z>am7)<+ZfbrNim9Vqu+U?_pU%@{i832eKdfDX}}#6T@((Bz3*c1bUp;N-wzDm!HOq zq&7hu%huT;mQ`ukRm*l{k7mPcN4^jDP+)#p3i#3;MLXHoHjybRcQWbSBF7S+<9d<) z*wSi(Z)Q-M27%C~#M{L+-IT%Rs)S;H&vCJ|Uwd}`b6gWA>^USA<3Xua3Zt;=5`Av z&~MzL`;hMNx_(G$;H!8X66%|PuUo9DC&4&<1Zx;98YG+EFBr-E-u_Amb=V}usQGBD z(D#Ojyou9>CxRB^<;{9CPLpFMQ!O{0qJF?wbOC(>%Eb2<%F2U|@0i)Q$ZHL=!-RK| zO+s>`1+8nG32!Ct(#j)6Nj9Wu)}t?U$EyQ!KxV(mn+5*~mS7H|LloCg=Ypk%qi!`R zvWfZ}KHQ>xmL!)5?5hF`^+xc(B5LxxBWvf2r9AZW;>xtE}RNt%5WK3vcgZp-}DS8!#erhY}jc0a2Oegn{Ujt zr^e5OXu*884A2a9`=|e8N8za+q>8PigF69urWB)?FkiwudlNK_)0RIQ~&1*v?EVz zeYlJ+a9GL>ME`wG;H|d;1yA$)-;OrYem-2U`tzT4B8LM0?~Gj7d#{q-%(!@-J5A}c z2Hl>dzko8qp!(tVaJ}{>Jvyu(+#c2umG}f!tPCO%thqn>wc`r09Gx237&%wnpk1*z zwbp)>9`?A5{m`!aV0z1*;2|s3yLoz%Y%z+`;czrISoX4g`C?QV5#OE@~Du9@T-8z!^!WY(vuAzLa*34K{3^avc(lp!*w3`ZVP`o;2WONiB*ZFkI1D&(i`@KfD z5&F&Y)13pZi=b2CA&~{~HI1m+xA@zbzPc2AgWmYDyB}q(!cgc}R64R$6T}y)j(_Y) zwXFTns9z{kJEQWH`d4^~Mqx?!MPykwc&Y*4X{6Y8TT?^FHxOh6>5}KY z47$Rw!ycl(?DIH_IG1QEvzgFe9KvwkbhY#jxn8li5mMWD^F-5}DWeIhX*c(V%$D!I zy^D?&bG&69lsTXq$}KEi&171|2taElfPOQ7N*sq7gk{z2Ux0CoZ4(3hn1+5W=E$(9 z($$I&yIV!j^8}163zTDj|N6#r_oeFAM{24@$#Lq*E=#L3A>ugtSMh{=woUloSUAX( zKoN0WLAB-Nl?95MAT0;}nW_y?9Si^2Yyy?wL@;F(9aY;uJl7^BJA20;L&FJ{W0-!N zEjvl}Psh-Q#)T-_J@xItv$cA-ezJlkP7K!fkT9kvF2SA5LfCj-M03hGa5;DElcYT^(|4 z2;euOPbcEK33O1W5k{YvkOLBL1g%$a=xKT*e7ergp9zb3+?ze|@y+TTY^OjRO6fHV zjogQ5>%p7aS00mm<=-_1{mY?m8{zjtPZ^E9lrV8N4xM@MNu(Cn9oMyPd(uIPZ0^0o zZ>^n-KDD2V@&3UBhB=MqD8~F)l9QreY<@N)FtR}WpEJ}0<=7v*XF$k29DaUby92{- z!z=SoMe-H@>Sb9lNXsLFg_@EYnVs~zcEbw*#==*VCz5c&3!Ss}NQjDZs;NBw$2x>8 z6qjI>&0W@2O=X>*c1(SC$vJj5onm{d$|@&3PIGJ!u02de-T-MHCm|vT!*!lvf-{DWY2$-*2*f0iEg2 zYyG(5+jOcSbFm56L`L08rf>-Zmwr$4JQOZ+jgCQ2(24#BcOaTpw&*8|ou<;9n-+Kd zx1>x4A)noh>cQL4Aoo%;l{X_09_bw6iL@Qi=8`{^CZ1x!_08k`PnHC#Sl+W6dM|fr zpWNe=!nX;TTp9TiHVm=8aH9&a1`>icR?lCb;0PheUSG zem^e4cqq-+y}u~vXOe86Aun%Utm2dTwO0nUIUWwkG#pw3C)osdcS3i?d>MAKU;_tN z-;lnOH+-_sLv39i?B*gGjrQm`t>Ym|c6r_Lw-a<0rxJ*UZx8FXFc8V%MrG_UQZ`sb zQ?{s^hMJa!4#!BAoroy;LufRLnK{OcSR}UpO{hPA+tb78YR`?tb6`Jr616tKV4wE4 z>37`}KrD%*9sETphCX8L_osD*_wJvs)Qh?|dq?o+`%8`?4EPp=Arf%kzwwXX(F;tV zna4r9-|&Bq0@>U+3uOUzuK$KXl{#Ut&( z{qe$HtBMZ}jJK=p-q-TmtE;!ZiJyu3A1nnLZ#aO`AeI#PpTDT5fFt~Ea7S1M7`OcF zJo9eZ?P;>n5PDhf(v`zGDfF?;69@qakG%MZ=LP8Xt#i;#;;1fqfeAmh%-k!7q|0j} z#%Ald)^_X`-ybJ-l>r-_QCK`m;`?z-zxjX0hb9Xu`{yT6M)Kui8fV{FYE12CH!(8G z?NeX#j7Q?tmut!o4t*Qq>KrdfCTz*k$kq#jm`l5;q7!@I%&6rRO>sr6R33=y%IzZ< zFRLm@TXvRBzA{6@riHvyH@A~fAry4wjE zyBdS^uE|`C!xVpE?1YA!fjqId1^Enf+39-_5k-5w%k0C%b$UH&%tq8C3m^roFR>He zG;o7|stQS^WE~0UY9WsWva)R zOF}1geudZMFPU@gtX;F+iB_{AYnmB>8b(O8MIAG^_V)LRUj79&qpA@Fw-5veb-gFg zJM|f6b-S(=;}KC*d)NqX$lVap$~xn8C1YC~Bc^E`jg`vJuHfkcQj^rU$}vRJaUZ># zIV&qJew?i1);0sxCR$i78?jP2$sf52xmblx!rD`7LDYGRKq zjyaScdntUTXH-y>n3ue#w?p)MYl9f>Mn-{t)EsSB2-KtaSwXPNbUPm_kMN8ln8`jm zp0PC)>7pddAU*z3LNmo*)K~`AKx7H`d;CV`sO)64Sw}JFaUycJ(SJqBv}5J+ZlC>p z`n=!R8bzOO$8ihO-Tzuv(HT|sTE{*=FMwI}c`LR_pgZEn@L#J5Rakayh+VN!)^mr% zfYKH4dYH*K+5$AviSgSj_Fv&GIzJ3N-OvskS4?zCdxu1m9K>zE*d*AH`-Nb+xL>nj zmwIO)ogwd-;_Ly6(O7ip;9w9V=!!*NE+0PuFJ{WlM!GmjV*gwih1=@y_qC1gks`@sA`#HoX8uJ zb(S(826^YshYKyM&LL&pmohSJG|b{?*`tkD0qjS!t7gwQailzXxm)dWVqQMC*6&01D$p2j&+HfO0aw)@3M`(b+V%Dn1t-6=f}<>6R^}jAKoZd zS-hjXadjOD{Afi0Tc#II$6l$G$XfB%rgptwpzbJiHCLVly5##p2G(T> zsH?mm5h{+>0=qkMQ0&naazR8tzk0Te@x%<#Qv^(pa*R^?zny-R0m@J~-}qf>`MY@z zsb$m@pkzBsW-gbzbAJ6Dn`4ik<8hM6RKo>F2SrAQ_x=Meq2EN04*he=q8=I2J^ zNX!VF*JaI%t$!z+i=@^55S(8Dz4nGSo~${JfNz0Pp;eqW8J-(wfE489df!dj!O5KW z4Bt3*vh={#Hgf`;##sLMjsC4WA+>KG*Ki+=glVOSy?|Ob_%A2D!do z;hyJ0ArUkw&T}IURWjBb;bLbTtLIJ=Lz|zRmOZzkqTD#?LxwlOhGZH4(sm<5C}&<+ z_BS)8y@kMZ`yO(!{efgIUYNGtW?YO?Nh<7n3r_lbf;Wo6SF3;2Y&mm+98uc=m5Msf^H8ytq2v6;&l&H}D& z^Lvz#i9fQ*^HEr9+LbL}1W*~Zl4NP%yhG*+v{w69O9kq06&Q;Gn=Th)H)E)cJTD8dQn_!k zG(Zu8Ya01s1(iV`sEM2r4vc;A4tOk=?9am34Wh*TS>NDT8_%3cRN*W&ZzoXb@`s@r zp{wL7K>XRnMl)HkXVUfFWyQhApKitef1%ZM98JNiJ9a(Mc9x{I|1oB8bW<4ukxW^| z%D*9%D4^S}y;qUOhMvTZ~7{BrA zdCNNyH4&&RoGa)8v}x#-(Xwf)4VjZGCMU$)Otb^ zT;7~8^tJT2zw{@CWoa*GXo@$9gRIS*y_aB$1Y>yX4vlfR;ici%OqjiE=F81&Rd3>i zm_!pI(SJW->e6qPb2X@~UuDzsz21{IgnwaSB{QjIVB`8RZ7@gUR-g)mcX(f zzG5TVCagPLWg?Q**-5jiJ|s>a@W{bYcJLc#pnqgCk-Sm4h8>AaJj)Z&ZoUC6T-l!S zJEnYOF-V~iY|PaYLK7eDym=+t#Q&3;Q0Yome6ABy??Z8migrC!8G+t%SdyJe>ulf^ z!6rtXfv}Y9B0CL1M;r@D)lUS?JABJp{vcY?8$uR@cZ8hEmClqoqy3uYK^m~boYmmD zp25Ph`QGo+KF~`aVtaqoj>S?ey3*d0Ay!7{={&i1gOaZ}DfWdAUP|z+p?DNYUV^bJ zFKWhH%lxa1gmNCV->$yHs=`4 zhBeagkpYntr&^k?IGZ2{lCtaE*rm~Jvv;YXhQ0JShHoJ>MeoHJWvR0GM-AIJ_ChAL zjbd64js(z62wJFFHW$igcq#O*v|d68ZJASYP54D&!u6iG1QUYargaIhN2cCP)G5c1 zL4e0ZBOxNAXzH4>e4vAJzBXd)&8c;f7Y>TX5wsFyN#;QYIu6nYG>CWtvX17>@w9IP z*{aaXOuI@5qU83)y?W4*q+&x{szzS{qV#E0KN}gJu;G~pa8>zlksEYv^6a@3D5uk# zFa}%i>usD+XvsP-MeiBpRTX+)82q~@cqjSDo5s?tu$__rsc}Rk{7p`4ubz&d!oFOa zYIx~)RWW)=1?pzQ(K2$Ofz~$CKVOqlWFnK3@*gA*CQ~5e$X@ZZCJhu5@Oi z1FOm!pJlCzBChn3M{#PI8N{x4vbxDK>+wpC`pILCi};f=4nQ8!AWfD&d#zj{Omy!aw*p$*@;3QWhrC_|5prPerWO#O%G7nt^LlBbDHDXPQF{LaGo zE$l^rgj)j3+nk1oW0I(0HoHGm0X`c`5(r+=I2na-d$d91EUR3cx2u+Gt+lgEkG5ZuYW0PpL*?*t3i^(TBnz1*vsB>FuTb??Ye;g#j;|+#X z#7-m-P&gEDic^)$Y`s&bfZ}TUt`)nwD3>D}(3p<}w)Y?3s;AB>T0C0)&F8wf9tqu5 z;7Ier8yztu;>Sc7vP_H0I;Q5}wU71lO)AGxf#!RQ9{Tp;GRml8$`3`#tP3j-$!YH5 z`?AS{JyyY%ep&BTdoU7%q^!oT<5+_X?SVNy#_vTLf>rv5J}#Lz64<%gw_S)I)#uQW zk!dwkrInj)m`wabj6+L5)04{$eE1jnZUEPGz!n$K&7Hrggz0^fxuB!I$$rUzEU3xp zOrX6Sn82xR_f4sCm-Lu>Tw>~?%~w^BXl#HDL+n!_af<%zR%-z`I)fW^R}=Dd^lR_7 zxNjYr?~q;a>$iVm<&lB<&O#$y&YvDLKmErCO7(dELTF<2z224{Bmv5>VYZw|FmdWh z(r^(yUY>N#WUXhtp`ULOBjRpA*}&=vZfUexIv`rB?HK+maW`I3?A8{ydJ!dA5Lw2= zM5RtdY6Z-0(qbh{kqNec#D)NR?j|78@nO(1OAg~+FOQJn#>|hY5WXBXQ@9DXL zk|*n^w>-1z3o!z2f+l8`Lohr@Onz7Jh=?vT&9^N9+mP{ZR$EbTPRsj$Hxu<5+<1098CjFmhg2m8<-p1UM&52XC$k5Lh6vAPpB&8Sj$GJHoYsT zr_q|4zq4{}Hq5ZlkCe<18!{@O^@_!lOmIWaFyQ#7gH}7nNbMhWM7H$5GH6oeR!M@V z)YQDvLr9&(%pG=mu7j^Z%L{ZWpuwdKI#n9w;u4;NZDece5hR|Wy#*R!Eb55_y5wqX zR7PyUi(&7IR}$J8*c<0NXe5O~&T5;X?4Qz*a8ukPYSQPO} zY1$xSk#^N%bXC1rnAYs8yh`vSe7xO_ z`6*_3;fNfX^yz}#<+>{0&oD&B)Su;B?OX0`5p#Rl&TI5i;VRWP-^S-(^GgwNr*Nab zT*Butk5SUFlraA0I~XIdlgz{VZ>fY6DaJ*X=~~cZk2yxBiaCGO9Eni6Nd|1eA(!QR zbOluZhS(oYf74(hw)!r$!YzRCMB}mK#31Gn@`Y4yz-)hmx@xdNN_dIP$>JE(Gh{dS z27{cL9=}1>5M>C;{FXR&JCdDQ2%nuBuj}j^@(2(&vnaeUJ1Mf6@f!8yzBZm?wA4-U zF<-?63{pRiBP-&=0vvEUSQe|x(`#{dP;PmD2LE>v>NdVGZB>p}46r*;M`rwMyM+wP z^_B1>GnWT-j0Y!BiZ{@=AsZeHj^q0eTm|DgYc%H~>*_1FYeViSa@hhzaQV9{lK`7T>`$65}OfUFo2VJ(&yU(=tol#X3Rf@(xEAg`+hANJ~ z7*X$eIa(5Csqr4t&{V=CX`R%4Yx1XJ-Y7me0^Yo;>A3=7f6#csmk*BzD|QTTsI7#< zyZAi-GaetWyD(4>wAzEcST=iA`CWf+fxvoZ5E9tLnM=wNgFdLDP^d91XAwp3|EFcH z{wlV*NZ5@SZGAi8ckvwu6PC?710N)?;+w=`v4XQg8zr`S+tDdtkBqu3t1X&Lc>2n@WzNzgOmO=xWl&+^+6ZwajC!WBBq9Bw_i1<-$Q|hz^SGqwXobqKelXyJFBP z{C&ZNfY9}D&%cFbGPxPrt}@Xy(Azi9(dKmk%et_sFK`@M45M!WQZ5glGZma`rvutl z@iDh!na_;R22zL^Wsr!7mNpj=`($~%35Py{#m;a*b1ei&tGsy;p4Gdz>cRZPL|L>L z>Q73}n3z*j7+_J@=$qv*WG4xg7iRmg0a~$h`HOZ7!@$LFo_-R$vSWKI?~N#xJ8v=1 z+DzO=G?5Q%i9uE_i%s!VS+ygxs70u@i3ZjI z)la5}b_(+xa@ZhdMY9(1K1S2vAmwj&A`l*V+KzZ}I->HY*g_2&nlX18tI_m+Dz_?( zSVNTtwHr6$Ra7#1@UK|fBxE}^Ze)uWu?APy5^%t30@Skh|L7#4C2`T0S1z$eOhQK{{_|1*t4KnJk@i`AS3g^Dc&w!1_A-I zJ?44`|4W&(Bk50&V>9x(qik2Bkl(j(T!}QTf;18ogiH!E8y*f7lYG4th>wXJQ~kAh zU2bOhZ(3DW=bjAaAzgaU1j{+s{NSVnwcM@3K;fp#zUb-d-V@Hj-jX=CwW$)pGM6(1 z2uvoeK?w{hIt^Qf%X)FMm5tMP6};u|l|)vG9(6Ys!_QAI6cza-nZ(%6Y5TN(;y#Jm zWE2egGbxUbLu!WielO9d3a@D1#@wX%rG>C6ja$5;Re|fY&+h&CCvM3zDK))cVSnS> ziA=*uVJEsXe%K8$9i_#h3}mc5NA$GW*Q}5S3Y;vqY~z5$rS3y z=TQ}32()YTOlBr_RMu2n=%HPAie=e%r;+pV#N94tDXlM4PW<|wWf&toA-xIMX@PKK z8X{>hbXY+U{oi^Imhss5>DqHF@jEM8Y zk`7GfUs(|~&9-gdlVGxGPl&cDQWG{op=MPjo`q9**g5V82u6i;6um6;+YpY2CnkYc z+6izU($U@^!-~!`SJzG|>?yBGJucd- zb~3TLqqVDNp9V13LD_4`2E>w$tt=gnOx?7(pbcsykp7xpx_=l#ww*W_cnmDKyD@%AD{IH3V``bPVa7aI2TT=me8nJ!0V^pwxxYsC{{#KLXMas~Jh zjclKb35;h>PajrJ%NIpU^KK$NdE;IDSE$M8 z4Rie2Z)27&e61kWOK8ZK(0M5W zeu^~|Sw)cl+*?hEO^0wBwis&V8$13^K5hmh33Cu-+&KlaG%?7mi`%8jAo3sUfvrxT zeH4ehSLg=SE>^W4M0Aiop^v=Nfis8BLBD#;9oLI}bWQFt?wwYp=OT#Fs=!DlJ=gBr zI?6sh^~8A1h0lJ2?0eF?z&$MVsfg1_=9^$N77B+8$FEz&r3Ugt9@yixw91Aq_OwK> zpXaQW+S^^QF}3&pW3?5Dz+7&m;)kjUGf-ZLyki{pbC`LL&2TGAUf}VNx32vMGhJ;T z-E)`!RSuW3E{_3ia^e)b+YG5<(s+jEeuv3n&bvLd8O}gMV9?>4S-zFg3U2b}rEu&+ zUA}D36zlc|8ykNJp=>x`Z_uDRb0(qN==K)54niZOuIiyS_L4>KY`>^Jjvh90#pUD} z8F(f%!;WH_1K1p^PI<3p3ex2IqvH{!8=+G@YBq~ssz>w}vL`%f`X2<+NO?0znh1tA z5%uv2Zms%=wq==?-!EJ|V-4*V_(TilSrVz&5_z0DKsVnN2mZ|=^SG~{3p(tv^MC7ru&IZL^ zhle?bDCBnCl?))yi~Ef8naePQZ;;|b9}l4&W4J@dd$}>6x%c2FK%nU??~RC6dM1Fd zT;9yMH~?{9%kP`;q6)?Edw{HRYkN3>97k!$(*yMBdVVEKL_&^~`^KlB8VL<^Yab{w zrOH(KlT7}d+mK!wLjg>fjq)8IW#8lygsskRMBV1P76>}Q$5mFvkR2Ky6v<_if`AHT z;(j}@DQWq%K+9R5>N(Y>eo1Pno3k0~s+^1QR><_2t|uyr#b+m;NfW*M8tvIV0Ad3M zQ(tzwml}emOZP5!5tzpek&P~htAWq>Y?Iqgx^mz2qc!*Ae`iUHl9KrO@HJn`qy&Of z*6!S4Bo>rF%f&&NKnEdciW=x@kHgWOv0LdyrJjbk7vHV`UWv9un{rdxLE4Km%sVBp z6j*?P5pxLL3>B5!qR_tHg+ud)*^Ozfc(eGEU4mP^ynrRD=MB>*uc7}7XO#QBUo0_w zfBVIHMWdgTiBIDdM|`Esa6uybVt8VcvGBGv5ja5WMMWASr>t&Wn-5KlW6Bb)m}}sWm)eYk zClGzmX=4nQ`|vh-IcbRm#*Mn?^ITbL$Q>Xa7_D>;EXDuuV3}gnF1fx&!-0jsa%BPs z1>2X8?Hlb2IL*HRv;@1R9MAu>q9I>7g%-7rY_$%N1JI&cHa8|RIu;&33btN{{?px` zPteR{?0k zKRVI*d$DQE1!cS@@n4jA)VuLkft*iBD$J}Lwm+Se)IBg#>#O1Fu)VLcT$q_kpVCx@=?hUh3 zMW9N~v+Syq170lgI!8p6%F?fy^y&G;F;)`3{r!n1idL6T_cLJgZNF19^=n^dTE2If zGnW|(iHsgG{9Y!KT#_7iz6(>-u$}evUl4A|oNIDS7Qn*iq4;7HJxdr%8>Qg?@(p14 z2mP^2a@!SJ^->jGJAG~=@x+f!`UE6VjfF?}EK8{`lDDC~KWRE-1jrEkK_XO-4o_DO ze>7pzRyjW}fEbL)5+M}D)-E_`thx_VbJWQEQ{H^f!)%3nz1w!UJLliAPhP(_2hR=E zHe}={k3_At7|cu(l>nfRt=4U(E+0(=z%1&9~;rkB(DS@r8`xD~kXuMUO!Q_@)y?JD;-UzL67V{Y@kTChmQoS!C_ zbxw?^WWS17bJ=ki@^HiN*q?vwJWxJziq@H1xZ>w;A`fsj9V<6@&Q{7dZN)3}8`4ZI zO-{b$@C*~InnWwY<_(xprVL;wbZ{@u6sXdnzWUgl9R#sm%#WsG8)Br^K4cXTRZB@^ zBH-#v4S_kvwc@U5Nc0=>CQA0WtTPkNcT809wGmgM`-n z6A<9QCD+Zm{SMpy<9GaLE|SAit169#h2GN-w};MmqjRu z79^MgBF>E?-^+|e7K32xeVI_{W42VWeeB@xJ?L@Z-i1mUsbKvdtaNkEnDe`%H{mW@ zS$r3XnLMF6#jNS#a(%noHI@pc{<$8@YCMvN%bzN?`4S+=J*s{?ey2j?a8YKz;L(D1 zomB6_`1t44>EhT-ko`%=J2n5*O8TO7Rh8Ukey--6N8TxM$^CffUR#CC4`l7M-}+ZG zg`)CGp)K>9;fQSdzX>A{UpFmt#E|)#E~% zGu@oukkhKUep+~zIcMHRM@Qp;#$J72cXRk`07L*Wj7njf(L(lAg`4-Z)CV2b&+poN zm=RbF*2zAnmR&}Qr&Zm&e8+qqprpENB>%(@+iHX1Ku(pXU zF5nM`4a6+Q8?mqgy%C(sB|V%uyAI;j(Z~&Y*|*<)))CZuL1x4O(LF%#3oSOT@19hs z(DJ@gt}$9ELzT!JKs^^3E0InWZJio!V+7J6VVuT>J>YH~TOsk2c53YpReyoz0B*r_d)|A@t2jATZL= z5RcXblzoUWlXIJdOrJte1|H;KvV*4MoBzHJnhGoU7Y_QXzoGGG>mab>m3G@)y_jp- zTiv`mAMId><7$!4oz{rp%PoZ{y%tMhEncO_X`&Z(dph7ar-W4xEYd5aEZvc4yH1NH z_751^5{9|cglq@|bdWau5rp*;{#lymc=dqLsC;=oj~~WTq6!i0@`lBQe`vpKot9FwT6Lo6DPqgaNjt zl-xwqWH(AcY_RD}lt(Z{3ilo&fSm9{s7v_^zPXybCh(+Wd5I^s>~Um&v=6G#w@Bkb2uVAAbpgcFAFLa z65K&rw4oCkC@?t;bejXte%c9|FRIA>+c#qliE&Pq+K2>9gnOcH0UAMLy$<usrsm~@zO{uK013%emK+4j<5T z6J#Hi4p~*fW`htswYAH_eG81Yh1GczgG8Tn^p++4HN{j?^Un@QeIc`B?#+P1lUa*M;rBa{dix71KoK-1cv$vU zH1Ef8g`|T1?p;GIBRTmwuwgyCwav7R9A*UBjjs-Tl($pGTvln(`|v1| z&U9{Q!@!N|C0#q6bJ(z-}*ms>b`!zEysEkyYSa|c~x0PV-1cHydw0LzVLMT0I70{il&Wl zUZ`h`)O{9N4~eS(wTFKr`{%anIu%WRbgB@l&M2Oy7`WwUVI{bA`q>f@ZjYm9j9C?@ zqtR<{!*%z9c=E%K1Xj*HI^!HPKDJDY?N~ zHW(*hQRwxVihzutNQJ6UEqX%`TyESoVrqDZKLS92obOnf?n`@do5GWUP;lxBhJRJVbPwcVu?*Lo|Bo;t_@`n1w4}B~0kR=^?L%J?lt`B1>d2=XCaD==ImEHsD`jc9wG=M-ULi#OxL!l1yx;Wl_w@68voS?0m(A5m_kK%i%E=fk>==zXvB2b(f_ zSP{@pIl2G*%~^s1m<*z5k5p)u-=%o^4@a5^%rH%0!H2!~6xwhv+*p2E+5x8G~R!a?)i zjPORcA}hWn$lw1ScKp07m2&IV=T^Wdznf*miL8xsF3|Z9c_0N=!3z8K9+w!agP2sK z15LuxOCJRme$BWR(y^7b*b$Np5?HsW;+v<4=DF;i_qwfc<_sBjL{&XkPP+TOP*G8E zDE!tXFaFm|!n_VVAoJ%AkAO(5&$WI-lSjb3(CFV0V9cVta5!QoeQ7dh-73ucV1{h~ zw-~$4i{+2luwJnr<4sGZT?l>6i|(tpu95yq=Mf@n?CrHJr>H}kFXaD^U?Mc6JMlTw zae9YLI^z*faJ9DUq9J}rk<|C0jThzH(!HGOTr;+rrTYTUbg|%gYbT|Li%EtCa%du6 zn=~tYM@RHM?v*t{GGgb$7`)imZ#sQ0mfZCk`Vpjm-r!t2s#;wy2d;}mGoJ&V5sj5F zvY$%2H6i*|EX*Xc%}fT@@OBY0&xVL7OOM^@#3RMXD9%B@$Uj~XS{qsWZ=1Vb3?Jj;6dQemUzsRzj_k`;r1ljKye`if5Yl;#X-}EQ1>)`6LTp-kX zr4s+Bdx_<6Hqrj7pz>D&z)gcCBo^e){qpy4yw%-Z;#w5NxQJ-?<%h7k0k z^*e%F95A>(8n^roi(2OC(FfpfqeE)}UYF;dFKClB6a+6VeR-Vr39s-}Y{pcv6d&CW&Hbq4wJCZ zf3n3Au)MZ617D`$XySp27=|3nKcJ?xcK&Zn3D5EMkoDn zPStW!u)3h@4>DpJ&rWXZ#{z2h++x?*7svnvPc*wI%Ln0wt`shap6Wl%`i_pzaMs4v z4*H`qYkZGoQPY@(SkVq3sYUd)PKwN(NCYT3FCB6**Iu0Zye*Q|RZ1mqwM1tlgbjCU z5CI7FH~OjIRYg0+v2?iS=+@`!`j0Q1J+7>wDIspPAeGej&X}&jG7$qm@4&G9mw+&( zDR!ns%ydvibnE*+%uEV>O<4ng%b^%SjCbwH%gDW9)m`2XcUO3V6JODE*55s{ePkL_ z*?YI%8-RMY3F%e+lyF@nE@!TIPN%Tthxp*0c%4{tGA0Sx0}kqev=kf=b8128E~@G- z_eRxk-A4!pYkYLtQ+bBe=|a|2|KDeq{nY}t4X^ae@HCun&mVrK#E*GxUiMm4^SZ!^ zm40k1P%Yr5nXE!2@Wg{I%w7&z#7iI{o5uA8M!94wOBeqYFN)FVIrc#++11)hysu@6Bghe9iVW(?5~`NIaIOG+=kdrmtW-gLaA%?g)!aL`>J( zp{H-*kTZllqtGW8D{9$eTItZTO5W*1gs7an>UwEzU*t0IO{UQ?R{Oq)F__&GLMzz( zHW0e;nt9<*dn!TZ^j~hHdJ1i0mhN{>WgT zZ{vO1X%@S(A-*B9lC|lAWp~u`G(%h*KzW!NE=8XFt{poj_FGm$*-AW9C?FZVU1Rh8 ze-ucMZ03(GGK++kVO&J(j|CjhbYH$ctMdI(1&X6iG!qRx3PR*o!y1Oo1T|FTf{g?@ z50X##jjB>)qVaD3>`AUX6a5l$`iY9}H(L-M+2dzrepGv>f5_}-I_tJnAbf$a6vyEB z`tjg#p_mF6;dn;25HUq#l`A5rPh20$w&3JH$NB8iXk zKrn{nyYR`%Dr?1buvdy^&v3SH3Z10pfW>b6*hvykE0j-H6j|}=FGik0HW+Yw9HzwE zTm_c=S$=o>m+Wo}a+9}&i9TdnV?bs!e^YGD)AZh0s@y*oJf9%A^LGQh8XM8%BQ zjCz~N?87yBE+o{hixv9ac=?iFQ*pYB95(K6+6wzA;DpiJjPWg@6H?fuGH3@9FVq>L zm~Z)VQi?>e4v1>2vc;}Pq7T~wKQ{eHGyJfWRCU3+Y48MaLwbZ^q=+3xKhp1nU$FEB zxLYO5t!dMjjW%0ctI6X0-PE5mq!g_d#zKXGt;Uvl4wKoGT0=rX#+_SM@R74KR*f?F zau4h?y#3i1|9vPql6iRP^i6GoMhRtUr{=4Pb)W&FqE^EQ>e9of|K%$5+4Md{$Nkum^-4v^$N)eYj^%P=7nyMWgA`bj7OlGxb)eWs;Pc*@*C6+vgSnMXp?w=iw1T2gPD zi0{<0I4iH0GDxg*f*QG02-3Ew6SFuePq^a}vbnR3cL?Q)>&!U_be;LQZ_H2eYg?DS zSb*-xwBc{D9D;1r2V?M@*{;B_H#^F^m>TzHV_!drZ#MkNd*gXIv1gdhm~OJZu=BFe zVXYbz{rdUW;YY}fUpu~~TjNJ^0Z7ji5zRQSGz(Ym2yWi^)W!_rcxLT`#&4l60qTuv zXb-T8~V_T()NS`y@YTg(h+u)EQH*MnwNv8gn2Y{{FLl~HwbXm?l6Es*WPO2SM zuOB}$S`O|G_+Rj$g2E@j?yLvadQ%x8jb^}EG`JpSskO-b;Znuig5(0B3U_CVmFvXX~G*ubbv330a)GqkjtnCEb zF$eNGmlrqB8YVtsl01eyRaB%q9nJ1O@?;MvVTgd!m0($au0@#e*i!4}&PMvr1;{G> zm!V&m@+wad6-5TT;SJ$viz!zDqg-NlNK=qfhhp6L-y`|vHpf#UJ$wLhmMQDfiKG8@;sE)VKwTe}p`4LZ@soD} z2(A`liVoYd88Yi+&pZ?+L)jNDd6B z7`Z}7_15V!tBBnV6NxlOaz=U*RSOT^859=x*5pOZic6|0EZ8*B0e&!H`^cJ^D7v~Z z_27-*Mg3Zh(PJq`Rd#|KP4zbcMvTYfrT%W>7rxIHiQ_SL=^b>8?#|gmld~x?h1I0J zt8c84FLLs5RchHZ2*;MAEx0rZpy*VC%Pp5r)JPr5ml`SXWoL-yOrZu{Jh8$_^^X~9 zHxF+%+$ump+Q~Z~TJ?S9kjwAH)Vp*Lpe@(xPFp{V;L27yUb#e5+N$5Od&K5Yww#fC z1DKkZ?w9*VrGwtB<7=i?U(sS5uvzsvh22+hd6Xo(Kl(`eT!eQ~#iL==Q)k*p7#J;g zqROg>b6k|0(vYp2ePZhi9S95YE1iFQo_`->W&Aj=?E)9dZ?b|>o3rsKevm#Q<~1uI zad6A*8YdSmdv6r~N+t1r;g|*_J^(3gsnD1ed|Tg7HMqZMz9C?de=pcx`H@$9i1vTK z5qM_4qDtz$OH`$vzibUnmuATrya%o?mNpDpkX&M!qX93F*y zZp3c<7d}#RXv@n)52UnG8;GaBZmUsl)YSAHpVfY%y>3*mqw!>NnWwF{nEHvPtv8e6 z8g2Dwx{Oh64LZasSR)1j`@9PNa!Mzm?!$;o3(=P)m0%2*aNasvSj%ww(|=^@L-Q-G z-liqT`8U-G(JYU5-npc7u6*Rxp?}SJ$jR*+AdcF0BM6w~rs8Mgkz|hPj-T(948|7= zv!!ou{_hX$mm)FC{5_pt)-SRC{JtFuqM_Uom-3-S%HE$Ng;E`gx$n;#GsGoQJ}prm zl4hUVQl&apzlL)>W_85F2Nph6z!$aTSHn1}@Kw2|6K8~$S=SqD_DQ6r&tlT)BEI(W zjlN}?U@EXc=`cEQfrMuDFD~6)DA!5mEC=XifOzq%^P0va0PDd{%c!~OWlCIr`|DY zTp0$&wLe!*>icXK+I5=>m>Zy6#^a2B0=6O5Kqe2dOQ4~7`QXNlDi2PQ`Cas^5oux) zZNS*T|NlWd;wj6P=BBE@njL;lHO!)mALvpn3kH{GTQ(F(vu8iofJ1}jPgOUq$&%QG zIuN6#e7%UnQ3e2{VzJ0 z?G2}E#ehK6LE=)cew$FtqNE96FPszq&v8c|lF0bcM3bqCcnDae<&(Hqw5??iP1!Mo zL(x=zAA}`hI~L>!NpsuUOa=J3!8VV>>}`-mkh;MPUGeV1tF3e+=!FLnE!xE_zN^h*PZYh&T%BXWWc*q|8S|Y^W7zQc3 zXACb_d3%#fxJJS_d(;r;#j`JPf0smHb85KOf1CWm={ts!)h%d7AH|I;Mb~DF!j_^n zZWN#tzr;Awh{*$FPx2S&6y4|~YFEcQ5|=^sA|!$$+##5^x3%}q6*feJ7#s}%fQF@A`5 zssHDRqXpZ*0ZYi=sg)bejH|Jw1|YHNdl`le1aJi3G0jBxhX^%qz3sq6D*uB}?g4ZT zRYIbW(}KKoQ2-n{Nek$V@=*1`o&RW+Vbb@U27~?~!ZG5_c~zbcolJ4qwN#6}Tah7& z*uCC^1$nGaQh4(+CMkZX+%M4m=S~@JZPOZ0S5H*n(NurhoOu|eCy%fez6eOqzR0|jyO`)mgx^o*?^?0>+&f&zZKwUP_Io1oOV4{AztF+u zJ~XeUEYv@n4_UT1ksYU13z|>Ss6eO`%<{Kbf%p3ybZ#S$T;TRv_^8uIU}dGtXKU(P zpJ7~Cy#Yx99y>=F=W_<_Ru?J6mw!PLNp`2Yz-EYX=#9YqdGB(Y-1}|}ooPu1pg=lq zA(KdZu@w)$s7iWinUoLa3k*MQZ-PM*1PX&>qn}2E-x__WO5ysK+A}{N3@3*_4q;No!Eal_hTE-hJk3OYBr?uk5psz= zOrOzbWmqwv-_q3$Uu>7qMfl$Am@?NYd?ji))pi}qGcow!ZK}x+J+ug?ga}GT!r3)1 zUI54p_4V;~5k+)0XkG_8TJn*CPw{;OMIqutk7)rnje5^noZG}>QkboUvw8HKqqf+{ddXmcL?-DDG(X+=>`rFeA+INZ^2zcb zh3Vvo1K5-|gL*1^!FDIlpb_^%k>c89$6%7~DV)LoVyS~c%5)zi^T6;yciX-Ms$6|u zl?gE1){d`couO4jGh^HyFGOlZ_x#TrV_P$QiiZDA4f?xl!7Sym`x2UgIg&W%Lha~w ztU*f+e_1nq;ymaMRV9iGC1fXnZR5r9?>UBveJUEQv`;kDU`7m0S2c#BEbEICE6`aw>ch4;Y@9GU-r2Zd zOM91);E6+}U;hw$v#;egTLK4ZT#x5Ii0_q1JR>SL) z6y824*;S-8&GkL1uvdR*xdk5?*zAE>fpaKGs`>jbs(;Gp`!F4DWbeu&OyIGYA;a9@ zJog>4Aw!1g1soQ=+No|6>HBvioMxPPv|%)DPk_O>o3+w5B;=wj?4Q=8`ZM1qQD)wrf5sdn5erA*qGqhc}fpsNjyJkl=;>$6jARsgInK2u{C z9UYgYtz5s#l|^|@f1{aGOo&p2*v^ah3_V4bC;R%;L>A(8n56 zQzm~y$0z0GQT>V^)^tAhAXmI;3Lk8iSh-Kk5FRttApFQeA2223c3_GsI&G|yhwcqF z&U@G7Z>f9GqANitY+I$ERpVl*xPE~x5ym4BZ9I` zeK5BTLTFX{_)Frw>%cv^5qsn}SI3>N8ub&~wuGu+zu$z#@UViTt+kiP7NJMzy!n!G zKKu;%lT7ZsiF@tl)uR}TVXmXP&oKsy*wn=-NY)r}2BYh7YX9loA8dgRBPSM`X= z#7eRNFSSdED%q4Ozq%3sf+fLw3dN5Q@hd-xKY z(kp9=OS4lxOt1F{oj~g4sE6}yWHqt$~j`fWYXh3;6d28 zb+}aREA_66Vgt=Tkby^pVf8k&S@Whq1Zqhy4f+fIOPl0Z(hpkGUmo9|7XhlM&NAAY zDV;ZcLfh&)bI1Jx*7<8iT9cZWu~=lR{_ro@UQ%`3%>=^d9XtE_gWeO<&BvrimnoA? zAKn(ck#*baKKd4dYyzRg^JIIwFWIoY&^NH(7!>RK6h0{&$K#5=qd@+45fzU2Dq8mG zNvLq>1!dEkm&qqp!%gX?sjS`P*%wA*AM$PA&+r|@G4sXpbg`@~ny*q_Z|y2>v0PG^ znpH0WAv`}qh*>jFqh1UUtn{~V% zWXmm$QRH#G2OK%?>Kq%ecWmmC%#i zb2=7lj}x5`vBlhm@EZNO@pic_#B#*Z#(uM1J~;RVlf8Pr2d3@bJTgtXGoTgDZm>Gk zji?QApeewY`$W$JJRC z-_6R@dkguVHrT#S0sY@Py{r6XXg0;Zv_qsu1Ba<%7ymWBFVK=OJ*~=$N*q*sxkx^- z1yA09**v6a$5C5#>J;>(+P??dFGDh+r@XG|f$7aOEok@*suucDH%=jaEvTX%tzA+< zP3@(i53<9=s7&`cKF$MBsWZE6ysMEKY4Lfpu}73>$|jtvANUvAa=e=gX{=&Cfp5@18@QGIWTMoyC$i1Dm`wUbTMYV-q&ZpynlfNEC}K zaPlGVHYw1##35=tKzA4!bjMT3Wly!^BBVPhG;*5w08dvA=F{O$>vg$I(<MN(T)fl#|_tAqjX(KeZI=f zMRve*&%vf?dhetCYFNeeNM~Hv!*vXb6yT@&n#DTc^ok}tI(RhGf^o9F_kK;|9OJnO z;SxfK%*I28b{8a)O^`mR|Usi%uCj z{weP&@iFNkjLTnX-o&zLWS#y}>$*^0y@XDM@xAdd_FI}UDsTz{4orB!zZv(P z!?}oZ_L@BEu4_QZT+mBJ-*KSn+Z2j$DXD?!%9Vcs|4j9eFoK6shnR$dqCw3Q!Y>+{ zqKu!X{>oS@l2Qdz<&zKQI{|LfjEdTGT>kjsLr+3!wX-j2Iyq} zU`t2hN#F+n4-@j&BQ(ZgNDH+E?AZ!tFfmP z{Vh*3^3@CR#u%Rs^;1zi-Vk9aO^s(f1i?!P$Z(&G=uXEmmyCgjNuZSjo|aQ(%2FGg zx{55(`EP+6CN%civE~}{^hi)<3Rt%@nx8WEGC~8#@4MKN2|lf$awvW@MmsIOp$W$c z^njDSBbS6W=`*sB)XZh>TB-U>Pm94J)5zC*g1{936Y)&x!>2lbHkf&i%j?;ucTP~c z4^qt}3Y8ezffBSx`GoM>ulf8W>UcCF+oboVP@b_f(zVj_Foyrne$NK7;k}ov^Q#u= z`eDz9A^5w4zUwc}JxkZ{*a^`*y&17_aQuASX`Gs_lalh^u-sbt- zrG>*URTBF9`qIT{Ybr z5^lKmxXe(jZJGIev_B|#d32H6{a)6PXkXq6w6MA6$40WhUol>(z~J<=j?RKKlQ&#H z;?GJ&pRiT#8r#h`_u4>#8SB?#u`4UBgom|7 zztf0^G|9QjycuA8=sEx616Gxs9rmV1^5<(7Zcnr>n3Y>sQ5H}8lk`;GbB7|96+t+T zMW`h!2zDT?r^|+8OBMw7RZPY!m370q#W4n{;*Pxf2DekkyT!q*?vQq_C(Tllb)5G) zv63vS6o^+UijP)1$wIZg3jM?gd^O_(hITs1@*c?d66-gA84S{xgI0VJH($dc9%zxE zzSj}~!`HJ9r02t0C9AmaC`T7m(Iz(LL4DQ+Tx2#jhbnZPg^_M5ozgc??iTy9q#)OD+&XhM^gUA?kCQ(emAAF!T?IYI zF{J*%*s5#dwRX`<#jHpEk)wkF)R9qQvgB@1ry{mnb$A^s5*V7+8=ceUziz@G1$#_p z>OJV}8bHq9a^RXG z^r#~6aHW3GZ_fatzV>_t2jzgeqfU?XY)RA=!k!}b1DWPOUP4H5^RI`Yvs5`{H>~sM;pk{FTg9@(k zC36moep+(V2x0LMao$;5X@d9A+I_wQXzJZ|o!@^YSHK{S9x;wvv$Vo^3a=bx1xr#a z&^Hw98mnUbL-!+i3s!A7He6N7j%g+)VYsdBCC7{6WxuL9W|AlN#T=fJ)Ue4WP=zzg zTm2j8?jk0t?^gbVVm5(`pFc71tkyOC{#<1fHj>I#4~aWQEMHys0_Sy&AL|ci8HQx$ z1L#Y0EORq>Z+ikwlP&Bk4@&Q&*no;OgzME-rfZEv(Upn4P+to!fR4v9z&{nkE&7w1 zM2W+A{0jfQ=vS9p9a%ywI+n4rtQnQ(#Fm3wOPju-%ydErMf;B-D^P=m5Nck*2;nrs zixsH}%T;q#ZSI{^9AKvN(&f3vyDHGb>-t>rMZYcGm8eW{jbp=Cou>2YvRhsaB^RR? zIUeMxrEg@uccYJ(kjY4LWD=`Ji&tF&TceJPtaobO{ zZnsJ<*MPv;z6$5bib6(;*7$Bp@=V-)11fUyNt_`U2?j0Oq~(56G|#XYRjRo`HdSDD z7ujPEc+JVOF*Njz15v zk~@ph@`Q7uiX^O8N;&uOkx^nAsj^K!>x|ldo(L1HCo`j;`o?NA`mRfFLT*MO&GJH6 zknjzl$-m~KaTHeHQH)W(M-ig#p#T{An2~aDO0)P8?BPh+mN2mDaCjy$$(wim(YK$Hs0$Mz#Peh84N}n+LS|z9(h;A0x>0TsjDF1i)tQ7gOyTLY zh|C{&`_h-KQ+8!^l!k*0Db~vJ{^fF1QQ{~r+i=9oxP^-F5(Cc~Kg}r9lUP)~!3YTD ztpDA%j6Sk+rre--7ONt;8}FyfdqsR7Z2?fWv{jLF)_VzGHR^G<_1s`}kBw$7wBi=b z;H0Z#d^~@-@_zj?PT=9ILEJXpS=cJpVhm52k-Ag|eu>MVgvSJ`w2UN}bomB-R_Y!g zyUJw8jsVBFbD(oH>JsjBJkNfrS*9%g-IE)9Y(PcNj5 zMGP8JV3>rL(zoSr9vD&ZY&z>q~G{h16l^N_i_5o6~P#=^$4xs5! z7FZx2FURLnzaYAD<~o9uZHDGluOD=eW*cgo?+4gEzzvZYe4@tT@49&6-dT7-IYTc2 zFfo}Wub0ST*9dYbpV1+HsPZM`XVdwsN}P^WTNbM=a^f24QH6G(g>XpHFYq_wC1{UW2w$%v>t&p@%8GFv^#A4ZLNuG}$qPPE{7DHG@g6^ZZYFTgF<)fQ{Q7_g-!Zmse6uY` zu%<=ya`j7?NG32@STlTDWfC9I;3Xoz&(6_984}M)pWE&C#z{|xvNo(Ajw1-w=W3?Y zjno)S47@dx$?daI_q8~zU7g&D-maC`EHIJSqi#{RK>wm(t{x+syS^#GTeFNLuAWeb z`@b<~8lHOP!(-RUd|1|a*aEK!1717%q&wlgXLolW!AJXtW2>drfP^O+HtcTfy4rLE3#$s>kG};rDg6P4OxS%?_J>w__LIDS8fQ+tbYznos7Cf?kk{3pn6qM z&FHGxcco{3fZHKd&o=;Ih&`vM*!1d)D${M89-mkSr8$f|Cv)#(-Tb5VxA;IiTTVo} z?=9JA$#5omM`U!pS|~8MjC)YhEYiO+NcbkdRk{49$FL$Esk_zvwqHEOV`Nc`b#>!Z zqwTDlb*{NAy3vlgEM$@azqm}E&un8n0?ujWIaMS&T2D;;)xS>EvC*F5?AX{TeUAf! z8^>ZfaoHrT)oZL8;A-n@AcLvE+@Wn<#bW~o_^G&BSi9znKL?9wT z0z2*bZ`eoRZNHogcv$M_A~q8;>X=EKfff=NZJ#7fYH3B%W!Ix!{m`VMmdr#`uCdlP9H}sLvABVlZI2o&Ub;u@vQe z`34n<0V1TcIUYt!xnt&mW@(^)+V+B-FMqhBVnf-XQeBf!)^RP6let2`_u+=y24V8+ z=b@&?J#G4aijSh0ePb)7V8mI{_vIgz5VrXM3zNu=&`c-DMygAwh$G=?#kjq<{{kw%-YSSna4waV$xS`+D6vJuftf8wwun!u0C)E5La>$+VXTJ!2e+#5 zYn9WP6qElJTuaA&;3_Czc7Lb&eB`6c-r1A1JWaGIxFrfALDIm*3_sG;ESB3Ej~iZf z5=k58UFqH2JYpW5#cV7V6s)Qb^dtKes=sEh1ra-$qj_4p;nC$z3}SeMb@quj5~Oz#%xMiD(I7bd4B94aeP}^ zO)-!MXdH`-AuzF|Mwk>Ya-<;x2Wo2-U%ff~cji`IS5g$GXIKC}72bIs=e&;w}akWja7- z%x)_L<(zgb=>sK-pb47zLsXY&%gs=2_a>~n!oL2JNI(5(qM&2~_PoYI{&i=^?hacfiO)o3 zx}Z3)G@KuDm{Iu|BM@jyoh^;l*|IH7AZ7I3T!hBoTh)>8WiiHg8J23$dV;)H7G|mc zmk_sP+U&}nIIBF^={*p{D6l%*YVU_U|9$REYPM7K4|9Imi?_mols_q1m-mQe*Zfnz z1TJcQy*2vrwfW|jY?Z=^eADvfAY~r1NrZn*?d_W!0pZ>1CfP%nFd!o8-*o#k-~2lw zD8D4tlnwfx+Cj;Xv6{yfpom)k=;7twG{h{{_9euPBxp5ZGiF zf}_RGJmEYh&R~TXuBWEO>enx{ZJ!LZ-OYu* z=6GV14Vf7;H=sI_hudy@Q|D?}+4FHv$g*@6X?-?=YcQk>8?^iZ{UsCHM3?xZO1Hv; zC@!%dbo*AbujmT3EU$Yx|EqVST8@Qx@X@_1;{A@Y%4%5*OU%@Y^!nGCSnQ%7F#7j~BPsPl1QTuF|>tq6Gjb>)?jVA*b>|BLKvsq`Q8i}4eQ z6t=CubA3`BfU)?u=_iQFFok9(Dp~grBxo^C-A`TAyR)PY@h==;-2-S6uMa*SUn=S5 zA2i}z%?-6RLGeW35S=lsd>S&c9HQEcF!THj+!_Y=6V^>bTuppcLE8`blA@OF&prHw z9%&x)%S~Z#-dpqb^irByHmNPp5Mth3k*KL#4%(=za}Ki%yapl{Oq5KwmbcR}^23SX zK};^o-gDT7%S$s}lJ(2^-i`$;@ji#|lm%e>vDmJ0LbClmhI#N_MppvryDP zMaU}xpAiN0kA5uptIQ-cH{^sWg55}s4}~56P0<|W>GiU`@LWfsg$xMx8kYK1iA|}- z^f5;6m;{%W646HkH=7L$AYH_Q{lv$if=4bsw`C7LS}`B`kqy*BaWu*mGE;m3;!=;H zpY7~2W&bPXDzhe8%GCO0K0139N@zC}sZBk_`4BXgbw4!Vi0JGf@0G@A;5*9G2qLS% zCqH9(94ZnaJb~?WP_zuZtyQaP2ceX2Gq7h_&&psCz4SEz^@0pPgmb}ZrUqpuWfyb= zCed&?0BpR%SzNEvze=Bo;TKaoV#Gpsvm0B>C zK=TI`)QRd!{^|h&1dff*=3bHmtqeP{SDYn}16k|^&Duu(tbr%dT6@#Vw=PGlX}cjj zkwKjx7D+f)YjXF~5otdsACz`gvkyBEDf_?zr>rAt1$8vofL~(JB zs7}tkg&nLf{(&$gUQPPPM$%c|p{@%U_i#|L!;8#8Mf@n1-xCohn^JmY+W0Wa%d5#& z$tGYc&A5&Q)T@9cbduyFJ5ozP?`$K*ka9k&2*w{ESeru8-2vqvOYnc&vx-J=zdff3 z;X>9IsrRfp)pC~bbC2LzC@xV$-+)_E5&(+cTBYEwK?{M~w}d=8Mc*Ms1s(sBl{Jje zQ@o+Eb@D<9nvA4ER_0?j|Ia#hM&>rBP9U955rECdGg_;hC-@dZ+&t(u@%QRl|5v&2 z&oRXviBalz$S@tnElmI}w2NZPajWD}%`dxp89;ZIiM(5I~| z`_@>)0w5nyKqn+@i9F&hNVpz52#+BU$_$1q#hlZ{bhon(E^2}dwbdJq%LpYy7U=HU zhSs>O;;7+c0@>x)()eh`7iU5pSQI^9*m_k-Y=fJk;ud7cBwWQaTi~X?N%|jJrtz-H zR&Z-x^9B`-i;GA1P3cSVfU0E#=U*9Oc|2YhXMnBOvSI_g?^xG1C2PlfLjy^~GK{;w zProRdOpd18gnD${$q5X7V^?v%HN-b;(H_a(Dty(9t7puIFCZaEvAJlKh?8c^LQT?5 zS*^|30)5Q;v#TvL9hGgq8OtTGse3a-fDQS*O-RCq#22?tcai8F@R0#frD=Q)v`B9Z)CP+Y^y(8EeyWSGgN$Ki$7Kx96>p z0oUe}5v4Gw6M#jE;gbICA;bLT{Ho|iTx#xQ>goPL+AT#Rp`QpY5c3H6TL}@f)is;o zga@g$+kUDDpbbF7fWt9NQmsWd9ELm2OkTWf%!`cFsXN z4p*H%^p5h%<0LXfQ&mZOHKHpNB!#~*T2*ltlMo|a1+h3^5X%8D`W zN!l7UE8XwoNfI^d>p=Qw8PRa<%qU;8s7O4rmPr>#nX)s0!Vcv43HxM?voPW!@OWT0 z2gqce%Ro4-wyu`qawd_NA}%J^L?gJoO|6NVB&@Vq5|7k5OA+FhP=>W(E9U?~Q2=Fh z#{T6{!|Sbdf%0`dG6rBVyZRW*uhEZt6p$KRk01S}P~GygX^7-hX}&rC8;-zKGKPT7 z4;GPk;!k@yY1+Bw_O&NKKBFr+Z;pJ?!N zw9ekd5sJ$L(I&sDG}!VR#+~9G$yW0T;f!lnq$B?d~0)fU}B{?4+ewSlOy1`9Jsn?1EnCz0NsQcY7y5~l{|#z zn|o^liPP!%wuZ;*n&CiO%oszN8s7?1kfwGzPKEGcz8JWlEa%Ot6CN5_lm?P)@Szp?1-g)<{w8EQJq8(?-eKPRzAt$ zaQo0l?|fzi&t6-qAm(Pm>xa#KhM~yhuI>$f!bOq5<~eBx_X}Q~nFHc4{kd)`Rjc3j z-8EXo{#k}=h=2%RI|Ak*1Z8EBV(ZK94EkzRtyYhK zj?8JeH+oF|ZPZV<_R~>SU4TMc!;QS>t|UgyGu}kY2@?Y`oEYD}Ijvdb8m82nWfvFa z<;@OLW14WhhMK-a7a`%v6OlsC*v_|`FYPn$4>{qH!&^+z8ZdOiO6db-@Dg#vBg%i?TINY7+%Svtz*8YlL4bG~C+5BVSmhrR7m-6!bqjW93cMsPwV&6NtGID@&y0E-3YWsl5;?X;S zl1-77QVKus{jdy$bKy!7{OtGpyU;eA;qn`@tDIT)@n{;s78lQCsINi9d#>QHiseOp zhGLSn24?%mtJ zhq!+>=?y+;&B}Vt@-W|LwU*MJR#}kH_WKCxf6A+(_`BEXhBry=4TfWbP=;zB$br#9 zqu~~xtI;198)laQoMFr?Aa*07%rp$8Qw<@IovFe;>Dqw3N?3SA%RJ=Q$nY_y@`a-? zC*>dUa9T?h0AAtoJ0a}5iSOYr9|q-Uo4kF8mfH13!1K$F-J%Pl2?{0^g?%NgLh5aW zJIpf}y14&glwuwxlitURi}|p*$o(R)c$vjnFwg==jqzjvish8^3hpnkc_iIZ(h$Bp zDb0E9HRUW-XlOLtI{$t=G<0JzaV_jzsBx-);wT5&>1mF2&+*{WsJAi}FmWy2BlG-` z*%{Hd8BZ&HQMC34XC;OF(;#x;k3YFw1lK!ixkwGm2nt?r9d8@J^oyc1j{jrfq}oP_ zOySb>C{%%4`Svo8@!Rc z$4bCObskkInAWU)n-;57Rj|OF+UR4d8!-3w>3Efi;0pf!l*4!Wl32e#?^oRQda_)Efp|G!gBNQB<8~y zUbzdHlz|6F1!=B=i$_A>`wW>(k}V=NDqY@*?4-ML!U0NrYG&Rc1v+qg=pV<4iIiuJ%pBfd{ zG70lM0djHNJV=wH$m!ee{Uex{3^(mQGAlA@JePyN7+*Um_K8`Dh`wM~{v)laqUJ}T zLu?Fd1`Pb(Ikt!G|Lrjy6DCpHLRL?&sf`*#7=Urhp(zr9ZC#_lan|ii%FPhdu7&b z%<}{4EJJf|vYnX}SpmOc<%e^B##M5Zvf4o-jMYcG*$^N4OWVvGaUBgU&|Kj_SU{)Q zN1x+!bfosFpva9I{+1m8N9n^`AB(Gp>StOk%2oM#RY5{DS{U%0brRHxEB{Vg z07q)Colvt$KBxjsbq&1MLwcW(8a%5Of8_RD<+X3S{ZhGoR-0uVz`FbI&reTN67+Dw z@HuC#zJ2=Onb<1ASMsvA=bX4l(VPjhS6hkDRSdFtMRTtz`zK-npn8waV^9M@{e z$qr0RhHermtBUBSEHM0lG(4bgBjR$@zv8Cl*`*E5VDzmD6m zVJ%HPRC^Hd0v@U6yXK-yy3NT%$o6uzVbpo@HjV$Ua#pdFULVP zU5CUXRhA3uVtZtdPO>BAACdOyXlPpCq{}191L~Xta#?G6WUj-n{$9^cM(=QJTtBx_ zO!}aZ$f~Mno?4tcEv-P_ETR?(IR937EZ(SCxQsuq?yuOHos59iCpW7LGZ_tA4edbq z?fi;Zb($f12+C^ZS0Be-pFt>3;uz563&*{>fmnlq?9uriX>lxNFWU(o~mV zlEnhHS>tPYSSlxClN+>L!dHemTHQ4iAUAEw$)KOXh#s1l*ESexg?QCT%EH#^=)i8N zcK|)CKufBzyUnpxRd}^`Q$yywiA}BNonPKEREIn!q3+M*Nq5_=t%9qkEcfmuMOV?U zHz9wZHL}jhAzSV2c13*AJ#F;tKBdR9Cs|^?KI9Nq{84n>`_vt=jr?#dgK?;@O7q2X z?8Nw;Ok|<_F?nAp(l$Wfymp2r;)I43de*sW*)b1C8Q(oDGa=1`kpApe>v>|K73t zpQd4XX_$=qtfR42Sg*pJi^Civ8g<=R{dY<(tHb{W)jH@DJ3HCF(aJe8YOd<3New2z zG+hg%3?L`f_P)yB^FyUJcbI1-G_wQO*%unXIq*vu08JHaRaU+{DD9^izm+9^D_O#I zDr7*%ACjYOh7+vaF!2w`Yn~bw2Ys!f=#|xYl73^z!dk2tIg{AKu6|+RUV)hM>L)7h zU6o%)nCedsZO88T%~sbXP7iC{PbbGIdPdBYDc5`PMI+@db-mL77X*0h$PgLEl?~YW zLCDf%!wQ2mDEDcFJ2yOX!>O4ac?*bs>#4#CHU}O^fYp0Tc|m7xN_y}YTjcM1n+KWI z*iQe4RoRa!#-}YN0MD>yQ)=E^@Pa(V-Oy6A@p(wkoG#f9qGz`Sh10X-2t##HFmwE| zReA0g$07l(E?+Ce{f?lud_`-b@fynS%+t}wXLRNz^_Cktwhv6PbMMpfH3nwV# zfv3`b2Reuvgrr(0TVR&9_b={^A=)cD3WR`5X{WHkpiB629DwCrx8^F{BQkZxl!w7}n$!qk9OQLLO zk00eCpHqpt!ow&v(j8u-dxdGyDza?|KUgRA?}IXe#@9p^9i;AMFC(`NKL)M2nVHg? z>wIj@yJYH9An~j+{K2}m&8Imz@;S_$FWh!4~tGq!WkA;QRKY2BC{)1J1Wb@?InzY`Wn zJq+@DOhfI5FETZnb|)2HdbW2RyAgHchy|pEAJw4FA=If)w1Z3@E1NAj%|~1f-d_pm zWq?7ib^dpEi=a!0Rg#H+vLcsh>R%N3@v1^**klmvTbqycs;g@0B^s6=Ud6g-wN>p{ zQ29;F1|9Mt0d5yFq6HuoL&UTGb72cz%zeqkdo@q%3++3Ktn_y-R#i|)W)eLz#&taC1 z##qHOxd4*#MV9QD6a6AP85oiI)?%+bhG3FYi23%*L#tX3V?BUVh4KH?~XkDag6f zsg8P@a(}L?UR_#JW4~jkzLz?9!)O(f)aPX&{M-HJRlS?JoR<|z8C@6dDV+QS2}nI( zO`FMocCP>JoPi3li6B)V&@9_6&-||_R^6k49~1l8o7sd_#st-xtvkWCTi#Ew?An-K zZXN}(Xj{slPi~vYw;|S2!b*8R5`4Z#^QhJf%5Co4w=X0z(_I46s3{$QwL^7^bi>CK z0)xU;S=bMzmF?NhLE>a0MQEtJx4L@W2Q9hj_+k|b26I&sagDp=I}4mY>IPB&NUe|Y zDEZIc+56=%bbdf+`wqA%iK;2ulItmnzDtQsM14TWG=CTMnj^VMm5N%Dy~{fGB0&)| z?Ixda79$WzD<6=g)?mFI=L8`VsVYD*4K_Km9-ZVqj)qLf@py1+AHV&Uq9QBdWjL`O+2ms%n`gev7xp&4!=m z2!^AVS^dH>=g9Nxt&P?n6Nn(z?y&kjh{xy^=9S0T&ud-WbH!$S4RzXxU?y-yvjkst zpLJNykBgm@dQVlrQuAjxQ+gVjbj8aY)R2JpQoER zTQ*_uIDxVa7(+EV3}h(p%R4L@n%~qc)tuTFHR!=8)!%H&4>enfs*%f>Z!5k}EB_vy z0;5&p4NkKzk1h23;alW345cfm8b;ln93JXl6%V66ACEAhoTQC0_64*Hg`3*%-uASA zAEiRp1x!@GhrAI1sjSL6ANc@bhyp+zBi>u*b-TDK{$Oph{la$V@-=QI)7WoS9m%m@ zi}Lt?xBVX8hzq9t)cnP5;v#)IkG#Rl2J{2pSx%nx{W+tfw&~*Qj5-BE=B>3vXMj%o zQgo|#jC6f{&rOGVs@tZh;cvZkUSRt0RnRnzVB2`i417L@>W0(j!gGiDy+GdBo!Rm9 z#MoLSp^nvceOScG?AlrR`~GEm&tmConN^MjIglc~KWVYyn^Sf1JQ;M`?q} zgBSl0aeK>&8Xkshl@6nBZue;jgaS z1Ci>-x+Hl(Duz`qN%-q4D{7%f?@wX==&STe5b@Zk3B>>EC-S*?>A#)z9cpviX98@0 zVyEdTjw}wnYS3BvU9LzT+whHhxrxxkY3PJH)#9vC%MsCBu>#%wulz07toxwgF`yC{ zAbCkJ&i?+DndMff8TvtDmbqfjw&9Q?tAh@7yZ+V_{$5E~S);^CFEwE0t)f0FeyP%M zfoyr&GM2owbR$nn$)qTiFpEers-!7*e4v0mDr z5)!pBb#@j>@CkTMwO4&_o}E2O>kA<@5~_YYF5aO0=G3|^JYu-xK&Bp2Eg$78R-cbp}| z`_*gx_Q6isekVh{R4qUPxI_-X6)}bI*TwV8~0*GKKU814)OX1C4|kw z2R8K+vw(BK$liO|gMb<<`$PE(~bau<}{ix`BnaIl!6>mV5DX%}^n-l3Bo zX<%{7^EK0Yp?m)r%=_tx*NPe>%>yq(s;V&aDYb({Z^q+*dl7o71r(LS(pY(HLfa~< z%}bzt<(SpNE#T2uUjeycVmX4|fR-X=w$2iB-`?bUz4^<#J0O9EYM6-h0QmO55NG$t z7FMMkIk5k$+&EgPC!h>*e8uR_j-|CEbBNY8OKxo>!Ni2G^Ys^@jx$%l(X-Jf-M-5< zA2*LICn_tXyuuj+rN?xB-UK5+=&XPeXabB?M7uW}O9j)DkyjXL4v5GhE+FQhJv8cVm)9rEPmjLtjsng# zYHL@&lp)M#uhOd>+D;aFLH2O^6M>g3_5VRFZ~$0>W6{q2uMfVaUSEJ|5rUA*Nw^eQ zIgagpz#RW``rv8P65AKJp9ldqpZI{Cz(3R%sN9lz0(SLRDU7aqNIlH!*8qbQqAXAX zU=W98uAG(F9fm#QAQ*CUppV*wZSyDQ7E*Mj8NH+jJX z6v8FJ9rFtUNBW-Gy9SnC3zInlc8s)251$+GP3w%EezY3687C3Y0S5j;LAxg-pV6Ev z+v-2<#?N3Gf9<~sejLt~&`^RS~e8RI{sq~xPzWM!}Y695QT)rFq zt7=R&;dIQ6P`W1pT)hqiPQMDhSq#s1L%V@Af)IDeP1ZeUl>GX$?w7gaXze9~*7?hm z5mr_BOZ6wwcWE2npR2IG{jN-mwe(JDZn#<|ZB`bs_zeD2n}%ODW8g(d)Iun*ox9XX z-r^V6Wz1&($bq8B6*g|s=P*|D(Y;GJscobx1X|A;Ii%Q_A#(F_Q4QIe`11b6N9oNu zhm*qwOBR66HoTIykhUE0Q~LJ1%}DqTZIXl$cAOUNFok41=1rMr>#*U>=%F6qD{KG=N?tWl9DVGQ{qjdU=)}c#@t5PWMUZuSw7q#5yM5`? z=Qzo?KW^1DYM-MI%FzQ7e$1*0dEVYPR_TcW11?8FKL4=Rd@1NPb(K5~`)icak43WdJRj)-~roh#V}8cA<2NIGCTo>7e=Q5_>0?UU2nesEpw2 zGUQY)IhM_zo}%8Zkc)gj;WK??&A*xFI&!wKRMuL0^FP&+KYM+%Qx+5lB<^1{`QIvR zt%pfGy&aQa9nQVGXH3bxLv0-khMT6xF54cTL|jVvrH^? zfELa;#j+594-wZQosRG!mKDQ@g3(RZVbU-V;vUqL_?>R8&HS}S*KS(MAGI6+&qR> z2p4vDIz|&iy9ePB<6rXX>KNPi&X*{d>Y7;szS^LHex@^GXq#9%{B8~C`-B!y*WxLU z2QNWT$thk*`4_}bg${!Q+$7A|e`cdweapboqHigXvfOF~pO->*a<2d61d+f&u;y=8 z&pO#uf0*M$e9%o~?dMr2==M#X4WC_7vHnHF>Z)k|y|^@hzKwxG^wsFI3%^!y%x*5y z`O<0p8YSwt$AIGVJ6A&8yM*NyA*y1TjAu{Z7G#9MJm?oEx_*h|8Be`;s^Tj3!K$IQ>j zB*a;^dWlb~^|U0Qe6Q~p;ek(HYYx$dBD(15`>ZSukPj!Yq+hQBC^)t3dfH$a#bPqt;r-;%K{ImmD41=gPY4h3hEVYH-kYmq&-M#!!tuKcL6r9u($j-5 z?d~_)X@_6 zP-t9u&epb&6vx3a%*uVm6305cuAx;Oju-bdSl8^~>=iukwC7 zGIeDnTEJ?G!Y8(#LquMUcZ!4V-pR%mbeLaT=T|(mXcAAzjrSD0Ug);^uGs9W_G8^t zYa(?ifJH#Z?AAl`vC3WYYDjNL;*dYPOd{jn#!uY4lw@=_*)j+)e-icbNcxp#xjG9kGWB&PZ)4@gPhy(j|nKx!wdp!)dxTBC0qua=;}0nXlS zqD7+Wa=#=lAOka8^A{9C4J7(b$#)Hxsy!St~AYuAn(t1sU zY$tfsr+&TZk^A)pK8(inj;d3g*MA(1a0#2W(dGN4(X@@s%vBRxpD$}94ADf3Xa3JI9)=3z2ef! zmBsc4hNaMB^V>>GF%D_$D{hxJx78Z_PhCAI@pex9>dF02*Xf_D;W`QLcG_m!Ggvh$k6Vt0mrk zH^zo)^r^UxnK*JP=F)99R!?r4c{+L0PzY#>_r2#LPmF_4l&1to*4U&J_lJ}3cIw-9 zafq^$3$Jr;*`HNDUcabSw(R%qGSr?Sup%21?DeK%k|YYm4Lk|v6#;;jgmE~L4_g4u zBeVK9`BXswJuKhrmz^RDyajX*#8fnfJ;znV>W~&H!Ienwj?kS}ZK84=;r`MVHM*0F zvj;)-kajs0;nz!9pP2@z5@=X%gYtNWPNPrWz;$;O5MOi|jP6pC?Oho*UZJ@ZSrU5% z98rg6RaO!)_keKhzR4P*QKwome6XJ^W5+1_6|#{AH6&xhmMGHOC2Ejv4cB_av`N@Q zAD87G?Zy}L{4NXoZ_H6VQ!+mB4@onOAv0yfN*OPcB<>E)d6=J9`|*gSxN98wzZ}m7 z1qzaNRY#3qZJ>9x_p@!6RezJWh)Cer>XFuNJ$`c#DYABA8 z{X`}qNrTu>d<6YY!T*WGfV{B&xVcx*L@iMJ2xA-Tkc*Io8R}gW{r32IZ%QB^En!qc zAqJe)ChRVA+a7-dWHdh`Q0WZ_>%A&b9n0NKb*bBO*B*hCaTKr+Mg}S5kktJwTW}rA2pE82Ta*lQ`73 zmvV(`Ave`2L7kPd!L~)OGbPXcJFpsNpmYQAnez#a$&LX7tCzeP z>NUik5nbwS#eOo*fK-WCO?gtM3+?)^7Io|(2ag4CDm|GG8Nlr`*VlKYo`lUJd6h*A zT51z}Z&)1bgiqW=@70%#MwLC~9HZ=}&E$s}3I|T9$I1H^f6SfTI1BSEi20?V`rr^^ zW9=F8ub&y)wBiwT(fU`jbMs z1;?zqUeW}uTg)nuh;fHG%`68QXyv=09S{RuxJPtDel+xoC1b0WZIFiIVG&EHrne-Z zLt{ug)}9oqKU(LmHwYrnR4t%ozu6YwOs;>Q?-xa!?}`qWl%0ri^xIS`FSVwZQ0?E| z`zMRW#5>^<{2c!yOA^bNd~Rf&l^pj=Yfa3m&%>Ny6Btj@-(0D#YVzcBYAHlIIZ5k& zNv)<4!tbSwX26c}D|;Mc8f1kj?1hP#f%QIGc|!9;lvYCR-B-_gR|=bRc_;U8ldF$Q zXpUKlz2Zd%sfd3nNuG(j_+ms1Te zNbah73=`bIf(5Y=TZz(^*tfITPz58{1rn0a=~Lz^bkcBzknu5R;1u zvbQxz{WYe0Z!5BMPDtxew7yFCmf`P{9EN01$xKQ~RcgCUG4{ZV8qI^ukX#Dk@7>BS zZsobz*b=s1gS8CWpeCGFcdi3sDFn!-H#lgkP=(FYI&`BDa!epe@H z5K({?l}jcLln#UdTthJId)&IeR-js{9jRiZ8X%R24ah>5m?fM2%*W8jqv>%L?7jHV znqC4C_85kR8fxDu4R3^Hh2*;)-JS5&mv6&yBcHO!NiI@-38H90iKlQ^+im9D4nKx6 zCR-+3vgC6Or$UXNB+E)R6-PLmE`9rP}5^ zrb$_-kkbq(^Q~TUqWBw|JUW=JB&TGeubC(f?IC^#BNwTv2*l12d%R7e1ub2}(&1ED zpOhc1J^2Plq3SQGkJ?^NFQcf0ACqcoMuvP|FSz=gAFjxrmoWE?P5Xn)M@_DOG{KIN zg>nj0IzJ0u(-!n&bW^;1R{oguS-9MHlg~xuxQ49_r;yc{-P%!M+dm@#7pGaS2c4(4 zemP_HmwT+X(C?jF%_ZT-C4>!rXO9Y@&7T5)4%-rT3Tr*Ln3TP{nBBU;4|8lAN}`;_XEq9pc_|(yAfTpN0R`^GI0PvEf8=WMkxm~jjQ4Hlws=W%8 zBK9r7k@~gQ#-x;5gpFH_0)Dsc%>ejrAmdSYI}jGs&_|-*;^KY0=q3RmlScf?9>#vz zyp!c}sCSNv7O4Hs%N4`}DJ^=n>xKr=x`nLIy=Q*~l-dYjo}@MVk8V|9!K!dids66JSR^Y#H9Tdh8)ORzEtPL|ng5!U$q?cfh#OUE<=$+lzazs0;R##ed=>w(tyHQ^MIOKQ`@ z#CrzbwNSm>Or#V1`?nu^kgqjI6WPe_!6mv+CdD3Pf|WfJCy3RBQ@1uXBs~v5v+>94lpfffesZ{Q=HYj~gK`OOnXCTrR_hCX4lnF;y4;?YojJ=;>E=x?>N+>0<&&-^&X>t`a?E!Ty|#r(6X26k92WTs z;H7Mi+^a$iSh*(BEIi&{4(%pW(0@|t@g5U%_}z0q;`_K25dYD_sL;pnU2nZ`t9G_JJlt}=dNc084!UL<^@PXY9vcz-D}TsC2PYYNu$AMc#N< zoPyb4e4;}6k|De3RZxTVY!YpEpO*#?LAYN6w~f4hs7Wc66*G+JIk)8;n!3YPx$ZJi z<4@;&x27PhYfiT8UTNJA1qa2PvaSC9hh%5Hon40LyreSmQ(MkqB+CW0+KOUvOu0TjhHaTDuXH>Jb%Gc{Ln2Zi00 zava{T1C*?NoI&dyLN1K4AOYAQ_FL+=9ceQx4*W}3}p!wY|6-osfV-~EH{SKj>tFOb|L)Ic~Y zVnXTdz6Ijcbh|jgw>f#izWPHUm)eqAOJ4y>t)s9dhT^d3OhR$;RR62;BDDC>-LLrY zS$9(I9qcUo(67|@l85ZsX4vfOeg7Dw{(Oha+rCYBcM?GDxhEScx|ch2KD_=>je4#_ z43VtCJYG2$=q$_ja!}JhF^kwy9kAbZGpLaC8t6E1ugTOsr~C4RHP>Jz=v%${>&xOM zRSoUHX;U%@n2A2!mAQw5L;pF;Uwvjctu?*i;kp93WcVrrkr-Y|zGm!a+VP?ogW>$z zs3#3fO%lfo1Q>~+RBL)Cc_T&mpyIMZ{8}Tz_gsimwb})M7q^p{!=9O+O(*^+aBYiq zN&mJaO=n+fhDP4kqK?j*lt}cV^GN=Xig9!a%1y->vTF9S*!yc>aruv zo`RDJoztp*79saD=$?m>DFqfiVSPtjTrUAzK>E%SiK50$L`Vl%#$euj*s+)$)I(p? z=;du-ClmFT9`QL0`jy7F?DW%&*=3?Or|LMQVwWeB#m8YHuXaaH;cQ(mJs0ek&#ss& zlN`FNg$)CaUm->`96zQRyMfw#ox3#^*G;!Htb=1_rUr$EwbMi4&W6STr~+7IK1z(>!^3j|N6`#p|}E zAL?_?KM>?D^n}{UwxfYgO8wG79#? znprIqx;$&J)#Gjd+aZGKU{mkO*GDj5cWK>>BU9rsvudyBVb3z&W~rlTyWP@|S+!-5 z&83g*JoG=rBk$hRyzjL~-Cw><)M||1r=|SY!%)uGt=kSC^dl0Q@c8>OV8Y@Xdob0c zJ!m*(@vF?21$gY71n&FH|t%t z!i-PBYYc94E@ncl;Oz~fRHqUj(k9k-n zCK2S@DS=Y+NgaRKH&cO~7HzQA9M5q8KeB;_vbn2y_F}b%U_$Jqr-yPasvWce!;YbP znm;*A#GbR4lPfQG=&k&Ziq2$xXuF$1{S2}-D?WUV<-9QC#qImDe~eQabnqHqK(9`2 z!Fj835}l^bLU=bBj=)+q&H=FG^GK#q{@L$}m#v2s);0b!Dk7C!0hR45V({BVYkv!;wbt*eVdPGubx=V!|ZH8a|1uqOK6;i2e0V3fFJz-55MwQkw{_A%b`E)sq`1%Z7__LNs*Gmxa#`G3 zsaHo$2-@SSknX$N-#t@mKkRC!T&b|#H<|#Dv`l_78wz$zn~BsyO(EdDH8YF;Y5xdYuenZj9pl zlg{}i9+51U^fS7#!pFVQWR_)uUAIO1PSgaJNsr2XPc~jv8+;uJEunI?|E!LQ&Anpk zG)NR@Bo<2vGky{G`4Yp}OufOr(M!m0LXM-) zM?OoOr;wZ@4|WFJZ{i6}Z!5g_G9nuHHBWd}c~^?XW}sO8#|QbV39cN9`|`B@7ed4G z&BaU5)bAGm9&{qmS-~DQNztn^m+GQ&y|1QPNim}?0T=u0`7p00q#ZQYcYW8I>+djxC^iuAD5OaKDUm0x*R|1zy%y*k*l+Qj&&}(#b z$oocZoSYPcb7(jUIl}b5{_#Eu%k6?-r5U?`+K|olySo9IRT&pP>o?YMTb0dU2QN35 zHiB$R{EeHXeD9iqZbJw} zejt6lBkrPgP`h`s=hIll9X|FlcW2|k3AM$(QTJ=SIULgcO4_V5rgnSo=AL*X!M}b9 z{@A(WX?5Uzu!8#~*W1B}%1Ey`xAHMLj&=~xwc+!w!X>NSJ9l$0N|)&+s0+GknpWe{ zTjw{h2V0+S2HKf2gtf@U?+X-gSh`?n(>xC5Nf3j;x!eeoxBhl+ha5%H$_Zv$%2Q(V z`a2!8h}Zh6~k7(oNIm2Bx=qXAv!B67whF z9-QuWG1wEBBws|HH14ad5Y7DJ#ZZrHt*3d?z-;a4zf*^Sm{hvY>p^ozti9xXnn4Q8W{(`1+#HE1CzkQz@{(BBbDGzUzM z?Hl}>+z!!QLdFhrGPd12nn>_J415 zdhb}Z&h+lm6&`o?KIhc*IOMILsRf(p=!r>FZfx%@sS^R#mYpcjP8}YQro|t^)<;0L z3aGHWCh%SbD#2GdKpWjz0B`Y!nq|W+VEF8$M4R0PA9yD-Lvw?OU_0w!G%G0*70e06 z#9^sVgK60c$gn3a&U}p|Z#UneMy%3Yg3xGJi^c>z2dI7RJUvv(A+xh5DiX&J{TpJ~ z80j)Ap21zIfHtwYxVGdvwr`fdJhLqkyj26f-(9w;dN7_DE+1ugU$7L552j|6LRv2p zPG5AQ?7=qYj^W5%p)+@&0Dcv5cPYi_d+>_de{$Ya{a|ryWozP>i3IUBnSa}T(^0&B ztI@64ryFFmwWL8_uMZmzzF57RLH!QhF0GRbR`!a^Fvs#O2AA|yQiS+lUZ~{GIX^LW zkbEu?xlg=h8Bw?+!%&*6jMaOBr`JjlvY^^2^IYkL^BIvGDVz*?@ACEscS!yRpSq~{ zj}4$9{i%Ow@DED@_DwbzEg%eS{GadMF#6Bq^rM@<{%yX0!Pl5)a231x_nHN@LgGpf zQg-;|i3jPEM~e&!6qT_L(|VpH{L4_=I#8Zj2J`P_tG;=pN&_QLBong6j%Pc%6W+Lu_gKc?M zrfhzcC(Xe@>tpWaCk_@@Jl&2%85NGR=7G=e7av!2%SKqG6U!-l8O$3m;rJFJc=U62 zg;synH`uh(KNT;_?R(vMid_g3vLRo3%pl3F!MOT5EQ<`M{YLtPXn8l7#T9uD;cPDB z6ubQHb2ur$PWO5D9sLFS(C1}(h=90~sMlEM?qF4@8EfBWU;eOMyDVaBuyTQ?@rLYN zC7|`z-T8pfVK0SVr*+4O|x4J60_Ksc`lqS za+sxD3O<}UgUqgI$$PfBp5DZjWx=ljH(7jj*UipBz<=g;OYmQ=uhL@2`hz(Sf%(`g zZfGRF__qj+T#dCp%gux>GBnx}^S*xI)wye!*48hka?4!HeaTvh@$RtWwC#%a^R*Wk zc=fW%RgC2x74Zx&&cA^}P`4063A_69Jxd9Z{l;0N<@KCYjPr%8H864uEF6pj`$=`h znTPsvKKu}4>wspi(>*6_!R7id!_s4`)WBtkiPyZmyXkXQ%*n!RS5szV$}Tg1e?Cer zi~lA!xD*A*yW}ioBE=`j*Hn$~=2kcoITVM{eVir~nBCc!I)@$?MO4EtHmA*{Zq1(% zuXSEGHFs83NbD2#K0^N8gj{Dr6f*7V6fF1XQ65f8xA|hG9cGIyEXFQ>My`N@+1D_j zW8TP40z~uc5Rfw+;)x|cGKaQG8ZFHlgZ-ONqT3=Y#uBg=M31XC-{xkrqF14sRK_|{ zE{D=@@d=IE>#hG>-b&nzR)%n>9A;OXu7$*GG&mS#%%heX?RI(H*w`@_8U(LBQUkOp z(_O-{eJ_ocz2GD%RhYj8+den{3~YIph?Zz?z-xji6*73afk_{ypybntk9dC|^((&G zFoFStDee?n9`FznNfp90rEmr(y``x}w(_Lbd?XEM+An7U< z>|;~tbl&LicqZQEplvFbLf+(7dxoh-zp?1LQdCj5H}4>mC6;Rc=MU3Z{BaAG!L17mNgRNZc_8Ug4*Izwq91Ts;YFsQr1Z z7BS@U>GRSv2F$T@Jl=iKFzvBIi*0plNefjM=J*cb;_JP}Ef6LE(A5tx5}S(0(RlQZ zw7dUR!mDu;2|=&eo|!>&^V1#ujfjajXoH-mlCzgPO1<3m}DkY#ey;${^bPf!EC8)h& z3CryMm^^qGjecskTbqe5DJuPrC0B2O5lzvpyd24B@L!p%7@E3BLJbRkP~OV5Q|HBk ztz{GGqi(Gg}aMCnj({3{*?iNNE; zWvn;CJe&9>xBU=&F12IhQqj+{hBs5l4_)z6flx3|yJ&rOcC6AC*1c&Tmc4|H3K=|dVtjkKrTWL^rKnG8f{J& z299O&(`)%GbrP4_X0mX_`cT)rjs*NV^3UNM?>a>FC5hrSby0?ejy@?J^hTrCv6Dnc65DZ0!e!tnW9M(JeJSIw48UI`T^0~G) zMvNY+G0%_nZFbkQE%i7eZZYDC3u}pIUS}U0(3jljrRMY|(tVz_!u6G#zKx&r(^%p} z<5(}gk6#c@-6}krKTG?ZUTnwY;D14MQxn5=6#;chmL7T9 zStGjibY7Wz;aT$;elpFAf^@3Qp)hgZ!$5g)Lx{oUa&@A3j2kxFzC7hGw|5#2{xQ1z zW!6e(*9mlH@)COJ%d=M3Ha8UZYl)XH&3*q$Vf`UHg|(6yozJAh45KwSG3zEcUE#4= zQTu2Y-E5NV^DIZ0gZLE$uXQ0je_1$;(}G5YRBfFi7FtsNP_PDyv-3nsQ%bsh_Xw2h z>YJl8ZE!Z9sE~l^4T{}PUe}uz1{GZ{-HxT?g4n$fb3BdbHW86oqG~s4pT@xW>xV=X ztz4~5dJGx_)I*<7_lrq~0IM=KiGQxrCZS3e3gOWH12=U!RiJe&GVZK%MupPxy?z(- zlt-K%vlxH`L4a#o8SI;T^$^I+KLG)=K(;R!xjT9WXK+xMHLxB-rsKfE7mJXj@e+d{ zntF&5ElaaKTuxsR*)7ERF>-Hj6((z8;ms5_ndL9C(b&3_QLqtzYBW7nos3QA?gB`O zrQ-2Oz2--F1S5PwjHQld?oXBO=0EQe#d*nijzy9VdNi?qwUYqig4>4vGez*-UgFn^1M729){iEV^4w7q1S>a5Z~ z>5XoDp)6$jT7nE}rbS|(CZxOHV-oIx;hlBc|2UbbK0P8=AR^jMe?T&ck831glX7)i zo7O)u*e+=(l~#@UB5X; zHvJNVxGyiUk8ANMlODkg^TsAmVZ%ek_XzNiV>Q0F!!zi!NAdIVgFbNLHiD--2lF*( zJRc^ezeN`5(_aQYJNhiT<{M;5ZEF1ZP;O9wPS#DAmJrStTg5#{dQWWqsemKRGMsWJ z$n)n270ET@VLZwoU+eeN1i6f%-vm$%ScC;#lCq{zVs6>Kuj4S>T3rsTDJ(_$;Ph zo}nWXG@tX5T^Jm=E&jem2t?CNoI=4=_e}egodq?fyJ~I|Gu-a7?Ss=7#78i6t19rr{zJCj?f35&#ap)p@_(h_aIypbDd zioJkKcr&V#2@?W7J^V zee%0s|LeNWr#u_q?fiZ|$8o%mzGP--byLr@nUy9p_2a$>whKb(4ui@W+P)sti)mWr zm=37>l7*G_=h!x^=7ovGEuPv5&br=U!w)Q5LEHuGPR)>f)f>KB6KPyLX*|W0SxkKk zed}_^8%bBNcLwIt?aec*aPlxl&OPMiTJ~Q?PTAhR6{lcX$1L9&HU*E41_bf`V%^UC z+FC}^#nr)d-Hf|-4Hy>f95c9D-*^XRiQW1Mo6*FFx?T$^W3k8XI=?i}JoSx5I|8~I zEj|~!LbM%qj(&`eA+OT&=8OE&P8C7LGmQZFJg;PJLiY4}??%HNmG& z;Q7=d%iw*j;<{f!UWZER3?As#-x^MEz~wGby3^Ct(kP?nyH-87p@ zbz0&>enzf5_TXciVEAJfFtx^9cQaFf3p!J@FDyB=|4B+c*L<(F9Qh-PPC>EbEzy@` zTs{7Wx^?hT0!DA<2);UV=K@!g(dARKRkyZ{4FN$c-FivljBdo?ept)6fh$qijh+OY%2}TFm52GR z0HEQ-i8SYQDPn=r1*RHHpP*rmoM7bj+WG;~w#+tQOkH~{klYuGdhxOUxER*OUvJK; zy%qi_w5rnb60!~o7lUJ3K!IA@xt+4uGk8<^N`9R?u)X)4iDuF*ZCo(nlH1{MEn};$ zHIfa;X}rsO-e$J1wSYgZ_QAxC&RmRUmcyIWob?>0Pmbm9jiUcC)Kh=SbtU}mT2Qax zGBO*V240jVdnd_IL9<2Ne`;k)*^;v>$TZPyRywJSBpV zoP=6CX_M~bgAerYSc$hpxJ7Lme)OFhMQ$tO!iXt9sXljQ5DE~2MJ4N#1tb{K6XxU4 zJW>D_cC%N-agR*5ZFeS<+C6{^2SV&}-yUB5l`F((Kqdg|QOOp_nr%m-b2 zXki#Ssb(B*kd~zSTE2Zo_@&KL>fZQARnFxN0Q#r0)>@Seq%=6np7w@bb};cw9CT-~ z(M`7ZE#yl~yLXv7cLlw;aUcnF$)&>mO_F#h1nfh!$x)#sWNxD~g&Qcvhph3pTxOr` zz3;*opWfr38;4%(nDJ<>{nc(;9F}YmNeyPA8c;HP3WvVo3qP04iGIV5ag#H_^0+T` zE#&vDR6jby=m~=7S8VU{$+-yG55T!0-!IrBV@keI*|YN42Y)p9naDelQX3!MZ1p&g zP#NtgJnmIZxK<&xXhLzvi}dM2VVT7*b%r44LecjU!b&QR6Iu2qU;RvB<>(BLT$K~s z9rb8vsbyiYg*m_YJ^wJ6`6UK7RzZ}kCnOrJ3(`iF^p|3_e zy3OGCXzrhO3I;NkuJ>DL@i4Nh+sN4#WiB5=m~-foAt(%jId-#u@5^h}7U|e4MbU?xff0=~7 zT+_{YR<;uGs+q+wH^$_y-iq8Mi}KAsl@t(znrd(R!fFXQNY6P3->_S2>sUvC!{6IM zE(!yjD|JU%(_?cjNfCsM^?wLsw7u!;&%(cMhK{_-pUwkyyFJiwgi=j!(*+=eVZTK~ z-`4uxixjF)3)Ex0Zt#%q%{X^(rG`#ECm{=xr`+3@Fs zZEKQ+4i2MyhOUtJmGg@(H>X&mdf4oF90uaZm-u}J%zmn3<9+QOlJ-5Z`IHwatYfHX z@+aoO1E6)tdu9RXP&FZq->XaP)aUe9>;Rl973Ym2*37*G196?NBfF z@kVT+Mb2;&jm3}I8gY&0;+1D|!YuR(MIy<¨pLOB~_W(Tu}6pjz;i*CyuLAy8B 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ⅆ<)=3xsc<&(tsUvQSTSSNYaw=`kz})E% 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 literal 0 HcmV?d00001 diff --git a/packages/twenty-website/public/images/releases/0.2.3_webhooks.png b/packages/twenty-website/public/images/releases/0.2.3_webhooks.png new file mode 100644 index 0000000000000000000000000000000000000000..25c214fdeacb5de31505b16bf9bedaf077d931a2 GIT binary patch literal 400124 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

(xwz}WW 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

    $Bki244Dms%eQn!Mns+%@u5jtd}zTyvJ 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 literal 0 HcmV?d00001 diff --git a/packages/twenty-website/public/images/releases/0.3.1_contributors.png b/packages/twenty-website/public/images/releases/0.3.1_contributors.png new file mode 100644 index 0000000000000000000000000000000000000000..e50da30b4f419c5e55f487e1b98c19bf596eb880 GIT binary patch literal 288277 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

    1^}Ru)Qnx*X!)qXJ4=yrA zq-D$^MTm5geDOBZ(XlPS2}JRa$ebfSE6Omo#nZ8Ka2shb*ayCVIW!vd`kbaldIEFQ z=|mX~m)e+J9{m#oY{ChQT!1zH&)D!o{YA3N@QWg4?L*{^UV0i7ABCLp|E14~9zxBZ z8?w2ND4rKcMXTlD@ZLtI1DSR|O-0#)+?G93%_%?oPYiYk7&)tqe?1HV5IXSgFzaVy zSw7z(wE|m|6oTU+3r=I%-1k99d;s3}Fv^U#$SC!bGG?99swmbjadTmq!uX!lO^bCL z1989Snw!MJE5S5V-p^tG?;6Ie0LKVN#TFkt$R`W+^a&a<2r)0~su2nYg}1uBub?qO zKNtUJXSkD%8M@d;XCY%euLncw#4!?wPhK(VBM~PJfO8V=cC)?PBB#e(Lw_HXiH`ai zGvUn-3botDo8nx)cbRzdCqQtV&KU>xMt;1^{%q<)Tl&Ez@G(MwTP{}UZC2r999BfJ zR)HWPL;hvrZ^ffQMO(9+_lA~MwN#lz=sp@6@xqJJlDvJXuC;aUvfV$Y6Y-B=9bly> zOhj>26Bt<1PRf6wz^MFbIPdLtF=t;)NyN&`lC;_$-D~+MXH)h|EZ+!svvs+LpEmBB z0qGv>tb8gDf?)Kty+5@1gI>}+mY+XG+@_GBD*PU1CXFWL2BBdv0k`9h^U;L3(aEaD zB;pb?kN)GF<}mb07aF#5Dw8G2Kj9r|z}N1q7;vu;5Mm~ojiEt@QOdL<41#k`PFwb} zx@FXZ&ZPkb*oGwuUzK(8$ji2gjPH4nMetM_5@p}ypV9uIqSWS0z)Gy}^V5g1Q)Nb! zX5?6odPKS>`;f@di;vp<51H<*Bt;E%@_^PP!S^7Wk<@JwBW0SOFvCn2kdr9A$F%WZsX5K{c8TpZ zF6Y|@!NtDSM_i?Q*20FdLMKh%_b;m>LEA>wH5>{_ZiUK)!%S&q3RDxcOu*2rACI~X zdU;>^VVPCGraL3Tgx-G77i>(Jn*2Jivt}lJjq@_UscW7&lbjs6djnW5!a2v{xFS=p z0E#|R!h(6&YPAlb_89)$E8yaUI$QO#0GkZL9)+oCGm7w!{A_&!_05}9(sZ5lEVznLytlYEfRdI;9D8`feD2cr?K_h2!6vbOHZE|!A^ zee>P@;uawpj=oLC2G8M5e!onKQH|#}D89kmWP z2A`ki{~_M%*aGWHL+?ePuS)dPj|YxSZ(3O`zB7QTiVegqq{6sFOdhmCI&tl(pn@yN zn7|CIyI+67)9g)tLTLD?7l5#SlsjC@>Hi+TG@P_%jLlX_y9irBCS~_NPeLo;O`(}~ zn5BPlFGkM5(>i?pu(|u5$tdK^^?_i>w=^`m)nv45DR&O7%>nZvyu|B!lfi21*GfH* zwQJU5)tN@t-xkjl%?1lQtX45h;N@E4PSnX_sZ$T+BxrDlSW{N5Lgw9PRlf=MvGF

    _e>tXUG(P&Anqh(ZQAHF}iHqRcN*S^(?BZV;0 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

      2meYtWfKvC<9{|D`X2_ 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

      113)tgT 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,Ju>9Yh8E&>uy@Ydaf54s=c8xVR3& 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 literal 0 HcmV?d00001 diff --git a/packages/twenty-website/public/images/releases/0.3.3_emails.png b/packages/twenty-website/public/images/releases/0.3.3_emails.png new file mode 100644 index 0000000000000000000000000000000000000000..2b7b72f704a7ec212df2bbb510d1c747d144d301 GIT binary patch literal 288970 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Ȋcd9{p1KYmC#5Wv|s%aD3y6Z#i}X&-Wsfy=E3^ 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

      HM* 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 z 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 literal 0 HcmV?d00001 diff --git a/packages/twenty-website/src/content/releases/0.2.3.mdx b/packages/twenty-website/src/content/releases/0.2.3.mdx new file mode 100644 index 000000000000..8b57478222b0 --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.2.3.mdx @@ -0,0 +1,16 @@ +--- +release: 0.2.3 +Date: Jan 17th 2024 +--- + +# Webhooks + +Developers can now use webhooks to synchronize customer data updates in real-time across applications. + +![Webhooks](/images/releases/0.2.3_webhooks.png) + +# Relations on Record Pages + +You can now navigate from one object to another directly from the record detail page. + +![Webhooks](/images/releases/0.2.3_relations.png) \ No newline at end of file diff --git a/packages/twenty-website/src/content/releases/0.3.0.mdx b/packages/twenty-website/src/content/releases/0.3.0.mdx new file mode 100644 index 000000000000..4d03b923a87b --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.3.0.mdx @@ -0,0 +1,10 @@ +--- +release: 0.3.0 +Date: Feb 3rd 2024 +--- + +# Rating field + +The new Rating field represents a numeric value from 0 to 5, it can be useful for various use-cases such as scoring leads. + +![rating](/images/releases/0.3.0_rating.png) \ No newline at end of file diff --git a/packages/twenty-website/src/content/releases/0.3.1.mdx b/packages/twenty-website/src/content/releases/0.3.1.mdx new file mode 100644 index 000000000000..9bde47aae0b9 --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.3.1.mdx @@ -0,0 +1,11 @@ +--- +release: 0.3.1 +Date: February 16th 2024 +--- + +# Contributors page + +Contributors now have their very own [hall of fame](https://twenty.com/contributors). + +![rating](/images/releases/0.3.1_contributors.png) + diff --git a/packages/twenty-website/src/content/releases/0.3.2.mdx b/packages/twenty-website/src/content/releases/0.3.2.mdx new file mode 100644 index 000000000000..3115bd4c84a6 --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.3.2.mdx @@ -0,0 +1,10 @@ +--- +release: 0.3.2 +Date: Feb 29th 2024 +--- + +# New record page + +The record page now features a clearer layout with increased space for content + +![](/images/releases/0.3.2_new_layout.png) \ No newline at end of file diff --git a/packages/twenty-website/src/content/releases/0.3.3.mdx b/packages/twenty-website/src/content/releases/0.3.3.mdx new file mode 100644 index 000000000000..704abcf8a4ec --- /dev/null +++ b/packages/twenty-website/src/content/releases/0.3.3.mdx @@ -0,0 +1,23 @@ +--- +release: 0.3.3 +Date: Mar 19th 2024 +--- + +# Gmail integration + +Connect your Gmail account to automatically associate emails with relevant 'People' and 'Companies'. Contacts you've emailed will be automatically added to 'People', excluding non-personal emails like support@ and team@. Control your privacy by selecting the information you share with your team. + +![](/images/releases/0.3.3_emails.png) + + +# Kanbans on any object + +Create a Kanban view on any object and streamline processes like recruitment or onboarding. + +![](/images/releases/0.3.3_kanban.png) + +# Self-Onboarding + +We are pleased to reopen the cloud subscription to everyone. No more waiting! + +![](/images/releases/0.3.3_sign_up.png) \ No newline at end of file diff --git a/packages/twenty-website/src/content/releases/CompactView.mdx b/packages/twenty-website/src/content/releases/CompactView.mdx deleted file mode 100644 index 24078f610a94..000000000000 --- a/packages/twenty-website/src/content/releases/CompactView.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -release: 0.3.2 -Date: May 6th 2024 ---- - -# Compact view - - -Standard objects are in-built objects with a set of attributes available for all users. All workspaces come with three standard objects by default: People, Companies, and Opportunities. Standard objects have standard fields that are also available for all Twenty users, like Account Owner and URL. - -![](/images/user-guide/view-all-objects-light.png) \ No newline at end of file diff --git a/packages/twenty-website/src/content/releases/Inbox.mdx b/packages/twenty-website/src/content/releases/Inbox.mdx deleted file mode 100644 index 4a76b8cdb215..000000000000 --- a/packages/twenty-website/src/content/releases/Inbox.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -release: 0.4.3 -Date: February 24th 2024 ---- - -# Inbox - - - -An inbox gathering task in a CRM system is an automated process that collects and organizes various types of communications such as notes, emails, and notifications. Notes are often summaries or details related to customer interactions that can be recorded and tracked. This system also archives and prioritizes emails and notifications, making it easier to manage customer relationships and ensure all communication is accounted for and responded to in a timely manner. \ No newline at end of file From 35d41e38c89fb11fbd9437e3f66256d8237a4fa7 Mon Sep 17 00:00:00 2001 From: martmull Date: Wed, 20 Mar 2024 07:04:07 +0100 Subject: [PATCH 27/44] Set optional checkout.session.url (#4569) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Set optional checkout.session.url * Lint * Edit .env.example * Vale CI --------- Co-authored-by: Félix Malfait --- packages/twenty-front/src/config/index.ts | 2 +- .../twenty-front/src/generated/graphql.tsx | 6 +++--- .../src/pages/settings/SettingsBilling.tsx | 7 +++++-- packages/twenty-server/.env.example | 1 + .../engine/modules/billing/billing.service.ts | 18 ++++++++++-------- .../modules/billing/dto/session.entity.ts | 2 +- .../src/content/releases/0.3.0.mdx | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/twenty-front/src/config/index.ts b/packages/twenty-front/src/config/index.ts index 1220a5b0a435..4dbb196252fd 100644 --- a/packages/twenty-front/src/config/index.ts +++ b/packages/twenty-front/src/config/index.ts @@ -27,4 +27,4 @@ const getDefaultUrl = () => { export const REACT_APP_SERVER_BASE_URL = window._env_?.REACT_APP_SERVER_BASE_URL || process.env.REACT_APP_SERVER_BASE_URL || - getDefaultUrl(); \ No newline at end of file + getDefaultUrl(); diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index abf8cb43f0d1..43192e2bc9ab 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -552,7 +552,7 @@ export type Sentry = { export type SessionEntity = { __typename?: 'SessionEntity'; - url: Scalars['String']; + url?: Maybe; }; /** Sort Directions */ @@ -1015,7 +1015,7 @@ export type BillingPortalSessionQueryVariables = Exact<{ }>; -export type BillingPortalSessionQuery = { __typename?: 'Query', billingPortalSession: { __typename?: 'SessionEntity', url: string } }; +export type BillingPortalSessionQuery = { __typename?: 'Query', billingPortalSession: { __typename?: 'SessionEntity', url?: string | null } }; export type CheckoutSessionMutationVariables = Exact<{ recurringInterval: Scalars['String']; @@ -1023,7 +1023,7 @@ export type CheckoutSessionMutationVariables = Exact<{ }>; -export type CheckoutSessionMutation = { __typename?: 'Mutation', checkoutSession: { __typename?: 'SessionEntity', url: string } }; +export type CheckoutSessionMutation = { __typename?: 'Mutation', checkoutSession: { __typename?: 'SessionEntity', url?: string | null } }; export type GetProductPricesQueryVariables = Exact<{ product: Scalars['String']; diff --git a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx index b4f332c6743f..13de2e854778 100644 --- a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx @@ -35,6 +35,9 @@ export const SettingsBilling = () => { }, }); + const billingPortalButtonDisabled = + loading || !isDefined(data) || !isDefined(data.billingPortalSession.url); + const displayPaymentFailInfo = onboardingStatus === OnboardingStatus.PastDue || onboardingStatus === OnboardingStatus.Unpaid; @@ -46,7 +49,7 @@ export const SettingsBilling = () => { onboardingStatus === OnboardingStatus.CompletedWithoutSubscription; const openBillingPortal = () => { - if (isDefined(data)) { + if (isDefined(data) && isDefined(data.billingPortalSession.url)) { window.location.replace(data.billingPortalSession.url); } }; @@ -95,7 +98,7 @@ export const SettingsBilling = () => { title="View billing details" variant="secondary" onClick={openBillingPortal} - disabled={loading} + disabled={billingPortalButtonDisabled} /> )} diff --git a/packages/twenty-server/.env.example b/packages/twenty-server/.env.example index 70c186e5d5f8..d8e3f31fb00e 100644 --- a/packages/twenty-server/.env.example +++ b/packages/twenty-server/.env.example @@ -8,6 +8,7 @@ FRONT_BASE_URL=http://localhost:3001 ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh +FILE_TOKEN_SECRET=replace_me_with_a_random_string_refresh SIGN_IN_PREFILLED=true # ———————— Optional ———————— diff --git a/packages/twenty-server/src/engine/modules/billing/billing.service.ts b/packages/twenty-server/src/engine/modules/billing/billing.service.ts index 705c6e0aadcb..b15c0f3d6cfe 100644 --- a/packages/twenty-server/src/engine/modules/billing/billing.service.ts +++ b/packages/twenty-server/src/engine/modules/billing/billing.service.ts @@ -131,10 +131,13 @@ export class BillingService { workspaceId: string, returnUrlPath?: string, ) { - const billingSubscription = - await this.billingSubscriptionRepository.findOneOrFail({ - where: { workspaceId }, - }); + const billingSubscription = await this.getCurrentBillingSubscription({ + workspaceId, + }); + + if (!billingSubscription) { + return; + } const frontBaseUrl = this.environmentService.get('FRONT_BASE_URL'); const returnUrl = returnUrlPath @@ -190,10 +193,9 @@ export class BillingService { } async deleteSubscription(workspaceId: string) { - const subscriptionToCancel = - await this.billingSubscriptionRepository.findOneBy({ - workspaceId, - }); + const subscriptionToCancel = await this.getCurrentBillingSubscription({ + workspaceId, + }); if (subscriptionToCancel) { await this.stripeService.cancelSubscription( diff --git a/packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts b/packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts index 95da4d4224a3..745a7364b749 100644 --- a/packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts +++ b/packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts @@ -2,6 +2,6 @@ import { Field, ObjectType } from '@nestjs/graphql'; @ObjectType() export class SessionEntity { - @Field(() => String) + @Field(() => String, { nullable: true }) url: string; } diff --git a/packages/twenty-website/src/content/releases/0.3.0.mdx b/packages/twenty-website/src/content/releases/0.3.0.mdx index 4d03b923a87b..73102d71f414 100644 --- a/packages/twenty-website/src/content/releases/0.3.0.mdx +++ b/packages/twenty-website/src/content/releases/0.3.0.mdx @@ -5,6 +5,6 @@ Date: Feb 3rd 2024 # Rating field -The new Rating field represents a numeric value from 0 to 5, it can be useful for various use-cases such as scoring leads. +The new Rating field represents a numeric value from zero to five, it can be useful for various use-cases such as scoring leads. ![rating](/images/releases/0.3.0_rating.png) \ No newline at end of file From 017b09ba352f680f2798690fd8b707d7d2666074 Mon Sep 17 00:00:00 2001 From: brendanlaschke Date: Wed, 20 Mar 2024 08:38:05 +0100 Subject: [PATCH 28/44] Blocknote custom slash menu (#4517) blocknote v12, cleaned up blockschema & specs, added custom slash menu --- package.json | 4 +- .../modules/activities/blocks/FileBlock.tsx | 169 ++++++++---------- .../modules/activities/blocks/blockSpecs.ts | 8 - .../src/modules/activities/blocks/schema.ts | 12 +- .../modules/activities/blocks/slashMenu.tsx | 57 +++--- .../components/ActivityBodyEditor.tsx | 27 ++- .../src/modules/ui/display/icon/index.ts | 4 + .../input/editor/components/BlockEditor.tsx | 45 ++++- .../editor/components/CustomSlashMenu.tsx | 42 +++++ .../components/MenuItemSuggestion.tsx | 79 ++++++++ yarn.lock | 38 ++-- 11 files changed, 305 insertions(+), 180 deletions(-) delete mode 100644 packages/twenty-front/src/modules/activities/blocks/blockSpecs.ts create mode 100644 packages/twenty-front/src/modules/ui/input/editor/components/CustomSlashMenu.tsx create mode 100644 packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemSuggestion.tsx diff --git a/package.json b/package.json index 8f43c73685d3..b99715b82988 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "@apollo/server": "^4.7.3", "@aws-sdk/client-s3": "^3.363.0", "@aws-sdk/credential-providers": "^3.363.0", - "@blocknote/core": "^0.11.2", - "@blocknote/react": "^0.11.2", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.1", "@chakra-ui/accordion": "^2.3.0", "@chakra-ui/system": "^2.6.0", "@codesandbox/sandpack-react": "^2.13.5", diff --git a/packages/twenty-front/src/modules/activities/blocks/FileBlock.tsx b/packages/twenty-front/src/modules/activities/blocks/FileBlock.tsx index de679ea553a0..1230d592b4bd 100644 --- a/packages/twenty-front/src/modules/activities/blocks/FileBlock.tsx +++ b/packages/twenty-front/src/modules/activities/blocks/FileBlock.tsx @@ -1,11 +1,4 @@ import { ChangeEvent, useRef } from 'react'; -import { - BlockFromConfig, - BlockNoteEditor, - InlineContentSchema, - PropSchema, - StyleSchema, -} from '@blocknote/core'; import { createReactBlockSpec } from '@blocknote/react'; import styled from '@emotion/styled'; import { isNonEmptyString } from '@sniptt/guards'; @@ -19,31 +12,10 @@ import { AttachmentIcon } from '../files/components/AttachmentIcon'; import { AttachmentType } from '../files/types/Attachment'; import { getFileType } from '../files/utils/getFileType'; -import { blockSpecs } from './blockSpecs'; - -export const filePropSchema = { - // File url - url: { - default: '' as string, - }, - name: { - default: '' as string, - }, - fileType: { - default: 'Other' as AttachmentType, - }, -} satisfies PropSchema; - const StyledFileInput = styled.input` display: none; `; -const FileBlockConfig = { - type: 'file' as const, - propSchema: filePropSchema, - content: 'none' as const, -}; - const StyledFileLine = styled.div` align-items: center; display: flex; @@ -66,75 +38,82 @@ const StyledUploadFileContainer = styled.div` gap: ${({ theme }) => theme.spacing(2)}; `; -const FileBlockRenderer = ({ - block, - editor, -}: { - block: BlockFromConfig< - typeof FileBlockConfig, - InlineContentSchema, - StyleSchema - >; - editor: BlockNoteEditor; -}) => { - const inputFileRef = useRef(null); - - const handleUploadAttachment = async (file: File) => { - if (isUndefinedOrNull(file)) { - return ''; - } - const fileUrl = await editor.uploadFile?.(file); - - editor.updateBlock(block.id, { - props: { - ...block.props, - ...{ url: fileUrl, fileType: getFileType(file.name), name: file.name }, +export const FileBlock = createReactBlockSpec( + { + type: 'file', + propSchema: { + url: { + default: '' as string, + }, + name: { + default: '' as string, + }, + fileType: { + default: 'Other' as AttachmentType, }, - }); - }; - const handleUploadFileClick = () => { - inputFileRef?.current?.click?.(); - }; - const handleFileChange = (e: ChangeEvent) => { - if (isDefined(e.target.files)) handleUploadAttachment?.(e.target.files[0]); - }; + }, + content: 'none', + }, + { + render: ({ block, editor }) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const inputFileRef = useRef(null); - if (isNonEmptyString(block.props.url)) { - return ( - - - - - {block.props.name} - - - - ); - } + const handleUploadAttachment = async (file: File) => { + if (isUndefinedOrNull(file)) { + return ''; + } + const fileUrl = await editor.uploadFile?.(file); + + editor.updateBlock(block.id, { + props: { + ...block.props, + ...{ + url: fileUrl, + fileType: getFileType(file.name), + name: file.name, + }, + }, + }); + }; + const handleUploadFileClick = () => { + inputFileRef?.current?.click?.(); + }; + const handleFileChange = (e: ChangeEvent) => { + if (isDefined(e.target.files)) + handleUploadAttachment?.(e.target.files[0]); + }; - return ( - - - - - - - ); -}; + if (isNonEmptyString(block.props.url)) { + return ( + + + + + {block.props.name} + + + + ); + } -export const FileBlock = createReactBlockSpec(FileBlockConfig, { - render: (block) => { - return ( - - ); + return ( + + + + + + + ); + }, }, -}); +); diff --git a/packages/twenty-front/src/modules/activities/blocks/blockSpecs.ts b/packages/twenty-front/src/modules/activities/blocks/blockSpecs.ts deleted file mode 100644 index fd95c52f241c..000000000000 --- a/packages/twenty-front/src/modules/activities/blocks/blockSpecs.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defaultBlockSpecs } from '@blocknote/core'; - -import { FileBlock } from './FileBlock'; - -export const blockSpecs: any = { - ...defaultBlockSpecs, - file: FileBlock, -}; diff --git a/packages/twenty-front/src/modules/activities/blocks/schema.ts b/packages/twenty-front/src/modules/activities/blocks/schema.ts index 78e83e7d20d6..d6ea82eac19b 100644 --- a/packages/twenty-front/src/modules/activities/blocks/schema.ts +++ b/packages/twenty-front/src/modules/activities/blocks/schema.ts @@ -1,8 +1,10 @@ -import { BlockSchema, defaultBlockSchema } from '@blocknote/core'; +import { BlockNoteSchema, defaultBlockSpecs } from '@blocknote/core'; import { FileBlock } from './FileBlock'; -export const blockSchema: BlockSchema = { - ...defaultBlockSchema, - file: FileBlock.config, -}; +export const blockSchema = BlockNoteSchema.create({ + blockSpecs: { + ...defaultBlockSpecs, + file: FileBlock, + }, +}); diff --git a/packages/twenty-front/src/modules/activities/blocks/slashMenu.tsx b/packages/twenty-front/src/modules/activities/blocks/slashMenu.tsx index 437d61f3fdcf..6689d1aa87f6 100644 --- a/packages/twenty-front/src/modules/activities/blocks/slashMenu.tsx +++ b/packages/twenty-front/src/modules/activities/blocks/slashMenu.tsx @@ -1,30 +1,45 @@ -import { - BlockNoteEditor, - InlineContentSchema, - StyleSchema, -} from '@blocknote/core'; import { getDefaultReactSlashMenuItems } from '@blocknote/react'; -import { IconFile } from '@/ui/display/icon'; +import { + IconFile, + IconH1, + IconH2, + IconH3, + IconList, + IconListNumbers, + IconPhoto, + IconPilcrow, + IconTable, +} from '@/ui/display/icon'; +import { IconComponent } from '@/ui/display/icon/types/IconComponent'; +import { SuggestionItem } from '@/ui/input/editor/components/CustomSlashMenu'; import { blockSchema } from './schema'; -export const getSlashMenu = () => { - const items = [ - ...getDefaultReactSlashMenuItems(blockSchema), +const Icons: Record = { + 'Heading 1': IconH1, + 'Heading 2': IconH2, + 'Heading 3': IconH3, + 'Numbered List': IconListNumbers, + 'Bullet List': IconList, + Paragraph: IconPilcrow, + Table: IconTable, + Image: IconPhoto, +}; + +export const getSlashMenu = (editor: typeof blockSchema.BlockNoteEditor) => { + const items: SuggestionItem[] = [ + ...getDefaultReactSlashMenuItems(editor).map((x) => ({ + ...x, + Icon: Icons[x.title], + })), { - name: 'File', + title: 'File', aliases: ['file', 'folder'], - group: 'Media', - icon: , - hint: 'Insert a file', - execute: ( - editor: BlockNoteEditor< - typeof blockSchema, - InlineContentSchema, - StyleSchema - >, - ) => { + Icon: IconFile, + onItemClick: () => { + const currentBlock = editor.getTextCursorPosition().block; + editor.insertBlocks( [ { @@ -34,7 +49,7 @@ export const getSlashMenu = () => { }, }, ], - editor.getTextCursorPosition().block, + currentBlock, 'before', ); }, diff --git a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx index 16a862c405e2..fbc61bb3cc1e 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx @@ -1,6 +1,5 @@ -import { useCallback, useMemo } from 'react'; -import { BlockNoteEditor } from '@blocknote/core'; -import { useBlockNote } from '@blocknote/react'; +import { ClipboardEvent, useCallback, useMemo } from 'react'; +import { useCreateBlockNote } from '@blocknote/react'; import styled from '@emotion/styled'; import { isArray, isNonEmptyString } from '@sniptt/guards'; import { useRecoilCallback, useRecoilState } from 'recoil'; @@ -8,6 +7,7 @@ import { Key } from 'ts-key-enum'; import { useDebouncedCallback } from 'use-debounce'; import { v4 } from 'uuid'; +import { blockSchema } from '@/activities/blocks/schema'; import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; import { activityBodyFamilyState } from '@/activities/states/activityBodyFamilyState'; import { activityTitleHasBeenSetFamilyState } from '@/activities/states/activityTitleHasBeenSetFamilyState'; @@ -28,8 +28,6 @@ import { FileFolder, useUploadFileMutation } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; -import { blockSpecs } from '../blocks/blockSpecs'; -import { getSlashMenu } from '../blocks/slashMenu'; import { getFileType } from '../files/utils/getFileType'; import '@blocknote/react/style.css'; @@ -121,8 +119,6 @@ export const ActivityBodyEditor = ({ canCreateActivityState(), ); - const slashMenuItems = getSlashMenu(); - const [uploadFile] = useUploadFileMutation(); const handleUploadAttachment = async (file: File): Promise => { @@ -216,8 +212,8 @@ export const ActivityBodyEditor = ({ const handleBodyChangeDebounced = useDebouncedCallback(handleBodyChange, 500); - const handleEditorChange = (newEditor: BlockNoteEditor) => { - const newStringifiedBody = JSON.stringify(newEditor.topLevelBlocks) ?? ''; + const handleEditorChange = () => { + const newStringifiedBody = JSON.stringify(editor.document) ?? ''; setActivityBody(newStringifiedBody); @@ -238,16 +234,11 @@ export const ActivityBodyEditor = ({ } }, [activity, activityBody]); - const editor: BlockNoteEditor | null = useBlockNote({ + const editor = useCreateBlockNote({ initialContent: initialBody, domAttributes: { editor: { class: 'editor' } }, - onEditorContentChange: handleEditorChange, - slashMenuItems, - blockSpecs: blockSpecs, + schema: blockSchema, uploadFile: handleUploadAttachment, - onEditorReady: (editor: BlockNoteEditor) => { - editor.domElement.addEventListener('paste', handleImagePaste); - }, }); const handleImagePaste = async (event: ClipboardEvent) => { @@ -361,7 +352,7 @@ export const ActivityBodyEditor = ({ const newBlockId = v4(); const newBlock = { id: newBlockId, - type: 'paragraph', + type: 'paragraph' as const, content: keyboardEvent.key, }; editor.insertBlocks([newBlock], blockIdentifier, 'after'); @@ -387,6 +378,8 @@ export const ActivityBodyEditor = ({ diff --git a/packages/twenty-front/src/modules/ui/display/icon/index.ts b/packages/twenty-front/src/modules/ui/display/icon/index.ts index ae1b058dc92c..74f81ccb9b9e 100644 --- a/packages/twenty-front/src/modules/ui/display/icon/index.ts +++ b/packages/twenty-front/src/modules/ui/display/icon/index.ts @@ -67,6 +67,9 @@ export { IconFilterOff, IconForbid, IconGripVertical, + IconH1, + IconH2, + IconH3, IconHeadphones, IconHeart, IconHeartOff, @@ -97,6 +100,7 @@ export { IconPencil, IconPhone, IconPhoto, + IconPilcrow, IconPlug, IconPlus, IconPresentation, diff --git a/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx b/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx index 0ca49bca52be..fc5138359763 100644 --- a/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx +++ b/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx @@ -1,12 +1,22 @@ -import { BlockNoteEditor } from '@blocknote/core'; -import { BlockNoteView } from '@blocknote/react'; +import { ClipboardEvent } from 'react'; +import { filterSuggestionItems } from '@blocknote/core'; +import { BlockNoteView, SuggestionMenuController } from '@blocknote/react'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import { blockSchema } from '@/activities/blocks/schema'; +import { getSlashMenu } from '@/activities/blocks/slashMenu'; +import { + CustomSlashMenu, + SuggestionItem, +} from '@/ui/input/editor/components/CustomSlashMenu'; + interface BlockEditorProps { - editor: BlockNoteEditor; + editor: typeof blockSchema.BlockNoteEditor; onFocus?: () => void; onBlur?: () => void; + onPaste?: (event: ClipboardEvent) => void; + onChange?: () => void; } const StyledEditor = styled.div` @@ -22,7 +32,13 @@ const StyledEditor = styled.div` } `; -export const BlockEditor = ({ editor, onFocus, onBlur }: BlockEditorProps) => { +export const BlockEditor = ({ + editor, + onFocus, + onBlur, + onChange, + onPaste, +}: BlockEditorProps) => { const theme = useTheme(); const blockNoteTheme = theme.name === 'light' ? 'light' : 'dark'; @@ -34,14 +50,33 @@ export const BlockEditor = ({ editor, onFocus, onBlur }: BlockEditorProps) => { onBlur?.(); }; + const handleChange = () => { + onChange?.(); + }; + + const handlePaste = (event: ClipboardEvent) => { + onPaste?.(event); + }; + return ( + slashMenu={false} + > + + filterSuggestionItems(getSlashMenu(editor), query) + } + suggestionMenuComponent={CustomSlashMenu} + /> + ); }; diff --git a/packages/twenty-front/src/modules/ui/input/editor/components/CustomSlashMenu.tsx b/packages/twenty-front/src/modules/ui/input/editor/components/CustomSlashMenu.tsx new file mode 100644 index 000000000000..509fd9a740f1 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/input/editor/components/CustomSlashMenu.tsx @@ -0,0 +1,42 @@ +import { SuggestionMenuProps } from '@blocknote/react'; +import styled from '@emotion/styled'; + +import { IconComponent } from '@/ui/display/icon/types/IconComponent'; +import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; +import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; +import { MenuItemSuggestion } from '@/ui/navigation/menu-item/components/MenuItemSuggestion'; + +export type SuggestionItem = { + title: string; + onItemClick: () => void; + aliases?: string[]; + Icon?: IconComponent; +}; + +type CustomSlashMenuProps = SuggestionMenuProps; + +const StyledSlashMenu = styled.div` + * { + box-sizing: content-box; + } +`; + +export const CustomSlashMenu = (props: CustomSlashMenuProps) => { + return ( + + + + {props.items.map((item, index) => ( + item.onItemClick()} + text={item.title} + LeftIcon={item.Icon} + selected={props.selectedIndex === index} + /> + ))} + + + + ); +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemSuggestion.tsx b/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemSuggestion.tsx new file mode 100644 index 000000000000..52d3a12ee8b4 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemSuggestion.tsx @@ -0,0 +1,79 @@ +import { MouseEvent } from 'react'; +import styled from '@emotion/styled'; + +import { IconComponent } from '@/ui/display/icon/types/IconComponent'; +import { HOVER_BACKGROUND } from '@/ui/theme/constants/HoverBackground'; + +import { MenuItemLeftContent } from '../internals/components/MenuItemLeftContent'; +import { StyledMenuItemLeftContent } from '../internals/components/StyledMenuItemBase'; + +export type MenuItemSuggestionProps = { + LeftIcon?: IconComponent | null; + text: string; + selected?: boolean; + className?: string; + onClick?: (event: MouseEvent) => void; +}; + +const StyledSuggestionMenuItem = styled.li<{ + selected?: boolean; +}>` + --horizontal-padding: ${({ theme }) => theme.spacing(1)}; + --vertical-padding: ${({ theme }) => theme.spacing(2)}; + + align-items: center; + + border-radius: ${({ theme }) => theme.border.radius.sm}; + cursor: pointer; + + display: flex; + + flex-direction: row; + + font-size: ${({ theme }) => theme.font.size.sm}; + + gap: ${({ theme }) => theme.spacing(2)}; + + height: calc(32px - 2 * var(--vertical-padding)); + justify-content: space-between; + + padding: var(--vertical-padding) var(--horizontal-padding); + + background: ${({ selected, theme }) => + selected ? theme.background.transparent.medium : ''}; + + ${HOVER_BACKGROUND}; + + position: relative; + user-select: none; + + width: calc(100% - 2 * var(--horizontal-padding)); +`; + +export const MenuItemSuggestion = ({ + LeftIcon, + text, + className, + selected, + onClick, +}: MenuItemSuggestionProps) => { + const handleMenuItemClick = (event: MouseEvent) => { + if (!onClick) return; + event.preventDefault(); + event.stopPropagation(); + + onClick?.(event); + }; + + return ( + + + + + + ); +}; diff --git a/yarn.lock b/yarn.lock index ce0cde229fab..f8806b2b7af7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3555,9 +3555,9 @@ __metadata: languageName: node linkType: hard -"@blocknote/core@npm:^0.11.2": - version: 0.11.2 - resolution: "@blocknote/core@npm:0.11.2" +"@blocknote/core@npm:^0.12.1": + version: 0.12.1 + resolution: "@blocknote/core@npm:0.12.1" dependencies: "@tiptap/core": "npm:^2.0.3" "@tiptap/extension-bold": "npm:^2.0.3" @@ -3598,23 +3598,21 @@ __metadata: y-prosemirror: "npm:1.2.1" y-protocols: "npm:^1.0.5" yjs: "npm:^13.6.1" - checksum: a9a5affe263481bf46b556ded4b5dd583f24e0b090d536550eb2484f7d091e76258d8a865171459fbf3be114abee638e406d419d0d32f07aa5a82c638d00fcb3 + checksum: 3b00572a2d98964722b7bcd75f8399856c3fcdcbc88e7217e883d7f6eba13fa36aeea8dde439335c9ea475a25f179b771fa397e9b78219c608c74663db1557f2 languageName: node linkType: hard -"@blocknote/react@npm:^0.11.2": - version: 0.11.2 - resolution: "@blocknote/react@npm:0.11.2" +"@blocknote/react@npm:^0.12.1": + version: 0.12.2 + resolution: "@blocknote/react@npm:0.12.2" dependencies: - "@blocknote/core": "npm:^0.11.2" + "@blocknote/core": "npm:^0.12.1" "@floating-ui/react": "npm:^0.26.4" "@mantine/core": "npm:^7.5.0" "@mantine/hooks": "npm:^7.5.0" "@mantine/utils": "npm:^6.0.21" "@tiptap/core": "npm:^2.0.3" "@tiptap/react": "npm:^2.0.3" - lodash.foreach: "npm:^4.5.0" - lodash.groupby: "npm:^4.6.0" lodash.merge: "npm:^4.6.2" react: "npm:^18" react-dom: "npm:^18.2.0" @@ -3623,7 +3621,7 @@ __metadata: peerDependencies: react: ^18 react-dom: ^18 - checksum: a3dcfd40ea3e3b0e4c238b161be908e726b1d404337efe9903e92b7cf518d3165a7df8d78bce606f86354198751fd009d96f1cc8f23de51734e9faa663225981 + checksum: 2dcae5268e104398bb2be13f650b6d141eecc74542dcc38b78b3cad7cc499e2e2fd5ecd225ce969fbfadd346cc74d2354316fbb2a61ce5f38c2d339849dd4b0e languageName: node linkType: hard @@ -33362,13 +33360,6 @@ __metadata: languageName: node linkType: hard -"lodash.foreach@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.foreach@npm:4.5.0" - checksum: bd9cc83e87e805b21058ce6cf718dd22db137c7ca08eddbd608549db59989911c571b7195707f615cb37f27bb4f9a9fa9980778940d768c24095f5a04b244c84 - languageName: node - linkType: hard - "lodash.get@npm:^4.4.2": version: 4.4.2 resolution: "lodash.get@npm:4.4.2" @@ -33376,13 +33367,6 @@ __metadata: languageName: node linkType: hard -"lodash.groupby@npm:^4.6.0": - version: 4.6.0 - resolution: "lodash.groupby@npm:4.6.0" - checksum: 3d136cad438ad6c3a078984ef60e057a3498b1312aa3621b00246ecb99e8f2c4d447e2815460db7a0b661a4fe4e2eeee96c84cb661a824bad04b6cf1f7bc6e9b - languageName: node - linkType: hard - "lodash.includes@npm:^4.3.0": version: 4.3.0 resolution: "lodash.includes@npm:4.3.0" @@ -45826,8 +45810,8 @@ __metadata: "@aws-sdk/credential-providers": "npm:^3.363.0" "@babel/core": "npm:^7.14.5" "@babel/preset-react": "npm:^7.14.5" - "@blocknote/core": "npm:^0.11.2" - "@blocknote/react": "npm:^0.11.2" + "@blocknote/core": "npm:^0.12.1" + "@blocknote/react": "npm:^0.12.1" "@chakra-ui/accordion": "npm:^2.3.0" "@chakra-ui/system": "npm:^2.6.0" "@codesandbox/sandpack-react": "npm:^2.13.5" From 20e14cb45560b010d2772d514e59d1bdceccce34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Wed, 20 Mar 2024 06:07:01 -0300 Subject: [PATCH 29/44] fix: fix typings in calendar utils tests (#4572) * fix: fix typings in calendar utils tests * fix: remove unstable test --- .../findUpcomingCalendarEvent.test.ts | 18 ++-- .../__tests__/hasCalendarEventEnded.test.ts | 31 ++----- .../__tests__/hasCalendarEventStarted.test.ts | 6 +- .../__tests__/sortCalendarEvents.test.ts | 92 +++++++++---------- 4 files changed, 65 insertions(+), 82 deletions(-) diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/findUpcomingCalendarEvent.test.ts b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/findUpcomingCalendarEvent.test.ts index d6d3d556fb4a..dce86cc71c20 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/findUpcomingCalendarEvent.test.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/findUpcomingCalendarEvent.test.ts @@ -5,32 +5,32 @@ import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; import { findUpcomingCalendarEvent } from '../findUpcomingCalendarEvent'; const pastEvent: Pick = { - startsAt: subHours(new Date(), 2), - endsAt: subHours(new Date(), 1), + startsAt: subHours(new Date(), 2).toISOString(), + endsAt: subHours(new Date(), 1).toISOString(), isFullDay: false, }; const fullDayPastEvent: Pick = { - startsAt: subDays(new Date(), 1), + startsAt: subDays(new Date(), 1).toISOString(), isFullDay: true, }; const currentEvent: Pick = { - startsAt: addHours(new Date(), 1), - endsAt: addHours(new Date(), 2), + startsAt: addHours(new Date(), 1).toISOString(), + endsAt: addHours(new Date(), 2).toISOString(), isFullDay: false, }; const currentFullDayEvent: Pick = { - startsAt: startOfDay(new Date()), + startsAt: startOfDay(new Date()).toISOString(), isFullDay: true, }; const futureEvent: Pick = { - startsAt: addDays(new Date(), 1), - endsAt: addDays(new Date(), 2), + startsAt: addDays(new Date(), 1).toISOString(), + endsAt: addDays(new Date(), 2).toISOString(), isFullDay: false, }; const fullDayFutureEvent: Pick = { - startsAt: addDays(new Date(), 2), + startsAt: addDays(new Date(), 2).toISOString(), isFullDay: false, }; diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventEnded.test.ts b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventEnded.test.ts index 0efcf75e4b4a..7519fb7e06f2 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventEnded.test.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventEnded.test.ts @@ -6,8 +6,8 @@ describe('hasCalendarEventEnded', () => { describe('Event with end date', () => { it('returns true for an event with a past end date', () => { // Given - const startsAt = subHours(new Date(), 2); - const endsAt = subHours(new Date(), 1); + const startsAt = subHours(new Date(), 2).toISOString(); + const endsAt = subHours(new Date(), 1).toISOString(); const isFullDay = false; // When @@ -21,27 +21,10 @@ describe('hasCalendarEventEnded', () => { expect(result).toBe(true); }); - it('returns false for an event if end date is now', () => { - // Given - const startsAt = subHours(new Date(), 1); - const endsAt = new Date(); - const isFullDay = false; - - // When - const result = hasCalendarEventEnded({ - startsAt, - endsAt, - isFullDay, - }); - - // Then - expect(result).toBe(false); - }); - it('returns false for an event with a future end date', () => { // Given - const startsAt = new Date(); - const endsAt = addHours(new Date(), 1); + const startsAt = new Date().toISOString(); + const endsAt = addHours(new Date(), 1).toISOString(); const isFullDay = false; // When @@ -59,7 +42,7 @@ describe('hasCalendarEventEnded', () => { describe('Full day event', () => { it('returns true for a past full day event', () => { // Given - const startsAt = subDays(new Date(), 1); + const startsAt = subDays(new Date(), 1).toISOString(); const isFullDay = true; // When @@ -74,7 +57,7 @@ describe('hasCalendarEventEnded', () => { it('returns false for a future full day event', () => { // Given - const startsAt = addDays(new Date(), 1); + const startsAt = addDays(new Date(), 1).toISOString(); const isFullDay = true; // When @@ -89,7 +72,7 @@ describe('hasCalendarEventEnded', () => { it('returns false if the full day event is today', () => { // Given - const startsAt = new Date(); + const startsAt = new Date().toISOString(); const isFullDay = true; // When diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventStarted.test.ts b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventStarted.test.ts index 2dcc38876fed..5e0ddaea4756 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventStarted.test.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/hasCalendarEventStarted.test.ts @@ -5,7 +5,7 @@ import { hasCalendarEventStarted } from '../hasCalendarEventStarted'; describe('hasCalendarEventStarted', () => { it('returns true for an event with a past start date', () => { // Given - const startsAt = subHours(new Date(), 2); + const startsAt = subHours(new Date(), 2).toISOString(); // When const result = hasCalendarEventStarted({ startsAt }); @@ -16,7 +16,7 @@ describe('hasCalendarEventStarted', () => { it('returns false for an event if start date is now', () => { // Given - const startsAt = new Date(); + const startsAt = new Date().toISOString(); // When const result = hasCalendarEventStarted({ startsAt }); @@ -27,7 +27,7 @@ describe('hasCalendarEventStarted', () => { it('returns false for an event with a future start date', () => { // Given - const startsAt = addHours(new Date(), 1); + const startsAt = addHours(new Date(), 1).toISOString(); // When const result = hasCalendarEventStarted({ startsAt }); diff --git a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/sortCalendarEvents.test.ts b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/sortCalendarEvents.test.ts index 2e0208d6eeef..dc1a42a9cc16 100644 --- a/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/sortCalendarEvents.test.ts +++ b/packages/twenty-front/src/modules/activities/calendar/utils/__tests__/sortCalendarEvents.test.ts @@ -14,13 +14,13 @@ describe('sortCalendarEventsAsc', () => { it('sorts non-intersecting events by ascending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusOneHour, + startsAt: someDate.toISOString(), + endsAt: someDatePlusOneHour.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusTwoHours, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusTwoHours.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -36,13 +36,13 @@ describe('sortCalendarEventsAsc', () => { it('sorts intersecting events by start date ascending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusTwoHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusTwoHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusOneHour, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusOneHour.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -58,13 +58,13 @@ describe('sortCalendarEventsAsc', () => { it('sorts events with same start date by end date ascending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusTwoHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusTwoHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDate, - endsAt: someDatePlusThreeHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -80,13 +80,13 @@ describe('sortCalendarEventsAsc', () => { it('sorts events with same end date by start date ascending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusThreeHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusOneHour, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusOneHour.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -102,11 +102,11 @@ describe('sortCalendarEventsAsc', () => { it('sorts events without end date by start date ascending order', () => { // Given const eventA = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; const eventB = { - startsAt: someDatePlusOneHour, + startsAt: someDatePlusOneHour.toISOString(), isFullDay: true, }; @@ -122,11 +122,11 @@ describe('sortCalendarEventsAsc', () => { it('returns 0 for full day events with the same start date', () => { // Given const eventA = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; const eventB = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; @@ -142,12 +142,12 @@ describe('sortCalendarEventsAsc', () => { it('sorts the full day event last for two events with the same start date if one is full day', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusOneHour, + startsAt: someDate.toISOString(), + endsAt: someDatePlusOneHour.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; @@ -165,13 +165,13 @@ describe('sortCalendarEventsDesc', () => { it('sorts non-intersecting events by descending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusOneHour, + startsAt: someDate.toISOString(), + endsAt: someDatePlusOneHour.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusTwoHours, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusTwoHours.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -187,13 +187,13 @@ describe('sortCalendarEventsDesc', () => { it('sorts intersecting events by start date descending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusTwoHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusTwoHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusOneHour, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusOneHour.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -209,13 +209,13 @@ describe('sortCalendarEventsDesc', () => { it('sorts events with same start date by end date descending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusTwoHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusTwoHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDate, - endsAt: someDatePlusThreeHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -231,13 +231,13 @@ describe('sortCalendarEventsDesc', () => { it('sorts events with same end date by start date descending order', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusThreeHours, + startsAt: someDate.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDatePlusOneHour, - endsAt: someDatePlusThreeHours, + startsAt: someDatePlusOneHour.toISOString(), + endsAt: someDatePlusThreeHours.toISOString(), isFullDay: false, }; @@ -253,11 +253,11 @@ describe('sortCalendarEventsDesc', () => { it('sorts events without end date by start date descending order', () => { // Given const eventA = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; const eventB = { - startsAt: someDatePlusOneHour, + startsAt: someDatePlusOneHour.toISOString(), isFullDay: true, }; @@ -273,11 +273,11 @@ describe('sortCalendarEventsDesc', () => { it('returns 0 for full day events with the same start date', () => { // Given const eventA = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; const eventB = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; @@ -293,12 +293,12 @@ describe('sortCalendarEventsDesc', () => { it('sorts the full day event first for two events with the same start date if one is full day', () => { // Given const eventA = { - startsAt: someDate, - endsAt: someDatePlusOneHour, + startsAt: someDate.toISOString(), + endsAt: someDatePlusOneHour.toISOString(), isFullDay: false, }; const eventB = { - startsAt: someDate, + startsAt: someDate.toISOString(), isFullDay: true, }; From cfb0cce9b86f9d6f0a5e3fc0681f079cd4535a22 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Wed, 20 Mar 2024 14:21:58 +0100 Subject: [PATCH 30/44] Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516) * Wip refactoring view * Post merge conflicts * Fix review * Add create view capability * Fix create object missing view * Fix tests --- package.json | 1 + packages/twenty-front/src/App.tsx | 2 +- .../effect-components/CommandMenuEffect.tsx | 2 +- .../effect-components/PageChangeEffect.tsx | 2 +- .../src/hooks/useDefaultHomePagePath.tsx | 2 +- packages/twenty-front/src/index.tsx | 5 + .../calendar/components/CalendarEventRow.tsx | 2 +- .../components/RightDrawerCalendarEvent.tsx | 4 +- .../useOpenCalendarEventRightDrawer.test.tsx | 4 +- .../hooks/useOpenCalendarEventRightDrawer.ts | 2 +- .../comment/__stories__/Comment.stories.tsx | 2 +- .../__stories__/CommentHeader.stories.tsx | 2 +- .../components/ActivityBodyEditor.tsx | 4 +- .../components/ActivityComments.tsx | 2 +- .../components/ActivityEditorEffect.tsx | 8 +- .../activities/components/ActivityTitle.tsx | 2 +- .../emails/components/EmailThreadPreview.tsx | 2 +- .../emails/components/EmailThreads.tsx | 4 +- .../hooks/__tests__/useEmailThread.test.tsx | 8 +- .../__tests__/useEmailThreadStates.test.ts | 2 +- .../hooks/internal/useEmailThreadStates.ts | 2 +- .../activities/emails/hooks/useEmailThread.ts | 8 +- .../components/RightDrawerEmailThread.tsx | 2 +- .../hooks/useRightDrawerEmailThread.ts | 2 +- .../files/hooks/useUploadAttachmentFile.tsx | 2 +- .../hooks/__tests__/useActivities.test.tsx | 2 +- .../useActivityConnectionUtils.test.tsx | 4 +- .../useActivityTargetObjectRecords.test.tsx | 4 +- ...ctivityTargetsForTargetableObject.test.tsx | 2 +- ...useAttachRelationInBothDirections.test.tsx | 4 +- .../useCreateActivityInCache.test.tsx | 4 +- .../useOpenActivityRightDrawer.test.tsx | 4 +- .../useOpenCreateActivityDrawer.test.tsx | 6 +- ...teActivityDrawerForSelectedRowIds.test.tsx | 6 +- .../__tests__/useUpsertActivity.test.tsx | 4 +- .../hooks/useActivityTargetObjectRecords.ts | 2 +- .../hooks/useCreateActivityInCache.ts | 2 +- .../hooks/useOpenActivityRightDrawer.ts | 4 +- .../hooks/useOpenCreateActivityDrawer.ts | 14 +- ...enCreateActivityDrawerForSelectedRowIds.ts | 6 +- .../activities/hooks/useUpsertActivity.ts | 6 +- .../ActivityTargetInlineCellEditMode.tsx | 4 +- .../components/ActivityActionBar.tsx | 16 +- .../create/RightDrawerCreateActivity.tsx | 2 +- .../edit/RightDrawerEditActivity.tsx | 2 +- .../CurrentUserDueTaskCountEffect.tsx | 4 +- .../tasks/components/TaskGroups.tsx | 4 +- .../tasks/hooks/useCurrentUserDueTaskCount.ts | 2 +- .../activities/tasks/hooks/useTasks.ts | 6 +- .../timeline/components/Timeline.tsx | 2 +- .../components/TimelineCreateButtonGroup.tsx | 4 +- .../components/TimelineItemsContainer.tsx | 2 +- .../components/TimelineQueryEffect.tsx | 4 +- .../analytics/hooks/useEventTracker.ts | 2 +- .../modules/apollo/hooks/useApolloFactory.ts | 4 +- .../triggerUpdateRelationsOptimisticEffect.ts | 236 +++++----- .../auth/hooks/__test__/useAuth.test.tsx | 14 +- .../auth/hooks/__test__/useIsLogged.test.ts | 2 +- .../__test__/useOnboardingStatus.test.ts | 10 +- .../src/modules/auth/hooks/useAuth.ts | 38 +- .../src/modules/auth/hooks/useIsLogged.ts | 4 +- .../modules/auth/hooks/useOnboardingStatus.ts | 6 +- .../sign-in-up/components/SignInUpForm.tsx | 2 +- .../hooks/useNavigateAfterSignInUp.ts | 2 +- .../auth/sign-in-up/hooks/useSignInUpForm.ts | 2 +- .../components/ClientConfigProvider.tsx | 16 +- .../command-menu/components/CommandMenu.tsx | 4 +- .../__stories__/CommandMenu.stories.tsx | 4 +- .../hooks/__test__/useCommandMenu.test.tsx | 2 +- .../command-menu/hooks/useCommandMenu.ts | 4 +- .../debug/components/ApolloDevLogEffect.tsx | 2 +- .../debug/components/RecoilDebugObserver.tsx | 2 +- .../components/SentryInitiEffect.tsx | 8 +- .../hooks/__tests__/useFavorites.test.tsx | 16 +- .../modules/favorites/hooks/useFavorites.ts | 2 +- .../components/AppNavigationDrawer.tsx | 4 +- .../components/MainNavigationDrawerItems.tsx | 6 +- .../components/MobileNavigationBar.tsx | 2 +- .../AppNavigationDrawer.stories.tsx | 2 +- .../ApolloMetadataClientProvider.tsx | 2 +- .../ObjectMetadataItemsLoadEffect.tsx | 2 +- .../ObjectMetadataItemsProvider.tsx | 4 +- ...rOutUnexistingObjectMetadataItems.test.tsx | 2 +- ...ectRecordIdentifierByNameSingular.test.tsx | 2 +- .../__tests__/useGetRelationMetadata.test.tsx | 2 +- .../useObjectMetadataItemForSettings.test.tsx | 6 +- .../hooks/useCreateOneObjectMetadataItem.ts | 5 +- ...GetObjectRecordIdentifierByNameSingular.ts | 2 +- .../hooks/useObjectMetadataItem.ts | 4 +- .../hooks/useObjectMetadataItemForSettings.ts | 2 +- .../hooks/useObjectMetadataItemOnly.ts | 4 +- .../hooks/useObjectMetadataItems.ts | 2 +- .../hooks/useObjectNamePluralFromSingular.ts | 2 +- .../hooks/useObjectNameSingularFromPlural.ts | 2 +- .../objectMetadataItemFamilySelector.ts | 2 +- ...ectMetadataItemsByNamePluralMapSelector.ts | 2 +- ...tMetadataItemsByNameSingularMapSelector.ts | 2 +- .../cache/hooks/useAddRecordInCache.ts | 2 +- .../cache/hooks/useGetRecordFromCache.ts | 44 +- .../cache/utils/getRecordEdgeFromRecord.ts | 3 +- .../__tests__/useFindManyRecords.test.tsx | 4 +- ...ordsForMultipleMetadataItemsQuery.test.tsx | 2 +- .../useMapConnectionToRecords.test.tsx | 2 +- .../object-record/hooks/useFindManyRecords.ts | 2 +- .../useGenerateCreateManyRecordMutation.ts | 2 +- .../useGenerateCreateOneRecordMutation.ts | 2 +- ...teExecuteQuickActionOnOneRecordMutation.ts | 2 +- .../useGenerateFindDuplicateRecordsQuery.ts | 2 +- ...anyRecordsForMultipleMetadataItemsQuery.ts | 12 +- .../hooks/useGenerateFindManyRecordsQuery.ts | 2 +- .../hooks/useGenerateFindOneRecordQuery.ts | 2 +- .../useGenerateUpdateOneRecordMutation.ts | 2 +- .../hooks/useMapConnectionToRecords.ts | 2 +- .../MultipleFiltersDropdownContent.tsx | 18 +- .../components/ObjectFilterDropdownButton.tsx | 9 +- .../ObjectFilterDropdownDateInput.tsx | 13 +- ...ObjectFilterDropdownEntitySearchSelect.tsx | 20 +- .../ObjectFilterDropdownFilterSelect.tsx | 8 +- .../ObjectFilterDropdownNumberInput.tsx | 12 +- .../ObjectFilterDropdownOperandButton.tsx | 13 +- .../ObjectFilterDropdownOperandSelect.tsx | 18 +- .../ObjectFilterDropdownOptionSelect.tsx | 22 +- .../ObjectFilterDropdownRecordSelect.tsx | 23 +- .../ObjectFilterDropdownSearchInput.tsx | 17 +- .../ObjectFilterDropdownTextSearchInput.tsx | 20 +- ...SingleEntityObjectFilterDropdownButton.tsx | 10 +- .../__tests__/useFilterDropdown.test.tsx | 188 ++++++-- .../hooks/useFilterDropdown.ts | 171 ++++--- .../hooks/useFilterDropdownStates.ts | 127 +++-- ...ailableFilterDefinitionsComponentState.ts} | 4 +- ...DefinitionUsedInDropdownComponentState.ts} | 4 +- ...downOperandSelectUnfoldedComponentState.ts | 7 + ...ctFilterDropdownUnfoldedComponentState.ts} | 2 +- ...ilterDropdownSearchInputComponentState.ts} | 4 +- ...DropdownSelectedEntityIdComponentState.ts} | 4 +- ...downSelectedOptionValuesComponentState.ts} | 4 +- ...ropdownSelectedRecordIdsComponentState.ts} | 4 +- ...ate.ts => onFilterSelectComponentState.ts} | 4 +- ...ate.ts => selectedFilterComponentState.ts} | 4 +- ...electedOperandInDropdownComponentState.ts} | 4 +- .../components/ObjectSortDropdownButton.tsx | 11 +- .../hooks/__tests__/useSortDropdown.test.tsx | 67 ++- .../hooks/useSortDropdown.ts | 18 +- .../hooks/useSortDropdownStates.ts | 32 +- ...availableSortDefinitionsComponentState.ts} | 4 +- .../states/isSortSelectedScopedState.ts | 4 +- .../states/onSortSelectScopedState.ts | 4 +- .../__tests__/turnSortsIntoOrderBy.test.tsx | 8 +- .../utils/turnSortsIntoOrderBy.ts | 23 +- .../hooks/useRecordActionBar.tsx | 4 +- .../components/RecordBoardActionBar.tsx | 4 +- .../record-board/components/RecordBoard.tsx | 4 +- .../components/RecordBoardContextMenu.tsx | 4 +- .../hooks/internal/useRecordBoardStates.ts | 23 +- .../internal/useSetRecordBoardColumns.ts | 8 +- .../internal/useSetRecordBoardRecordIds.ts | 6 +- .../record-board/hooks/useRecordBoard.ts | 20 +- .../hooks/useRecordBoardSelection.ts | 6 +- .../components/RecordBoardCard.tsx | 16 +- .../RecordBoardColumnFetchMoreLoader.tsx | 8 +- .../record-field/hooks/useClearField.ts | 2 +- .../RelationFieldInput.stories.tsx | 4 +- ...turnObjectDropdownFilterIntoQueryFilter.ts | 6 +- .../RecordIndexBoardContainerEffect.tsx | 10 +- .../components/RecordIndexContainer.tsx | 51 +- .../RecordIndexTableContainerEffect.tsx | 15 +- .../components/RecordIndexViewBarEffect.tsx | 4 +- .../hooks/useLoadRecordIndexBoard.ts | 25 +- .../hooks/useLoadRecordIndexTable.ts | 12 +- .../components/RecordIndexOptionsDropdown.tsx | 40 +- .../RecordIndexOptionsDropdownContent.tsx | 36 +- .../options/hooks/useExportTableData.ts | 6 +- .../hooks/useRecordIndexOptionsForBoard.ts | 39 +- .../hooks/useRecordIndexOptionsForTable.ts | 6 +- .../RecordDetailRelationSection.tsx | 2 +- .../recordStoreIdentifierSelector.ts | 2 +- .../components/RecordTableActionBar.tsx | 4 +- .../record-table/components/CheckboxCell.tsx | 2 +- .../record-table/components/ColumnHead.tsx | 2 +- .../record-table/components/RecordTable.tsx | 2 +- .../components/RecordTableBody.tsx | 4 +- .../components/RecordTableBodyEffect.tsx | 4 +- .../components/RecordTableCellContainer.tsx | 4 +- .../RecordTableColumnDropdownMenu.tsx | 4 +- .../components/RecordTableHeader.tsx | 7 +- .../components/RecordTableHeaderCell.tsx | 15 +- .../RecordTableHeaderPlusButtonContent.tsx | 4 +- .../components/RecordTableRow.tsx | 4 +- .../components/RecordTableWithWrappers.tsx | 14 +- .../components/SelectAllCheckbox.tsx | 6 +- .../components/RecordTableContextMenu.tsx | 4 +- .../useCloseCurrentTableCellInEditMode.ts | 9 +- .../hooks/internal/useDisableSoftFocus.ts | 12 +- .../internal/useGetIsSomeCellInEditMode.ts | 9 +- .../hooks/internal/useLeaveTableFocus.ts | 8 +- .../internal/useMoveEditModeToCellPosition.ts | 11 +- .../hooks/internal/useRecordTableStates.ts | 44 +- .../internal/useResetTableRowSelection.ts | 6 +- .../hooks/internal/useSelectAllRows.ts | 14 +- .../hooks/internal/useSetRecordTableData.ts | 10 +- .../hooks/internal/useSetSoftFocusPosition.ts | 14 +- .../record-table/hooks/useRecordTable.ts | 58 ++- .../hooks/useRecordTableMoveFocus.ts | 44 +- .../record-table/hooks/useTableColumns.ts | 19 +- .../components/RecordTableCellContainer.tsx | 2 +- .../RecordTableCellSoftFocusMode.tsx | 2 +- .../useCloseRecordTableCell.test.tsx | 4 +- ...MoveSoftFocusToCurrentCellOnHover.test.tsx | 6 +- .../useMoveSoftFocusToCurrentCellOnHover.ts | 8 +- .../hooks/useSetSoftFocus.ts | 6 +- ...attedAsObjectRecordForSelectArray.test.tsx | 2 +- .../__tests__/useMultiObjectSearch.test.tsx | 2 +- ...atchesSearchFilterAndSelectedItemsQuery.ts | 4 +- ...archMatchesSearchFilterAndToSelectQuery.ts | 4 +- .../useMultiObjectSearchSelectedItemsQuery.ts | 4 +- .../useSpreadsheetRecordImport.test.tsx | 2 +- .../components/PrefetchRunQueriesEffect.tsx | 19 +- .../useFilteredSearchEntityQuery.test.tsx | 4 +- ...ttingsAccountsCalendarAccountsListCard.tsx | 2 +- ...SettingsAccountsEmailsAccountsListCard.tsx | 2 +- ...SettingsAccountsEmailsBlocklistSection.tsx | 2 +- .../SettingsNavigationDrawerItems.tsx | 2 +- .../profile/components/ChangePassword.tsx | 2 +- .../profile/components/DeleteAccount.tsx | 2 +- .../profile/components/DeleteWorkspace.tsx | 2 +- .../profile/components/EmailField.tsx | 2 +- .../profile/components/NameFields.tsx | 4 +- .../components/ProfilePictureUploader.tsx | 2 +- .../workspace/components/NameField.tsx | 2 +- .../components/ToggleImpersonate.tsx | 2 +- .../components/WorkspaceLogoUploader.tsx | 2 +- .../SignInBackgroundMockContainer.tsx | 1 + .../SignInBackgroundMockContainerEffect.tsx | 13 +- .../__tests__/useSpreadsheetImport.test.tsx | 2 +- .../hooks/useSpreadsheetImport.ts | 2 +- .../components/SpreadsheetImportProvider.tsx | 2 +- .../support/components/SupportChat.tsx | 6 +- .../display/icon/components/IconsProvider.tsx | 2 +- .../modules/ui/display/icon/hooks/useIcons.ts | 2 +- .../modules/ui/input/hooks/useIconPicker.ts | 2 +- .../dropdown/components/DropdownMenuInput.tsx | 3 +- .../useInternalHotkeyScopeManagement.test.tsx | 2 +- .../ui/layout/dropdown/hooks/useDropdown.ts | 10 +- .../hooks/useInternalHotkeyScopeManagement.ts | 2 +- .../right-drawer/components/RightDrawer.tsx | 10 +- .../components/RightDrawerRouter.tsx | 2 +- .../RightDrawerTopBarExpandButton.tsx | 2 +- .../hooks/__tests__/useRightDrawer.test.tsx | 8 +- .../right-drawer/hooks/useRightDrawer.ts | 16 +- .../hooks/__tests__/useSelectableList.test.ts | 7 +- .../internal/useSelectableListHotKeys.tsx | 13 +- .../hooks/useSelectableList.ts | 6 +- .../components/ShowPageMoreButton.tsx | 2 +- .../components/ShowPageRightContainer.tsx | 4 +- .../ui/layout/tab/components/TabList.tsx | 4 +- .../tab/hooks/__tests__/useTabList.test.tsx | 6 +- .../tab/hooks/internal/useTabListStates.ts | 5 +- .../modules/ui/layout/tab/hooks/useTabList.ts | 6 +- .../action-bar/components/ActionBar.tsx | 4 +- .../__stories__/ActionBar.stories.tsx | 2 +- .../context-menu/components/ContextMenu.tsx | 8 +- .../__stories__/ContextMenu.stories.tsx | 4 +- .../menu-item/components/MenuItemToggle.tsx | 6 +- .../components/StyledMenuItemBase.tsx | 2 + .../components/NavigationDrawerBackButton.tsx | 2 +- .../hooks/__tests__/useStepBar.test.tsx | 2 +- .../navigation/step-bar/hooks/useStepBar.ts | 5 +- .../hooks/__tests__/useColorScheme.test.tsx | 2 +- .../modules/ui/theme/hooks/useColorScheme.ts | 2 +- .../hotkey/hooks/usePreviousHotkeyScope.ts | 8 +- .../hotkey/hooks/useScopedHotkeyCallback.ts | 2 +- .../hotkey/hooks/useScopedHotkeys.ts | 3 +- .../hotkey/hooks/useSequenceScopedHotkeys.ts | 3 +- .../hotkey/hooks/useSetHotkeyScope.ts | 6 +- .../useClickOutsideListener.test.tsx | 4 +- .../hooks/useClickOutsideListener.ts | 14 +- .../hooks/useListenClickOutsideV2.ts | 8 +- .../utils/getScopedFamilyStateDeprecated.ts | 19 - .../utils/getScopedSelectorDeprecated.ts | 10 - .../hooks/__tests__/useListenScroll.test.tsx | 2 +- .../utilities/scroll/hooks/useListenScroll.ts | 10 +- .../utils/extractComponentState.ts | 2 +- .../ui/utilities/state/utils/createState.ts | 2 +- .../modules/users/components/UserProvider.tsx | 6 +- .../views/components/EditableFilterChip.tsx | 4 +- .../EditableFilterDropdownButton.tsx | 21 +- .../views/components/EditableSortChip.tsx | 13 +- .../components/FilterQueryParamsEffect.tsx | 43 +- .../components/UpdateViewButtonGroup.tsx | 20 +- .../src/modules/views/components/ViewBar.tsx | 42 +- .../views/components/ViewBarDetails.tsx | 79 ++-- .../views/components/ViewBarEffect.tsx | 121 +++-- .../views/components/ViewBarFilterEffect.tsx | 40 +- .../views/components/ViewBarSortEffect.tsx | 34 +- .../views/components/ViewsDropdownButton.tsx | 59 +-- .../src/modules/views/constants/index.ts | 2 - .../views/hooks/__tests__/useViewBar.test.tsx | 238 +--------- .../__tests__/useViewBar_ViewFields.test.tsx | 170 ------- .../__tests__/useViewBar_ViewFilters.test.tsx | 178 ------- .../__tests__/useViewBar_ViewSorts.test.tsx | 165 ------- .../internal/usePersistViewFieldRecords.ts | 115 +++++ .../internal/usePersistViewFilterRecords.ts | 156 +++++++ .../internal/usePersistViewSortRecords.ts | 151 ++++++ .../views/hooks/internal/useViewFields.ts | 160 ------- .../views/hooks/internal/useViewFilters.ts | 246 ---------- ...eryParams.ts => useViewFromQueryParams.ts} | 34 +- .../hooks/internal/useViewScopedStates.ts | 90 ---- .../views/hooks/internal/useViewSorts.ts | 236 ---------- .../views/hooks/internal/useViewStates.ts | 96 ++++ .../modules/views/hooks/internal/useViews.ts | 80 ---- .../views/hooks/useCombinedViewFilters.ts | 158 +++++++ .../views/hooks/useCombinedViewSorts.ts | 159 +++++++ .../modules/views/hooks/useGetCurrentView.ts | 107 +++++ .../views/hooks/useGetViewFromCache.ts | 48 ++ .../src/modules/views/hooks/useHandleViews.ts | 130 ++++++ .../src/modules/views/hooks/useInitViewBar.ts | 31 ++ .../views/hooks/useResetCurrentView.ts | 32 ++ .../views/hooks/useSaveCurrentViewFields.ts | 87 ++++ .../useSaveCurrentViewFiltersAndSorts.ts | 147 ++++++ .../hooks/useSetRecordCountInCurrentView.ts | 15 + .../src/modules/views/hooks/useViewBar.ts | 441 ------------------ .../modules/views/hooks/useViewBarEditMode.ts | 14 + .../src/modules/views/scopes/ViewScope.tsx | 26 +- .../init-effect/ViewScopeInitEffect.tsx | 56 +-- ...vailableFieldDefinitionsComponentState.ts} | 4 +- ...ailableFilterDefinitionsComponentState.ts} | 4 +- ...availableSortDefinitionsComponentState.ts} | 4 +- .../currentViewFieldsScopedFamilyState.ts | 11 - .../currentViewFiltersScopedFamilyState.ts | 11 - ...tate.ts => currentViewIdComponentState.ts} | 4 +- .../currentViewSortsScopedFamilyState.ts | 11 - .../entityCountInCurrentViewComponentState.ts | 7 + .../entityCountInCurrentViewScopedState.ts | 8 - .../isCurrentViewIndexComponentState.ts | 7 + .../isPersistingViewFieldsComponentState.ts} | 4 +- .../states/isPersistingViewScopedState.ts | 6 - ....ts => isViewBarExpandedComponentState.ts} | 4 +- .../views/states/noneScopedFamilyState.ts | 6 - .../onCurrentViewChangeComponentState.ts | 9 + .../onViewCompactModeChangeScopeState.ts | 8 - .../states/onViewFieldsChangeScopedState.ts | 10 - .../states/onViewFiltersChangeScopedState.ts | 9 - .../states/onViewSortsChangeScopedState.ts | 9 - .../states/onViewTypeChangeScopedState.ts | 9 - .../savedViewFieldsScopedFamilyState.ts | 11 - .../savedViewFiltersScopedFamilyState.ts | 11 - .../states/savedViewSortsScopedFamilyState.ts | 11 - .../canPersistViewComponentSelector.ts | 21 + ...nPersistViewFiltersScopedFamilySelector.ts | 32 -- ...canPersistViewSortsScopedFamilySelector.ts | 31 -- .../canResetViewComponentSelector.ts | 22 + .../selectors/currentViewComponentSelector.ts | 21 - ...savedViewFieldByKeyScopedFamilySelector.ts | 32 -- ...vedViewFiltersByKeyScopedFamilySelector.ts | 25 - ...savedViewSortsByKeyScopedFamilySelector.ts | 25 - .../selectors/savedViewSortsFamilySelector.ts | 16 - .../selectors/viewsByIdScopedSelector.ts | 18 - ...avedToDeleteViewFilterIdsComponentState.ts | 8 + ...nsavedToDeleteViewSortIdsComponentState.ts | 8 + ...nsavedToUpsertViewFiltersComponentState.ts | 10 + .../unsavedToUpsertViewSortsComponentState.ts | 10 + ...State.ts => viewEditModeComponentState.ts} | 4 +- ... => viewObjectMetadataIdComponentState.ts} | 4 +- .../views/states/viewTypeScopedState.ts | 8 - .../modules/views/states/viewsScopedState.ts | 7 - .../src/modules/views/types/ViewField.ts | 1 + .../src/modules/views/types/ViewFilter.ts | 7 +- .../src/modules/views/types/ViewSort.ts | 3 +- .../utils/__tests__/viewMapFunctions.test.ts | 36 +- .../views/utils/combinedViewFilters.ts | 34 ++ .../modules/views/utils/combinedViewSorts.ts | 34 ++ .../getViewScopedStateValuesFromSnapshot.ts | 115 ----- .../utils/getViewScopedStatesFromSnapshot.ts | 87 ---- .../utils/internal/getViewScopedStates.ts | 225 --------- .../mapBoardFieldDefinitionsToViewFields.ts | 5 +- .../utils/mapColumnDefinitionToViewField.ts | 1 + .../views/utils/mapViewFiltersToFilters.ts | 30 +- .../views/utils/mapViewSortsToSorts.ts | 29 +- .../workspace/hooks/useIsFeatureEnabled.ts | 2 +- .../src/pages/auth/ChooseYourPlan.tsx | 2 +- .../src/pages/auth/CreateProfile.tsx | 2 +- .../src/pages/auth/VerifyEffect.tsx | 2 +- .../__stories__/CreateWorkspace.stories.tsx | 2 +- .../pages/impersonate/ImpersonateEffect.tsx | 4 +- .../object-record/RecordIndexPageHeader.tsx | 2 +- .../settings/SettingsWorkspaceMembers.tsx | 4 +- .../settings/accounts/SettingsAccounts.tsx | 2 +- .../accounts/SettingsAccountsCalendars.tsx | 2 +- .../src/pages/tasks/TasksEffect.tsx | 2 +- .../ObjectMetadataItemsDecorator.tsx | 4 +- .../timeline-calendar-event.service.ts | 2 +- yarn.lock | 8 + 392 files changed, 3476 insertions(+), 4412 deletions(-) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{availableFilterDefinitionsScopedState.ts => availableFilterDefinitionsComponentState.ts} (66%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{filterDefinitionUsedInDropdownScopedState.ts => filterDefinitionUsedInDropdownComponentState.ts} (67%) create mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState.ts rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{isObjectFilterDropdownUnfoldedScopedState.ts => isObjectFilterDropdownUnfoldedComponentState.ts} (78%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{objectFilterDropdownSearchInputScopedState.ts => objectFilterDropdownSearchInputComponentState.ts} (58%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{objectFilterDropdownSelectedEntityIdScopedState.ts => objectFilterDropdownSelectedEntityIdComponentState.ts} (57%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{objectFilterDropdownSelectedRecordIdsScopedState.ts => objectFilterDropdownSelectedOptionValuesComponentState.ts} (55%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{objectFilterDropdownSelectedOptionValuesScopedState.ts => objectFilterDropdownSelectedRecordIdsComponentState.ts} (57%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{onFilterSelectScopedState.ts => onFilterSelectComponentState.ts} (68%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{selectedFilterScopedState.ts => selectedFilterComponentState.ts} (66%) rename packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/{selectedOperandInDropdownScopedState.ts => selectedOperandInDropdownComponentState.ts} (70%) rename packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/{availableSortDefinitionsScopedState.ts => availableSortDefinitionsComponentState.ts} (62%) delete mode 100644 packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated.ts delete mode 100644 packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedSelectorDeprecated.ts delete mode 100644 packages/twenty-front/src/modules/views/constants/index.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFields.test.tsx delete mode 100644 packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFilters.test.tsx delete mode 100644 packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewSorts.test.tsx create mode 100644 packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFieldRecords.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterRecords.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSortRecords.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViewFields.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViewFilters.ts rename packages/twenty-front/src/modules/views/hooks/internal/{useFiltersFromQueryParams.ts => useViewFromQueryParams.ts} (89%) delete mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViewSorts.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViewStates.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/internal/useViews.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useCombinedViewFilters.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useCombinedViewSorts.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useGetCurrentView.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useGetViewFromCache.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useHandleViews.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useInitViewBar.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useResetCurrentView.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFiltersAndSorts.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useSetRecordCountInCurrentView.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/useViewBar.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useViewBarEditMode.ts rename packages/twenty-front/src/modules/views/states/{availableFieldDefinitionsScopedState.ts => availableFieldDefinitionsComponentState.ts} (72%) rename packages/twenty-front/src/modules/views/states/{availableFilterDefinitionsScopedState.ts => availableFilterDefinitionsComponentState.ts} (66%) rename packages/twenty-front/src/modules/views/states/{availableSortDefinitionsScopedState.ts => availableSortDefinitionsComponentState.ts} (66%) delete mode 100644 packages/twenty-front/src/modules/views/states/currentViewFieldsScopedFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/currentViewFiltersScopedFamilyState.ts rename packages/twenty-front/src/modules/views/states/{currentViewIdScopedState.ts => currentViewIdComponentState.ts} (60%) delete mode 100644 packages/twenty-front/src/modules/views/states/currentViewSortsScopedFamilyState.ts create mode 100644 packages/twenty-front/src/modules/views/states/entityCountInCurrentViewComponentState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/entityCountInCurrentViewScopedState.ts create mode 100644 packages/twenty-front/src/modules/views/states/isCurrentViewIndexComponentState.ts rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedScopedState.ts => views/states/isPersistingViewFieldsComponentState.ts} (55%) delete mode 100644 packages/twenty-front/src/modules/views/states/isPersistingViewScopedState.ts rename packages/twenty-front/src/modules/views/states/{isViewBarExpandedScopedState.ts => isViewBarExpandedComponentState.ts} (51%) delete mode 100644 packages/twenty-front/src/modules/views/states/noneScopedFamilyState.ts create mode 100644 packages/twenty-front/src/modules/views/states/onCurrentViewChangeComponentState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/onViewCompactModeChangeScopeState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/onViewFieldsChangeScopedState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/onViewFiltersChangeScopedState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/onViewSortsChangeScopedState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/savedViewFieldsScopedFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/savedViewFiltersScopedFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/savedViewSortsScopedFamilyState.ts create mode 100644 packages/twenty-front/src/modules/views/states/selectors/canPersistViewComponentSelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/canPersistViewFiltersScopedFamilySelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/canPersistViewSortsScopedFamilySelector.ts create mode 100644 packages/twenty-front/src/modules/views/states/selectors/canResetViewComponentSelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/currentViewComponentSelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/savedViewFieldByKeyScopedFamilySelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/savedViewSortsByKeyScopedFamilySelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/savedViewSortsFamilySelector.ts delete mode 100644 packages/twenty-front/src/modules/views/states/selectors/viewsByIdScopedSelector.ts create mode 100644 packages/twenty-front/src/modules/views/states/unsavedToDeleteViewFilterIdsComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/states/unsavedToDeleteViewSortIdsComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/states/unsavedToUpsertViewFiltersComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/states/unsavedToUpsertViewSortsComponentState.ts rename packages/twenty-front/src/modules/views/states/{viewEditModeScopedState.ts => viewEditModeComponentState.ts} (62%) rename packages/twenty-front/src/modules/views/states/{viewObjectMetadataIdScopeState.ts => viewObjectMetadataIdComponentState.ts} (57%) delete mode 100644 packages/twenty-front/src/modules/views/states/viewTypeScopedState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/viewsScopedState.ts create mode 100644 packages/twenty-front/src/modules/views/utils/combinedViewFilters.ts create mode 100644 packages/twenty-front/src/modules/views/utils/combinedViewSorts.ts delete mode 100644 packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts delete mode 100644 packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts delete mode 100644 packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts diff --git a/package.json b/package.json index b99715b82988..da21618c9743 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "libphonenumber-js": "^1.10.26", "lodash.camelcase": "^4.3.0", "lodash.debounce": "^4.0.8", + "lodash.groupby": "^4.6.0", "lodash.isempty": "^4.4.0", "lodash.isequal": "^4.5.0", "lodash.isobject": "^3.0.2", diff --git a/packages/twenty-front/src/App.tsx b/packages/twenty-front/src/App.tsx index 81b665165c1c..71f0e211c8f8 100644 --- a/packages/twenty-front/src/App.tsx +++ b/packages/twenty-front/src/App.tsx @@ -47,7 +47,7 @@ import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMemb import { Tasks } from '~/pages/tasks/Tasks'; export const App = () => { - const billing = useRecoilValue(billingState()); + const billing = useRecoilValue(billingState); return ( <> diff --git a/packages/twenty-front/src/effect-components/CommandMenuEffect.tsx b/packages/twenty-front/src/effect-components/CommandMenuEffect.tsx index 7803c81032ef..ece319312e91 100644 --- a/packages/twenty-front/src/effect-components/CommandMenuEffect.tsx +++ b/packages/twenty-front/src/effect-components/CommandMenuEffect.tsx @@ -5,7 +5,7 @@ import { COMMAND_MENU_COMMANDS } from '@/command-menu/constants/CommandMenuComma import { commandMenuCommandsState } from '@/command-menu/states/commandMenuCommandsState'; export const CommandMenuEffect = () => { - const setCommands = useSetRecoilState(commandMenuCommandsState()); + const setCommands = useSetRecoilState(commandMenuCommandsState); const commands = COMMAND_MENU_COMMANDS; useEffect(() => { diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 65c57eefaceb..2cf692c3e3b5 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -45,7 +45,7 @@ export const PageChangeEffect = () => { const openCreateActivity = useOpenCreateActivityDrawer(); - const isSignUpDisabled = useRecoilValue(isSignUpDisabledState()); + const isSignUpDisabled = useRecoilValue(isSignUpDisabledState); useEffect(() => { if (!previousLocation || previousLocation !== location.pathname) { diff --git a/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx b/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx index c0f332791709..8ed52fe8cff4 100644 --- a/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx +++ b/packages/twenty-front/src/hooks/useDefaultHomePagePath.tsx @@ -13,7 +13,7 @@ export const useDefaultHomePagePath = () => { const companyViewId = records.find( (view: any) => view?.objectMetadataId === companyObjectMetadataItem.id, - )?.node.id; + )?.id; const defaultHomePagePath = '/objects/companies' + (companyViewId ? `?view=${companyViewId}` : ''); diff --git a/packages/twenty-front/src/index.tsx b/packages/twenty-front/src/index.tsx index c23babc438ea..ac59cf8827ea 100644 --- a/packages/twenty-front/src/index.tsx +++ b/packages/twenty-front/src/index.tsx @@ -2,6 +2,7 @@ import { StrictMode } from 'react'; import ReactDOM from 'react-dom/client'; import { HelmetProvider } from 'react-helmet-async'; import { BrowserRouter } from 'react-router-dom'; +import { loadDevMessages, loadErrorMessages } from '@apollo/client/dev'; import { RecoilRoot } from 'recoil'; import { ApolloProvider } from '@/apollo/components/ApolloProvider'; @@ -33,6 +34,10 @@ import 'react-loading-skeleton/dist/skeleton.css'; const root = ReactDOM.createRoot(document.getElementById('root')!); +// Adds messages only in a dev environment +loadDevMessages(); +loadErrorMessages(); + root.render( diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx index da0c22a72d38..8ea22bc6dbc7 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventRow.tsx @@ -102,7 +102,7 @@ export const CalendarEventRow = ({ className, }: CalendarEventRowProps) => { const theme = useTheme(); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { displayCurrentEventCursor = false } = useContext(CalendarContext); const { openCalendarEventRightDrawer } = useOpenCalendarEventRightDrawer(); diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx index 2a60859646f7..845885e7cd7d 100644 --- a/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/components/RightDrawerCalendarEvent.tsx @@ -9,10 +9,10 @@ import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRe export const RightDrawerCalendarEvent = () => { const { setRecords } = useSetRecordInStore(); - const calendarEventId = useRecoilValue(viewableCalendarEventIdState()); + const viewableCalendarEventId = useRecoilValue(viewableCalendarEventIdState); const { record: calendarEvent } = useFindOneRecord({ objectNameSingular: CoreObjectNameSingular.CalendarEvent, - objectRecordId: calendarEventId ?? '', + objectRecordId: viewableCalendarEventId ?? '', onCompleted: (record) => setRecords([record]), }); diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx index 04544ed53bc3..027f7f87557a 100644 --- a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/__tests__/useOpenCalendarEventRightDrawer.test.tsx @@ -9,9 +9,9 @@ describe('useOpenCalendarEventRightDrawer', () => { it('opens the right drawer with the calendar event', () => { const { result } = renderHook( () => { - const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState()); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); const viewableCalendarEventId = useRecoilValue( - viewableCalendarEventIdState(), + viewableCalendarEventIdState, ); return { ...useOpenCalendarEventRightDrawer(), diff --git a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts index ccf3e4fce57a..9cd27d017e52 100644 --- a/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts +++ b/packages/twenty-front/src/modules/activities/calendar/right-drawer/hooks/useOpenCalendarEventRightDrawer.ts @@ -10,7 +10,7 @@ export const useOpenCalendarEventRightDrawer = () => { const { openRightDrawer } = useRightDrawer(); const setHotkeyScope = useSetHotkeyScope(); const setViewableCalendarEventId = useSetRecoilState( - viewableCalendarEventIdState(), + viewableCalendarEventIdState, ); const openCalendarEventRightDrawer = (calendarEventId: string) => { diff --git a/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx b/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx index 3c1b39bcbc79..876d5a2517ad 100644 --- a/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx +++ b/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx @@ -11,7 +11,7 @@ import { Comment } from '../Comment'; import { mockComment, mockCommentWithLongValues } from './mock-comment'; const CommentSetterEffect = () => { - const setViewableActivity = useSetRecoilState(viewableActivityIdState()); + const setViewableActivity = useSetRecoilState(viewableActivityIdState); useEffect(() => { setViewableActivity('test-id'); diff --git a/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx b/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx index 5206587ac08f..d61ebc25b23e 100644 --- a/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx +++ b/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx @@ -13,7 +13,7 @@ import { CommentHeader } from '../CommentHeader'; import { mockComment, mockCommentWithLongValues } from './mock-comment'; const CommentHeaderSetterEffect = () => { - const setViewableActivity = useSetRecoilState(viewableActivityIdState()); + const setViewableActivity = useSetRecoilState(viewableActivityIdState); useEffect(() => { setViewableActivity('test-id'); diff --git a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx index fbc61bb3cc1e..b9c4c84c242a 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx @@ -116,7 +116,7 @@ export const ActivityBodyEditor = ({ ); const [canCreateActivity, setCanCreateActivity] = useRecoilState( - canCreateActivityState(), + canCreateActivityState, ); const [uploadFile] = useUploadFileMutation(); @@ -339,7 +339,7 @@ export const ActivityBodyEditor = ({ if ( isDefined(currentBlockContent) && isArray(currentBlockContent) && - currentBlockContent[0] && + isDefined(currentBlockContent[0]) && currentBlockContent[0].type === 'text' ) { // Text block case diff --git a/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx b/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx index 8647c485e8cc..16bdbed6961c 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx @@ -61,7 +61,7 @@ export const ActivityComments = ({ objectNameSingular: CoreObjectNameSingular.Comment, }); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { records: comments } = useFindManyRecords({ objectNameSingular: CoreObjectNameSingular.Comment, diff --git a/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx b/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx index 1f839640e9d8..93b6f5405671 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx @@ -29,15 +29,15 @@ export const ActivityEditorEffect = ({ ({ snapshot, set }) => () => { const isUpsertingActivityInDB = snapshot - .getLoadable(isUpsertingActivityInDBState()) + .getLoadable(isUpsertingActivityInDBState) .getValue(); const canCreateActivity = snapshot - .getLoadable(canCreateActivityState()) + .getLoadable(canCreateActivityState) .getValue(); const isActivityInCreateMode = snapshot - .getLoadable(isActivityInCreateModeState()) + .getLoadable(isActivityInCreateModeState) .getValue(); const activityFromStore = snapshot @@ -71,7 +71,7 @@ export const ActivityEditorEffect = ({ deleteActivityFromCache(activity); } - set(isActivityInCreateModeState(), false); + set(isActivityInCreateModeState, false); } else if (isDefined(activity)) { if ( activity.title !== activityTitle || diff --git a/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx b/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx index 7a4a11f273b1..05cc0bdd3e52 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx @@ -71,7 +71,7 @@ export const ActivityTitle = ({ activityId }: ActivityTitleProps) => { const activity = activityInStore as Activity; const [canCreateActivity, setCanCreateActivity] = useRecoilState( - canCreateActivityState(), + canCreateActivityState, ); const { upsertActivity } = useUpsertActivity(); diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx index 8c7b10aae2ab..ce085a8e7b3d 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadPreview.tsx @@ -122,7 +122,7 @@ export const EmailThreadPreview = ({ isSameEventThanRightDrawerClose(event.nativeEvent); const emailThreadIdWhenEmailThreadWasClosed = snapshot - .getLoadable(emailThreadIdWhenEmailThreadWasClosedState()) + .getLoadable(emailThreadIdWhenEmailThreadWasClosedState) .getValue(); const canOpen = diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx index 65251d76be43..91cc33ece60e 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreads.tsx @@ -58,12 +58,12 @@ export const EmailThreads = ({ }) => { const { enqueueSnackBar } = useSnackBar(); - const { getEmailThreadsPageState } = useEmailThreadStates({ + const { emailThreadsPageState } = useEmailThreadStates({ emailThreadScopeId: getScopeIdFromComponentId(entity.id), }); const [emailThreadsPage, setEmailThreadsPage] = useRecoilState( - getEmailThreadsPageState(), + emailThreadsPageState, ); const [isFetchingMoreEmails, setIsFetchingMoreEmails] = useState(false); diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx index f68a8872085f..4dae422ca2fd 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx +++ b/packages/twenty-front/src/modules/activities/emails/hooks/__tests__/useEmailThread.test.tsx @@ -12,9 +12,9 @@ describe('useEmailThread', () => { const { result } = renderHook( () => { const emailThread = useEmailThread(); - const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState()); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); const viewableEmailThreadId = useRecoilValue( - viewableEmailThreadIdState(), + viewableEmailThreadIdState, ); return { ...emailThread, isRightDrawerOpen, viewableEmailThreadId }; @@ -38,10 +38,10 @@ describe('useEmailThread', () => { () => { const emailThread = useEmailThread(); const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState( - isRightDrawerOpenState(), + isRightDrawerOpenState, ); const [viewableEmailThreadId, setViewableEmailThreadId] = - useRecoilState(viewableEmailThreadIdState()); + useRecoilState(viewableEmailThreadIdState); return { ...emailThread, diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/internal/__tests__/useEmailThreadStates.test.ts b/packages/twenty-front/src/modules/activities/emails/hooks/internal/__tests__/useEmailThreadStates.test.ts index a1a65c99c27a..0f77de3a96c1 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/internal/__tests__/useEmailThreadStates.test.ts +++ b/packages/twenty-front/src/modules/activities/emails/hooks/internal/__tests__/useEmailThreadStates.test.ts @@ -30,7 +30,7 @@ describe('useEmailThreadStates hook', () => { ); expect(result.current.scopeId).toBe(mockScopeId); - expect(result.current.getEmailThreadsPageState).toBe( + expect(result.current.emailThreadsPageState).toBe( mockGetEmailThreadsPageState, ); }); diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts b/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts index 0162ee6d4feb..472377dfecdf 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts +++ b/packages/twenty-front/src/modules/activities/emails/hooks/internal/useEmailThreadStates.ts @@ -17,7 +17,7 @@ export const useEmailThreadStates = ({ return { scopeId, - getEmailThreadsPageState: extractComponentState( + emailThreadsPageState: extractComponentState( emailThreadsPageComponentState, scopeId, ), diff --git a/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts b/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts index 5ca934b73852..a0757a18af57 100644 --- a/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts +++ b/packages/twenty-front/src/modules/activities/emails/hooks/useEmailThread.ts @@ -13,21 +13,21 @@ export const useEmailThread = () => { ({ snapshot, set }) => (threadId: string) => { const isRightDrawerOpen = snapshot - .getLoadable(isRightDrawerOpenState()) + .getLoadable(isRightDrawerOpenState) .getValue(); const viewableEmailThreadId = snapshot - .getLoadable(viewableEmailThreadIdState()) + .getLoadable(viewableEmailThreadIdState) .getValue(); if (isRightDrawerOpen && viewableEmailThreadId === threadId) { - set(viewableEmailThreadIdState(), null); + set(viewableEmailThreadIdState, null); closeRightDrawer(); return; } openEmailThredRightDrawer(); - set(viewableEmailThreadIdState(), threadId); + set(viewableEmailThreadIdState, threadId); }, [closeRightDrawer, openEmailThredRightDrawer], ); diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx index fc71fdfe3a0c..e353f1dd4a9b 100644 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/components/RightDrawerEmailThread.tsx @@ -34,7 +34,7 @@ export const RightDrawerEmailThread = () => { callbackFunction: useRecoilCallback( ({ set }) => () => { - set(emailThreadIdWhenEmailThreadWasClosedState(), thread.id); + set(emailThreadIdWhenEmailThreadWasClosedState, thread.id); }, [thread], ), diff --git a/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts index dac62986ff75..a6abbd80e27b 100644 --- a/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts +++ b/packages/twenty-front/src/modules/activities/emails/right-drawer/hooks/useRightDrawerEmailThread.ts @@ -9,7 +9,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; export const useRightDrawerEmailThread = () => { - const viewableEmailThreadId = useRecoilValue(viewableEmailThreadIdState()); + const viewableEmailThreadId = useRecoilValue(viewableEmailThreadIdState); const apolloClient = useApolloClient(); const thread = apolloClient.readFragment({ diff --git a/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx b/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx index bfc66abd4846..1a0cceee7a5d 100644 --- a/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx +++ b/packages/twenty-front/src/modules/activities/files/hooks/useUploadAttachmentFile.tsx @@ -10,7 +10,7 @@ import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { FileFolder, useUploadFileMutation } from '~/generated/graphql'; export const useUploadAttachmentFile = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const [uploadFile] = useUploadFileMutation(); const { createOneRecord: createOneAttachment } = diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx index 56730f9c8ffe..53d32b2694f6 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx @@ -201,7 +201,7 @@ describe('useActivities', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const activities = useActivities({ diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityConnectionUtils.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityConnectionUtils.test.tsx index ddda904ee442..c596ecfbd67e 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityConnectionUtils.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityConnectionUtils.test.tsx @@ -58,7 +58,7 @@ describe('useActivityConnectionUtils', () => { { snapshot.set( - objectMetadataItemsState(), + objectMetadataItemsState, getObjectMetadataItemsMock(), ); }} @@ -86,7 +86,7 @@ describe('useActivityConnectionUtils', () => { { snapshot.set( - objectMetadataItemsState(), + objectMetadataItemsState, getObjectMetadataItemsMock(), ); }} diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx index 0a1b8f7b405f..e1041843dc88 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx @@ -186,10 +186,10 @@ describe('useActivityTargetObjectRecords', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); const { activityTargetObjectRecords, loadingActivityTargets } = diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx index e1e55e9c3102..dedd2e3a0cfd 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx @@ -102,7 +102,7 @@ describe('useActivityTargetsForTargetableObject', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const res = useActivityTargetsForTargetableObject({ diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useAttachRelationInBothDirections.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useAttachRelationInBothDirections.test.tsx index e55118b7a05c..a3e8fd73f063 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useAttachRelationInBothDirections.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useAttachRelationInBothDirections.test.tsx @@ -29,10 +29,10 @@ describe('useAttachRelationInBothDirections', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); const res = useAttachRelationInBothDirections(); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx index 08a571a2e77c..a23ee3b4eb85 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx @@ -59,10 +59,10 @@ describe('useCreateActivityInCache', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); const res = useCreateActivityInCache(); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx index 2a323f3bde7c..19a027551a21 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx @@ -18,8 +18,8 @@ describe('useOpenActivityRightDrawer', () => { const { result } = renderHook( () => { const openActivityRightDrawer = useOpenActivityRightDrawer(); - const viewableActivityId = useRecoilValue(viewableActivityIdState()); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); + const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); return { openActivityRightDrawer, activityIdInDrawer, diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx index ee294657c8ef..eb60717a4125 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx @@ -28,10 +28,10 @@ describe('useOpenCreateActivityDrawer', () => { const { result } = renderHook( () => { const openActivityRightDrawer = useOpenCreateActivityDrawer(); - const viewableActivityId = useRecoilValue(viewableActivityIdState()); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); + const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); return { openActivityRightDrawer, diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawerForSelectedRowIds.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawerForSelectedRowIds.test.tsx index 6a4ecc83de2b..7df977a2ad65 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawerForSelectedRowIds.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawerForSelectedRowIds.test.tsx @@ -41,10 +41,10 @@ describe('useOpenCreateActivityDrawerForSelectedRowIds', () => { () => { const openCreateActivityDrawerForSelectedRowIds = useOpenCreateActivityDrawerForSelectedRowIds(recordTableId); - const viewableActivityId = useRecoilValue(viewableActivityIdState()); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); + const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); const scopeId = `${recordTableId}-scope`; const setTableRowIds = useSetRecoilState( diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useUpsertActivity.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useUpsertActivity.test.tsx index fcfb2c94c225..ddf4d40e5eea 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useUpsertActivity.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useUpsertActivity.test.tsx @@ -105,7 +105,7 @@ describe('useUpsertActivity', () => { () => { const res = useUpsertActivity(); const setIsActivityInCreateMode = useSetRecoilState( - isActivityInCreateModeState(), + isActivityInCreateModeState, ); return { ...res, setIsActivityInCreateMode }; @@ -134,7 +134,7 @@ describe('useUpsertActivity', () => { () => { const res = useUpsertActivity(); const setIsActivityInCreateMode = useSetRecoilState( - isActivityInCreateModeState(), + isActivityInCreateModeState, ); const setObjectShowPageTargetableObject = useSetRecoilState( objectShowPageTargetableObjectState, diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts index 63e87ba07d27..359b1c7550b6 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts @@ -14,7 +14,7 @@ export const useActivityTargetObjectRecords = ({ }: { activityId: string; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const { records: activityTargets, loading: loadingActivityTargets } = useFindManyRecords({ diff --git a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts b/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts index 1479b0580a13..4c1a927f7ad3 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts @@ -27,7 +27,7 @@ export const useCreateActivityInCache = () => { objectNameSingular: CoreObjectNameSingular.Activity, }); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { record: currentWorkspaceMemberRecord } = useFindOneRecord({ objectNameSingular: CoreObjectNameSingular.WorkspaceMember, diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts index ae4d579a7c16..b0279e17eece 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts @@ -12,9 +12,9 @@ export const useOpenActivityRightDrawer = () => { const { openRightDrawer, isRightDrawerOpen, rightDrawerPage } = useRightDrawer(); const [viewableActivityId, setViewableActivityId] = useRecoilState( - viewableActivityIdState(), + viewableActivityIdState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState()); + const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); const setHotkeyScope = useSetHotkeyScope(); return (activityId: string) => { diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts index 5b4c313fbb0d..bcd10fcd776a 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts @@ -24,22 +24,20 @@ export const useOpenCreateActivityDrawer = () => { const { createActivityInCache } = useCreateActivityInCache(); const setActivityTargetableEntityArray = useSetRecoilState( - activityTargetableEntityArrayState(), + activityTargetableEntityArrayState, ); - const setViewableActivityId = useSetRecoilState(viewableActivityIdState()); + const setViewableActivityId = useSetRecoilState(viewableActivityIdState); - const setIsCreatingActivity = useSetRecoilState( - isActivityInCreateModeState(), - ); + const setIsCreatingActivity = useSetRecoilState(isActivityInCreateModeState); const setTemporaryActivityForEditor = useSetRecoilState( - temporaryActivityForEditorState(), + temporaryActivityForEditorState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState()); + const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); const [, setIsUpsertingActivityInDB] = useRecoilState( - isUpsertingActivityInDBState(), + isUpsertingActivityInDBState, ); const openCreateActivityDrawer = async ({ diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts index 11cd38d5416a..90713931b61f 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts @@ -14,7 +14,7 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = ( ) => { const openCreateActivityDrawer = useOpenCreateActivityDrawer(); - const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId); + const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); return useRecoilCallback( ({ snapshot }) => @@ -25,7 +25,7 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = ( ) => { const selectedRowIds = getSnapshotValue( snapshot, - getSelectedRowIdsSelector(), + selectedRowIdsSelector(), ); let activityTargetableObjectArray: ActivityTargetableObject[] = @@ -59,6 +59,6 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = ( targetableObjects: activityTargetableObjectArray, }); }, - [openCreateActivityDrawer, getSelectedRowIdsSelector], + [selectedRowIdsSelector, openCreateActivityDrawer], ); }; diff --git a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts index 2634eddc1057..c383d22dfee4 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts @@ -21,7 +21,7 @@ import { isDefined } from '~/utils/isDefined'; // TODO: create a generic way to have records only in cache for create mode and delete them afterwards ? export const useUpsertActivity = () => { const [isActivityInCreateMode, setIsActivityInCreateMode] = useRecoilState( - isActivityInCreateModeState(), + isActivityInCreateModeState, ); const { updateOneRecord: updateOneActivity } = useUpdateOneRecord({ @@ -31,10 +31,10 @@ export const useUpsertActivity = () => { const { createActivityInDB } = useCreateActivityInDB(); const [, setIsUpsertingActivityInDB] = useRecoilState( - isUpsertingActivityInDBState(), + isUpsertingActivityInDBState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState()); + const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); const objectShowPageTargetableObject = useRecoilValue( objectShowPageTargetableObjectState, diff --git a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx index 2c2c3a68edb4..3275f09233ee 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx +++ b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx @@ -34,9 +34,7 @@ export const ActivityTargetInlineCellEditMode = ({ activity, activityTargetWithTargetRecords, }: ActivityTargetInlineCellEditModeProps) => { - const [isActivityInCreateMode] = useRecoilState( - isActivityInCreateModeState(), - ); + const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); const selectedTargetObjectIds = activityTargetWithTargetRecords.map( (activityTarget) => ({ diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx index 1069e8f794fe..40ed872f97fb 100644 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx +++ b/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx @@ -36,13 +36,13 @@ const StyledButtonContainer = styled.div` `; export const ActivityActionBar = () => { - const viewableActivityId = useRecoilValue(viewableActivityIdState()); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); + const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); const activityTargetableEntityArray = useRecoilValue( - activityTargetableEntityArrayState(), + activityTargetableEntityArrayState, ); - const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState()); + const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({ objectNameSingular: CoreObjectNameSingular.Activity, }); @@ -54,15 +54,13 @@ export const ActivityActionBar = () => { ); const [temporaryActivityForEditor, setTemporaryActivityForEditor] = - useRecoilState(temporaryActivityForEditorState()); + useRecoilState(temporaryActivityForEditorState); const { deleteActivityFromCache } = useDeleteActivityFromCache(); - const [isActivityInCreateMode] = useRecoilState( - isActivityInCreateModeState(), - ); + const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); const [isUpsertingActivityInDB] = useRecoilState( - isUpsertingActivityInDBState(), + isUpsertingActivityInDBState, ); const objectShowPageTargetableObject = useRecoilValue( diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx index 4ec49de22aca..fe6ac8ecaf43 100644 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx +++ b/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx @@ -5,7 +5,7 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS import { RightDrawerActivity } from '../RightDrawerActivity'; export const RightDrawerCreateActivity = () => { - const viewableActivityId = useRecoilValue(viewableActivityIdState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); return ( <> diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx index 971d34b81bb4..288d7aca88af 100644 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx +++ b/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx @@ -5,7 +5,7 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS import { RightDrawerActivity } from '../RightDrawerActivity'; export const RightDrawerEditActivity = () => { - const viewableActivityId = useRecoilValue(viewableActivityIdState()); + const viewableActivityId = useRecoilValue(viewableActivityIdState); return ( <> diff --git a/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx b/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx index a6819f2342ca..3f82be635be6 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx @@ -9,10 +9,10 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { parseDate } from '~/utils/date-utils'; export const CurrentUserDueTaskCountEffect = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const [currentUserDueTaskCount, setCurrentUserDueTaskCount] = useRecoilState( - currentUserDueTaskCountState(), + currentUserDueTaskCountState, ); const { records: tasks } = useFindManyRecords({ diff --git a/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx b/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx index bdc9b1c17049..3d1ad6a43bb1 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx @@ -48,8 +48,8 @@ export const TaskGroups = ({ const openCreateActivity = useOpenCreateActivityDrawer(); - const { getActiveTabIdState } = useTabList(TASKS_TAB_LIST_COMPONENT_ID); - const activeTabId = useRecoilValue(getActiveTabIdState()); + const { activeTabIdState } = useTabList(TASKS_TAB_LIST_COMPONENT_ID); + const activeTabId = useRecoilValue(activeTabIdState); if (!initialized) { return <>; diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts index 8ef7e168f925..836ed21bad86 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts @@ -7,7 +7,7 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { parseDate } from '~/utils/date-utils'; export const useCurrentUserTaskCount = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { records: tasks } = useFindManyRecords({ objectNameSingular: CoreObjectNameSingular.Activity, diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts index b4d7b0179f00..0adbe01f18b3 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts @@ -1,7 +1,7 @@ import { useEffect, useMemo } from 'react'; import { isNonEmptyArray } from '@sniptt/guards'; import { DateTime } from 'luxon'; -import { useRecoilState } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import { useActivities } from '@/activities/hooks/useActivities'; import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState'; @@ -23,10 +23,12 @@ export const useTasks = ({ targetableObjects, filterDropdownId, }: UseTasksProps) => { - const { selectedFilter } = useFilterDropdown({ + const { selectedFilterState } = useFilterDropdown({ filterDropdownId, }); + const selectedFilter = useRecoilValue(selectedFilterState); + const assigneeIdFilter = useMemo( () => selectedFilter diff --git a/packages/twenty-front/src/modules/activities/timeline/components/Timeline.tsx b/packages/twenty-front/src/modules/activities/timeline/components/Timeline.tsx index 96621b34a45a..37cc77560ed9 100644 --- a/packages/twenty-front/src/modules/activities/timeline/components/Timeline.tsx +++ b/packages/twenty-front/src/modules/activities/timeline/components/Timeline.tsx @@ -33,7 +33,7 @@ export const Timeline = ({ targetableObject: ActivityTargetableObject; }) => { const { initialized, noActivities } = useRecoilValue( - timelineActivitiesNetworkingState(), + timelineActivitiesNetworkingState, ); const showEmptyState = noActivities; diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx index b8542cd19fee..e53b9ddd84f4 100644 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx +++ b/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx @@ -16,8 +16,8 @@ export const TimelineCreateButtonGroup = ({ }: { targetableObject: ActivityTargetableObject; }) => { - const { getActiveTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); - const setActiveTabId = useSetRecoilState(getActiveTabIdState()); + const { activeTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); + const setActiveTabId = useSetRecoilState(activeTabIdState); const openCreateActivity = useOpenCreateActivityDrawer(); diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx index 59a5a925e529..f509a4781aae 100644 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx +++ b/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx @@ -26,7 +26,7 @@ const StyledScrollWrapper = styled(ScrollWrapper)``; export const TimelineItemsContainer = () => { const timelineActivitiesForGroup = useRecoilValue( - timelineActivitiesForGroupState(), + timelineActivitiesForGroupState, ); const groupedActivities = groupActivitiesByMonth(timelineActivitiesForGroup); diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx index cc0f24fdc144..26a2b781b791 100644 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx +++ b/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx @@ -35,10 +35,10 @@ export const TimelineQueryEffect = ({ }); const [timelineActivitiesNetworking, setTimelineActivitiesNetworking] = - useRecoilState(timelineActivitiesNetworkingState()); + useRecoilState(timelineActivitiesNetworkingState); const [timelineActivitiesForGroup, setTimelineActivitiesForGroup] = - useRecoilState(timelineActivitiesForGroupState()); + useRecoilState(timelineActivitiesForGroupState); useEffect(() => { if (!isDefined(targetableObject)) { diff --git a/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts b/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts index d2c34d023075..88d1d656740b 100644 --- a/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts +++ b/packages/twenty-front/src/modules/analytics/hooks/useEventTracker.ts @@ -13,7 +13,7 @@ export interface EventData { } export const useEventTracker = () => { - const telemetry = useRecoilValue(telemetryState()); + const telemetry = useRecoilValue(telemetryState); const [createEventMutation] = useTrackMutation(); return useCallback( diff --git a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts index 4a2014779358..4da2bc786311 100644 --- a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts +++ b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts @@ -16,11 +16,11 @@ import { ApolloFactory } from '../services/apollo.factory'; export const useApolloFactory = () => { // eslint-disable-next-line @nx/workspace-no-state-useref const apolloRef = useRef | null>(null); - const [isDebugMode] = useRecoilState(isDebugModeState()); + const [isDebugMode] = useRecoilState(isDebugModeState); const navigate = useNavigate(); const isMatchingLocation = useIsMatchingLocation(); - const [tokenPair, setTokenPair] = useRecoilState(tokenPairState()); + const [tokenPair, setTokenPair] = useRecoilState(tokenPairState); const apolloClient = useMemo(() => { apolloRef.current = new ApolloFactory({ diff --git a/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerUpdateRelationsOptimisticEffect.ts b/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerUpdateRelationsOptimisticEffect.ts index 0597a89ed733..f76074e284a6 100644 --- a/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerUpdateRelationsOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerUpdateRelationsOptimisticEffect.ts @@ -26,127 +26,129 @@ export const triggerUpdateRelationsOptimisticEffect = ({ currentSourceRecord: CachedObjectRecord | null; updatedSourceRecord: CachedObjectRecord | null; objectMetadataItems: ObjectMetadataItem[]; -}) => - sourceObjectMetadataItem.fields.forEach((fieldMetadataItemOnSourceRecord) => { - const notARelationField = - fieldMetadataItemOnSourceRecord.type !== FieldMetadataType.Relation; - - if (notARelationField) { - return; - } - - const fieldDoesNotExist = - isDefined(updatedSourceRecord) && - !(fieldMetadataItemOnSourceRecord.name in updatedSourceRecord); - - if (fieldDoesNotExist) { - return; - } - - const relationDefinition = getRelationDefinition({ - fieldMetadataItemOnSourceRecord, - objectMetadataItems, - }); - - if (!relationDefinition) { - return; - } - - const { targetObjectMetadataItem, fieldMetadataItemOnTargetRecord } = - relationDefinition; - - const currentFieldValueOnSourceRecord: - | ObjectRecordConnection - | CachedObjectRecord - | null = currentSourceRecord?.[fieldMetadataItemOnSourceRecord.name]; - - const updatedFieldValueOnSourceRecord: - | ObjectRecordConnection - | CachedObjectRecord - | null = updatedSourceRecord?.[fieldMetadataItemOnSourceRecord.name]; - - if ( - isDeeplyEqual( - currentFieldValueOnSourceRecord, - updatedFieldValueOnSourceRecord, - ) - ) { - return; - } - - // TODO: replace this by a relation type check, if it's one to many, - // it's an object record connection (we can still check it though as a safeguard) - const currentFieldValueOnSourceRecordIsARecordConnection = - isObjectRecordConnection( - targetObjectMetadataItem.nameSingular, - currentFieldValueOnSourceRecord, - ); - - const targetRecordsToDetachFrom = - currentFieldValueOnSourceRecordIsARecordConnection - ? currentFieldValueOnSourceRecord.edges.map( - ({ node }) => node as CachedObjectRecord, - ) - : [currentFieldValueOnSourceRecord].filter(isDefined); - - const updatedFieldValueOnSourceRecordIsARecordConnection = - isObjectRecordConnection( - targetObjectMetadataItem.nameSingular, - updatedFieldValueOnSourceRecord, - ); - - const targetRecordsToAttachTo = - updatedFieldValueOnSourceRecordIsARecordConnection - ? updatedFieldValueOnSourceRecord.edges.map( - ({ node }) => node as CachedObjectRecord, - ) - : [updatedFieldValueOnSourceRecord].filter(isDefined); - - const shouldDetachSourceFromAllTargets = - isDefined(currentSourceRecord) && targetRecordsToDetachFrom.length > 0; - - if (shouldDetachSourceFromAllTargets) { - // TODO: see if we can de-hardcode this, put cascade delete in relation metadata item - // Instead of hardcoding it here - const shouldCascadeDeleteTargetRecords = - CORE_OBJECT_NAMES_TO_DELETE_ON_TRIGGER_RELATION_DETACH.includes( - targetObjectMetadataItem.nameSingular as CoreObjectNameSingular, +}) => { + return sourceObjectMetadataItem.fields.forEach( + (fieldMetadataItemOnSourceRecord) => { + const notARelationField = + fieldMetadataItemOnSourceRecord.type !== FieldMetadataType.Relation; + + if (notARelationField) { + return; + } + + const fieldDoesNotExist = + isDefined(updatedSourceRecord) && + !(fieldMetadataItemOnSourceRecord.name in updatedSourceRecord); + + if (fieldDoesNotExist) { + return; + } + + const relationDefinition = getRelationDefinition({ + fieldMetadataItemOnSourceRecord, + objectMetadataItems, + }); + if (!relationDefinition) { + return; + } + + const { targetObjectMetadataItem, fieldMetadataItemOnTargetRecord } = + relationDefinition; + + const currentFieldValueOnSourceRecord: + | ObjectRecordConnection + | CachedObjectRecord + | null = currentSourceRecord?.[fieldMetadataItemOnSourceRecord.name]; + + const updatedFieldValueOnSourceRecord: + | ObjectRecordConnection + | CachedObjectRecord + | null = updatedSourceRecord?.[fieldMetadataItemOnSourceRecord.name]; + + if ( + isDeeplyEqual( + currentFieldValueOnSourceRecord, + updatedFieldValueOnSourceRecord, + ) + ) { + return; + } + + // TODO: replace this by a relation type check, if it's one to many, + // it's an object record connection (we can still check it though as a safeguard) + const currentFieldValueOnSourceRecordIsARecordConnection = + isObjectRecordConnection( + targetObjectMetadataItem.nameSingular, + currentFieldValueOnSourceRecord, ); - if (shouldCascadeDeleteTargetRecords) { - triggerDeleteRecordsOptimisticEffect({ - cache, - objectMetadataItem: targetObjectMetadataItem, - recordsToDelete: targetRecordsToDetachFrom, - objectMetadataItems, - }); - } else { - targetRecordsToDetachFrom.forEach((targetRecordToDetachFrom) => { - triggerDetachRelationOptimisticEffect({ + const targetRecordsToDetachFrom = + currentFieldValueOnSourceRecordIsARecordConnection + ? currentFieldValueOnSourceRecord.edges.map( + ({ node }) => node as CachedObjectRecord, + ) + : [currentFieldValueOnSourceRecord].filter(isDefined); + + const updatedFieldValueOnSourceRecordIsARecordConnection = + isObjectRecordConnection( + targetObjectMetadataItem.nameSingular, + updatedFieldValueOnSourceRecord, + ); + + const targetRecordsToAttachTo = + updatedFieldValueOnSourceRecordIsARecordConnection + ? updatedFieldValueOnSourceRecord.edges.map( + ({ node }) => node as CachedObjectRecord, + ) + : [updatedFieldValueOnSourceRecord].filter(isDefined); + + const shouldDetachSourceFromAllTargets = + isDefined(currentSourceRecord) && targetRecordsToDetachFrom.length > 0; + + if (shouldDetachSourceFromAllTargets) { + // TODO: see if we can de-hardcode this, put cascade delete in relation metadata item + // Instead of hardcoding it here + const shouldCascadeDeleteTargetRecords = + CORE_OBJECT_NAMES_TO_DELETE_ON_TRIGGER_RELATION_DETACH.includes( + targetObjectMetadataItem.nameSingular as CoreObjectNameSingular, + ); + + if (shouldCascadeDeleteTargetRecords) { + triggerDeleteRecordsOptimisticEffect({ + cache, + objectMetadataItem: targetObjectMetadataItem, + recordsToDelete: targetRecordsToDetachFrom, + objectMetadataItems, + }); + } else { + targetRecordsToDetachFrom.forEach((targetRecordToDetachFrom) => { + triggerDetachRelationOptimisticEffect({ + cache, + sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular, + sourceRecordId: currentSourceRecord.id, + fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name, + targetObjectNameSingular: targetObjectMetadataItem.nameSingular, + targetRecordId: targetRecordToDetachFrom.id, + }); + }); + } + } + + const shouldAttachSourceToAllTargets = + isDefined(updatedSourceRecord) && targetRecordsToAttachTo.length > 0; + + if (shouldAttachSourceToAllTargets) { + targetRecordsToAttachTo.forEach((targetRecordToAttachTo) => + triggerAttachRelationOptimisticEffect({ cache, sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular, - sourceRecordId: currentSourceRecord.id, + sourceRecordId: updatedSourceRecord.id, fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name, targetObjectNameSingular: targetObjectMetadataItem.nameSingular, - targetRecordId: targetRecordToDetachFrom.id, - }); - }); + targetRecordId: targetRecordToAttachTo.id, + }), + ); } - } - - const shouldAttachSourceToAllTargets = - isDefined(updatedSourceRecord) && targetRecordsToAttachTo.length > 0; - - if (shouldAttachSourceToAllTargets) { - targetRecordsToAttachTo.forEach((targetRecordToAttachTo) => - triggerAttachRelationOptimisticEffect({ - cache, - sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular, - sourceRecordId: updatedSourceRecord.id, - fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name, - targetObjectNameSingular: targetObjectMetadataItem.nameSingular, - targetRecordId: targetRecordToAttachTo.id, - }), - ); - } - }); + }, + ); +}; diff --git a/packages/twenty-front/src/modules/auth/hooks/__test__/useAuth.test.tsx b/packages/twenty-front/src/modules/auth/hooks/__test__/useAuth.test.tsx index 230075cdb5a5..25bfda7511b2 100644 --- a/packages/twenty-front/src/modules/auth/hooks/__test__/useAuth.test.tsx +++ b/packages/twenty-front/src/modules/auth/hooks/__test__/useAuth.test.tsx @@ -76,13 +76,13 @@ describe('useAuth', () => { const { result } = renderHook( () => { const client = useApolloClient(); - const icons = useRecoilValue(iconsState()); - const authProviders = useRecoilValue(authProvidersState()); - const billing = useRecoilValue(billingState()); - const isSignInPrefilled = useRecoilValue(isSignInPrefilledState()); - const supportChat = useRecoilValue(supportChatState()); - const telemetry = useRecoilValue(telemetryState()); - const isDebugMode = useRecoilValue(isDebugModeState()); + const icons = useRecoilValue(iconsState); + const authProviders = useRecoilValue(authProvidersState); + const billing = useRecoilValue(billingState); + const isSignInPrefilled = useRecoilValue(isSignInPrefilledState); + const supportChat = useRecoilValue(supportChatState); + const telemetry = useRecoilValue(telemetryState); + const isDebugMode = useRecoilValue(isDebugModeState); return { ...useAuth(), client, diff --git a/packages/twenty-front/src/modules/auth/hooks/__test__/useIsLogged.test.ts b/packages/twenty-front/src/modules/auth/hooks/__test__/useIsLogged.test.ts index a441c479708b..2674f26d9c93 100644 --- a/packages/twenty-front/src/modules/auth/hooks/__test__/useIsLogged.test.ts +++ b/packages/twenty-front/src/modules/auth/hooks/__test__/useIsLogged.test.ts @@ -9,7 +9,7 @@ const renderHooks = () => { const { result } = renderHook( () => { const isLogged = useIsLogged(); - const setTokenPair = useSetRecoilState(tokenPairState()); + const setTokenPair = useSetRecoilState(tokenPairState); return { isLogged, diff --git a/packages/twenty-front/src/modules/auth/hooks/__test__/useOnboardingStatus.test.ts b/packages/twenty-front/src/modules/auth/hooks/__test__/useOnboardingStatus.test.ts index ec035d3c80ad..c57337c914c9 100644 --- a/packages/twenty-front/src/modules/auth/hooks/__test__/useOnboardingStatus.test.ts +++ b/packages/twenty-front/src/modules/auth/hooks/__test__/useOnboardingStatus.test.ts @@ -38,13 +38,13 @@ const renderHooks = () => { const { result } = renderHook( () => { const onboardingStatus = useOnboardingStatus(); - const setBilling = useSetRecoilState(billingState()); - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); + const setBilling = useSetRecoilState(billingState); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); - const setTokenPair = useSetRecoilState(tokenPairState()); - const setVerifyPending = useSetRecoilState(isVerifyPendingState()); + const setTokenPair = useSetRecoilState(tokenPairState); + const setVerifyPending = useSetRecoilState(isVerifyPendingState); return { onboardingStatus, diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index 3ecd5271e5f4..a39d49bcd19b 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -32,14 +32,14 @@ import { currentUserState } from '../states/currentUserState'; import { tokenPairState } from '../states/tokenPairState'; export const useAuth = () => { - const [, setTokenPair] = useRecoilState(tokenPairState()); - const setCurrentUser = useSetRecoilState(currentUserState()); + const [, setTokenPair] = useRecoilState(tokenPairState); + const setCurrentUser = useSetRecoilState(currentUserState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); - const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState()); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); + const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState); const [challenge] = useChallengeMutation(); const [signUp] = useSignUpMutation(); @@ -141,26 +141,26 @@ export const useAuth = () => { ({ snapshot }) => async () => { const emptySnapshot = snapshot_UNSTABLE(); - const iconsValue = snapshot.getLoadable(iconsState()).getValue(); + const iconsValue = snapshot.getLoadable(iconsState).getValue(); const authProvidersValue = snapshot - .getLoadable(authProvidersState()) + .getLoadable(authProvidersState) .getValue(); - const billing = snapshot.getLoadable(billingState()).getValue(); + const billing = snapshot.getLoadable(billingState).getValue(); const isSignInPrefilled = snapshot - .getLoadable(isSignInPrefilledState()) + .getLoadable(isSignInPrefilledState) .getValue(); - const supportChat = snapshot.getLoadable(supportChatState()).getValue(); - const telemetry = snapshot.getLoadable(telemetryState()).getValue(); - const isDebugMode = snapshot.getLoadable(isDebugModeState()).getValue(); + const supportChat = snapshot.getLoadable(supportChatState).getValue(); + const telemetry = snapshot.getLoadable(telemetryState).getValue(); + const isDebugMode = snapshot.getLoadable(isDebugModeState).getValue(); const initialSnapshot = emptySnapshot.map(({ set }) => { - set(iconsState(), iconsValue); - set(authProvidersState(), authProvidersValue); - set(billingState(), billing); - set(isSignInPrefilledState(), isSignInPrefilled); - set(supportChatState(), supportChat); - set(telemetryState(), telemetry); - set(isDebugModeState(), isDebugMode); + set(iconsState, iconsValue); + set(authProvidersState, authProvidersValue); + set(billingState, billing); + set(isSignInPrefilledState, isSignInPrefilled); + set(supportChatState, supportChat); + set(telemetryState, telemetry); + set(isDebugModeState, isDebugMode); return undefined; }); diff --git a/packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts b/packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts index 1c235a747e9d..4399b564c069 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts @@ -5,8 +5,8 @@ import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState'; import { tokenPairState } from '../states/tokenPairState'; export const useIsLogged = (): boolean => { - const [tokenPair] = useRecoilState(tokenPairState()); - const isVerifyPending = useRecoilValue(isVerifyPendingState()); + const [tokenPair] = useRecoilState(tokenPairState); + const isVerifyPending = useRecoilValue(isVerifyPendingState); return !!tokenPair && !isVerifyPending; }; diff --git a/packages/twenty-front/src/modules/auth/hooks/useOnboardingStatus.ts b/packages/twenty-front/src/modules/auth/hooks/useOnboardingStatus.ts index bd8ed6b0dfe1..91a8a60e84e9 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useOnboardingStatus.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useOnboardingStatus.ts @@ -11,9 +11,9 @@ import { } from '../utils/getOnboardingStatus'; export const useOnboardingStatus = (): OnboardingStatus | undefined => { - const billing = useRecoilValue(billingState()); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const billing = useRecoilValue(billingState); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const isLoggedIn = useIsLogged(); return getOnboardingStatus({ diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx index b028ba01ad2b..bc1997f2d483 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx @@ -46,7 +46,7 @@ const StyledInputContainer = styled.div` `; export const SignInUpForm = () => { - const [authProviders] = useRecoilState(authProvidersState()); + const [authProviders] = useRecoilState(authProvidersState); const [showErrors, setShowErrors] = useState(false); const { handleResetPassword } = useHandleResetPassword(); const workspace = useWorkspaceFromInviteHash(); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts index e659696c4cef..ee090c127086 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts @@ -9,7 +9,7 @@ import { WorkspaceMember } from '~/generated/graphql.tsx'; export const useNavigateAfterSignInUp = () => { const navigate = useNavigate(); - const billing = useRecoilValue(billingState()); + const billing = useRecoilValue(billingState); const navigateAfterSignInUp = useCallback( ( currentWorkspace: CurrentWorkspace, diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts index 6677754d26ab..591abf368fb2 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts @@ -19,7 +19,7 @@ const validationSchema = z export type Form = z.infer; export const useSignInUpForm = () => { - const isSignInPrefilled = useRecoilValue(isSignInPrefilledState()); + const isSignInPrefilled = useRecoilValue(isSignInPrefilledState); const form = useForm

      ({ mode: 'onChange', defaultValues: { diff --git a/packages/twenty-front/src/modules/client-config/components/ClientConfigProvider.tsx b/packages/twenty-front/src/modules/client-config/components/ClientConfigProvider.tsx index f7caad94b25f..db62ad64fa8e 100644 --- a/packages/twenty-front/src/modules/client-config/components/ClientConfigProvider.tsx +++ b/packages/twenty-front/src/modules/client-config/components/ClientConfigProvider.tsx @@ -15,17 +15,17 @@ import { isDefined } from '~/utils/isDefined'; export const ClientConfigProvider: React.FC = ({ children, }) => { - const setAuthProviders = useSetRecoilState(authProvidersState()); - const setIsDebugMode = useSetRecoilState(isDebugModeState()); + const setAuthProviders = useSetRecoilState(authProvidersState); + const setIsDebugMode = useSetRecoilState(isDebugModeState); - const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState()); - const setIsSignUpDisabled = useSetRecoilState(isSignUpDisabledState()); + const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState); + const setIsSignUpDisabled = useSetRecoilState(isSignUpDisabledState); - const setBilling = useSetRecoilState(billingState()); - const setTelemetry = useSetRecoilState(telemetryState()); - const setSupportChat = useSetRecoilState(supportChatState()); + const setBilling = useSetRecoilState(billingState); + const setTelemetry = useSetRecoilState(telemetryState); + const setSupportChat = useSetRecoilState(supportChatState); - const setSentryConfig = useSetRecoilState(sentryConfigState()); + const setSentryConfig = useSetRecoilState(sentryConfigState); const { data, loading } = useGetClientConfigQuery(); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx index 0a7a6c554174..b7f281eb1560 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx @@ -109,9 +109,9 @@ export const CommandMenu = () => { const openActivityRightDrawer = useOpenActivityRightDrawer(); const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); const [commandMenuSearch, setCommandMenuSearch] = useRecoilState( - commandMenuSearchState(), + commandMenuSearchState, ); - const commandMenuCommands = useRecoilValue(commandMenuCommandsState()); + const commandMenuCommands = useRecoilValue(commandMenuCommandsState); const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu(); const handleSearchChange = (event: React.ChangeEvent) => { diff --git a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx index 95e4da7d182d..6cf5c7fbf3c5 100644 --- a/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/__stories__/CommandMenu.stories.tsx @@ -27,9 +27,9 @@ const meta: Meta = { component: CommandMenu, decorators: [ (Story) => { - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const { addToCommandMenu, setToInitialCommandMenu, openCommandMenu } = useCommandMenu(); diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__test__/useCommandMenu.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__test__/useCommandMenu.test.tsx index 2cdec0fdc4a4..e1ee5501382f 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__test__/useCommandMenu.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__test__/useCommandMenu.test.tsx @@ -25,7 +25,7 @@ const renderHooks = () => { const commandMenu = useCommandMenu(); const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); const [commandMenuCommands, setCommandMenuCommands] = useRecoilState( - commandMenuCommandsState(), + commandMenuCommandsState, ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts index 438e3b11d8ac..1a8e085064e2 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts @@ -17,7 +17,7 @@ import { Command } from '../types/Command'; export const useCommandMenu = () => { const navigate = useNavigate(); const setIsCommandMenuOpened = useSetRecoilState(isCommandMenuOpenedState); - const setCommands = useSetRecoilState(commandMenuCommandsState()); + const setCommands = useSetRecoilState(commandMenuCommandsState); const { resetSelectedItem } = useSelectableList('command-menu-list'); const { setHotkeyScopeAndMemorizePreviousScope, @@ -52,7 +52,7 @@ export const useCommandMenu = () => { .getLoadable(isCommandMenuOpenedState) .getValue(); - set(commandMenuSearchState(), ''); + set(commandMenuSearchState, ''); if (isCommandMenuOpened) { closeCommandMenu(); diff --git a/packages/twenty-front/src/modules/debug/components/ApolloDevLogEffect.tsx b/packages/twenty-front/src/modules/debug/components/ApolloDevLogEffect.tsx index 7ce1508463ac..93a6af6f0c5b 100644 --- a/packages/twenty-front/src/modules/debug/components/ApolloDevLogEffect.tsx +++ b/packages/twenty-front/src/modules/debug/components/ApolloDevLogEffect.tsx @@ -5,7 +5,7 @@ import { useRecoilValue } from 'recoil'; import { isDebugModeState } from '@/client-config/states/isDebugModeState'; export const ApolloDevLogEffect = () => { - const isDebugMode = useRecoilValue(isDebugModeState()); + const isDebugMode = useRecoilValue(isDebugModeState); useEffect(() => { if (isDebugMode) { diff --git a/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx b/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx index e603623f78ec..5031c1963f9c 100644 --- a/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx +++ b/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx @@ -15,7 +15,7 @@ const formatTitle = (stateName: string) => { }; export const RecoilDebugObserverEffect = () => { - const isDebugMode = useRecoilValue(isDebugModeState()); + const isDebugMode = useRecoilValue(isDebugModeState); useRecoilTransactionObserver_UNSTABLE(({ snapshot }) => { if (!isDebugMode) { diff --git a/packages/twenty-front/src/modules/error-handler/components/SentryInitiEffect.tsx b/packages/twenty-front/src/modules/error-handler/components/SentryInitiEffect.tsx index 874b5ac4b7f9..463810674409 100644 --- a/packages/twenty-front/src/modules/error-handler/components/SentryInitiEffect.tsx +++ b/packages/twenty-front/src/modules/error-handler/components/SentryInitiEffect.tsx @@ -11,11 +11,11 @@ import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { isDefined } from '~/utils/isDefined'; export const SentryInitEffect = () => { - const sentryConfig = useRecoilValue(sentryConfigState()); + const sentryConfig = useRecoilValue(sentryConfigState); - const currentUser = useRecoilValue(currentUserState()); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentUser = useRecoilValue(currentUserState); + const currentWorkspace = useRecoilValue(currentWorkspaceState); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const [isSentryInitialized, setIsSentryInitialized] = useState(false); diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx index a060750e48fc..3d9347f0bcf0 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx +++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx @@ -46,11 +46,11 @@ describe('useFavorites', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember(mockWorkspaceMember); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useFavorites(); @@ -67,11 +67,11 @@ describe('useFavorites', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember(mockWorkspaceMember); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useFavorites(); @@ -95,11 +95,11 @@ describe('useFavorites', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember(mockWorkspaceMember); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useFavorites(); @@ -120,11 +120,11 @@ describe('useFavorites', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember(mockWorkspaceMember); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useFavorites(); diff --git a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts index 25595a40980a..f01cdd1d4fc2 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts @@ -16,7 +16,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql'; import { isDefined } from '~/utils/isDefined'; export const useFavorites = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { objectMetadataItem: favoriteObjectMetadataItem } = useObjectMetadataItem({ diff --git a/packages/twenty-front/src/modules/navigation/components/AppNavigationDrawer.tsx b/packages/twenty-front/src/modules/navigation/components/AppNavigationDrawer.tsx index 216a12462f58..0a8a50cdd21d 100644 --- a/packages/twenty-front/src/modules/navigation/components/AppNavigationDrawer.tsx +++ b/packages/twenty-front/src/modules/navigation/components/AppNavigationDrawer.tsx @@ -28,12 +28,12 @@ export const AppNavigationDrawer = ({ const isMobile = useIsMobile(); const isSettingsPage = useIsSettingsPage(); const currentMobileNavigationDrawer = useRecoilValue( - currentMobileNavigationDrawerState(), + currentMobileNavigationDrawerState, ); const setIsNavigationDrawerOpen = useSetRecoilState( isNavigationDrawerOpenState, ); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const isSettingsDrawer = isMobile ? currentMobileNavigationDrawer === 'settings' diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx index 102f5d7cf333..f8a437ed7c55 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx @@ -24,13 +24,11 @@ export const MainNavigationDrawerItems = () => { const isMobile = useIsMobile(); const { toggleCommandMenu } = useCommandMenu(); const isTasksPage = useIsTasksPage(); - const currentUserDueTaskCount = useRecoilValue( - currentUserDueTaskCountState(), - ); + const currentUserDueTaskCount = useRecoilValue(currentUserDueTaskCountState); const navigate = useNavigate(); const location = useLocation(); const setNavigationMemorizedUrl = useSetRecoilState( - navigationMemorizedUrlState(), + navigationMemorizedUrlState, ); return ( diff --git a/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx b/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx index d671a284e852..3680415ba45a 100644 --- a/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx @@ -30,7 +30,7 @@ export const MobileNavigationBar = () => { isNavigationDrawerOpenState, ); const [currentMobileNavigationDrawer, setCurrentMobileNavigationDrawer] = - useRecoilState(currentMobileNavigationDrawerState()); + useRecoilState(currentMobileNavigationDrawerState); const activeItemName = isNavigationDrawerOpen ? currentMobileNavigationDrawer diff --git a/packages/twenty-front/src/modules/navigation/components/__stories__/AppNavigationDrawer.stories.tsx b/packages/twenty-front/src/modules/navigation/components/__stories__/AppNavigationDrawer.stories.tsx index 3c538ccd6352..e267c7e24aad 100644 --- a/packages/twenty-front/src/modules/navigation/components/__stories__/AppNavigationDrawer.stories.tsx +++ b/packages/twenty-front/src/modules/navigation/components/__stories__/AppNavigationDrawer.stories.tsx @@ -24,7 +24,7 @@ const MobileNavigationDrawerStateSetterEffect = ({ isNavigationDrawerOpenState, ); const setCurrentMobileNavigationDrawer = useSetRecoilState( - currentMobileNavigationDrawerState(), + currentMobileNavigationDrawerState, ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-metadata/components/ApolloMetadataClientProvider.tsx b/packages/twenty-front/src/modules/object-metadata/components/ApolloMetadataClientProvider.tsx index 38bd8fc66d1f..2af8362986e1 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ApolloMetadataClientProvider.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ApolloMetadataClientProvider.tsx @@ -13,7 +13,7 @@ export const ApolloMetadataClientProvider = ({ }: { children: React.ReactNode; }) => { - const [tokenPair] = useRecoilState(tokenPairState()); + const [tokenPair] = useRecoilState(tokenPairState); const apolloMetadataClient = useMemo(() => { if (isNonEmptyString(tokenPair?.accessToken.token)) { return new ApolloClient({ diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsLoadEffect.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsLoadEffect.tsx index 0313a164fbb1..9288ec017b39 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsLoadEffect.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsLoadEffect.tsx @@ -10,7 +10,7 @@ export const ObjectMetadataItemsLoadEffect = () => { useFindManyObjectMetadataItems(); const [objectMetadataItems, setObjectMetadataItems] = useRecoilState( - objectMetadataItemsState(), + objectMetadataItemsState, ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsProvider.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsProvider.tsx index a4a50ac352b5..0c3ebdadc586 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsProvider.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataItemsProvider.tsx @@ -9,8 +9,8 @@ import { RelationPickerScope } from '@/object-record/relation-picker/scopes/Rela export const ObjectMetadataItemsProvider = ({ children, }: React.PropsWithChildren) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const shouldDisplayChildren = objectMetadataItems.length > 0 || !currentWorkspaceMember; diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useFilterOutUnexistingObjectMetadataItems.test.tsx b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useFilterOutUnexistingObjectMetadataItems.test.tsx index d23f347d67a4..e544f642c0b5 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useFilterOutUnexistingObjectMetadataItems.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useFilterOutUnexistingObjectMetadataItems.test.tsx @@ -12,7 +12,7 @@ describe('useFilterOutUnexistingObjectMetadataItems', () => { it('should work as expected', async () => { const { result } = renderHook( () => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems.slice(1)); return useFilterOutUnexistingObjectMetadataItems(); diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetObjectRecordIdentifierByNameSingular.test.tsx b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetObjectRecordIdentifierByNameSingular.test.tsx index 6f25e039ca6b..1a4c0e2cbfcc 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetObjectRecordIdentifierByNameSingular.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetObjectRecordIdentifierByNameSingular.test.tsx @@ -17,7 +17,7 @@ describe('useGetObjectRecordIdentifierByNameSingular', () => { record: any; objectNameSingular: string; }) => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetRelationMetadata.test.tsx b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetRelationMetadata.test.tsx index 45486629086c..b13554ed6e14 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetRelationMetadata.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useGetRelationMetadata.test.tsx @@ -31,7 +31,7 @@ describe('useGetRelationMetadata', () => { const { result } = renderHook( () => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); useEffect(() => { setMetadataItems(objectMetadataItems); diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useObjectMetadataItemForSettings.test.tsx b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useObjectMetadataItemForSettings.test.tsx index e13c468e4ead..c93057e2e8f5 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useObjectMetadataItemForSettings.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useObjectMetadataItemForSettings.test.tsx @@ -44,7 +44,7 @@ describe('useObjectMetadataItemForSettings', () => { it('should findActiveObjectMetadataItemBySlug', async () => { const { result } = renderHook( () => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useObjectMetadataItemForSettings(); @@ -64,7 +64,7 @@ describe('useObjectMetadataItemForSettings', () => { it('should findObjectMetadataItemById', async () => { const { result } = renderHook( () => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useObjectMetadataItemForSettings(); @@ -86,7 +86,7 @@ describe('useObjectMetadataItemForSettings', () => { it('should findObjectMetadataItemByNamePlural', async () => { const { result } = renderHook( () => { - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); return useObjectMetadataItemForSettings(); diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useCreateOneObjectMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useCreateOneObjectMetadataItem.ts index e187ba832105..624cc4066fd8 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useCreateOneObjectMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useCreateOneObjectMetadataItem.ts @@ -28,7 +28,10 @@ export const useCreateOneObjectMetadataItem = () => { input: { object: input }, }, awaitRefetchQueries: true, - refetchQueries: [getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? ''], + refetchQueries: [ + getOperationName(FIND_MANY_OBJECT_METADATA_ITEMS) ?? '', + 'FindManyRecordsMultipleMetadataItems', + ], }); }; diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular.ts index 53c878f873ab..be32e2162949 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular.ts @@ -5,7 +5,7 @@ import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectReco import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier'; export const useGetObjectRecordIdentifierByNameSingular = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); return (record: any, objectNameSingular: string): ObjectRecordIdentifier => { const objectMetadataItem = objectMetadataItems.find( diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItem.ts index 5bd2c94a36f0..a4edf8c39c59 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItem.ts @@ -42,7 +42,7 @@ export const useObjectMetadataItem = ( depth?: number, eagerLoadedRelations?: Record, ) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const mockObjectMetadataItems = getObjectMetadataItemsMock(); @@ -53,7 +53,7 @@ export const useObjectMetadataItem = ( }), ); - let objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + let objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (currentWorkspace?.activationStatus !== 'active') { objectMetadataItem = diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemForSettings.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemForSettings.ts index fce0388690b8..eb8bfe651f18 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemForSettings.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemForSettings.ts @@ -5,7 +5,7 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat import { getObjectSlug } from '../utils/getObjectSlug'; export const useObjectMetadataItemForSettings = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const activeObjectMetadataItems = objectMetadataItems.filter( ({ isActive, isSystem }) => isActive && !isSystem, diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemOnly.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemOnly.ts index aa74d57cc4b2..d5e5b3f552dc 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemOnly.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItemOnly.ts @@ -12,7 +12,7 @@ import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentif export const useObjectMetadataItemOnly = ({ objectNameSingular, }: ObjectMetadataItemIdentifier) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const mockObjectMetadataItems = getObjectMetadataItemsMock(); @@ -23,7 +23,7 @@ export const useObjectMetadataItemOnly = ({ }), ); - let objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + let objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (currentWorkspace?.activationStatus !== 'active') { objectMetadataItem = diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItems.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItems.ts index 0085cccabcfa..215d61200c57 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItems.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectMetadataItems.ts @@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; export const useObjectMetadataItems = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); return { objectMetadataItems, diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNamePluralFromSingular.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNamePluralFromSingular.ts index 5af4b781f970..3cf1c60bbb7c 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNamePluralFromSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNamePluralFromSingular.ts @@ -10,7 +10,7 @@ export const useObjectNamePluralFromSingular = ({ }: { objectNameSingular: string; }) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const mockObjectMetadataItems = getObjectMetadataItemsMock(); let objectMetadataItem = useRecoilValue( diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNameSingularFromPlural.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNameSingularFromPlural.ts index 3e189e224784..432a3b718700 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNameSingularFromPlural.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectNameSingularFromPlural.ts @@ -10,7 +10,7 @@ export const useObjectNameSingularFromPlural = ({ }: { objectNamePlural: string; }) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const mockObjectMetadataItems = getObjectMetadataItemsMock(); diff --git a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemFamilySelector.ts b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemFamilySelector.ts index 7e0d695b3e6f..b264758fbaef 100644 --- a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemFamilySelector.ts +++ b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemFamilySelector.ts @@ -16,7 +16,7 @@ export const objectMetadataItemFamilySelector = selectorFamily< get: ({ objectNameType, objectName }: ObjectMetadataItemSelector) => ({ get }) => { - const objectMetadataItems = get(objectMetadataItemsState()); + const objectMetadataItems = get(objectMetadataItemsState); if (objectNameType === 'singular') { return ( diff --git a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNamePluralMapSelector.ts b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNamePluralMapSelector.ts index 7168e5054ea6..30dfb115ef8e 100644 --- a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNamePluralMapSelector.ts +++ b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNamePluralMapSelector.ts @@ -8,7 +8,7 @@ export const objectMetadataItemsByNamePluralMapSelector = selector< >({ key: 'objectMetadataItemsByNamePluralMapSelector', get: ({ get }) => { - const objectMetadataItems = get(objectMetadataItemsState()); + const objectMetadataItems = get(objectMetadataItemsState); return new Map( objectMetadataItems.map((objectMetadataItem) => [ diff --git a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNameSingularMapSelector.ts b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNameSingularMapSelector.ts index 9111cc6c2d4b..2eddad42b1f9 100644 --- a/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNameSingularMapSelector.ts +++ b/packages/twenty-front/src/modules/object-metadata/states/objectMetadataItemsByNameSingularMapSelector.ts @@ -8,7 +8,7 @@ export const objectMetadataItemsByNameSingularMapSelector = selector< >({ key: 'objectMetadataItemsByNameSingularMapSelector', get: ({ get }) => { - const objectMetadataItems = get(objectMetadataItemsState()); + const objectMetadataItems = get(objectMetadataItemsState); return new Map( objectMetadataItems.map((objectMetadataItem) => [ diff --git a/packages/twenty-front/src/modules/object-record/cache/hooks/useAddRecordInCache.ts b/packages/twenty-front/src/modules/object-record/cache/hooks/useAddRecordInCache.ts index c8d821927e2d..3ef788f6cc16 100644 --- a/packages/twenty-front/src/modules/object-record/cache/hooks/useAddRecordInCache.ts +++ b/packages/twenty-front/src/modules/object-record/cache/hooks/useAddRecordInCache.ts @@ -15,7 +15,7 @@ export const useAddRecordInCache = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const apolloClient = useApolloClient(); const { injectIntoFindOneRecordQueryCache } = diff --git a/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts b/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts index ae30c5897648..3f9e35a95cb7 100644 --- a/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts +++ b/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts @@ -1,3 +1,4 @@ +import { useCallback } from 'react'; import { gql, useApolloClient } from '@apollo/client'; import { useRecoilValue } from 'recoil'; @@ -13,21 +14,22 @@ export const useGetRecordFromCache = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const apolloClient = useApolloClient(); - return ( - recordId: string, - cache = apolloClient.cache, - ) => { - if (isUndefinedOrNull(objectMetadataItem)) { - return null; - } + return useCallback( + ( + recordId: string, + cache = apolloClient.cache, + ) => { + if (isUndefinedOrNull(objectMetadataItem)) { + return null; + } - const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular); + const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular); - const cacheReadFragment = gql` + const cacheReadFragment = gql` fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} ${mapObjectMetadataToGraphQLQuery( { objectMetadataItems, @@ -36,14 +38,16 @@ export const useGetRecordFromCache = ({ )} `; - const cachedRecordId = cache.identify({ - __typename: capitalize(objectMetadataItem.nameSingular), - id: recordId, - }); - - return cache.readFragment({ - id: cachedRecordId, - fragment: cacheReadFragment, - }); - }; + const cachedRecordId = cache.identify({ + __typename: capitalize(objectMetadataItem.nameSingular), + id: recordId, + }); + + return cache.readFragment({ + id: cachedRecordId, + fragment: cacheReadFragment, + }); + }, + [objectMetadataItem, objectMetadataItems, apolloClient], + ); }; diff --git a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts index b82b77ff847a..86a09e9f8c15 100644 --- a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts +++ b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordEdgeFromRecord.ts @@ -17,7 +17,8 @@ export const getRecordEdgeFromRecord = ({ return [ key, getRecordConnectionFromRecords({ - objectNameSingular: key, + // Todo: this is a ugly and broken hack to get the singular, we need to infer this from metadata + objectNameSingular: key.slice(0, -1), records: value as ObjectRecord[], }), ]; diff --git a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useFindManyRecords.test.tsx b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useFindManyRecords.test.tsx index 9da0f77fc28c..480e74bab650 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useFindManyRecords.test.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useFindManyRecords.test.tsx @@ -57,7 +57,7 @@ describe('useFindManyRecords', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember({ id: '32219445-f587-4c40-b2b1-6d3205ed96da', @@ -67,7 +67,7 @@ describe('useFindManyRecords', () => { const mockObjectMetadataItems = getObjectMetadataItemsMock(); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); diff --git a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.test.tsx b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.test.tsx index 2b1ef39614ea..9120bb026ee4 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.test.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.test.tsx @@ -16,7 +16,7 @@ describe('useGenerateFindManyRecordsForMultipleMetadataItemsQuery', () => { const mockObjectMetadataItems = getObjectMetadataItemsMock(); return useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ - objectMetadataItems: mockObjectMetadataItems.slice(0, 2), + targetObjectMetadataItems: mockObjectMetadataItems.slice(0, 2), }); }, { diff --git a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useMapConnectionToRecords.test.tsx b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useMapConnectionToRecords.test.tsx index a975e7cb077f..6d58d3b7dbf3 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useMapConnectionToRecords.test.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useMapConnectionToRecords.test.tsx @@ -18,7 +18,7 @@ import { isDefined } from '~/utils/isDefined'; const Wrapper = getJestHookWrapper({ apolloMocks: [], onInitializeRecoilSnapshot: (snapshot) => { - snapshot.set(objectMetadataItemsState(), getObjectMetadataItemsMock()); + snapshot.set(objectMetadataItemsState, getObjectMetadataItemsMock()); }, }); diff --git a/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts index f3d201bac482..4531e47e6e12 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useFindManyRecords.ts @@ -69,7 +69,7 @@ export const useFindManyRecords = ({ ); const { enqueueSnackBar } = useSnackBar(); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { data, loading, error, fetchMore } = useQuery< ObjectRecordQueryResult diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateManyRecordMutation.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateManyRecordMutation.ts index c36c99f5ce5d..686a5cc5ca49 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateManyRecordMutation.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateManyRecordMutation.ts @@ -17,7 +17,7 @@ export const useGenerateCreateManyRecordMutation = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (isUndefinedOrNull(objectMetadataItem)) { return EMPTY_MUTATION; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateOneRecordMutation.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateOneRecordMutation.ts index 61cef84604ac..b6837892af73 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateOneRecordMutation.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateCreateOneRecordMutation.ts @@ -17,7 +17,7 @@ export const useGenerateCreateOneRecordMutation = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (isUndefinedOrNull(objectMetadataItem)) { return EMPTY_MUTATION; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateExecuteQuickActionOnOneRecordMutation.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateExecuteQuickActionOnOneRecordMutation.ts index 80719fe39fe6..0eb9d6b6c7d2 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateExecuteQuickActionOnOneRecordMutation.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateExecuteQuickActionOnOneRecordMutation.ts @@ -21,7 +21,7 @@ export const useGenerateExecuteQuickActionOnOneRecordMutation = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (isUndefinedOrNull(objectMetadataItem)) { return EMPTY_MUTATION; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindDuplicateRecordsQuery.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindDuplicateRecordsQuery.ts index 51bba8e5feed..747018d0da8d 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindDuplicateRecordsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindDuplicateRecordsQuery.ts @@ -11,7 +11,7 @@ export const getFindDuplicateRecordsQueryResponseField = ( ) => `${objectNameSingular}Duplicates`; export const useGenerateFindDuplicateRecordsQuery = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); return ({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts index a85b4068d623..60b1ca38f086 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery.ts @@ -8,14 +8,14 @@ import { isNonEmptyArray } from '~/utils/isNonEmptyArray'; import { capitalize } from '~/utils/string/capitalize'; export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ - objectMetadataItems, + targetObjectMetadataItems, depth, }: { - objectMetadataItems: ObjectMetadataItem[]; + targetObjectMetadataItems: ObjectMetadataItem[]; depth?: number; }) => { - const allObjectMetadataItems = useRecoilValue(objectMetadataItemsState()); - const capitalizedObjectNameSingulars = objectMetadataItems.map( + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + const capitalizedObjectNameSingulars = targetObjectMetadataItems.map( ({ nameSingular }) => capitalize(nameSingular), ); @@ -58,7 +58,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ ${lastCursorPerMetadataItemArray}, ${limitPerMetadataItemArray} ) { - ${objectMetadataItems + ${targetObjectMetadataItems .map( (objectMetadataItem) => `${objectMetadataItem.namePlural}(filter: $filter${capitalize( @@ -72,7 +72,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({ )}){ edges { node ${mapObjectMetadataToGraphQLQuery({ - objectMetadataItems: allObjectMetadataItems, + objectMetadataItems: objectMetadataItems, objectMetadataItem, depth, })} diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsQuery.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsQuery.ts index db6d0778177e..5a21fe3de6ad 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindManyRecordsQuery.ts @@ -7,7 +7,7 @@ import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObje import { capitalize } from '~/utils/string/capitalize'; export const useGenerateFindManyRecordsQuery = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); return ({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindOneRecordQuery.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindOneRecordQuery.ts index 77a14395a845..e9260cd710f7 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindOneRecordQuery.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateFindOneRecordQuery.ts @@ -7,7 +7,7 @@ import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObje import { capitalize } from '~/utils/string/capitalize'; export const useGenerateFindOneRecordQuery = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); return ({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/hooks/useGenerateUpdateOneRecordMutation.ts b/packages/twenty-front/src/modules/object-record/hooks/useGenerateUpdateOneRecordMutation.ts index 1ba33a915d6d..8880f3a0b820 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useGenerateUpdateOneRecordMutation.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useGenerateUpdateOneRecordMutation.ts @@ -17,7 +17,7 @@ export const useGenerateUpdateOneRecordMutation = ({ }: { objectMetadataItem: ObjectMetadataItem; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); if (isUndefinedOrNull(objectMetadataItem)) { return EMPTY_MUTATION; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useMapConnectionToRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useMapConnectionToRecords.ts index bde4e4e92cb2..a682f1e2b6dd 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useMapConnectionToRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useMapConnectionToRecords.ts @@ -11,7 +11,7 @@ import { FieldMetadataType } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; export const useMapConnectionToRecords = () => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const mapConnectionToRecords = useCallback( ({ diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx index 070d8bf8e4e4..152fb1f82a53 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { ObjectFilterDropdownSearchInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; @@ -20,11 +22,21 @@ export const MultipleFiltersDropdownContent = ({ filterDropdownId, }: MultipleFiltersDropdownContentProps) => { const { - isObjectFilterDropdownOperandSelectUnfolded, - filterDefinitionUsedInDropdown, - selectedOperandInDropdown, + isObjectFilterDropdownOperandSelectUnfoldedState, + filterDefinitionUsedInDropdownState, + selectedOperandInDropdownState, } = useFilterDropdown({ filterDropdownId }); + const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + return ( <> {!filterDefinitionUsedInDropdown ? ( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx index 0a4a16e62b41..3b5672783714 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; @@ -14,9 +16,14 @@ export const ObjectFilterDropdownButton = ({ filterDropdownId, hotkeyScope, }: ObjectFilterDropdownButtonProps) => { - const { availableFilterDefinitions } = useFilterDropdown({ + const { availableFilterDefinitionsState } = useFilterDropdown({ filterDropdownId: filterDropdownId, }); + + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, + ); + const hasOnlyOneEntityFilter = availableFilterDefinitions.length === 1 && availableFilterDefinitions[0].type === 'RELATION'; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx index d3098859ef9e..11c9f1ab2820 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx @@ -1,15 +1,24 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker'; import { isDefined } from '~/utils/isDefined'; export const ObjectFilterDropdownDateInput = () => { const { - filterDefinitionUsedInDropdown, - selectedOperandInDropdown, + filterDefinitionUsedInDropdownState, + selectedOperandInDropdownState, setIsObjectFilterDropdownUnfolded, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const handleChange = (date: Date | null) => { if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect.tsx index 0d19879da2ca..27b155975058 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import { useRecoilValue } from 'recoil'; import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; @@ -15,13 +16,24 @@ export const ObjectFilterDropdownEntitySearchSelect = ({ }) => { const { setObjectFilterDropdownSelectedEntityId, - filterDefinitionUsedInDropdown, - selectedOperandInDropdown, - objectFilterDropdownSearchInput, - selectedFilter, + filterDefinitionUsedInDropdownState, + selectedOperandInDropdownState, + objectFilterDropdownSearchInputState, + selectedFilterState, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const objectFilterDropdownSearchInput = useRecoilValue( + objectFilterDropdownSearchInputState, + ); + const selectedFilter = useRecoilValue(selectedFilterState); + const { closeDropdown } = useDropdown(OBJECT_FILTER_DROPDOWN_ID); const [isAllEntitySelected, setIsAllEntitySelected] = useState(false); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx index 93bc71a1be4b..676fcb9a32bb 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; import { useIcons } from '@/ui/display/icon/hooks/useIcons'; @@ -12,9 +14,13 @@ export const ObjectFilterDropdownFilterSelect = () => { setFilterDefinitionUsedInDropdown, setSelectedOperandInDropdown, setObjectFilterDropdownSearchInput, - availableFilterDefinitions, + availableFilterDefinitionsState, } = useFilterDropdown(); + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, + ); + const { getIcon } = useIcons(); const setHotkeyScope = useSetHotkeyScope(); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownNumberInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownNumberInput.tsx index aec637714094..d6cc92eaaf1f 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownNumberInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownNumberInput.tsx @@ -1,15 +1,23 @@ import { ChangeEvent } from 'react'; +import { useRecoilValue } from 'recoil'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput'; export const ObjectFilterDropdownNumberInput = () => { const { - selectedOperandInDropdown, - filterDefinitionUsedInDropdown, + selectedOperandInDropdownState, + filterDefinitionUsedInDropdownState, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + return ( filterDefinitionUsedInDropdown && selectedOperandInDropdown && ( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx index 7c5e0b251353..6641de0dd480 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { IconChevronDown } from '@/ui/display/icon'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; @@ -6,11 +8,18 @@ import { getOperandLabel } from '../utils/getOperandLabel'; export const ObjectFilterDropdownOperandButton = () => { const { - selectedOperandInDropdown, + selectedOperandInDropdownState, setIsObjectFilterDropdownOperandSelectUnfolded, - isObjectFilterDropdownOperandSelectUnfolded, + isObjectFilterDropdownOperandSelectUnfoldedState, } = useFilterDropdown(); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + if (isObjectFilterDropdownOperandSelectUnfolded) { return null; } diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx index 43886b392152..d3f0ccccfd6a 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; @@ -9,14 +11,24 @@ import { getOperandsForFilterType } from '../utils/getOperandsForFilterType'; export const ObjectFilterDropdownOperandSelect = () => { const { - filterDefinitionUsedInDropdown, + filterDefinitionUsedInDropdownState, setSelectedOperandInDropdown, - isObjectFilterDropdownOperandSelectUnfolded, + isObjectFilterDropdownOperandSelectUnfoldedState, setIsObjectFilterDropdownOperandSelectUnfolded, - selectedFilter, + selectedFilterState, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + + const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + + const selectedFilter = useRecoilValue(selectedFilterState); + const operandsForFilterType = getOperandsForFilterType( filterDefinitionUsedInDropdown?.type, ); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx index db46aa88d131..9e09777fa50a 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import { useRecoilValue } from 'recoil'; import { MenuItem, MenuItemMultiSelect } from 'tsup.ui.index'; import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem'; @@ -16,13 +17,26 @@ type SelectOptionForFilter = FieldMetadataItemOption & { export const ObjectFilterDropdownOptionSelect = () => { const { - filterDefinitionUsedInDropdown, - objectFilterDropdownSearchInput, - selectedOperandInDropdown, - objectFilterDropdownSelectedOptionValues, + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + selectedOperandInDropdownState, + objectFilterDropdownSelectedOptionValuesState, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const objectFilterDropdownSearchInput = useRecoilValue( + objectFilterDropdownSearchInputState, + ); + const objectFilterDropdownSelectedOptionValues = useRecoilValue( + objectFilterDropdownSelectedOptionValuesState, + ); + const fieldMetaDataId = filterDefinitionUsedInDropdown?.fieldMetadataId ?? ''; const { selectOptions } = useOptionsForSelect(fieldMetaDataId); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx index 0b41a5c5df00..65a2c3263dc3 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect.tsx @@ -1,3 +1,5 @@ +import { useRecoilValue } from 'recoil'; + import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { MultipleRecordSelectDropdown } from '@/object-record/select/components/MultipleRecordSelectDropdown'; import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect'; @@ -9,15 +11,28 @@ export const MAX_RECORDS_TO_DISPLAY = 3; export const ObjectFilterDropdownRecordSelect = () => { const { - filterDefinitionUsedInDropdown, - objectFilterDropdownSearchInput, - selectedOperandInDropdown, + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + selectedOperandInDropdownState, setObjectFilterDropdownSelectedRecordIds, - objectFilterDropdownSelectedRecordIds, + objectFilterDropdownSelectedRecordIdsState, selectFilter, emptyFilterButKeepDefinition, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const objectFilterDropdownSearchInput = useRecoilValue( + objectFilterDropdownSearchInputState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const objectFilterDropdownSelectedRecordIds = useRecoilValue( + objectFilterDropdownSelectedRecordIdsState, + ); + const objectNameSingular = filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? ''; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput.tsx index 1a45f6aa3794..d84d2e4dde8e 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSearchInput.tsx @@ -1,16 +1,27 @@ import { ChangeEvent } from 'react'; +import { useRecoilValue } from 'recoil'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; export const ObjectFilterDropdownSearchInput = () => { const { - filterDefinitionUsedInDropdown, - selectedOperandInDropdown, - objectFilterDropdownSearchInput, + filterDefinitionUsedInDropdownState, + selectedOperandInDropdownState, + objectFilterDropdownSearchInputState, setObjectFilterDropdownSearchInput, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const objectFilterDropdownSearchInput = useRecoilValue( + objectFilterDropdownSearchInputState, + ); + return ( filterDefinitionUsedInDropdown && selectedOperandInDropdown && ( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx index 999fd6403020..445d080ad699 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx @@ -1,18 +1,30 @@ import { ChangeEvent } from 'react'; +import { useRecoilValue } from 'recoil'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; export const ObjectFilterDropdownTextSearchInput = () => { const { - filterDefinitionUsedInDropdown, - selectedOperandInDropdown, - objectFilterDropdownSearchInput, + filterDefinitionUsedInDropdownState, + selectedOperandInDropdownState, + objectFilterDropdownSearchInputState, setObjectFilterDropdownSearchInput, - selectedFilter, + selectedFilterState, selectFilter, } = useFilterDropdown(); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + const selectedOperandInDropdown = useRecoilValue( + selectedOperandInDropdownState, + ); + const objectFilterDropdownSearchInput = useRecoilValue( + objectFilterDropdownSearchInputState, + ); + const selectedFilter = useRecoilValue(selectedFilterState); + return ( filterDefinitionUsedInDropdown && selectedOperandInDropdown && ( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButton.tsx index 8e8d52fe5b95..e6de651105e7 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButton.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { useTheme } from '@emotion/react'; +import { useRecoilValue } from 'recoil'; import { ObjectFilterDropdownRecordRemoveFilterMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordRemoveFilterMenuItem'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; @@ -22,12 +23,17 @@ export const SingleEntityObjectFilterDropdownButton = ({ hotkeyScope: HotkeyScope; }) => { const { - availableFilterDefinitions, - selectedFilter, + availableFilterDefinitionsState, + selectedFilterState, setFilterDefinitionUsedInDropdown, setSelectedOperandInDropdown, } = useFilterDropdown(); + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, + ); + const selectedFilter = useRecoilValue(selectedFilterState); + const availableFilter = availableFilterDefinitions[0]; React.useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/__tests__/useFilterDropdown.test.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/__tests__/useFilterDropdown.test.tsx index 76316b9dcd8d..3b3cd45a4431 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/__tests__/useFilterDropdown.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/__tests__/useFilterDropdown.test.tsx @@ -1,8 +1,9 @@ import { expect } from '@storybook/test'; import { act, renderHook, waitFor } from '@testing-library/react'; -import { RecoilRoot } from 'recoil'; +import { RecoilRoot, useRecoilState } from 'recoil'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; +import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; @@ -31,10 +32,15 @@ const mockFilter: Filter = { describe('useFilterDropdown', () => { it('should set availableFilterDefinitions', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { availableFilterDefinitionsState } = + useFilterDropdownStates(filterDropdownId); + + const [availableFilterDefinitions, setAvailableFilterDefinitions] = + useRecoilState(availableFilterDefinitionsState); + return { availableFilterDefinitions, setAvailableFilterDefinitions }; + }, renderHookConfig); expect(result.current.availableFilterDefinitions).toEqual([]); @@ -50,10 +56,14 @@ describe('useFilterDropdown', () => { }); it('should set onFilterSelect', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId); + + const [onFilterSelect, setOnFilterSelect] = + useRecoilState(onFilterSelectState); + return { onFilterSelect, setOnFilterSelect }; + }, renderHookConfig); expect(result.current.onFilterSelect).toBeUndefined(); @@ -68,10 +78,16 @@ describe('useFilterDropdown', () => { }); it('should set selectedOperandInDropdown', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { selectedOperandInDropdownState } = + useFilterDropdownStates(filterDropdownId); + + const [selectedOperandInDropdown, setSelectedOperandInDropdown] = + useRecoilState(selectedOperandInDropdownState); + return { selectedOperandInDropdown, setSelectedOperandInDropdown }; + }, renderHookConfig); + const mockOperand = ViewFilterOperand.Contains; expect(result.current.selectedOperandInDropdown).toBeNull(); @@ -84,10 +100,14 @@ describe('useFilterDropdown', () => { }); it('should set selectedFilter', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { selectedFilterState } = useFilterDropdownStates(filterDropdownId); + + const [selectedFilter, setSelectedFilter] = + useRecoilState(selectedFilterState); + return { selectedFilter, setSelectedFilter }; + }, renderHookConfig); expect(result.current.selectedFilter).toBeUndefined(); @@ -101,10 +121,20 @@ describe('useFilterDropdown', () => { }); it('should set filterDefinitionUsedInDropdown', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { filterDefinitionUsedInDropdownState } = + useFilterDropdownStates(filterDropdownId); + + const [ + filterDefinitionUsedInDropdown, + setFilterDefinitionUsedInDropdown, + ] = useRecoilState(filterDefinitionUsedInDropdownState); + return { + filterDefinitionUsedInDropdown, + setFilterDefinitionUsedInDropdown, + }; + }, renderHookConfig); expect(result.current.filterDefinitionUsedInDropdown).toBeNull(); @@ -121,10 +151,20 @@ describe('useFilterDropdown', () => { it('should set objectFilterDropdownSearchInput', async () => { const mockResult = 'value'; - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { objectFilterDropdownSearchInputState } = + useFilterDropdownStates(filterDropdownId); + + const [ + objectFilterDropdownSearchInput, + setObjectFilterDropdownSearchInput, + ] = useRecoilState(objectFilterDropdownSearchInputState); + return { + objectFilterDropdownSearchInput, + setObjectFilterDropdownSearchInput, + }; + }, renderHookConfig); expect(result.current.objectFilterDropdownSearchInput).toBe(''); @@ -139,10 +179,20 @@ describe('useFilterDropdown', () => { it('should set objectFilterDropdownSelectedEntityId', async () => { const mockResult = 'value'; - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { objectFilterDropdownSelectedEntityIdState } = + useFilterDropdownStates(filterDropdownId); + + const [ + objectFilterDropdownSelectedEntityId, + setObjectFilterDropdownSelectedEntityId, + ] = useRecoilState(objectFilterDropdownSelectedEntityIdState); + return { + objectFilterDropdownSelectedEntityId, + setObjectFilterDropdownSelectedEntityId, + }; + }, renderHookConfig); expect(result.current.objectFilterDropdownSelectedEntityId).toBeNull(); @@ -159,10 +209,20 @@ describe('useFilterDropdown', () => { it('should set objectFilterDropdownSelectedRecordIds', async () => { const mockResult = ['id-0', 'id-1', 'id-2']; - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { objectFilterDropdownSelectedRecordIdsState } = + useFilterDropdownStates(filterDropdownId); + + const [ + objectFilterDropdownSelectedRecordIds, + setObjectFilterDropdownSelectedRecordIds, + ] = useRecoilState(objectFilterDropdownSelectedRecordIdsState); + return { + objectFilterDropdownSelectedRecordIds, + setObjectFilterDropdownSelectedRecordIds, + }; + }, renderHookConfig); expect(result.current.objectFilterDropdownSelectedRecordIds).toHaveLength( 0, @@ -180,10 +240,20 @@ describe('useFilterDropdown', () => { }); it('should set isObjectFilterDropdownOperandSelectUnfolded', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { isObjectFilterDropdownOperandSelectUnfoldedState } = + useFilterDropdownStates(filterDropdownId); + + const [ + isObjectFilterDropdownOperandSelectUnfolded, + setIsObjectFilterDropdownOperandSelectUnfolded, + ] = useRecoilState(isObjectFilterDropdownOperandSelectUnfoldedState); + return { + isObjectFilterDropdownOperandSelectUnfolded, + setIsObjectFilterDropdownOperandSelectUnfolded, + }; + }, renderHookConfig); expect(result.current.isObjectFilterDropdownOperandSelectUnfolded).toBe( false, @@ -201,10 +271,20 @@ describe('useFilterDropdown', () => { }); it('should set isObjectFilterDropdownUnfolded', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useFilterDropdown({ filterDropdownId }); + const { isObjectFilterDropdownUnfoldedState } = + useFilterDropdownStates(filterDropdownId); + + const [ + isObjectFilterDropdownUnfolded, + setIsObjectFilterDropdownUnfolded, + ] = useRecoilState(isObjectFilterDropdownUnfoldedState); + return { + isObjectFilterDropdownUnfolded, + setIsObjectFilterDropdownUnfolded, + }; + }, renderHookConfig); expect(result.current.isObjectFilterDropdownUnfolded).toBe(false); @@ -218,10 +298,16 @@ describe('useFilterDropdown', () => { }); it('should reset filter', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + const { selectFilter, resetFilter } = useFilterDropdown({ + filterDropdownId, + }); + const { selectedFilterState } = useFilterDropdownStates(filterDropdownId); + + const [selectedFilter, setSelectedFilter] = + useRecoilState(selectedFilterState); + return { selectedFilter, setSelectedFilter, selectFilter, resetFilter }; + }, renderHookConfig); act(() => { result.current.selectFilter(mockFilter); @@ -241,10 +327,14 @@ describe('useFilterDropdown', () => { }); it('should call onFilterSelect when a filter option is set', async () => { - const { result } = renderHook( - () => useFilterDropdown({ filterDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + const { selectFilter } = useFilterDropdown({ filterDropdownId }); + const { onFilterSelectState } = useFilterDropdownStates(filterDropdownId); + + const [onFilterSelect, setOnFilterSelect] = + useRecoilState(onFilterSelectState); + return { onFilterSelect, setOnFilterSelect, selectFilter }; + }, renderHookConfig); const onFilterSelectMock = jest.fn(); expect(result.current.onFilterSelect).toBeUndefined(); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdown.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdown.ts index 90d6f77f1e35..945d19c68954 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdown.ts @@ -1,7 +1,8 @@ -import { useCallback } from 'react'; +import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useFilterDropdownStates } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownStates'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; +import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { ObjectFilterDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectFilterDropdownScopeInternalContext'; import { Filter } from '../types/Filter'; @@ -17,92 +18,122 @@ export const useFilterDropdown = (props?: UseFilterDropdownProps) => { ); const { - availableFilterDefinitions, - setAvailableFilterDefinitions, - filterDefinitionUsedInDropdown, - setFilterDefinitionUsedInDropdown, - objectFilterDropdownSearchInput, - setObjectFilterDropdownSearchInput, - objectFilterDropdownSelectedEntityId, - setObjectFilterDropdownSelectedEntityId, - objectFilterDropdownSelectedRecordIds, - setObjectFilterDropdownSelectedRecordIds, - objectFilterDropdownSelectedOptionValues, - setObjectFilterDropdownSelectedOptionValues, - isObjectFilterDropdownOperandSelectUnfolded, - setIsObjectFilterDropdownOperandSelectUnfolded, - isObjectFilterDropdownUnfolded, - setIsObjectFilterDropdownUnfolded, - selectedFilter, - setSelectedFilter, - selectedOperandInDropdown, - setSelectedOperandInDropdown, - onFilterSelect, - setOnFilterSelect, + availableFilterDefinitionsState, + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + objectFilterDropdownSelectedEntityIdState, + objectFilterDropdownSelectedRecordIdsState, + objectFilterDropdownSelectedOptionValuesState, + isObjectFilterDropdownOperandSelectUnfoldedState, + isObjectFilterDropdownUnfoldedState, + selectedFilterState, + selectedOperandInDropdownState, + onFilterSelectState, } = useFilterDropdownStates(scopeId); - const selectFilter = useCallback( - (filter: Filter | null) => { - setSelectedFilter(filter); - onFilterSelect?.(filter); - }, - [setSelectedFilter, onFilterSelect], + const selectFilter = useRecoilCallback( + ({ set, snapshot }) => + (filter: Filter | null) => { + set(selectedFilterState, filter); + const onFilterSelect = getSnapshotValue(snapshot, onFilterSelectState); + + onFilterSelect?.(filter); + }, + [selectedFilterState, onFilterSelectState], ); - const emptyFilterButKeepDefinition = useCallback(() => { - setObjectFilterDropdownSearchInput(''); - setObjectFilterDropdownSelectedEntityId(null); - setObjectFilterDropdownSelectedRecordIds([]); - setSelectedFilter(undefined); - }, [ - setSelectedFilter, - setObjectFilterDropdownSelectedRecordIds, - setObjectFilterDropdownSelectedEntityId, - setObjectFilterDropdownSearchInput, - ]); + const emptyFilterButKeepDefinition = useRecoilCallback( + ({ set }) => + () => { + set(objectFilterDropdownSearchInputState, ''); + set(objectFilterDropdownSelectedEntityIdState, null); + set(objectFilterDropdownSelectedRecordIdsState, []); + set(selectedFilterState, undefined); + }, + [ + objectFilterDropdownSearchInputState, + objectFilterDropdownSelectedEntityIdState, + objectFilterDropdownSelectedRecordIdsState, + selectedFilterState, + ], + ); - const resetFilter = useCallback(() => { - setObjectFilterDropdownSearchInput(''); - setObjectFilterDropdownSelectedEntityId(null); - setObjectFilterDropdownSelectedRecordIds([]); - setSelectedFilter(undefined); - setFilterDefinitionUsedInDropdown(null); - setSelectedOperandInDropdown(null); - }, [ - setFilterDefinitionUsedInDropdown, - setObjectFilterDropdownSearchInput, - setObjectFilterDropdownSelectedEntityId, - setObjectFilterDropdownSelectedRecordIds, - setSelectedFilter, - setSelectedOperandInDropdown, - ]); + const resetFilter = useRecoilCallback( + ({ set }) => + () => { + set(objectFilterDropdownSearchInputState, ''); + set(objectFilterDropdownSelectedEntityIdState, null); + set(objectFilterDropdownSelectedRecordIdsState, []); + set(selectedFilterState, undefined); + set(filterDefinitionUsedInDropdownState, null); + set(selectedOperandInDropdownState, null); + }, + [ + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + objectFilterDropdownSelectedEntityIdState, + objectFilterDropdownSelectedRecordIdsState, + selectedFilterState, + selectedOperandInDropdownState, + ], + ); + + const setAvailableFilterDefinitions = useSetRecoilState( + availableFilterDefinitionsState, + ); + const setSelectedFilter = useSetRecoilState(selectedFilterState); + const setSelectedOperandInDropdown = useSetRecoilState( + selectedOperandInDropdownState, + ); + const setFilterDefinitionUsedInDropdown = useSetRecoilState( + filterDefinitionUsedInDropdownState, + ); + const setObjectFilterDropdownSearchInput = useSetRecoilState( + objectFilterDropdownSearchInputState, + ); + const setObjectFilterDropdownSelectedEntityId = useSetRecoilState( + objectFilterDropdownSelectedEntityIdState, + ); + const setObjectFilterDropdownSelectedRecordIds = useSetRecoilState( + objectFilterDropdownSelectedRecordIdsState, + ); + const setObjectFilterDropdownSelectedOptionValues = useSetRecoilState( + objectFilterDropdownSelectedOptionValuesState, + ); + const setIsObjectFilterDropdownOperandSelectUnfolded = useSetRecoilState( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + const setIsObjectFilterDropdownUnfolded = useSetRecoilState( + isObjectFilterDropdownUnfoldedState, + ); + const setOnFilterSelect = useSetRecoilState(onFilterSelectState); return { scopeId, - availableFilterDefinitions, + selectFilter, + resetFilter, + setSelectedFilter, + setSelectedOperandInDropdown, setAvailableFilterDefinitions, - filterDefinitionUsedInDropdown, setFilterDefinitionUsedInDropdown, - objectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput, - objectFilterDropdownSelectedEntityId, setObjectFilterDropdownSelectedEntityId, - objectFilterDropdownSelectedRecordIds, setObjectFilterDropdownSelectedRecordIds, - objectFilterDropdownSelectedOptionValues, setObjectFilterDropdownSelectedOptionValues, - isObjectFilterDropdownOperandSelectUnfolded, setIsObjectFilterDropdownOperandSelectUnfolded, - isObjectFilterDropdownUnfolded, setIsObjectFilterDropdownUnfolded, - selectedFilter, - setSelectedFilter, - selectedOperandInDropdown, - setSelectedOperandInDropdown, - selectFilter, - resetFilter, - onFilterSelect, setOnFilterSelect, emptyFilterButKeepDefinition, + availableFilterDefinitionsState, + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + objectFilterDropdownSelectedEntityIdState, + objectFilterDropdownSelectedRecordIdsState, + objectFilterDropdownSelectedOptionValuesState, + isObjectFilterDropdownOperandSelectUnfoldedState, + isObjectFilterDropdownUnfoldedState, + selectedFilterState, + selectedOperandInDropdownState, + onFilterSelectState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdownStates.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdownStates.ts index 94b969b84a34..47a4835c1d18 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdownStates.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useFilterDropdownStates.ts @@ -1,97 +1,84 @@ -import { objectFilterDropdownSelectedRecordIdsScopedState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState'; -import { onFilterSelectScopedState } from '@/object-record/object-filter-dropdown/states/onFilterSelectScopedState'; -import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2'; - -import { availableFilterDefinitionsScopedState } from '../states/availableFilterDefinitionsScopedState'; -import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState'; -import { isObjectFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isObjectFilterDropdownOperandSelectUnfoldedScopedState'; -import { isObjectFilterDropdownUnfoldedScopedState } from '../states/isObjectFilterDropdownUnfoldedScopedState'; -import { objectFilterDropdownSearchInputScopedState } from '../states/objectFilterDropdownSearchInputScopedState'; -import { objectFilterDropdownSelectedEntityIdScopedState } from '../states/objectFilterDropdownSelectedEntityIdScopedState'; -import { objectFilterDropdownSelectedOptionValuesScopedState } from '../states/objectFilterDropdownSelectedOptionValuesScopedState'; -import { selectedFilterScopedState } from '../states/selectedFilterScopedState'; -import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState'; +import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState'; +import { isObjectFilterDropdownOperandSelectUnfoldedComponentState } from '@/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState'; +import { isObjectFilterDropdownUnfoldedComponentState } from '@/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedComponentState'; +import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState'; +import { objectFilterDropdownSelectedEntityIdComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdComponentState'; +import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState'; +import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState'; +import { onFilterSelectComponentState } from '@/object-record/object-filter-dropdown/states/onFilterSelectComponentState'; +import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState'; +import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; +import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState'; export const useFilterDropdownStates = (scopeId: string) => { - const [availableFilterDefinitions, setAvailableFilterDefinitions] = - useRecoilScopedStateV2(availableFilterDefinitionsScopedState, scopeId); - - const [filterDefinitionUsedInDropdown, setFilterDefinitionUsedInDropdown] = - useRecoilScopedStateV2(filterDefinitionUsedInDropdownScopedState, scopeId); + const availableFilterDefinitionsState = extractComponentState( + availableFilterDefinitionsComponentState, + scopeId, + ); - const [objectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput] = - useRecoilScopedStateV2(objectFilterDropdownSearchInputScopedState, scopeId); + const filterDefinitionUsedInDropdownState = extractComponentState( + filterDefinitionUsedInDropdownComponentState, + scopeId, + ); - const [ - objectFilterDropdownSelectedEntityId, - setObjectFilterDropdownSelectedEntityId, - ] = useRecoilScopedStateV2( - objectFilterDropdownSelectedEntityIdScopedState, + const objectFilterDropdownSearchInputState = extractComponentState( + objectFilterDropdownSearchInputComponentState, scopeId, ); - const [ - objectFilterDropdownSelectedRecordIds, - setObjectFilterDropdownSelectedRecordIds, - ] = useRecoilScopedStateV2( - objectFilterDropdownSelectedRecordIdsScopedState, + const objectFilterDropdownSelectedEntityIdState = extractComponentState( + objectFilterDropdownSelectedEntityIdComponentState, scopeId, ); - const [ - objectFilterDropdownSelectedOptionValues, - setObjectFilterDropdownSelectedOptionValues, - ] = useRecoilScopedStateV2( - objectFilterDropdownSelectedOptionValuesScopedState, + const objectFilterDropdownSelectedRecordIdsState = extractComponentState( + objectFilterDropdownSelectedRecordIdsComponentState, scopeId, ); - const [ - isObjectFilterDropdownOperandSelectUnfolded, - setIsObjectFilterDropdownOperandSelectUnfolded, - ] = useRecoilScopedStateV2( - isObjectFilterDropdownOperandSelectUnfoldedScopedState, + const objectFilterDropdownSelectedOptionValuesState = extractComponentState( + objectFilterDropdownSelectedOptionValuesComponentState, scopeId, ); - const [isObjectFilterDropdownUnfolded, setIsObjectFilterDropdownUnfolded] = - useRecoilScopedStateV2(isObjectFilterDropdownUnfoldedScopedState, scopeId); + const isObjectFilterDropdownOperandSelectUnfoldedState = + extractComponentState( + isObjectFilterDropdownOperandSelectUnfoldedComponentState, + scopeId, + ); - const [selectedFilter, setSelectedFilter] = useRecoilScopedStateV2( - selectedFilterScopedState, + const isObjectFilterDropdownUnfoldedState = extractComponentState( + isObjectFilterDropdownUnfoldedComponentState, scopeId, ); - const [selectedOperandInDropdown, setSelectedOperandInDropdown] = - useRecoilScopedStateV2(selectedOperandInDropdownScopedState, scopeId); + const selectedFilterState = extractComponentState( + selectedFilterComponentState, + scopeId, + ); + + const selectedOperandInDropdownState = extractComponentState( + selectedOperandInDropdownComponentState, + scopeId, + ); - const [onFilterSelect, setOnFilterSelect] = useRecoilScopedStateV2( - onFilterSelectScopedState, + const onFilterSelectState = extractComponentState( + onFilterSelectComponentState, scopeId, ); return { - availableFilterDefinitions, - setAvailableFilterDefinitions, - filterDefinitionUsedInDropdown, - setFilterDefinitionUsedInDropdown, - objectFilterDropdownSearchInput, - setObjectFilterDropdownSearchInput, - objectFilterDropdownSelectedEntityId, - setObjectFilterDropdownSelectedEntityId, - objectFilterDropdownSelectedRecordIds, - objectFilterDropdownSelectedOptionValues, - setObjectFilterDropdownSelectedOptionValues, - setObjectFilterDropdownSelectedRecordIds, - isObjectFilterDropdownOperandSelectUnfolded, - setIsObjectFilterDropdownOperandSelectUnfolded, - isObjectFilterDropdownUnfolded, - setIsObjectFilterDropdownUnfolded, - selectedFilter, - setSelectedFilter, - selectedOperandInDropdown, - setSelectedOperandInDropdown, - onFilterSelect, - setOnFilterSelect, + availableFilterDefinitionsState, + filterDefinitionUsedInDropdownState, + objectFilterDropdownSearchInputState, + objectFilterDropdownSelectedEntityIdState, + objectFilterDropdownSelectedRecordIdsState, + objectFilterDropdownSelectedOptionValuesState, + isObjectFilterDropdownOperandSelectUnfoldedState, + isObjectFilterDropdownUnfoldedState, + selectedFilterState, + selectedOperandInDropdownState, + onFilterSelectState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsComponentState.ts similarity index 66% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsComponentState.ts index 8433868e1b12..9a3f649ea491 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/availableFilterDefinitionsComponentState.ts @@ -1,9 +1,9 @@ import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const availableFilterDefinitionsScopedState = createComponentState< +export const availableFilterDefinitionsComponentState = createComponentState< FilterDefinition[] >({ - key: 'availableFilterDefinitionsScopedState', + key: 'availableFilterDefinitionsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState.ts similarity index 67% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState.ts index 874d06a63059..c7fd89f92902 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState.ts @@ -2,8 +2,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils import { FilterDefinition } from '../types/FilterDefinition'; -export const filterDefinitionUsedInDropdownScopedState = +export const filterDefinitionUsedInDropdownComponentState = createComponentState({ - key: 'filterDefinitionUsedInDropdownScopedState', + key: 'filterDefinitionUsedInDropdownComponentState', defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState.ts new file mode 100644 index 000000000000..389c6d30f928 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedComponentState.ts @@ -0,0 +1,7 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const isObjectFilterDropdownOperandSelectUnfoldedComponentState = + createComponentState({ + key: 'isObjectFilterDropdownOperandSelectUnfoldedComponentState', + defaultValue: false, + }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedComponentState.ts similarity index 78% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedComponentState.ts index e07f31ca1b9b..cfd6dea10c8f 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownUnfoldedComponentState.ts @@ -1,6 +1,6 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const isObjectFilterDropdownUnfoldedScopedState = +export const isObjectFilterDropdownUnfoldedComponentState = createComponentState({ key: 'isObjectFilterDropdownUnfoldedScopedState', defaultValue: false, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState.ts similarity index 58% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState.ts index 83c73842daae..8addf2fb6cc6 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState.ts @@ -1,7 +1,7 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const objectFilterDropdownSearchInputScopedState = +export const objectFilterDropdownSearchInputComponentState = createComponentState({ - key: 'objectFilterDropdownSearchInputScopedState', + key: 'objectFilterDropdownSearchInputComponentState', defaultValue: '', }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdComponentState.ts similarity index 57% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdComponentState.ts index 9eba05a6b796..3f62c3d65b1b 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedEntityIdComponentState.ts @@ -1,7 +1,7 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const objectFilterDropdownSelectedEntityIdScopedState = +export const objectFilterDropdownSelectedEntityIdComponentState = createComponentState({ - key: 'objectFilterDropdownSelectedEntityIdScopedState', + key: 'objectFilterDropdownSelectedEntityIdComponentState', defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState.ts similarity index 55% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState.ts index e5e1b396c0d2..feef87220c1e 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState.ts @@ -1,7 +1,7 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const objectFilterDropdownSelectedRecordIdsScopedState = +export const objectFilterDropdownSelectedOptionValuesComponentState = createComponentState({ - key: 'objectFilterDropdownSelectedRecordIdsScopedState', + key: 'objectFilterDropdownSelectedOptionValuesComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState.ts similarity index 57% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState.ts index db1124959fc7..de23b3b0daa5 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState.ts @@ -1,7 +1,7 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const objectFilterDropdownSelectedOptionValuesScopedState = +export const objectFilterDropdownSelectedRecordIdsComponentState = createComponentState({ - key: 'objectFilterDropdownSelectedOptionValuesScopedState', + key: 'objectFilterDropdownSelectedRecordIdsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectComponentState.ts similarity index 68% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectComponentState.ts index 43a90fa7aa4c..b73c2cbe962f 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/onFilterSelectComponentState.ts @@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils import { Filter } from '../types/Filter'; -export const onFilterSelectScopedState = createComponentState< +export const onFilterSelectComponentState = createComponentState< ((filter: Filter | null) => void) | undefined >({ - key: 'onFilterSelectScopedState', + key: 'onFilterSelectComponentState', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterComponentState.ts similarity index 66% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterComponentState.ts index c9df2abcea31..7b4183c74841 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedFilterComponentState.ts @@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils import { Filter } from '../types/Filter'; -export const selectedFilterScopedState = createComponentState< +export const selectedFilterComponentState = createComponentState< Filter | undefined | null >({ - key: 'selectedFilterScopedState', + key: 'selectedFilterComponentState', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownScopedState.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState.ts similarity index 70% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState.ts index 087ac6d07f49..eef8fe552a96 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState.ts @@ -1,8 +1,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; -export const selectedOperandInDropdownScopedState = +export const selectedOperandInDropdownComponentState = createComponentState({ - key: 'selectedOperandInDropdownScopedState', + key: 'selectedOperandInDropdownComponentState', defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx index 4487463fa5e1..2b3fb2541c95 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react'; +import { useRecoilValue } from 'recoil'; import { OBJECT_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ObjectSortDropdownId'; import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown'; @@ -37,7 +38,7 @@ export const ObjectSortDropdownButton = ({ setSelectedSortDirection('asc'); }, []); - const { isSortSelected } = useSortDropdown({ + const { isSortSelectedState } = useSortDropdown({ sortDropdownId: sortDropdownId, }); @@ -48,10 +49,16 @@ export const ObjectSortDropdownButton = ({ resetState(); }; - const { availableSortDefinitions, onSortSelect } = useSortDropdown({ + const { availableSortDefinitionsState, onSortSelectState } = useSortDropdown({ sortDropdownId: sortDropdownId, }); + const isSortSelected = useRecoilValue(isSortSelectedState); + const availableSortDefinitions = useRecoilValue( + availableSortDefinitionsState, + ); + const onSortSelect = useRecoilValue(onSortSelectState); + const handleAddSort = (selectedSortDefinition: SortDefinition) => { toggleDropdown(); onSortSelect?.({ diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/__tests__/useSortDropdown.test.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/__tests__/useSortDropdown.test.tsx index 108055202573..6bf6ddf0d53e 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/__tests__/useSortDropdown.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/__tests__/useSortDropdown.test.tsx @@ -1,7 +1,9 @@ +import { expect } from '@storybook/test'; import { act, renderHook, waitFor } from '@testing-library/react'; -import { RecoilRoot } from 'recoil'; +import { RecoilRoot, useRecoilState } from 'recoil'; import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown'; +import { useSortDropdownStates } from '@/object-record/object-sort-dropdown/hooks/useSortDropdownStates'; import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition'; @@ -20,10 +22,19 @@ const sortDefinitions: SortDefinition[] = [ describe('useSortDropdown', () => { it('should set availableSortDefinitions', async () => { - const { result } = renderHook( - () => useSortDropdown({ sortDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useSortDropdown({ sortDropdownId }); + const { availableSortDefinitionsState } = + useSortDropdownStates(sortDropdownId); + + const [availableSortDefinitions, setAvailableSortDefinitions] = + useRecoilState(availableSortDefinitionsState); + + return { + availableSortDefinitions, + setAvailableSortDefinitions, + }; + }, renderHookConfig); expect(result.current.availableSortDefinitions).toEqual([]); act(() => { result.current.setAvailableSortDefinitions(sortDefinitions); @@ -35,10 +46,18 @@ describe('useSortDropdown', () => { }); it('should set isSortSelected', async () => { - const { result } = renderHook( - () => useSortDropdown({ sortDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useSortDropdown({ sortDropdownId }); + const { isSortSelectedState } = useSortDropdownStates(sortDropdownId); + + const [isSortSelected, setIsSortSelected] = + useRecoilState(isSortSelectedState); + + return { + isSortSelected, + setIsSortSelected, + }; + }, renderHookConfig); expect(result.current.isSortSelected).toBe(false); @@ -54,10 +73,17 @@ describe('useSortDropdown', () => { it('should set onSortSelect', async () => { const OnSortSelectFunction = () => {}; const mockOnSortSelect = jest.fn(() => OnSortSelectFunction); - const { result } = renderHook( - () => useSortDropdown({ sortDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useSortDropdown({ sortDropdownId }); + const { onSortSelectState } = useSortDropdownStates(sortDropdownId); + + const [onSortSelect, setOnSortSelect] = useRecoilState(onSortSelectState); + + return { + onSortSelect, + setOnSortSelect, + }; + }, renderHookConfig); expect(result.current.onSortSelect).toBeUndefined(); @@ -78,10 +104,17 @@ describe('useSortDropdown', () => { definition: sortDefinitions[0], }; - const { result } = renderHook( - () => useSortDropdown({ sortDropdownId }), - renderHookConfig, - ); + const { result } = renderHook(() => { + useSortDropdown({ sortDropdownId }); + const { onSortSelectState } = useSortDropdownStates(sortDropdownId); + + const [onSortSelect, setOnSortSelect] = useRecoilState(onSortSelectState); + + return { + onSortSelect, + setOnSortSelect, + }; + }, renderHookConfig); act(() => { result.current.setOnSortSelect(mockOnSortSelect); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts index 696dae8cd631..aee777aa1217 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts @@ -13,21 +13,15 @@ export const useSortDropdown = (props?: UseSortProps) => { props?.sortDropdownId, ); const { - availableSortDefinitions, - setAvailableSortDefinitions, - isSortSelected, - setIsSortSelected, - onSortSelect, - setOnSortSelect, + availableSortDefinitionsState, + isSortSelectedState, + onSortSelectState, } = useSortDropdownStates(scopeId); return { scopeId, - availableSortDefinitions, - isSortSelected, - setIsSortSelected, - setAvailableSortDefinitions, - onSortSelect, - setOnSortSelect, + availableSortDefinitionsState, + isSortSelectedState, + onSortSelectState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts index 9453508fee46..74c6bdb5481a 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts @@ -1,29 +1,27 @@ -import { onSortSelectScopedState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState'; -import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2'; - -import { availableSortDefinitionsScopedState } from '../states/availableSortDefinitionsScopedState'; -import { isSortSelectedScopedState } from '../states/isSortSelectedScopedState'; +import { isSortSelectedComponentState } from '@/object-record/object-sort-dropdown/states/isSortSelectedScopedState'; +import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; +import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState'; export const useSortDropdownStates = (scopeId: string) => { - const [availableSortDefinitions, setAvailableSortDefinitions] = - useRecoilScopedStateV2(availableSortDefinitionsScopedState, scopeId); + const availableSortDefinitionsState = extractComponentState( + availableSortDefinitionsComponentState, + scopeId, + ); - const [isSortSelected, setIsSortSelected] = useRecoilScopedStateV2( - isSortSelectedScopedState, + const isSortSelectedState = extractComponentState( + isSortSelectedComponentState, scopeId, ); - const [onSortSelect, setOnSortSelect] = useRecoilScopedStateV2( - onSortSelectScopedState, + const onSortSelectState = extractComponentState( + onSortSelectComponentState, scopeId, ); return { - availableSortDefinitions, - setAvailableSortDefinitions, - isSortSelected, - setIsSortSelected, - onSortSelect, - setOnSortSelect, + availableSortDefinitionsState, + isSortSelectedState, + onSortSelectState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsScopedState.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsComponentState.ts similarity index 62% rename from packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsScopedState.ts rename to packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsComponentState.ts index 3f8165b63d59..db559fa52f6b 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/availableSortDefinitionsComponentState.ts @@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils import { SortDefinition } from '../types/SortDefinition'; -export const availableSortDefinitionsScopedState = createComponentState< +export const availableSortDefinitionsComponentState = createComponentState< SortDefinition[] >({ - key: 'availableSortDefinitionsScopedState', + key: 'availableSortDefinitionsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/isSortSelectedScopedState.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/isSortSelectedScopedState.ts index 071d662741ce..180a2f017221 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/isSortSelectedScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/isSortSelectedScopedState.ts @@ -1,6 +1,6 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const isSortSelectedScopedState = createComponentState({ - key: 'isSortSelectedScopedState', +export const isSortSelectedComponentState = createComponentState({ + key: 'isSortSelectedComponentState', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/onSortSelectScopedState.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/onSortSelectScopedState.ts index 9e0661722961..8b6ca0a8cb35 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/onSortSelectScopedState.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/onSortSelectScopedState.ts @@ -2,9 +2,9 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils import { Sort } from '../types/Sort'; -export const onSortSelectScopedState = createComponentState< +export const onSortSelectComponentState = createComponentState< ((sort: Sort) => void) | undefined >({ - key: 'onSortSelectScopedState', + key: 'onSortSelectComponentState', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/__tests__/turnSortsIntoOrderBy.test.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/__tests__/turnSortsIntoOrderBy.test.tsx index b46ee87ac717..5a9dc2de62a5 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/__tests__/turnSortsIntoOrderBy.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/__tests__/turnSortsIntoOrderBy.test.tsx @@ -55,7 +55,7 @@ describe('turnSortsIntoOrderBy', () => { }); }); - it('should throw error if field not found', () => { + it('should ignore if field not found', () => { const sorts: Sort[] = [ { fieldMetadataId: 'invalidField', @@ -63,8 +63,8 @@ describe('turnSortsIntoOrderBy', () => { definition: sortDefinition, }, ]; - expect(() => turnSortsIntoOrderBy(sorts, [])).toThrow( - 'Could not find field invalidField in metadata object', - ); + expect(turnSortsIntoOrderBy(sorts, [])).toEqual({ + position: 'AscNullsFirst', + }); }); }); diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy.ts index b2c487f6ec92..85452ddfcf65 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy.ts @@ -2,6 +2,7 @@ import { OrderBy } from '@/object-metadata/types/OrderBy'; import { OrderByField } from '@/object-metadata/types/OrderByField'; import { Field } from '~/generated/graphql'; import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; +import { isDefined } from '~/utils/isDefined'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { Sort } from '../types/Sort'; @@ -12,20 +13,20 @@ export const turnSortsIntoOrderBy = ( ): OrderByField => { const fieldsById = mapArrayToObject(fields, ({ id }) => id); const sortsOrderBy = Object.fromEntries( - sorts.map((sort) => { - const correspondingField = fieldsById[sort.fieldMetadataId]; + sorts + .map((sort) => { + const correspondingField = fieldsById[sort.fieldMetadataId]; - if (isUndefinedOrNull(correspondingField)) { - throw new Error( - `Could not find field ${sort.fieldMetadataId} in metadata object`, - ); - } + if (isUndefinedOrNull(correspondingField)) { + return undefined; + } - const direction: OrderBy = - sort.direction === 'asc' ? 'AscNullsFirst' : 'DescNullsLast'; + const direction: OrderBy = + sort.direction === 'asc' ? 'AscNullsFirst' : 'DescNullsLast'; - return [correspondingField.name, direction]; - }), + return [correspondingField.name, direction]; + }) + .filter(isDefined), ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx index 7ee44441afc6..090647575d5a 100644 --- a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx @@ -34,8 +34,8 @@ export const useRecordActionBar = ({ selectedRecordIds, callback, }: useRecordActionBarProps) => { - const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState()); - const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState()); + const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState); + const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState); const { createFavorite, favorites, deleteFavorite } = useFavorites(); diff --git a/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx index d0d810222011..2bb43e96ceee 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx @@ -10,9 +10,9 @@ type RecordBoardActionBarProps = { export const RecordBoardActionBar = ({ recordBoardId, }: RecordBoardActionBarProps) => { - const { getSelectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); + const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); - const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector()); + const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); if (!selectedRecordIds.length) { return null; diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx index f8aa66909a56..c877865d9810 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx @@ -50,12 +50,12 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => { const boardRef = useRef(null); const { - getColumnIdsState, + columnIdsState, columnsFamilySelector, recordIdsByColumnIdFamilyState, } = useRecordBoardStates(recordBoardId); - const columnIds = useRecoilValue(getColumnIdsState()); + const columnIds = useRecoilValue(columnIdsState); const { resetRecordSelection, setRecordAsSelected } = useRecordBoardSelection(recordBoardId); diff --git a/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx b/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx index b98245d90165..fed35a6506d3 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx @@ -10,9 +10,9 @@ type RecordBoardContextMenuProps = { export const RecordBoardContextMenu = ({ recordBoardId, }: RecordBoardContextMenuProps) => { - const { getSelectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); + const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); - const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector()); + const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); if (!selectedRecordIds.length) { return null; diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts index cd5b2cf31412..1c8f8a1849bd 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts @@ -28,15 +28,15 @@ export const useRecordBoardStates = (recordBoardId?: string) => { return { scopeId, - getObjectSingularNameState: extractComponentState( + objectSingularNameState: extractComponentState( recordBoardObjectSingularNameComponentState, scopeId, ), - getIsFetchingRecordState: extractComponentState( + isFetchingRecordState: extractComponentState( isRecordBoardFetchingRecordsComponentState, scopeId, ), - getColumnIdsState: extractComponentState( + columnIdsState: extractComponentState( recordBoardColumnIdsComponentState, scopeId, ), @@ -53,19 +53,16 @@ export const useRecordBoardStates = (recordBoardId?: string) => { scopeId, ), - getFiltersState: extractComponentState( + filtersState: extractComponentState( recordBoardFiltersComponentState, scopeId, ), - getSortsState: extractComponentState( - recordBoardSortsComponentState, - scopeId, - ), - getFieldDefinitionsState: extractComponentState( + sortsState: extractComponentState(recordBoardSortsComponentState, scopeId), + fieldDefinitionsState: extractComponentState( recordBoardFieldDefinitionsComponentState, scopeId, ), - getVisibleFieldDefinitionsState: extractComponentReadOnlySelector( + visibleFieldDefinitionsState: extractComponentReadOnlySelector( recordBoardVisibleFieldDefinitionsComponentSelector, scopeId, ), @@ -78,17 +75,17 @@ export const useRecordBoardStates = (recordBoardId?: string) => { isRecordBoardCardSelectedComponentFamilyState, scopeId, ), - getSelectedRecordIdsSelector: extractComponentReadOnlySelector( + selectedRecordIdsSelector: extractComponentReadOnlySelector( recordBoardSelectedRecordIdsComponentSelector, scopeId, ), - getIsCompactModeActiveState: extractComponentState( + isCompactModeActiveState: extractComponentState( isRecordBoardCompactModeActiveComponentState, scopeId, ), - getOnFetchMoreVisibilityChangeState: extractComponentState( + onFetchMoreVisibilityChangeState: extractComponentState( onRecordBoardFetchMoreVisibilityChangeComponentState, scopeId, ), diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardColumns.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardColumns.ts index 34ca406203a9..d330a476d64f 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardColumns.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardColumns.ts @@ -5,14 +5,14 @@ import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const useSetRecordBoardColumns = (recordBoardId?: string) => { - const { scopeId, getColumnIdsState, columnsFamilySelector } = + const { scopeId, columnIdsState, columnsFamilySelector } = useRecordBoardStates(recordBoardId); const setColumns = useRecoilCallback( ({ set, snapshot }) => (columns: RecordBoardColumnDefinition[]) => { const currentColumnsIds = snapshot - .getLoadable(getColumnIdsState()) + .getLoadable(columnIdsState) .getValue(); const columnIds = columns.map(({ id }) => id); @@ -22,7 +22,7 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => { } set( - getColumnIdsState(), + columnIdsState, columns.map((column) => column.id), ); @@ -38,7 +38,7 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => { set(columnsFamilySelector(column.id), column); }); }, - [columnsFamilySelector, getColumnIdsState], + [columnsFamilySelector, columnIdsState], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts index 03db29158c6c..90f5a1ad93fd 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts @@ -9,13 +9,13 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => { scopeId, recordIdsByColumnIdFamilyState, columnsFamilySelector, - getColumnIdsState, + columnIdsState, } = useRecordBoardStates(recordBoardId); const setRecordIds = useRecoilCallback( ({ set, snapshot }) => (records: ObjectRecord[]) => { - const columnIds = snapshot.getLoadable(getColumnIdsState()).getValue(); + const columnIds = snapshot.getLoadable(columnIdsState).getValue(); columnIds.forEach((columnId) => { const column = snapshot @@ -36,7 +36,7 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => { } }); }, - [columnsFamilySelector, getColumnIdsState, recordIdsByColumnIdFamilyState], + [columnsFamilySelector, columnIdsState, recordIdsByColumnIdFamilyState], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts index 59429b254652..f6a266d4746b 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts @@ -7,17 +7,17 @@ import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/i export const useRecordBoard = (recordBoardId?: string) => { const { scopeId, - getFieldDefinitionsState, - getObjectSingularNameState, - getSelectedRecordIdsSelector, - getIsCompactModeActiveState, - getOnFetchMoreVisibilityChangeState, + fieldDefinitionsState, + objectSingularNameState, + selectedRecordIdsSelector, + isCompactModeActiveState, + onFetchMoreVisibilityChangeState, } = useRecordBoardStates(recordBoardId); const { setColumns } = useSetRecordBoardColumns(recordBoardId); const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId); - const setFieldDefinitions = useSetRecoilState(getFieldDefinitionsState()); - const setObjectSingularName = useSetRecoilState(getObjectSingularNameState()); + const setFieldDefinitions = useSetRecoilState(fieldDefinitionsState); + const setObjectSingularName = useSetRecoilState(objectSingularNameState); return { scopeId, @@ -25,8 +25,8 @@ export const useRecordBoard = (recordBoardId?: string) => { setRecordIds, setFieldDefinitions, setObjectSingularName, - getSelectedRecordIdsSelector, - getIsCompactModeActiveState, - getOnFetchMoreVisibilityChangeState, + selectedRecordIdsSelector, + isCompactModeActiveState, + onFetchMoreVisibilityChangeState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts index ae89223c79ee..a2024d4ba683 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts @@ -3,21 +3,21 @@ import { useRecoilCallback } from 'recoil'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; export const useRecordBoardSelection = (recordBoardId?: string) => { - const { getSelectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = + const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); const resetRecordSelection = useRecoilCallback( ({ snapshot, set }) => () => { const recordIds = snapshot - .getLoadable(getSelectedRecordIdsSelector()) + .getLoadable(selectedRecordIdsSelector()) .getValue(); for (const recordId of recordIds) { set(isRecordBoardCardSelectedFamilyState(recordId), false); } }, - [getSelectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState], + [selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState], ); const setRecordAsSelected = useRecoilCallback( diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 034466873714..dda3bc34e83c 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -133,12 +133,12 @@ export const RecordBoardCard = () => { const { updateOneRecord, objectMetadataItem } = useContext(RecordBoardContext); const { - getIsCompactModeActiveState, + isCompactModeActiveState, isRecordBoardCardSelectedFamilyState, - getVisibleFieldDefinitionsState, + visibleFieldDefinitionsState, } = useRecordBoardStates(); - const isCompactModeActive = useRecoilValue(getIsCompactModeActiveState()); + const isCompactModeActive = useRecoilValue(isCompactModeActiveState); const [isCardInCompactMode, setIsCardInCompactMode] = useState(true); @@ -146,14 +146,14 @@ export const RecordBoardCard = () => { isRecordBoardCardSelectedFamilyState(recordId), ); - const visibleBoardCardFieldDefinitions = useRecoilValue( - getVisibleFieldDefinitionsState(), + const visibleFieldDefinitions = useRecoilValue( + visibleFieldDefinitionsState(), ); const record = useRecoilValue(recordStoreFamilyState(recordId)); - const setContextMenuPosition = useSetRecoilState(contextMenuPositionState()); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState()); + const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); const handleContextMenu = (event: React.MouseEvent) => { event.preventDefault(); @@ -247,7 +247,7 @@ export const RecordBoardCard = () => { isOpen={!isCardInCompactMode || !isCompactModeActive} initial={false} > - {visibleBoardCardFieldDefinitions.map((fieldDefinition) => ( + {visibleFieldDefinitions.map((fieldDefinition) => ( diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx index 072120d68063..56127562c05b 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader.tsx @@ -16,12 +16,12 @@ const StyledText = styled.div` `; export const RecordBoardColumnFetchMoreLoader = () => { - const { getIsFetchingRecordState, getOnFetchMoreVisibilityChangeState } = + const { isFetchingRecordState, onFetchMoreVisibilityChangeState } = useRecordBoardStates(); - const isFetchingRecords = useRecoilValue(getIsFetchingRecordState()); + const isFetchingRecord = useRecoilValue(isFetchingRecordState); const onFetchMoreVisibilityChange = useRecoilValue( - getOnFetchMoreVisibilityChangeState(), + onFetchMoreVisibilityChangeState, ); const { ref } = useInView({ @@ -30,7 +30,7 @@ export const RecordBoardColumnFetchMoreLoader = () => { return (
      - {isFetchingRecords && Loading more...} + {isFetchingRecord && Loading more...}
      ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useClearField.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useClearField.ts index f65fbe900ad6..548e212f98c7 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useClearField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useClearField.ts @@ -20,7 +20,7 @@ export const useClearField = () => { ({ snapshot, set }) => () => { const objectMetadataItems = snapshot - .getLoadable(objectMetadataItemsState()) + .getLoadable(objectMetadataItemsState) .getValue(); const foundObjectMetadataItem = objectMetadataItems.find( diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RelationFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RelationFieldInput.stories.tsx index 9d8dd603400f..3cbe87a498aa 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RelationFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RelationFieldInput.stories.tsx @@ -30,9 +30,9 @@ import { } from '../RelationFieldInput'; const RelationWorkspaceSetterEffect = () => { - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts index 49918c73718c..728c681d5cf2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts @@ -35,13 +35,11 @@ export const turnObjectDropdownFilterIntoQueryFilter = ( ); if (!correspondingField) { - throw new Error( - `Could not find field ${rawUIFilter.fieldMetadataId} in metadata object`, - ); + continue; } if (!isDefined(rawUIFilter.value) || rawUIFilter.value === '') { - return undefined; + continue; } switch (rawUIFilter.definition.type) { diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx index 08e3bd35d900..3e7fff5bd0e7 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx @@ -28,9 +28,9 @@ export const RecordIndexBoardContainerEffect = ({ const { setColumns, setObjectSingularName, - getSelectedRecordIdsSelector, + selectedRecordIdsSelector, setFieldDefinitions, - getOnFetchMoreVisibilityChangeState, + onFetchMoreVisibilityChangeState, } = useRecordBoard(recordBoardId); const { fetchMoreRecords, loading } = useLoadRecordIndexBoard({ @@ -40,7 +40,7 @@ export const RecordIndexBoardContainerEffect = ({ }); const setOnFetchMoreVisibilityChange = useSetRecoilState( - getOnFetchMoreVisibilityChangeState(), + onFetchMoreVisibilityChangeState, ); useEffect(() => { @@ -78,14 +78,14 @@ export const RecordIndexBoardContainerEffect = ({ ]); const recordIndexFieldDefinitions = useRecoilValue( - recordIndexFieldDefinitionsState(), + recordIndexFieldDefinitionsState, ); useEffect(() => { setFieldDefinitions(recordIndexFieldDefinitions); }, [objectMetadataItem, setFieldDefinitions, recordIndexFieldDefinitions]); - const selectedRecordIds = useRecoilValue(getSelectedRecordIdsSelector()); + const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index d9873a1b14bd..1d9e89b250d0 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -47,7 +47,7 @@ export const RecordIndexContainer = ({ objectNamePlural, }: RecordIndexContainerProps) => { const [recordIndexViewType, setRecordIndexViewType] = useRecoilState( - recordIndexViewTypeState(), + recordIndexViewTypeState, ); const { objectNameSingular } = useObjectNameSingularFromPlural({ objectNamePlural, @@ -57,13 +57,13 @@ export const RecordIndexContainer = ({ objectNameSingular, }); - const { columnDefinitions } = + const { columnDefinitions, filterDefinitions, sortDefinitions } = useColumnDefinitionsFromFieldMetadata(objectMetadataItem); - const setRecordIndexFilters = useSetRecoilState(recordIndexFiltersState()); - const setRecordIndexSorts = useSetRecoilState(recordIndexSortsState()); + const setRecordIndexFilters = useSetRecoilState(recordIndexFiltersState); + const setRecordIndexSorts = useSetRecoilState(recordIndexSortsState); const setRecordIndexIsCompactModeActive = useSetRecoilState( - recordIndexIsCompactModeActiveState(), + recordIndexIsCompactModeActiveState, ); const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({ @@ -85,7 +85,7 @@ export const RecordIndexContainer = ({ ); const existingRecordIndexFieldDefinitions = snapshot - .getLoadable(recordIndexFieldDefinitionsState()) + .getLoadable(recordIndexFieldDefinitionsState) .getValue(); if ( @@ -94,10 +94,7 @@ export const RecordIndexContainer = ({ newRecordIndexFieldDefinitions, ) ) { - set( - recordIndexFieldDefinitionsState(), - newRecordIndexFieldDefinitions, - ); + set(recordIndexFieldDefinitionsState, newRecordIndexFieldDefinitions); } }, [columnDefinitions, setTableColumns], @@ -115,22 +112,26 @@ export const RecordIndexContainer = ({ viewType={recordIndexViewType ?? ViewType.Table} /> } - optionsDropdownScopeId={RECORD_INDEX_OPTIONS_DROPDOWN_ID} - onViewFieldsChange={onViewFieldsChange} - onViewFiltersChange={(viewFilters) => { - setTableFilters(mapViewFiltersToFilters(viewFilters)); - setRecordIndexFilters(mapViewFiltersToFilters(viewFilters)); - }} - onViewSortsChange={(viewSorts) => { - setTableSorts(mapViewSortsToSorts(viewSorts)); - setRecordIndexSorts(mapViewSortsToSorts(viewSorts)); - }} - onViewTypeChange={(viewType: ViewType) => { - setRecordIndexViewType(viewType); - }} - onViewCompactModeChange={(isCompactModeActive: boolean) => { - setRecordIndexIsCompactModeActive(isCompactModeActive); + onCurrentViewChange={(view) => { + if (!view) { + return; + } + + onViewFieldsChange(view.viewFields); + setTableFilters( + mapViewFiltersToFilters(view.viewFilters, filterDefinitions), + ); + setRecordIndexFilters( + mapViewFiltersToFilters(view.viewFilters, filterDefinitions), + ); + setTableSorts(mapViewSortsToSorts(view.viewSorts, sortDefinitions)); + setRecordIndexSorts( + mapViewSortsToSorts(view.viewSorts, sortDefinitions), + ); + setRecordIndexViewType(view.type); + setRecordIndexIsCompactModeActive(view.isCompact); }} + optionsDropdownScopeId={RECORD_INDEX_OPTIONS_DROPDOWN_ID} /> { setAvailableTableColumns(columnDefinitions); }, [columnDefinitions, setAvailableTableColumns]); - const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector()); + const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ objectMetadataItem, @@ -57,9 +56,9 @@ export const RecordIndexTableContainerEffect = ({ useEffect(() => { setOnEntityCountChange( - () => (entityCount: number) => setEntityCountInCurrentView(entityCount), + () => (entityCount: number) => setRecordCountInCurrentView(entityCount), ); - }, [setEntityCountInCurrentView, setOnEntityCountChange]); + }, [setRecordCountInCurrentView, setOnEntityCountChange]); return <>; }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewBarEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewBarEffect.tsx index 51d27b0c38d0..44ae8879625f 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewBarEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewBarEffect.tsx @@ -3,7 +3,7 @@ import { useEffect } from 'react'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useInitViewBar } from '@/views/hooks/useInitViewBar'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; type RecordIndexViewBarEffectProps = { @@ -31,7 +31,7 @@ export const RecordIndexViewBarEffect = ({ setAvailableSortDefinitions, setAvailableFilterDefinitions, setAvailableFieldDefinitions, - } = useViewBar({ viewBarId }); + } = useInitViewBar(viewBarId); useEffect(() => { if (isUndefinedOrNull(objectMetadataItem)) { diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoard.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoard.ts index fa894ebb19a5..0efe9e2f5e75 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexBoard.ts @@ -11,7 +11,7 @@ import { recordIndexFiltersState } from '@/object-record/record-index/states/rec import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState'; import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState'; import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useSetRecordCountInCurrentView } from '@/views/hooks/useSetRecordCountInCurrentView'; type UseLoadRecordIndexBoardProps = { objectNameSingular: string; @@ -30,19 +30,19 @@ export const useLoadRecordIndexBoard = ({ const { setRecordIds: setRecordIdsInBoard, setFieldDefinitions, - getIsCompactModeActiveState, + isCompactModeActiveState, } = useRecordBoard(recordBoardId); const { setRecords: setRecordsInStore } = useSetRecordInStore(); const recordIndexFieldDefinitions = useRecoilValue( - recordIndexFieldDefinitionsState(), + recordIndexFieldDefinitionsState, ); useEffect(() => { setFieldDefinitions(recordIndexFieldDefinitions); }, [recordIndexFieldDefinitions, setFieldDefinitions]); - const recordIndexFilters = useRecoilValue(recordIndexFiltersState()); - const recordIndexSorts = useRecoilValue(recordIndexSortsState()); + const recordIndexFilters = useRecoilValue(recordIndexFiltersState); + const recordIndexSorts = useRecoilValue(recordIndexSortsState); const requestFilters = turnObjectDropdownFilterIntoQueryFilter( recordIndexFilters, objectMetadataItem?.fields ?? [], @@ -53,7 +53,7 @@ export const useLoadRecordIndexBoard = ({ ); const recordIndexIsCompactModeActive = useRecoilValue( - recordIndexIsCompactModeActiveState(), + recordIndexIsCompactModeActiveState, ); const { @@ -68,13 +68,10 @@ export const useLoadRecordIndexBoard = ({ orderBy, }); - const { setEntityCountInCurrentView } = useViewBar({ - viewBarId, - }); + const { setRecordCountInCurrentView } = + useSetRecordCountInCurrentView(viewBarId); - const setIsCompactModeActive = useSetRecoilState( - getIsCompactModeActiveState(), - ); + const setIsCompactModeActive = useSetRecoilState(isCompactModeActiveState); useEffect(() => { setRecordIdsInBoard(records); @@ -85,8 +82,8 @@ export const useLoadRecordIndexBoard = ({ }, [records, setRecordsInStore]); useEffect(() => { - setEntityCountInCurrentView(totalCount); - }, [totalCount, setEntityCountInCurrentView]); + setRecordCountInCurrentView(totalCount); + }, [totalCount, setRecordCountInCurrentView]); useEffect(() => { setIsCompactModeActive(recordIndexIsCompactModeActive); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexTable.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexTable.ts index 90c4d46e200e..4594d516d409 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexTable.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexTable.ts @@ -18,11 +18,11 @@ export const useFindManyParams = ( objectNameSingular, }); - const { getTableFiltersState, getTableSortsState } = + const { tableFiltersState, tableSortsState } = useRecordTableStates(recordTableId); - const tableFilters = useRecoilValue(getTableFiltersState()); - const tableSorts = useRecoilValue(getTableSortsState()); + const tableFilters = useRecoilValue(tableFiltersState); + const tableSorts = useRecoilValue(tableSortsState); const filter = turnObjectDropdownFilterIntoQueryFilter( tableFilters, @@ -40,9 +40,9 @@ export const useFindManyParams = ( export const useLoadRecordIndexTable = (objectNameSingular: string) => { const { setRecordTableData, setIsRecordTableInitialLoading } = useRecordTable(); - const { getTableLastRowVisibleState } = useRecordTableStates(); - const setLastRowVisible = useSetRecoilState(getTableLastRowVisibleState()); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const { tableLastRowVisibleState } = useRecordTableStates(); + const setLastRowVisible = useSetRecoilState(tableLastRowVisibleState); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const params = useFindManyParams(objectNameSingular); const { diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdown.tsx b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdown.tsx index d79427c0fef9..69b7b567dc08 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdown.tsx @@ -1,11 +1,9 @@ import { RecordIndexOptionsDropdownButton } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdownButton'; import { RecordIndexOptionsDropdownContent } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdownContent'; import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId'; -import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; -import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope'; import { TableOptionsHotkeyScope } from '@/object-record/record-table/types/TableOptionsHotkeyScope'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useViewBarEditMode } from '@/views/hooks/useViewBarEditMode'; import { ViewType } from '@/views/types/ViewType'; type RecordIndexOptionsDropdownProps = { @@ -19,28 +17,22 @@ export const RecordIndexOptionsDropdown = ({ objectNameSingular, viewType, }: RecordIndexOptionsDropdownProps) => { - const { setViewEditMode } = useViewBar(); - const { scopeId } = useRecordTableStates(recordIndexId); + const { setViewEditMode } = useViewBarEditMode(recordIndexId); return ( - false} - > - } - dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }} - dropdownOffset={{ y: 8 }} - dropdownComponents={ - - } - onClickOutside={() => setViewEditMode('none')} - /> - + } + dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }} + dropdownOffset={{ y: 8 }} + dropdownComponents={ + + } + onClickOutside={() => setViewEditMode('none')} + /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx index 59831da2936d..19f1e2594736 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx @@ -1,6 +1,6 @@ import { useRef, useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { Key } from 'ts-key-enum'; +import { v4 } from 'uuid'; import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId'; import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard'; @@ -22,8 +22,9 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemToggle'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; +import { useHandleViews } from '@/views/hooks/useHandleViews'; +import { useViewBarEditMode } from '@/views/hooks/useViewBarEditMode'; import { ViewType } from '@/views/types/ViewType'; type RecordIndexOptionsMenu = 'fields'; @@ -39,13 +40,11 @@ export const RecordIndexOptionsDropdownContent = ({ recordIndexId, objectNameSingular, }: RecordIndexOptionsDropdownContentProps) => { - const { setViewEditMode, handleViewNameSubmit } = useViewBar({ - viewBarId: recordIndexId, - }); - const { viewEditModeState, currentViewSelector } = useViewScopedStates(); + const { updateCurrentView, createEmptyView, selectView } = + useHandleViews(recordIndexId); + const { viewEditMode, setViewEditMode } = useViewBarEditMode(recordIndexId); + const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView(); - const viewEditMode = useRecoilValue(viewEditModeState); - const currentView = useRecoilValue(currentViewSelector); const { closeDropdown } = useDropdown(RECORD_INDEX_OPTIONS_DROPDOWN_ID); const [currentMenu, setCurrentMenu] = useState< @@ -70,9 +69,16 @@ export const RecordIndexOptionsDropdownContent = ({ useScopedHotkeys( Key.Enter, - () => { + async () => { const name = viewEditInputRef.current?.value; - handleViewNameSubmit(name); + if (viewEditMode === 'create') { + const id = v4(); + await createEmptyView(id, name ?? ''); + selectView(id); + } else { + updateCurrentView({ name }); + } + resetMenu(); setViewEditMode('none'); closeDropdown(); @@ -133,7 +139,11 @@ export const RecordIndexOptionsDropdownContent = ({ ? 'View name' : '' } - defaultValue={viewEditMode === 'create' ? '' : currentView?.name} + defaultValue={ + viewEditMode === 'create' + ? '' + : currentViewWithCombinedFiltersAndSorts?.name + } /> @@ -185,7 +195,7 @@ export const RecordIndexOptionsDropdownContent = ({ onToggleChange={() => setAndPersistIsCompactModeActive( !isCompactModeActive, - currentView, + currentViewWithCombinedFiltersAndSorts, ) } toggled={isCompactModeActive} diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts index ab72add28050..8ee5ecb1726f 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useExportTableData.ts @@ -109,11 +109,11 @@ export const useExportTableData = ({ const [progress, setProgress] = useState(undefined); const [hasNextPage, setHasNextPage] = useState(true); - const { getVisibleTableColumnsSelector, getSelectedRowIdsSelector } = + const { visibleTableColumnsSelector, selectedRowIdsSelector } = useRecordTableStates(recordIndexId); - const columns = useRecoilValue(getVisibleTableColumnsSelector()); - const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector()); + const columns = useRecoilValue(visibleTableColumnsSelector()); + const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); const hasSelectedRows = selectedRowIds.length > 0; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard.ts index 33da264c9679..da059ea5045d 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard.ts @@ -8,8 +8,8 @@ import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoar import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; -import { useViewFields } from '@/views/hooks/internal/useViewFields'; -import { useViews } from '@/views/hooks/internal/useViews'; +import { useHandleViews } from '@/views/hooks/useHandleViews'; +import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields'; import { GraphQLView } from '@/views/types/GraphQLView'; import { mapBoardFieldDefinitionsToViewFields } from '@/views/utils/mapBoardFieldDefinitionsToViewFields'; import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; @@ -28,14 +28,14 @@ export const useRecordIndexOptionsForBoard = ({ viewBarId, }: useRecordIndexOptionsForBoardParams) => { const [recordIndexFieldDefinitions, setRecordIndexFieldDefinitions] = - useRecoilState(recordIndexFieldDefinitionsState()); + useRecoilState(recordIndexFieldDefinitionsState); - const { persistViewFields } = useViewFields(viewBarId); - const { updateView } = useViews(viewBarId); - const { getIsCompactModeActiveState } = useRecordBoard(recordBoardId); + const { saveViewFields } = useSaveCurrentViewFields(viewBarId); + const { updateCurrentView } = useHandleViews(viewBarId); + const { isCompactModeActiveState } = useRecordBoard(recordBoardId); const [isCompactModeActive, setIsCompactModeActive] = useRecoilState( - getIsCompactModeActiveState(), + isCompactModeActiveState, ); const { objectMetadataItem } = useObjectMetadataItemOnly({ @@ -105,20 +105,14 @@ export const useRecordIndexOptionsForBoard = ({ if (isDeeplyEqual(visibleBoardFields, reorderedVisibleBoardFields)) return; - const updatedFields = [ - ...reorderedVisibleBoardFields, - ...hiddenBoardFields, - ].map((field, index) => ({ ...field, position: index })); + const updatedFields = [...reorderedVisibleBoardFields].map( + (field, index) => ({ ...field, position: index }), + ); setRecordIndexFieldDefinitions(updatedFields); - persistViewFields(mapBoardFieldDefinitionsToViewFields(updatedFields)); + saveViewFields(mapBoardFieldDefinitionsToViewFields(updatedFields)); }, - [ - hiddenBoardFields, - persistViewFields, - setRecordIndexFieldDefinitions, - visibleBoardFields, - ], + [saveViewFields, setRecordIndexFieldDefinitions, visibleBoardFields], ); // Todo : this seems over complex and should at least be extracted to an util with unit test. @@ -172,14 +166,14 @@ export const useRecordIndexOptionsForBoard = ({ setRecordIndexFieldDefinitions(updatedFieldsDefinitions); - persistViewFields( + saveViewFields( mapBoardFieldDefinitionsToViewFields(updatedFieldsDefinitions), ); }, [ recordIndexFieldDefinitionsByKey, setRecordIndexFieldDefinitions, - persistViewFields, + saveViewFields, availableColumnDefinitions, visibleBoardFields, recordIndexFieldDefinitions, @@ -190,12 +184,11 @@ export const useRecordIndexOptionsForBoard = ({ (isCompactModeActive: boolean, view: GraphQLView | undefined) => { if (!view) return; setIsCompactModeActive(isCompactModeActive); - updateView({ - ...view, + updateCurrentView({ isCompact: isCompactModeActive, }); }, - [setIsCompactModeActive, updateView], + [setIsCompactModeActive, updateCurrentView], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForTable.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForTable.ts index 011c6f87d42d..e72bc7534306 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForTable.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useRecordIndexOptionsForTable.ts @@ -7,11 +7,11 @@ import { useTableColumns } from '@/object-record/record-table/hooks/useTableColu import { moveArrayItem } from '~/utils/array/moveArrayItem'; export const useRecordIndexOptionsForTable = (recordTableId: string) => { - const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } = + const { hiddenTableColumnsSelector, visibleTableColumnsSelector } = useRecordTableStates(recordTableId); - const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector()); - const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector()); + const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector()); + const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector()); const { handleColumnVisibilityChange, handleColumnReorder } = useTableColumns( { recordTableId: recordTableId }, diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx index c3c2133377dd..76035fb7815f 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx @@ -24,7 +24,7 @@ import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; -import { FilterQueryParams } from '@/views/hooks/internal/useFiltersFromQueryParams'; +import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; const StyledAddDropdown = styled(Dropdown)` diff --git a/packages/twenty-front/src/modules/object-record/record-store/states/selectors/recordStoreIdentifierSelector.ts b/packages/twenty-front/src/modules/object-record/record-store/states/selectors/recordStoreIdentifierSelector.ts index 10167cc4c8e0..24502a28810a 100644 --- a/packages/twenty-front/src/modules/object-record/record-store/states/selectors/recordStoreIdentifierSelector.ts +++ b/packages/twenty-front/src/modules/object-record/record-store/states/selectors/recordStoreIdentifierSelector.ts @@ -17,7 +17,7 @@ export const recordStoreIdentifierFamilySelector = selectorFamily({ ({ get }) => { const recordFromStore = get(recordStoreFamilyState(recordId)); - const objectMetadataItems = get(objectMetadataItemsState()); + const objectMetadataItems = get(objectMetadataItemsState); const objectMetadataItem = objectMetadataItems.find( (item) => item.nameSingular === objectNameSingular, diff --git a/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx index 86b5e3534b2c..14b3768d08be 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx @@ -8,9 +8,9 @@ export const RecordTableActionBar = ({ }: { recordTableId: string; }) => { - const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId); + const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); - const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector()); + const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); if (!selectedRowIds.length) { return null; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/CheckboxCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/CheckboxCell.tsx index d6c432c8154d..2aff77e1b162 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/CheckboxCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/CheckboxCell.tsx @@ -22,7 +22,7 @@ const StyledContainer = styled.div` export const CheckboxCell = () => { const { recordId } = useContext(RecordTableRowContext); const { isRowSelectedFamilyState } = useRecordTableStates(); - const setActionBarOpenState = useSetRecoilState(actionBarOpenState()); + const setActionBarOpenState = useSetRecoilState(actionBarOpenState); const { setCurrentRowSelected } = useSetCurrentRowSelected(); const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId)); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/ColumnHead.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/ColumnHead.tsx index 2cd9432bd2f2..5f3207bfa27e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/ColumnHead.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/ColumnHead.tsx @@ -53,7 +53,7 @@ export const ColumnHead = ({ column }: ColumnHeadProps) => { const { getIcon } = useIcons(); const Icon = getIcon(column.iconName); - const scrollLeft = useRecoilValue(scrollLeftState()); + const scrollLeft = useRecoilValue(scrollLeftState); return ( 0}> diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx index 6d9a60ca708d..80dbedafd405 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -122,7 +122,7 @@ export const RecordTable = ({ createRecord, }: RecordTableProps) => { const { scopeId } = useRecordTableStates(recordTableId); - const scrollLeft = useRecoilValue(scrollLeftState()); + const scrollLeft = useRecoilValue(scrollLeftState); const { objectMetadataItem } = useObjectMetadataItemOnly({ objectNameSingular, diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBody.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBody.tsx index 4ba288f2282f..3f9ad3da582e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBody.tsx @@ -11,9 +11,9 @@ type RecordTableBodyProps = { export const RecordTableBody = ({ objectNameSingular, }: RecordTableBodyProps) => { - const { getTableRowIdsState } = useRecordTableStates(); + const { tableRowIdsState } = useRecordTableStates(); - const tableRowIds = useRecoilValue(getTableRowIdsState()); + const tableRowIds = useRecoilValue(tableRowIdsState); return ( <> diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffect.tsx index 6b215db7ed7b..bb70caea388b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableBodyEffect.tsx @@ -21,10 +21,10 @@ export const RecordTableBodyEffect = ({ loading, } = useLoadRecordIndexTable(objectNameSingular); - const { getTableLastRowVisibleState } = useRecordTableStates(); + const { tableLastRowVisibleState } = useRecordTableStates(); const [tableLastRowVisible, setTableLastRowVisible] = useRecoilState( - getTableLastRowVisibleState(), + tableLastRowVisibleState, ); const isFetchingMoreObjects = useRecoilValue( diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableCellContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableCellContainer.tsx index da9c038b561d..a879ed19afc1 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableCellContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableCellContainer.tsx @@ -23,8 +23,8 @@ const StyledContainer = styled.td<{ isSelected: boolean }>` `; export const RecordTableCellContainer = () => { - const setContextMenuPosition = useSetRecoilState(contextMenuPositionState()); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState()); + const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); const { setCurrentRowSelected } = useSetCurrentRowSelected(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableColumnDropdownMenu.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableColumnDropdownMenu.tsx index 911bb3d87ff7..17417a832970 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableColumnDropdownMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableColumnDropdownMenu.tsx @@ -17,9 +17,9 @@ export type RecordTableColumnDropdownMenuProps = { export const RecordTableColumnDropdownMenu = ({ column, }: RecordTableColumnDropdownMenuProps) => { - const { getVisibleTableColumnsSelector } = useRecordTableStates(); + const { visibleTableColumnsSelector } = useRecordTableStates(); - const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector()); + const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector()); const secondVisibleColumn = visibleTableColumns[1]; const canMoveLeft = diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeader.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeader.tsx index 6cde82074ca4..90611c0eb29f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeader.tsx @@ -56,16 +56,15 @@ export const RecordTableHeader = ({ }: { createRecord: () => void; }) => { - const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } = - useRecordTableStates(); + const { visibleTableColumnsSelector } = useRecordTableStates(); const scrollWrapper = useScrollWrapperScopedRef(); const isTableWiderThanScreen = (scrollWrapper.current?.clientWidth ?? 0) < (scrollWrapper.current?.scrollWidth ?? 0); - const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector()); - const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector()); + const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector()); + const hiddenTableColumns = useRecoilValue(visibleTableColumnsSelector()); const theme = useTheme(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderCell.tsx index 9d1f7f89a90b..ec96d4990ff2 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderCell.tsx @@ -82,14 +82,13 @@ export const RecordTableHeaderCell = ({ column: ColumnDefinition; createRecord: () => void; }) => { - const { getResizeFieldOffsetState, getTableColumnsState } = - useRecordTableStates(); + const { resizeFieldOffsetState, tableColumnsState } = useRecordTableStates(); const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState( - getResizeFieldOffsetState(), + resizeFieldOffsetState, ); - const tableColumns = useRecoilValue(getTableColumnsState()); + const tableColumns = useRecoilValue(tableColumnsState); const tableColumnsByKey = useMemo( () => mapArrayToObject(tableColumns, ({ fieldMetadataId }) => fieldMetadataId), @@ -124,7 +123,7 @@ export const RecordTableHeaderCell = ({ const resizeFieldOffset = getSnapshotValue( snapshot, - getResizeFieldOffsetState(), + resizeFieldOffsetState, ); const nextWidth = Math.round( @@ -134,7 +133,7 @@ export const RecordTableHeaderCell = ({ ), ); - set(getResizeFieldOffsetState(), 0); + set(resizeFieldOffsetState, 0); setInitialPointerPositionX(null); setResizedFieldKey(null); @@ -150,7 +149,7 @@ export const RecordTableHeaderCell = ({ }, [ resizedFieldKey, - getResizeFieldOffsetState, + resizeFieldOffsetState, tableColumnsByKey, tableColumns, handleColumnsChange, @@ -165,7 +164,7 @@ export const RecordTableHeaderCell = ({ }); const isMobile = useIsMobile(); - const scrollLeft = useRecoilValue(scrollLeftState()); + const scrollLeft = useRecoilValue(scrollLeftState); const disableColumnResize = column.isLabelIdentifier && isMobile && scrollLeft > 0; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderPlusButtonContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderPlusButtonContent.tsx index b08140cea4a5..91b3f8527cc6 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderPlusButtonContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableHeaderPlusButtonContent.tsx @@ -17,9 +17,9 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; export const RecordTableHeaderPlusButtonContent = () => { const { closeDropdown } = useDropdown(); - const { getHiddenTableColumnsSelector } = useRecordTableStates(); + const { hiddenTableColumnsSelector } = useRecordTableStates(); - const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector()); + const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector()); const { getIcon } = useIcons(); const { handleColumnVisibilityChange } = useTableColumns(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRow.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRow.tsx index b6af608f61c3..9f018f8f5cc8 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRow.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRow.tsx @@ -23,12 +23,12 @@ const StyledTd = styled.td` `; export const RecordTableRow = ({ recordId, rowIndex }: RecordTableRowProps) => { - const { getVisibleTableColumnsSelector, isRowSelectedFamilyState } = + const { visibleTableColumnsSelector, isRowSelectedFamilyState } = useRecordTableStates(); const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId)); const { objectMetadataItem } = useContext(RecordTableContext); - const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector()); + const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector()); const scrollWrapperRef = useContext(ScrollWrapperContext); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 8eca73187155..cb071bfffd45 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -20,7 +20,7 @@ import { } from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled'; import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; -import { useViewFields } from '@/views/hooks/internal/useViewFields'; +import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields'; import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField'; import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext'; @@ -59,13 +59,13 @@ export const RecordTableWithWrappers = ({ }: RecordTableWithWrappersProps) => { const tableBodyRef = useRef(null); - const { getNumberOfTableRowsState, getIsRecordTableInitialLoadingState } = + const { numberOfTableRowsState, isRecordTableInitialLoadingState } = useRecordTableStates(recordTableId); - const numberOfTableRows = useRecoilValue(getNumberOfTableRowsState()); + const numberOfTableRows = useRecoilValue(numberOfTableRowsState); const isRecordTableInitialLoading = useRecoilValue( - getIsRecordTableInitialLoadingState(), + isRecordTableInitialLoadingState, ); const { resetTableRowSelection, setRowSelectedState } = useRecordTable({ @@ -78,7 +78,7 @@ export const RecordTableWithWrappers = ({ }, ); - const { persistViewFields } = useViewFields(viewBarId); + const { saveViewFields } = useSaveCurrentViewFields(viewBarId); const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular }); @@ -96,13 +96,13 @@ export const RecordTableWithWrappers = ({ objectNameSingular={objectNameSingular} onColumnsChange={useRecoilCallback( () => (columns) => { - persistViewFields( + saveViewFields( mapColumnDefinitionsToViewFields( columns as ColumnDefinition[], ), ); }, - [persistViewFields], + [saveViewFields], )} createRecord={createRecord} /> diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/SelectAllCheckbox.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/SelectAllCheckbox.tsx index 9f9a46a70ffd..c5036f288878 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/SelectAllCheckbox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/SelectAllCheckbox.tsx @@ -17,11 +17,9 @@ const StyledContainer = styled.div` `; export const SelectAllCheckbox = () => { - const { getAllRowsSelectedStatusSelector } = useRecordTableStates(); + const { allRowsSelectedStatusSelector } = useRecordTableStates(); - const allRowsSelectedStatus = useRecoilValue( - getAllRowsSelectedStatusSelector(), - ); + const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector()); const { selectAllRows } = useRecordTable(); const checked = allRowsSelectedStatus === 'all'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx b/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx index 2ccbae769852..d9f712ef82e4 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx @@ -8,9 +8,9 @@ export const RecordTableContextMenu = ({ }: { recordTableId: string; }) => { - const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId); + const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); - const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector()); + const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); if (!selectedRowIds.length) { return null; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts index d8c21c844051..a9976aa05fac 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts @@ -5,7 +5,7 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { const { - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState, } = useRecordTableStates(recordTableId); @@ -14,7 +14,7 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { return async () => { const currentTableCellInEditModePosition = getSnapshotValue( snapshot, - getCurrentTableCellInEditModePositionState(), + currentTableCellInEditModePositionState, ); set( @@ -23,9 +23,6 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { ); }; }, - [ - getCurrentTableCellInEditModePositionState, - isTableCellInEditModeFamilyState, - ], + [currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useDisableSoftFocus.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useDisableSoftFocus.ts index fed4211c976e..2e1704dfa5c5 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useDisableSoftFocus.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useDisableSoftFocus.ts @@ -5,8 +5,8 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV export const useDisableSoftFocus = (recordTableId?: string) => { const { - getSoftFocusPositionState, - getIsSoftFocusActiveState, + softFocusPositionState, + isSoftFocusActiveState, isSoftFocusOnTableCellFamilyState, } = useRecordTableStates(recordTableId); @@ -15,17 +15,17 @@ export const useDisableSoftFocus = (recordTableId?: string) => { return () => { const currentPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); - set(getIsSoftFocusActiveState(), false); + set(isSoftFocusActiveState, false); set(isSoftFocusOnTableCellFamilyState(currentPosition), false); }; }, [ - getIsSoftFocusActiveState, - getSoftFocusPositionState, + isSoftFocusActiveState, + softFocusPositionState, isSoftFocusOnTableCellFamilyState, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode.ts index 8a4b486258e2..ecc422eecd1e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode.ts @@ -5,7 +5,7 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => { const { - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState, } = useRecordTableStates(recordTableId); @@ -14,7 +14,7 @@ export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => { () => { const currentTableCellInEditModePosition = getSnapshotValue( snapshot, - getCurrentTableCellInEditModePositionState(), + currentTableCellInEditModePositionState, ); const isSomeCellInEditModeState = isTableCellInEditModeFamilyState( @@ -23,9 +23,6 @@ export const useGetIsSomeCellInEditModeState = (recordTableId?: string) => { return isSomeCellInEditModeState; }, - [ - getCurrentTableCellInEditModePositionState, - isTableCellInEditModeFamilyState, - ], + [currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useLeaveTableFocus.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useLeaveTableFocus.ts index ff2e2b877c40..0ee3aa62d6a8 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useLeaveTableFocus.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useLeaveTableFocus.ts @@ -14,18 +14,18 @@ export const useLeaveTableFocus = (recordTableId?: string) => { const closeCurrentCellInEditMode = useCloseCurrentTableCellInEditMode(recordTableId); - const { getIsSoftFocusActiveState } = useRecordTableStates(recordTableId); + const { isSoftFocusActiveState } = useRecordTableStates(recordTableId); return useRecoilCallback( ({ snapshot }) => () => { const isSoftFocusActive = getSnapshotValue( snapshot, - getIsSoftFocusActiveState(), + isSoftFocusActiveState, ); const currentHotkeyScope = snapshot - .getLoadable(currentHotkeyScopeState()) + .getLoadable(currentHotkeyScopeState) .getValue(); if (!isSoftFocusActive) { @@ -39,6 +39,6 @@ export const useLeaveTableFocus = (recordTableId?: string) => { closeCurrentCellInEditMode(); disableSoftFocus(); }, - [closeCurrentCellInEditMode, disableSoftFocus, getIsSoftFocusActiveState], + [closeCurrentCellInEditMode, disableSoftFocus, isSoftFocusActiveState], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useMoveEditModeToCellPosition.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useMoveEditModeToCellPosition.ts index 5bb32c4abe99..02e04a259d31 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useMoveEditModeToCellPosition.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useMoveEditModeToCellPosition.ts @@ -8,7 +8,7 @@ import { TableCellPosition } from '../../types/TableCellPosition'; export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => { const { isTableCellInEditModeFamilyState, - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, } = useRecordTableStates(recordTableId); return useRecoilCallback( @@ -16,7 +16,7 @@ export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => { return (newPosition: TableCellPosition) => { const currentTableCellInEditModePosition = getSnapshotValue( snapshot, - getCurrentTableCellInEditModePositionState(), + currentTableCellInEditModePositionState, ); set( @@ -24,14 +24,11 @@ export const useMoveEditModeToTableCellPosition = (recordTableId?: string) => { false, ); - set(getCurrentTableCellInEditModePositionState(), newPosition); + set(currentTableCellInEditModePositionState, newPosition); set(isTableCellInEditModeFamilyState(newPosition), true); }; }, - [ - getCurrentTableCellInEditModePositionState, - isTableCellInEditModeFamilyState, - ], + [currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useRecordTableStates.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useRecordTableStates.ts index 21414ec2d703..1d7fff60f152 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useRecordTableStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useRecordTableStates.ts @@ -35,44 +35,41 @@ export const useRecordTableStates = (recordTableId?: string) => { return { scopeId, - getAvailableTableColumnsState: extractComponentState( + availableTableColumnsState: extractComponentState( availableTableColumnsComponentState, scopeId, ), - getTableFiltersState: extractComponentState( + tableFiltersState: extractComponentState( tableFiltersComponentState, scopeId, ), - getTableSortsState: extractComponentState( - tableSortsComponentState, - scopeId, - ), - getTableColumnsState: extractComponentState( + tableSortsState: extractComponentState(tableSortsComponentState, scopeId), + tableColumnsState: extractComponentState( tableColumnsComponentState, scopeId, ), - getOnColumnsChangeState: extractComponentState( + onColumnsChangeState: extractComponentState( onColumnsChangeComponentState, scopeId, ), - getOnEntityCountChangeState: extractComponentState( + onEntityCountChangeState: extractComponentState( onEntityCountChangeComponentState, scopeId, ), - getTableLastRowVisibleState: extractComponentState( + tableLastRowVisibleState: extractComponentState( tableLastRowVisibleComponentState, scopeId, ), - getSoftFocusPositionState: extractComponentState( + softFocusPositionState: extractComponentState( softFocusPositionComponentState, scopeId, ), - getNumberOfTableRowsState: extractComponentState( + numberOfTableRowsState: extractComponentState( numberOfTableRowsComponentState, scopeId, ), - getCurrentTableCellInEditModePositionState: extractComponentState( + currentTableCellInEditModePositionState: extractComponentState( currentTableCellInEditModePositionComponentState, scopeId, ), @@ -80,19 +77,16 @@ export const useRecordTableStates = (recordTableId?: string) => { isTableCellInEditModeComponentFamilyState, scopeId, ), - getIsSoftFocusActiveState: extractComponentState( + isSoftFocusActiveState: extractComponentState( isSoftFocusActiveComponentState, scopeId, ), - getTableRowIdsState: extractComponentState( - tableRowIdsComponentState, - scopeId, - ), - getIsRecordTableInitialLoadingState: extractComponentState( + tableRowIdsState: extractComponentState(tableRowIdsComponentState, scopeId), + isRecordTableInitialLoadingState: extractComponentState( isRecordTableInitialLoadingComponentState, scopeId, ), - getResizeFieldOffsetState: extractComponentState( + resizeFieldOffsetState: extractComponentState( resizeFieldOffsetComponentState, scopeId, ), @@ -104,23 +98,23 @@ export const useRecordTableStates = (recordTableId?: string) => { isRowSelectedComponentFamilyState, scopeId, ), - getAllRowsSelectedStatusSelector: extractComponentReadOnlySelector( + allRowsSelectedStatusSelector: extractComponentReadOnlySelector( allRowsSelectedStatusComponentSelector, scopeId, ), - getHiddenTableColumnsSelector: extractComponentReadOnlySelector( + hiddenTableColumnsSelector: extractComponentReadOnlySelector( hiddenTableColumnsComponentSelector, scopeId, ), - getNumberOfTableColumnsSelector: extractComponentReadOnlySelector( + numberOfTableColumnsSelector: extractComponentReadOnlySelector( numberOfTableColumnsComponentSelector, scopeId, ), - getSelectedRowIdsSelector: extractComponentReadOnlySelector( + selectedRowIdsSelector: extractComponentReadOnlySelector( selectedRowIdsComponentSelector, scopeId, ), - getVisibleTableColumnsSelector: extractComponentReadOnlySelector( + visibleTableColumnsSelector: extractComponentReadOnlySelector( visibleTableColumnsComponentSelector, scopeId, ), diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts index c722d40bb509..7e86f581909c 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts @@ -4,18 +4,18 @@ import { useRecordTableStates } from '@/object-record/record-table/hooks/interna import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; export const useResetTableRowSelection = (recordTableId?: string) => { - const { getTableRowIdsState, isRowSelectedFamilyState } = + const { tableRowIdsState, isRowSelectedFamilyState } = useRecordTableStates(recordTableId); return useRecoilCallback( ({ snapshot, set }) => () => { - const tableRowIds = getSnapshotValue(snapshot, getTableRowIdsState()); + const tableRowIds = getSnapshotValue(snapshot, tableRowIdsState); for (const rowId of tableRowIds) { set(isRowSelectedFamilyState(rowId), false); } }, - [getTableRowIdsState, isRowSelectedFamilyState], + [tableRowIdsState, isRowSelectedFamilyState], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts index 1a7e563c15d2..c76683e6ae87 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts @@ -5,8 +5,8 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV export const useSelectAllRows = (recordTableId?: string) => { const { - getAllRowsSelectedStatusSelector, - getTableRowIdsState, + allRowsSelectedStatusSelector, + tableRowIdsState, isRowSelectedFamilyState, } = useRecordTableStates(recordTableId); @@ -15,10 +15,10 @@ export const useSelectAllRows = (recordTableId?: string) => { () => { const allRowsSelectedStatus = getSnapshotValue( snapshot, - getAllRowsSelectedStatusSelector(), + allRowsSelectedStatusSelector(), ); - const tableRowIds = getSnapshotValue(snapshot, getTableRowIdsState()); + const tableRowIds = getSnapshotValue(snapshot, tableRowIdsState); if ( allRowsSelectedStatus === 'none' || @@ -33,11 +33,7 @@ export const useSelectAllRows = (recordTableId?: string) => { } } }, - [ - getAllRowsSelectedStatusSelector, - getTableRowIdsState, - isRowSelectedFamilyState, - ], + [allRowsSelectedStatusSelector, tableRowIdsState, isRowSelectedFamilyState], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts index 01fa47fe3b39..32c1986ec42d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts @@ -14,7 +14,7 @@ export const useSetRecordTableData = ({ recordTableId, onEntityCountChange, }: useSetRecordTableDataProps) => { - const { getTableRowIdsState, getNumberOfTableRowsState } = + const { tableRowIdsState, numberOfTableRowsState } = useRecordTableStates(recordTableId); return useRecoilCallback( @@ -30,17 +30,17 @@ export const useSetRecordTableData = ({ set(recordStoreFamilyState(entity.id), entity); } } - const currentRowIds = getSnapshotValue(snapshot, getTableRowIdsState()); + const currentRowIds = getSnapshotValue(snapshot, tableRowIdsState); const entityIds = newEntityArray.map((entity) => entity.id); if (!isDeeplyEqual(currentRowIds, entityIds)) { - set(getTableRowIdsState(), entityIds); + set(tableRowIdsState, entityIds); } - set(getNumberOfTableRowsState(), totalCount); + set(numberOfTableRowsState, totalCount); onEntityCountChange(totalCount); }, - [getNumberOfTableRowsState, getTableRowIdsState, onEntityCountChange], + [numberOfTableRowsState, tableRowIdsState, onEntityCountChange], ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetSoftFocusPosition.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetSoftFocusPosition.ts index 5c0408c625e3..edf8f7a904e0 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetSoftFocusPosition.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetSoftFocusPosition.ts @@ -7,8 +7,8 @@ import { TableCellPosition } from '../../types/TableCellPosition'; export const useSetSoftFocusPosition = (recordTableId?: string) => { const { - getSoftFocusPositionState, - getIsSoftFocusActiveState, + softFocusPositionState, + isSoftFocusActiveState, isSoftFocusOnTableCellFamilyState, } = useRecordTableStates(recordTableId); @@ -17,21 +17,21 @@ export const useSetSoftFocusPosition = (recordTableId?: string) => { return (newPosition: TableCellPosition) => { const currentPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); - set(getIsSoftFocusActiveState(), true); + set(isSoftFocusActiveState, true); set(isSoftFocusOnTableCellFamilyState(currentPosition), false); - set(getSoftFocusPositionState(), newPosition); + set(softFocusPositionState, newPosition); set(isSoftFocusOnTableCellFamilyState(newPosition), true); }; }, [ - getSoftFocusPositionState, - getIsSoftFocusActiveState, + softFocusPositionState, + isSoftFocusActiveState, isSoftFocusOnTableCellFamilyState, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTable.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTable.ts index a530bb63533b..e876c51844a1 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTable.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTable.ts @@ -32,51 +32,49 @@ export const useRecordTable = (props?: useRecordTableProps) => { const { scopeId, - getAvailableTableColumnsState, - getTableFiltersState, - getTableSortsState, - getTableColumnsState, - getOnEntityCountChangeState, - getOnColumnsChangeState, - getIsRecordTableInitialLoadingState, - getTableLastRowVisibleState, - getSelectedRowIdsSelector, + availableTableColumnsState, + tableFiltersState, + tableSortsState, + tableColumnsState, + onEntityCountChangeState, + onColumnsChangeState, + isRecordTableInitialLoadingState, + tableLastRowVisibleState, + selectedRowIdsSelector, } = useRecordTableStates(recordTableId); const setAvailableTableColumns = useRecoilCallback( ({ snapshot, set }) => (columns: ColumnDefinition[]) => { - const availableTableColumnsState = getSnapshotValue( + const availableTableColumns = getSnapshotValue( snapshot, - getAvailableTableColumnsState(), + availableTableColumnsState, ); - if (isDeeplyEqual(availableTableColumnsState, columns)) { + if (isDeeplyEqual(availableTableColumns, columns)) { return; } - set(getAvailableTableColumnsState(), columns); + set(availableTableColumnsState, columns); }, - [getAvailableTableColumnsState], + [availableTableColumnsState], ); - const setOnEntityCountChange = useSetRecoilState( - getOnEntityCountChangeState(), - ); + const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState); - const setTableFilters = useSetRecoilState(getTableFiltersState()); + const setTableFilters = useSetRecoilState(tableFiltersState); - const setTableSorts = useSetRecoilState(getTableSortsState()); + const setTableSorts = useSetRecoilState(tableSortsState); - const setTableColumns = useSetRecoilState(getTableColumnsState()); + const setTableColumns = useSetRecoilState(tableColumnsState); - const setOnColumnsChange = useSetRecoilState(getOnColumnsChangeState()); + const setOnColumnsChange = useSetRecoilState(onColumnsChangeState); const setIsRecordTableInitialLoading = useSetRecoilState( - getIsRecordTableInitialLoadingState(), + isRecordTableInitialLoadingState, ); const setRecordTableLastRowVisible = useSetRecoilState( - getTableLastRowVisibleState(), + tableLastRowVisibleState, ); const onColumnsChange = useRecoilCallback( @@ -84,12 +82,12 @@ export const useRecordTable = (props?: useRecordTableProps) => { (columns: ColumnDefinition[]) => { const onColumnsChange = getSnapshotValue( snapshot, - getOnColumnsChangeState(), + onColumnsChangeState, ); onColumnsChange?.(columns); }, - [getOnColumnsChangeState], + [onColumnsChangeState], ); const onEntityCountChange = useRecoilCallback( @@ -97,12 +95,12 @@ export const useRecordTable = (props?: useRecordTableProps) => { (count: number) => { const onEntityCountChange = getSnapshotValue( snapshot, - getOnEntityCountChangeState(), + onEntityCountChangeState, ); onEntityCountChange?.(count); }, - [getOnEntityCountChangeState], + [onEntityCountChangeState], ); const setRecordTableData = useSetRecordTableData({ @@ -116,7 +114,7 @@ export const useRecordTable = (props?: useRecordTableProps) => { const resetTableRowSelection = useResetTableRowSelection(recordTableId); - const upsertRecordTableItem = useUpsertRecordFromState(); + const upsertRecordTableItem = useUpsertRecordFromState; const setSoftFocusPosition = useSetSoftFocusPosition(recordTableId); @@ -128,7 +126,7 @@ export const useRecordTable = (props?: useRecordTableProps) => { const setHotkeyScope = useSetHotkeyScope(); const setIsSoftFocusUsingMouseState = useSetRecoilState( - isSoftFocusUsingMouseState(), + isSoftFocusUsingMouseState, ); useScopedHotkeys( @@ -212,6 +210,6 @@ export const useRecordTable = (props?: useRecordTableProps) => { setRecordTableLastRowVisible, setSoftFocusPosition, isSomeCellInEditModeState, - getSelectedRowIdsSelector, + selectedRowIdsSelector, }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocus.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocus.ts index 7c5de53e7045..2291659af820 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocus.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocus.ts @@ -8,10 +8,10 @@ import { useSetSoftFocusPosition } from './internal/useSetSoftFocusPosition'; export const useRecordTableMoveFocus = (recordTableId?: string) => { const { scopeId, - getSoftFocusPositionState, - getNumberOfTableRowsState, - getNumberOfTableColumnsSelector, - getSelectedRowIdsSelector, + softFocusPositionState, + numberOfTableRowsState, + numberOfTableColumnsSelector, + selectedRowIdsSelector, } = useRecordTableStates(recordTableId); const setSoftFocusPosition = useSetSoftFocusPosition(recordTableId); @@ -21,7 +21,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { () => { const softFocusPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); let newRowNumber = softFocusPosition.row - 1; @@ -35,7 +35,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { row: newRowNumber, }); }, - [getSoftFocusPositionState, setSoftFocusPosition], + [softFocusPositionState, setSoftFocusPosition], ); const moveDown = useRecoilCallback( @@ -43,12 +43,12 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { () => { const softFocusPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); const numberOfTableRows = getSnapshotValue( snapshot, - getNumberOfTableRowsState(), + numberOfTableRowsState, ); let newRowNumber = softFocusPosition.row + 1; @@ -62,11 +62,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { row: newRowNumber, }); }, - [ - getNumberOfTableRowsState, - setSoftFocusPosition, - getSoftFocusPositionState, - ], + [numberOfTableRowsState, setSoftFocusPosition, softFocusPositionState], ); const moveRight = useRecoilCallback( @@ -74,17 +70,17 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { () => { const softFocusPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); const numberOfTableColumns = getSnapshotValue( snapshot, - getNumberOfTableColumnsSelector(), + numberOfTableColumnsSelector(), ); const numberOfTableRows = getSnapshotValue( snapshot, - getNumberOfTableRowsState(), + numberOfTableRowsState, ); const currentColumnNumber = softFocusPosition.column; const currentRowNumber = softFocusPosition.row; @@ -117,9 +113,9 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { } }, [ - getSoftFocusPositionState, - getNumberOfTableColumnsSelector, - getNumberOfTableRowsState, + softFocusPositionState, + numberOfTableColumnsSelector, + numberOfTableRowsState, setSoftFocusPosition, ], ); @@ -129,12 +125,12 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { () => { const softFocusPosition = getSnapshotValue( snapshot, - getSoftFocusPositionState(), + softFocusPositionState, ); const numberOfTableColumns = getSnapshotValue( snapshot, - getNumberOfTableColumnsSelector(), + numberOfTableColumnsSelector(), ); const currentColumnNumber = softFocusPosition.column; @@ -165,8 +161,8 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { } }, [ - getNumberOfTableColumnsSelector, - getSoftFocusPositionState, + numberOfTableColumnsSelector, + softFocusPositionState, setSoftFocusPosition, ], ); @@ -178,6 +174,6 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => { moveRight, moveUp, setSoftFocusPosition, - getSelectedRowIdsSelector, + selectedRowIdsSelector, }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useTableColumns.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useTableColumns.ts index 1cc9fa344416..534db9462588 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useTableColumns.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useTableColumns.ts @@ -18,15 +18,15 @@ export const useTableColumns = (props?: useRecordTableProps) => { }); const { - getAvailableTableColumnsState, - getTableColumnsState, - getVisibleTableColumnsSelector, + availableTableColumnsState, + tableColumnsState, + visibleTableColumnsSelector, } = useRecordTableStates(props?.recordTableId); - const availableTableColumns = useRecoilValue(getAvailableTableColumnsState()); + const availableTableColumns = useRecoilValue(availableTableColumnsState); - const tableColumns = useRecoilValue(getTableColumnsState()); - const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector()); + const tableColumns = useRecoilValue(tableColumnsState); + const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector()); const { handleColumnMove } = useMoveViewColumns(); @@ -47,6 +47,11 @@ export const useTableColumns = (props?: useRecordTableProps) => { (tableColumns) => tableColumns.fieldMetadataId === viewField.fieldMetadataId, ); + const lastTableColumnPosition = [...tableColumns] + .sort((a, b) => b.position - a.position) + .map((column) => column.position); + + const lastPosition = lastTableColumnPosition[0] ?? 0; if (isNewColumn) { const newColumn = availableTableColumns.find( @@ -57,7 +62,7 @@ export const useTableColumns = (props?: useRecordTableProps) => { const nextColumns = [ ...tableColumns, - { ...newColumn, isVisible: true }, + { ...newColumn, isVisible: true, position: lastPosition + 1 }, ]; await handleColumnsChange(nextColumns); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellContainer.tsx index b5ac47aafccb..344988c941af 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellContainer.tsx @@ -64,7 +64,7 @@ export const RecordTableCellContainer = ({ const isSomeCellInEditMode = useRecoilValue(isSomeCellInEditModeState()); const setIsSoftFocusUsingMouseState = useSetRecoilState( - isSoftFocusUsingMouseState(), + isSoftFocusUsingMouseState, ); const moveSoftFocusToCurrentCellOnHover = diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx index b75d36e29a46..7f10d98ba72a 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx @@ -29,7 +29,7 @@ export const RecordTableCellSoftFocusMode = ({ const toggleEditOnlyInput = useToggleEditOnlyInput(); const scrollRef = useRef(null); - const isSoftFocusUsingMouse = useRecoilValue(isSoftFocusUsingMouseState()); + const isSoftFocusUsingMouse = useRecoilValue(isSoftFocusUsingMouseState); const clearField = useClearField(); useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useCloseRecordTableCell.test.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useCloseRecordTableCell.test.tsx index c608e921e635..7e6dfb6f501c 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useCloseRecordTableCell.test.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useCloseRecordTableCell.test.tsx @@ -55,11 +55,11 @@ describe('useCloseRecordTableCell', () => { const { result } = renderHook( () => { const { - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState, } = useRecordTableStates(); const currentTableCellInEditModePosition = useRecoilValue( - getCurrentTableCellInEditModePositionState(), + currentTableCellInEditModePositionState, ); const isTableCellInEditMode = useRecoilValue( isTableCellInEditModeFamilyState(currentTableCellInEditModePosition), diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useMoveSoftFocusToCurrentCellOnHover.test.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useMoveSoftFocusToCurrentCellOnHover.test.tsx index 1ebad63a8fe2..b7946416501a 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useMoveSoftFocusToCurrentCellOnHover.test.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useMoveSoftFocusToCurrentCellOnHover.test.tsx @@ -65,11 +65,11 @@ jest.mock( '@/object-record/record-table/hooks/internal/useRecordTableStates', () => ({ useRecordTableStates: () => ({ - getSoftFocusPositionState: () => mockSoftFocusPositionState, - getIsSoftFocusActiveState: () => mockSoftFocusActiveState, + softFocusPositionState: mockSoftFocusPositionState, + isSoftFocusActiveState: mockSoftFocusActiveState, isSoftFocusOnTableCellFamilyState: () => mockIsSoftFocusOnTableCellFamilyState, - getCurrentTableCellInEditModePositionState: () => + currentTableCellInEditModePositionState: mockCurrentTableCellInEditModePositionState, isTableCellInEditModeFamilyState: () => mockIsTableCellInEditModeFamilyState, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover.ts index 0ddc6fe6a116..3d53b8d9b0c9 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveSoftFocusToCurrentCellOnHover.ts @@ -12,7 +12,7 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => { const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell(); const { - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState, } = useRecordTableStates(); @@ -21,7 +21,7 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => { () => { const currentTableCellInEditModePosition = getSnapshotValue( snapshot, - getCurrentTableCellInEditModePositionState(), + currentTableCellInEditModePositionState, ); const isSomeCellInEditMode = snapshot @@ -33,7 +33,7 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => { .getValue(); const currentHotkeyScope = snapshot - .getLoadable(currentHotkeyScopeState()) + .getLoadable(currentHotkeyScopeState) .getValue(); if ( @@ -49,7 +49,7 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => { } }, [ - getCurrentTableCellInEditModePositionState, + currentTableCellInEditModePositionState, isTableCellInEditModeFamilyState, setSoftFocusOnCurrentTableCell, ], diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetSoftFocus.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetSoftFocus.ts index 9c2ef5f73a14..9b630f4e2f36 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetSoftFocus.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetSoftFocus.ts @@ -10,7 +10,7 @@ import { TableHotkeyScope } from '../../types/TableHotkeyScope'; export const useSetSoftFocus = () => { const setSoftFocusPosition = useSetSoftFocusPosition(); - const { getIsSoftFocusActiveState } = useRecordTableStates(); + const { isSoftFocusActiveState } = useRecordTableStates(); const setHotkeyScope = useSetHotkeyScope(); @@ -19,10 +19,10 @@ export const useSetSoftFocus = () => { (newPosition: TableCellPosition) => { setSoftFocusPosition(newPosition); - set(getIsSoftFocusActiveState(), true); + set(isSoftFocusActiveState, true); setHotkeyScope(TableHotkeyScope.TableSoftFocus); }, - [setSoftFocusPosition, getIsSoftFocusActiveState, setHotkeyScope], + [setSoftFocusPosition, isSoftFocusActiveState, setHotkeyScope], ); }; diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray.test.tsx b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray.test.tsx index 92661b8e6113..decadcd2e519 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray.test.tsx +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray.test.tsx @@ -58,7 +58,7 @@ describe('useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray' }, }, ), - setObjectMetadata: useSetRecoilState(objectMetadataItemsState()), + setObjectMetadata: useSetRecoilState(objectMetadataItemsState), }; }, { diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx index d48688e51d41..fa85d8629076 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/__tests__/useMultiObjectSearch.test.tsx @@ -105,7 +105,7 @@ describe('useMultiObjectSearch', () => { }, ], }), - setObjectMetadata: useSetRecoilState(objectMetadataItemsState()), + setObjectMetadata: useSetRecoilState(objectMetadataItemsState), }), { wrapper: Wrapper, diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery.ts b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery.ts index 2da828779022..3f91947262b4 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery.ts @@ -25,7 +25,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery = ({ searchFilterValue: string; limit?: number; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const { searchFilterPerMetadataItemNameSingular } = useSearchFilterPerMetadataItem({ @@ -85,7 +85,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery = ({ const multiSelectQueryForSelectedIds = useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ - objectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery, + targetObjectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery, depth: 0, }); diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts index 16ce8e1cf3b3..675dd938df0c 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts @@ -28,7 +28,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({ searchFilterValue: string; limit?: number; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const nonSystemObjectMetadataItems = objectMetadataItems.filter( ({ nameSingular, isSystem }) => @@ -86,7 +86,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({ const multiSelectQuery = useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ - objectMetadataItems: nonSystemObjectMetadataItems, + targetObjectMetadataItems: nonSystemObjectMetadataItems, depth: 0, }); diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchSelectedItemsQuery.ts b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchSelectedItemsQuery.ts index a390c13f7ca3..0cfdaebf79b2 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchSelectedItemsQuery.ts +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchSelectedItemsQuery.ts @@ -26,7 +26,7 @@ export const useMultiObjectSearchSelectedItemsQuery = ({ }: { selectedObjectRecordIds: SelectedObjectRecordId[]; }) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItemsUsedInSelectedIdsQuery = objectMetadataItems.filter( ({ nameSingular }) => { @@ -69,7 +69,7 @@ export const useMultiObjectSearchSelectedItemsQuery = ({ const multiSelectQueryForSelectedIds = useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ - objectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery, + targetObjectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery, }); const { diff --git a/packages/twenty-front/src/modules/object-record/spreadsheet-import/__tests__/useSpreadsheetRecordImport.test.tsx b/packages/twenty-front/src/modules/object-record/spreadsheet-import/__tests__/useSpreadsheetRecordImport.test.tsx index 6e400e579d52..a925b36c8c74 100644 --- a/packages/twenty-front/src/modules/object-record/spreadsheet-import/__tests__/useSpreadsheetRecordImport.test.tsx +++ b/packages/twenty-front/src/modules/object-record/spreadsheet-import/__tests__/useSpreadsheetRecordImport.test.tsx @@ -92,7 +92,7 @@ describe('useSpreadsheetCompanyImport', () => { it('should work as expected', async () => { const { result } = renderHook( () => { - const spreadsheetImport = useRecoilValue(spreadsheetImportState()); + const spreadsheetImport = useRecoilValue(spreadsheetImportState); const { openRecordSpreadsheetImport } = useSpreadsheetRecordImport( CoreObjectNameSingular.Company, ); diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx index 18a73506f99b..0554b0388037 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx @@ -1,6 +1,9 @@ import { useEffect } from 'react'; import { useQuery } from '@apollo/client'; +import { useRecoilValue } from 'recoil'; +import { currentUserState } from '@/auth/states/currentUserState'; +import { EMPTY_QUERY } from '@/object-metadata/hooks/useObjectMetadataItem'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useGenerateFindManyRecordsForMultipleMetadataItemsQuery } from '@/object-record/hooks/useGenerateFindManyRecordsForMultipleMetadataItemsQuery'; import { MultiObjectRecordQueryResult } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray'; @@ -9,6 +12,8 @@ import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { isDefined } from '~/utils/isDefined'; export const PrefetchRunQueriesEffect = () => { + const currentUser = useRecoilValue(currentUserState); + const { objectMetadataItem: objectMetadataItemView, upsertRecordsInCache: upsertViewsInCache, @@ -27,16 +32,18 @@ export const PrefetchRunQueriesEffect = () => { const prefetchFindManyQuery = useGenerateFindManyRecordsForMultipleMetadataItemsQuery({ - objectMetadataItems: [objectMetadataItemView, objectMetadataItemFavorite], + targetObjectMetadataItems: [ + objectMetadataItemView, + objectMetadataItemFavorite, + ], depth: 2, }); - if (!isDefined(prefetchFindManyQuery)) { - throw new Error('Could not prefetch recrds'); - } - const { data } = useQuery( - prefetchFindManyQuery, + prefetchFindManyQuery ?? EMPTY_QUERY, + { + skip: !currentUser, + }, ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/search/hooks/__tests__/useFilteredSearchEntityQuery.test.tsx b/packages/twenty-front/src/modules/search/hooks/__tests__/useFilteredSearchEntityQuery.test.tsx index ea46bac44bfa..57a93cdec66c 100644 --- a/packages/twenty-front/src/modules/search/hooks/__tests__/useFilteredSearchEntityQuery.test.tsx +++ b/packages/twenty-front/src/modules/search/hooks/__tests__/useFilteredSearchEntityQuery.test.tsx @@ -67,7 +67,7 @@ describe('useFilteredSearchEntityQuery', () => { const { result } = renderHook( () => { const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember({ id: '32219445-f587-4c40-b2b1-6d3205ed96da', @@ -76,7 +76,7 @@ describe('useFilteredSearchEntityQuery', () => { const mockObjectMetadataItems = getObjectMetadataItemsMock(); - const setMetadataItems = useSetRecoilState(objectMetadataItemsState()); + const setMetadataItems = useSetRecoilState(objectMetadataItemsState); setMetadataItems(mockObjectMetadataItems); diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarAccountsListCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarAccountsListCard.tsx index b157fb588fca..5425976316ec 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarAccountsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarAccountsListCard.tsx @@ -20,7 +20,7 @@ const StyledRowRightContainer = styled.div` `; export const SettingsAccountsCalendarAccountsListCard = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const navigate = useNavigate(); const { records: _accounts, loading } = useFindManyRecords({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsAccountsListCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsAccountsListCard.tsx index 7999f062b9a7..2fc6154f1e42 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsAccountsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsAccountsListCard.tsx @@ -20,7 +20,7 @@ const StyledRowRightContainer = styled.div` `; export const SettingsAccountsEmailsAccountsListCard = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const navigate = useNavigate(); const { records: accounts, loading: accountsLoading } = diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx index 03e6a9e25bd5..28646b9d8cb9 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx @@ -12,7 +12,7 @@ import { H2Title } from '@/ui/display/typography/components/H2Title'; import { Section } from '@/ui/layout/section/components/Section'; export const SettingsAccountsEmailsBlocklistSection = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { records: blocklist } = useFindManyRecords({ objectNameSingular: CoreObjectNameSingular.Blocklist, diff --git a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx index 0c9aa2f19d09..fb3ab5f1cc67 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx @@ -37,7 +37,7 @@ export const SettingsNavigationDrawerItems = () => { }, [signOut, navigate]); const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED'); - const billing = useRecoilValue(billingState()); + const billing = useRecoilValue(billingState); return ( <> diff --git a/packages/twenty-front/src/modules/settings/profile/components/ChangePassword.tsx b/packages/twenty-front/src/modules/settings/profile/components/ChangePassword.tsx index eb08cd04526d..ee60971528c5 100644 --- a/packages/twenty-front/src/modules/settings/profile/components/ChangePassword.tsx +++ b/packages/twenty-front/src/modules/settings/profile/components/ChangePassword.tsx @@ -9,7 +9,7 @@ import { useEmailPasswordResetLinkMutation } from '~/generated/graphql'; export const ChangePassword = () => { const { enqueueSnackBar } = useSnackBar(); - const currentUser = useRecoilValue(currentUserState()); + const currentUser = useRecoilValue(currentUserState); const [emailPasswordResetLink] = useEmailPasswordResetLinkMutation(); diff --git a/packages/twenty-front/src/modules/settings/profile/components/DeleteAccount.tsx b/packages/twenty-front/src/modules/settings/profile/components/DeleteAccount.tsx index bd0de3f17a2f..d3e52ad09eca 100644 --- a/packages/twenty-front/src/modules/settings/profile/components/DeleteAccount.tsx +++ b/packages/twenty-front/src/modules/settings/profile/components/DeleteAccount.tsx @@ -15,7 +15,7 @@ export const DeleteAccount = () => { useState(false); const [deleteUserAccount] = useDeleteUserAccountMutation(); - const currentUser = useRecoilValue(currentUserState()); + const currentUser = useRecoilValue(currentUserState); const userEmail = currentUser?.email; const { signOut } = useAuth(); const navigate = useNavigate(); diff --git a/packages/twenty-front/src/modules/settings/profile/components/DeleteWorkspace.tsx b/packages/twenty-front/src/modules/settings/profile/components/DeleteWorkspace.tsx index b0fcdf1215e2..4264bd928299 100644 --- a/packages/twenty-front/src/modules/settings/profile/components/DeleteWorkspace.tsx +++ b/packages/twenty-front/src/modules/settings/profile/components/DeleteWorkspace.tsx @@ -17,7 +17,7 @@ export const DeleteWorkspace = () => { useState(false); const [deleteCurrentWorkspace] = useDeleteCurrentWorkspaceMutation(); - const currentUser = useRecoilValue(currentUserState()); + const currentUser = useRecoilValue(currentUserState); const userEmail = currentUser?.email; const { signOut } = useAuth(); const navigate = useNavigate(); diff --git a/packages/twenty-front/src/modules/settings/profile/components/EmailField.tsx b/packages/twenty-front/src/modules/settings/profile/components/EmailField.tsx index 80494ebbbeef..02c1e87341a4 100644 --- a/packages/twenty-front/src/modules/settings/profile/components/EmailField.tsx +++ b/packages/twenty-front/src/modules/settings/profile/components/EmailField.tsx @@ -4,7 +4,7 @@ import { currentUserState } from '@/auth/states/currentUserState'; import { TextInput } from '@/ui/input/components/TextInput'; export const EmailField = () => { - const currentUser = useRecoilValue(currentUserState()); + const currentUser = useRecoilValue(currentUserState); return ( { - const currentUser = useRecoilValue(currentUserState()); + const currentUser = useRecoilValue(currentUserState); const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const [firstName, setFirstName] = useState( diff --git a/packages/twenty-front/src/modules/settings/profile/components/ProfilePictureUploader.tsx b/packages/twenty-front/src/modules/settings/profile/components/ProfilePictureUploader.tsx index 8da64b0f1a94..4a65b1ff3aa3 100644 --- a/packages/twenty-front/src/modules/settings/profile/components/ProfilePictureUploader.tsx +++ b/packages/twenty-front/src/modules/settings/profile/components/ProfilePictureUploader.tsx @@ -15,7 +15,7 @@ export const ProfilePictureUploader = () => { useUploadProfilePictureMutation(); const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const [uploadController, setUploadController] = diff --git a/packages/twenty-front/src/modules/settings/workspace/components/NameField.tsx b/packages/twenty-front/src/modules/settings/workspace/components/NameField.tsx index 62dc739305c7..b72e76b4e87d 100644 --- a/packages/twenty-front/src/modules/settings/workspace/components/NameField.tsx +++ b/packages/twenty-front/src/modules/settings/workspace/components/NameField.tsx @@ -27,7 +27,7 @@ export const NameField = ({ autoSave = true, onNameUpdate, }: NameFieldProps) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const [displayName, setDisplayName] = useState( currentWorkspace?.displayName ?? '', diff --git a/packages/twenty-front/src/modules/settings/workspace/components/ToggleImpersonate.tsx b/packages/twenty-front/src/modules/settings/workspace/components/ToggleImpersonate.tsx index ebb909ede871..453cfc21dd05 100644 --- a/packages/twenty-front/src/modules/settings/workspace/components/ToggleImpersonate.tsx +++ b/packages/twenty-front/src/modules/settings/workspace/components/ToggleImpersonate.tsx @@ -9,7 +9,7 @@ export const ToggleImpersonate = () => { const { enqueueSnackBar } = useSnackBar(); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( - currentWorkspaceState(), + currentWorkspaceState, ); const [updateWorkspace] = useUpdateWorkspaceMutation(); diff --git a/packages/twenty-front/src/modules/settings/workspace/components/WorkspaceLogoUploader.tsx b/packages/twenty-front/src/modules/settings/workspace/components/WorkspaceLogoUploader.tsx index ba410823af07..009c32d54f5d 100644 --- a/packages/twenty-front/src/modules/settings/workspace/components/WorkspaceLogoUploader.tsx +++ b/packages/twenty-front/src/modules/settings/workspace/components/WorkspaceLogoUploader.tsx @@ -13,7 +13,7 @@ export const WorkspaceLogoUploader = () => { const [uploadLogo] = useUploadWorkspaceLogoMutation(); const [updateWorkspce] = useUpdateWorkspaceMutation(); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( - currentWorkspaceState(), + currentWorkspaceState, ); const onUpload = async (file: File) => { diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx index 941647853c63..447ca98aa402 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx @@ -24,6 +24,7 @@ export const SignInBackgroundMockContainer = () => { {}} optionsDropdownButton={ { setViewObjectMetadataId?.(objectMetadataItem.id); @@ -85,9 +88,9 @@ export const SignInBackgroundMockContainerEffect = ({ useEffect(() => { setOnEntityCountChange( - () => (entityCount: number) => setEntityCountInCurrentView(entityCount), + () => (entityCount: number) => setRecordCountInCurrentView(entityCount), ); - }, [setEntityCountInCurrentView, setOnEntityCountChange]); + }, [setRecordCountInCurrentView, setOnEntityCountChange]); return <>; }; diff --git a/packages/twenty-front/src/modules/spreadsheet-import/hooks/__tests__/useSpreadsheetImport.test.tsx b/packages/twenty-front/src/modules/spreadsheet-import/hooks/__tests__/useSpreadsheetImport.test.tsx index a2948066346d..c54a5498a539 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/hooks/__tests__/useSpreadsheetImport.test.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/hooks/__tests__/useSpreadsheetImport.test.tsx @@ -44,7 +44,7 @@ describe('useSpreadsheetImport', () => { const { result } = renderHook( () => ({ useSpreadsheetImport: useSpreadsheetImport(), - spreadsheetImportState: useRecoilState(spreadsheetImportState())[0], + spreadsheetImportState: useRecoilState(spreadsheetImportState)[0], }), { wrapper: Wrapper, diff --git a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useSpreadsheetImport.ts b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useSpreadsheetImport.ts index 160ba49caa81..0259faad6041 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useSpreadsheetImport.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useSpreadsheetImport.ts @@ -4,7 +4,7 @@ import { spreadsheetImportState } from '@/spreadsheet-import/states/spreadsheetI import { SpreadsheetOptions } from '@/spreadsheet-import/types'; export const useSpreadsheetImport = () => { - const setSpreadSheetImport = useSetRecoilState(spreadsheetImportState()); + const setSpreadSheetImport = useSetRecoilState(spreadsheetImportState); const openSpreadsheetImport = ( options: Omit, 'isOpen' | 'onClose'>, diff --git a/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImportProvider.tsx b/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImportProvider.tsx index 3bec782699da..5c5b7a137704 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImportProvider.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImportProvider.tsx @@ -11,7 +11,7 @@ export const SpreadsheetImportProvider = ( props: SpreadsheetImportProviderProps, ) => { const [spreadsheetImport, setSpreadsheetImport] = useRecoilState( - spreadsheetImportState(), + spreadsheetImportState, ); const handleClose = () => { diff --git a/packages/twenty-front/src/modules/support/components/SupportChat.tsx b/packages/twenty-front/src/modules/support/components/SupportChat.tsx index ab15532b4a8d..4a41c61688ed 100644 --- a/packages/twenty-front/src/modules/support/components/SupportChat.tsx +++ b/packages/twenty-front/src/modules/support/components/SupportChat.tsx @@ -33,9 +33,9 @@ const insertScript = ({ }; export const SupportChat = () => { - const currentUser = useRecoilValue(currentUserState()); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); - const supportChat = useRecoilValue(supportChatState()); + const currentUser = useRecoilValue(currentUserState); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + const supportChat = useRecoilValue(supportChatState); const [isFrontChatLoaded, setIsFrontChatLoaded] = useState(false); const configureFront = useCallback( diff --git a/packages/twenty-front/src/modules/ui/display/icon/components/IconsProvider.tsx b/packages/twenty-front/src/modules/ui/display/icon/components/IconsProvider.tsx index 16112d90fcbd..918d7d32d600 100644 --- a/packages/twenty-front/src/modules/ui/display/icon/components/IconsProvider.tsx +++ b/packages/twenty-front/src/modules/ui/display/icon/components/IconsProvider.tsx @@ -8,7 +8,7 @@ type IconsProviderProps = { }; export const IconsProvider = ({ children }: IconsProviderProps) => { - const setIcons = useSetRecoilState(iconsState()); + const setIcons = useSetRecoilState(iconsState); useEffect(() => { import('../constants/index').then((lazyLoadedIcons) => { diff --git a/packages/twenty-front/src/modules/ui/display/icon/hooks/useIcons.ts b/packages/twenty-front/src/modules/ui/display/icon/hooks/useIcons.ts index e3619b770da4..4efd71e7f63d 100644 --- a/packages/twenty-front/src/modules/ui/display/icon/hooks/useIcons.ts +++ b/packages/twenty-front/src/modules/ui/display/icon/hooks/useIcons.ts @@ -4,7 +4,7 @@ import { Icon123 } from '@/ui/display/icon'; import { iconsState } from '@/ui/display/icon/states/iconsState'; export const useIcons = () => { - const icons = useRecoilValue(iconsState()); + const icons = useRecoilValue(iconsState); const defaultIcon = Icon123; const getIcons = () => { diff --git a/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts b/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts index 998dd0dee4d1..141431c715cf 100644 --- a/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts +++ b/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts @@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil'; import { iconPickerState } from '../states/iconPickerState'; export const useIconPicker = () => { - const [iconPicker, setIconPicker] = useRecoilState(iconPickerState()); + const [iconPicker, setIconPicker] = useRecoilState(iconPickerState); return { Icon: iconPicker.Icon, diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInput.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInput.tsx index 913534a8d7b9..be3f42d2e003 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInput.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInput.tsx @@ -30,13 +30,14 @@ const StyledInputContainer = styled.div` export const DropdownMenuInput = forwardRef< HTMLInputElement, InputHTMLAttributes ->(({ autoFocus, defaultValue, placeholder }, ref) => { +>(({ autoFocus, defaultValue, placeholder, onChange }, ref) => { return ( diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/__tests__/useInternalHotkeyScopeManagement.test.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/__tests__/useInternalHotkeyScopeManagement.test.tsx index 9bdb17bae49f..3bfd0f3a3585 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/__tests__/useInternalHotkeyScopeManagement.test.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/__tests__/useInternalHotkeyScopeManagement.test.tsx @@ -27,7 +27,7 @@ describe('useInternalHotkeyScopeManagement', () => { const { dropdownHotkeyScopeState } = useDropdownStates({ dropdownScopeId, }); - const dropdownHotkeyScope = useRecoilValue(dropdownHotkeyScopeState()); + const dropdownHotkeyScope = useRecoilValue(dropdownHotkeyScopeState); return { dropdownHotkeyScope }; }, { diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useDropdown.ts b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useDropdown.ts index 0a671a40e9f4..f3b196f41808 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useDropdown.ts +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useDropdown.ts @@ -20,14 +20,12 @@ export const useDropdown = (dropdownId?: string) => { goBackToPreviousHotkeyScope, } = usePreviousHotkeyScope(); - const [dropdownHotkeyScope] = useRecoilState(dropdownHotkeyScopeState()); + const [dropdownHotkeyScope] = useRecoilState(dropdownHotkeyScopeState); - const [dropdownWidth, setDropdownWidth] = - useRecoilState(dropdownWidthState()); + const [dropdownWidth, setDropdownWidth] = useRecoilState(dropdownWidthState); - const [isDropdownOpen, setIsDropdownOpen] = useRecoilState( - isDropdownOpenState(), - ); + const [isDropdownOpen, setIsDropdownOpen] = + useRecoilState(isDropdownOpenState); const closeDropdown = () => { goBackToPreviousHotkeyScope(); diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement.ts b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement.ts index 74f29b508d17..9ea9db797362 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement.ts +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement.ts @@ -15,7 +15,7 @@ export const useInternalHotkeyScopeManagement = ({ const { dropdownHotkeyScopeState } = useDropdownStates({ dropdownScopeId }); const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilState( - dropdownHotkeyScopeState(), + dropdownHotkeyScopeState, ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx index 1ab9143e9844..a73e674dfd3f 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx @@ -42,12 +42,12 @@ const StyledRightDrawer = styled.div` export const RightDrawer = () => { const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState( - isRightDrawerOpenState(), + isRightDrawerOpenState, ); - const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState()); + const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState); - const rightDrawerPage = useRecoilValue(rightDrawerPageState()); + const rightDrawerPage = useRecoilValue(rightDrawerPageState); const { closeRightDrawer } = useRightDrawer(); @@ -63,11 +63,11 @@ export const RightDrawer = () => { ({ snapshot, set }) => (event) => { const isRightDrawerOpen = snapshot - .getLoadable(isRightDrawerOpenState()) + .getLoadable(isRightDrawerOpenState) .getValue(); if (isRightDrawerOpen) { - set(rightDrawerCloseEventState(), event); + set(rightDrawerCloseEventState, event); closeRightDrawer(); } }, diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx index 7eced58ff4a8..a0eb83b409e2 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx @@ -47,7 +47,7 @@ const RIGHT_DRAWER_PAGES_CONFIG = { }; export const RightDrawerRouter = () => { - const [rightDrawerPage] = useRecoilState(rightDrawerPageState()); + const [rightDrawerPage] = useRecoilState(rightDrawerPageState); const { topBar = null, page = null } = rightDrawerPage ? RIGHT_DRAWER_PAGES_CONFIG[rightDrawerPage] diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx index d22700e7324f..701c69edfabf 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx @@ -10,7 +10,7 @@ import { isRightDrawerExpandedState } from '../states/isRightDrawerExpandedState export const RightDrawerTopBarExpandButton = () => { const [isRightDrawerExpanded, setIsRightDrawerExpanded] = useRecoilState( - isRightDrawerExpandedState(), + isRightDrawerExpandedState, ); const handleButtonClick = () => { diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx index 727f6a7ca901..843de0118c6c 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx @@ -12,12 +12,10 @@ describe('useRightDrawer', () => { it('Should test the default behavior of useRightDrawer and change the states as the function calls', async () => { const useCombinedHooks = () => { const { openRightDrawer, closeRightDrawer } = useRightDrawer(); - const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState()); - const isRightDrawerExpanded = useRecoilValue( - isRightDrawerExpandedState(), - ); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); + const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState); - const rightDrawerPage = useRecoilValue(rightDrawerPageState()); + const rightDrawerPage = useRecoilValue(rightDrawerPageState); return { openRightDrawer, diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts index fe04ac5a1b5f..5cf5cc621456 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts @@ -8,16 +8,16 @@ import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerPages } from '../types/RightDrawerPages'; export const useRightDrawer = () => { - const [isRightDrawerOpen] = useRecoilState(isRightDrawerOpenState()); + const [isRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); - const [rightDrawerPage] = useRecoilState(rightDrawerPageState()); + const [rightDrawerPage] = useRecoilState(rightDrawerPageState); const openRightDrawer = useRecoilCallback( ({ set }) => (rightDrawerPage: RightDrawerPages) => { - set(rightDrawerPageState(), rightDrawerPage); - set(isRightDrawerExpandedState(), false); - set(isRightDrawerOpenState(), true); + set(rightDrawerPageState, rightDrawerPage); + set(isRightDrawerExpandedState, false); + set(isRightDrawerOpenState, true); }, [], ); @@ -25,8 +25,8 @@ export const useRightDrawer = () => { const closeRightDrawer = useRecoilCallback( ({ set }) => () => { - set(isRightDrawerExpandedState(), false); - set(isRightDrawerOpenState(), false); + set(isRightDrawerExpandedState, false); + set(isRightDrawerOpenState, false); }, [], ); @@ -35,7 +35,7 @@ export const useRightDrawer = () => { ({ snapshot }) => (event: MouseEvent | TouchEvent) => { const rightDrawerCloseEvent = snapshot - .getLoadable(rightDrawerCloseEventState()) + .getLoadable(rightDrawerCloseEventState) .getValue(); const isSameEvent = diff --git a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/__tests__/useSelectableList.test.ts b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/__tests__/useSelectableList.test.ts index a7bbe398dd50..930ea10ad521 100644 --- a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/__tests__/useSelectableList.test.ts +++ b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/__tests__/useSelectableList.test.ts @@ -21,7 +21,7 @@ describe('useSelectableList', () => { selectableListScopeId, }); - const selectableItemIds = useRecoilValue(selectableItemIdsState()); + const selectableItemIds = useRecoilValue(selectableItemIdsState); return { setSelectableItemIds, @@ -51,9 +51,8 @@ describe('useSelectableList', () => { selectableListScopeId, }); - const [selectedItemId, setSelectedItemId] = useRecoilState( - selectedItemIdState(), - ); + const [selectedItemId, setSelectedItemId] = + useRecoilState(selectedItemIdState); return { resetSelectedItem, diff --git a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx index 91340db8d05c..9d668f3e0a3e 100644 --- a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx +++ b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx @@ -40,13 +40,10 @@ export const useSelectableListHotKeys = ( const handleSelect = useRecoilCallback( ({ snapshot, set }) => (direction: Direction) => { - const selectedItemId = getSnapshotValue( - snapshot, - selectedItemIdState(), - ); + const selectedItemId = getSnapshotValue(snapshot, selectedItemIdState); const selectableItemIds = getSnapshotValue( snapshot, - selectableItemIdsState(), + selectableItemIdsState, ); const currentPosition = findPosition(selectableItemIds, selectedItemId); @@ -107,7 +104,7 @@ export const useSelectableListHotKeys = ( if (selectedItemId !== nextId) { if (isNonEmptyString(nextId)) { set(isSelectedItemIdSelector(nextId), true); - set(selectedItemIdState(), nextId); + set(selectedItemIdState, nextId); } if (isNonEmptyString(selectedItemId)) { @@ -138,11 +135,11 @@ export const useSelectableListHotKeys = ( () => { const selectedItemId = getSnapshotValue( snapshot, - selectedItemIdState(), + selectedItemIdState, ); const onEnter = getSnapshotValue( snapshot, - selectableListOnEnterState(), + selectableListOnEnterState, ); if (isNonEmptyString(selectedItemId)) { diff --git a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/useSelectableList.ts b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/useSelectableList.ts index 7d33e15ac18e..37098d3c90c3 100644 --- a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/useSelectableList.ts +++ b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/useSelectableList.ts @@ -13,12 +13,12 @@ export const useSelectableList = (selectableListId?: string) => { selectableListScopeId: selectableListId, }); - const setSelectableItemIds = useSetRecoilState(selectableItemIdsState()); + const setSelectableItemIds = useSetRecoilState(selectableItemIdsState); const setSelectableListOnEnter = useSetRecoilState( - selectableListOnEnterState(), + selectableListOnEnterState, ); - const resetSelectedItemIdState = useResetRecoilState(selectedItemIdState()); + const resetSelectedItemIdState = useResetRecoilState(selectedItemIdState); const resetSelectedItem = () => { resetSelectedItemIdState(); diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx index 3b75efe6269a..fee1454b6f8c 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx @@ -26,7 +26,7 @@ export const ShowPageMoreButton = ({ objectNameSingular: string; }) => { const { closeDropdown, toggleDropdown } = useDropdown('more-show-page'); - const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState()); + const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); const navigate = useNavigate(); const { deleteOneRecord } = useDeleteOneRecord({ diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx index f8d4b9deefcd..390e5e9e1020 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx @@ -61,8 +61,8 @@ export const ShowPageRightContainer = ({ notes, emails, }: ShowPageRightContainerProps) => { - const { getActiveTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); - const activeTabId = useRecoilValue(getActiveTabIdState()); + const { activeTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); + const activeTabId = useRecoilValue(activeTabIdState); const shouldDisplayCalendarTab = useIsFeatureEnabled('IS_CALENDAR_ENABLED'); const shouldDisplayEmailsTab = diff --git a/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx b/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx index 8554be46b83c..ce1f2a942021 100644 --- a/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx +++ b/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx @@ -36,9 +36,9 @@ const StyledContainer = styled.div` export const TabList = ({ tabs, tabListId }: TabListProps) => { const initialActiveTabId = tabs[0].id; - const { getActiveTabIdState, setActiveTabId } = useTabList(tabListId); + const { activeTabIdState, setActiveTabId } = useTabList(tabListId); - const activeTabId = useRecoilValue(getActiveTabIdState()); + const activeTabId = useRecoilValue(activeTabIdState); React.useEffect(() => { setActiveTabId(initialActiveTabId); diff --git a/packages/twenty-front/src/modules/ui/layout/tab/hooks/__tests__/useTabList.test.tsx b/packages/twenty-front/src/modules/ui/layout/tab/hooks/__tests__/useTabList.test.tsx index 986e243bfa8b..83e30532fcf3 100644 --- a/packages/twenty-front/src/modules/ui/layout/tab/hooks/__tests__/useTabList.test.tsx +++ b/packages/twenty-front/src/modules/ui/layout/tab/hooks/__tests__/useTabList.test.tsx @@ -8,12 +8,11 @@ describe('useTabList', () => { it('Should update the activeTabId state', async () => { const { result } = renderHook( () => { - const { getActiveTabIdState, setActiveTabId } = + const { activeTabIdState, setActiveTabId } = useTabList('TEST_TAB_LIST_ID'); - const activeTabId = useRecoilValue(getActiveTabIdState()); + const activeTabId = useRecoilValue(activeTabIdState); return { - getActiveTabIdState: getActiveTabIdState, activeTabId, setActiveTabId: setActiveTabId, }; @@ -22,7 +21,6 @@ describe('useTabList', () => { wrapper: RecoilRoot, }, ); - expect(result.current.getActiveTabIdState).toBeInstanceOf(Function); expect(result.current.setActiveTabId).toBeInstanceOf(Function); expect(result.current.activeTabId).toBeNull(); diff --git a/packages/twenty-front/src/modules/ui/layout/tab/hooks/internal/useTabListStates.ts b/packages/twenty-front/src/modules/ui/layout/tab/hooks/internal/useTabListStates.ts index 6915852548ef..2d33932be5a7 100644 --- a/packages/twenty-front/src/modules/ui/layout/tab/hooks/internal/useTabListStates.ts +++ b/packages/twenty-front/src/modules/ui/layout/tab/hooks/internal/useTabListStates.ts @@ -15,9 +15,6 @@ export const useTabListStates = ({ tabListScopeId }: useTabListStatesProps) => { return { scopeId, - getActiveTabIdState: extractComponentState( - activeTabIdComponentState, - scopeId, - ), + activeTabIdState: extractComponentState(activeTabIdComponentState, scopeId), }; }; diff --git a/packages/twenty-front/src/modules/ui/layout/tab/hooks/useTabList.ts b/packages/twenty-front/src/modules/ui/layout/tab/hooks/useTabList.ts index c02624ada45e..9925dec4c655 100644 --- a/packages/twenty-front/src/modules/ui/layout/tab/hooks/useTabList.ts +++ b/packages/twenty-front/src/modules/ui/layout/tab/hooks/useTabList.ts @@ -3,14 +3,14 @@ import { useSetRecoilState } from 'recoil'; import { useTabListStates } from '@/ui/layout/tab/hooks/internal/useTabListStates'; export const useTabList = (tabListId?: string) => { - const { getActiveTabIdState } = useTabListStates({ + const { activeTabIdState } = useTabListStates({ tabListScopeId: `${tabListId}-scope`, }); - const setActiveTabId = useSetRecoilState(getActiveTabIdState()); + const setActiveTabId = useSetRecoilState(activeTabIdState); return { - getActiveTabIdState, + activeTabIdState, setActiveTabId, }; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx index 2c7b9db3b552..bf5c2586a0af 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx @@ -28,8 +28,8 @@ const StyledContainerActionBar = styled.div` `; export const ActionBar = () => { - const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState()); - const actionBarEntries = useRecoilValue(actionBarEntriesState()); + const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); + const actionBarEntries = useRecoilValue(actionBarEntriesState); const wrapperRef = useRef(null); if (contextMenuIsOpen) { diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx index 460ee2048789..24daaea85575 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx @@ -9,7 +9,7 @@ import { actionBarOpenState } from '../../states/actionBarIsOpenState'; import { ActionBar } from '../ActionBar'; const FilledActionBar = () => { - const setActionBarOpenState = useSetRecoilState(actionBarOpenState()); + const setActionBarOpenState = useSetRecoilState(actionBarOpenState); setActionBarOpenState(true); return ; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx index 519c6bf87a09..8a3a1cfd0e83 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx @@ -37,10 +37,10 @@ const StyledContainerContextMenu = styled.div` `; export const ContextMenu = () => { - const contextMenuPosition = useRecoilValue(contextMenuPositionState()); - const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState()); - const contextMenuEntries = useRecoilValue(contextMenuEntriesState()); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState()); + const contextMenuPosition = useRecoilValue(contextMenuPositionState); + const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); + const contextMenuEntries = useRecoilValue(contextMenuEntriesState); + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); const wrapperRef = useRef(null); useListenClickOutside({ diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx index d0a5f4a79823..ee9eddd2f817 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx @@ -10,12 +10,12 @@ import { contextMenuPositionState } from '../../states/contextMenuPositionState' import { ContextMenu } from '../ContextMenu'; const FilledContextMenu = () => { - const setContextMenuPosition = useSetRecoilState(contextMenuPositionState()); + const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); setContextMenuPosition({ x: 100, y: 10, }); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState()); + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); setContextMenuOpenState(true); return ; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemToggle.tsx b/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemToggle.tsx index 70ed9dfb6a6e..99465e0ca8d5 100644 --- a/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemToggle.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/menu-item/components/MenuItemToggle.tsx @@ -24,12 +24,8 @@ export const MenuItemToggle = ({ onToggleChange, toggleSize, }: MenuItemToggleProps) => { - const handleOnClick = () => { - onToggleChange?.(!toggled); - }; - return ( - + theme.spacing(2)}; + opacity: 0; transition: opacity ${({ theme }) => theme.animation.duration.instant}s ease; } &:hover { & .hoverable-buttons { + opacity: 1; pointer-events: auto; position: static; } diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx index 14f4cc3b6c91..30f478a9336f 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx @@ -37,7 +37,7 @@ export const NavigationDrawerBackButton = ({ }: NavigationDrawerBackButtonProps) => { const theme = useTheme(); const navigate = useNavigate(); - const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState()); + const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); return ( diff --git a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx index 5dfbd9c79a89..9acd228fb980 100644 --- a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx @@ -11,7 +11,7 @@ const renderHooks = (initialStep: number) => { const { nextStep, prevStep, reset, setStep } = useStepBar({ initialStep, }); - const stepBarInternal = useRecoilValue(stepBarInternalState()); + const stepBarInternal = useRecoilValue(stepBarInternalState); return { nextStep, diff --git a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts index f567d9c4da9e..0bc14494209c 100644 --- a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts +++ b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts @@ -8,9 +8,8 @@ export type StepsOptions = { }; export const useStepBar = ({ initialStep }: StepsOptions) => { - const [stepBarInternal, setStepBarInternal] = useRecoilState( - stepBarInternalState(), - ); + const [stepBarInternal, setStepBarInternal] = + useRecoilState(stepBarInternalState); const nextStep = () => { setStepBarInternal((prevState) => ({ diff --git a/packages/twenty-front/src/modules/ui/theme/hooks/__tests__/useColorScheme.test.tsx b/packages/twenty-front/src/modules/ui/theme/hooks/__tests__/useColorScheme.test.tsx index 84125306122c..f84692bfad9e 100644 --- a/packages/twenty-front/src/modules/ui/theme/hooks/__tests__/useColorScheme.test.tsx +++ b/packages/twenty-front/src/modules/ui/theme/hooks/__tests__/useColorScheme.test.tsx @@ -32,7 +32,7 @@ describe('useColorScheme', () => { const colorScheme = useColorScheme(); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); setCurrentWorkspaceMember(workspaceMember); diff --git a/packages/twenty-front/src/modules/ui/theme/hooks/useColorScheme.ts b/packages/twenty-front/src/modules/ui/theme/hooks/useColorScheme.ts index 46cfa93571d2..e3b46c7adbad 100644 --- a/packages/twenty-front/src/modules/ui/theme/hooks/useColorScheme.ts +++ b/packages/twenty-front/src/modules/ui/theme/hooks/useColorScheme.ts @@ -8,7 +8,7 @@ import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; export const useColorScheme = () => { const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const { updateOneRecord: updateOneWorkspaceMember } = useUpdateOneRecord({ diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/usePreviousHotkeyScope.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/usePreviousHotkeyScope.ts index d3eb6d043e7f..d332b9df0eb5 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/usePreviousHotkeyScope.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/usePreviousHotkeyScope.ts @@ -13,7 +13,7 @@ export const usePreviousHotkeyScope = () => { ({ snapshot, set }) => () => { const previousHotkeyScope = snapshot - .getLoadable(previousHotkeyScopeState()) + .getLoadable(previousHotkeyScopeState) .getValue(); if (!previousHotkeyScope) { @@ -25,7 +25,7 @@ export const usePreviousHotkeyScope = () => { previousHotkeyScope.customScopes, ); - set(previousHotkeyScopeState(), null); + set(previousHotkeyScopeState, null); }, [setHotkeyScope], ); @@ -34,11 +34,11 @@ export const usePreviousHotkeyScope = () => { ({ snapshot, set }) => (scope: string, customScopes?: CustomHotkeyScopes) => { const currentHotkeyScope = snapshot - .getLoadable(currentHotkeyScopeState()) + .getLoadable(currentHotkeyScopeState) .getValue(); setHotkeyScope(scope, customScopes); - set(previousHotkeyScopeState(), currentHotkeyScope); + set(previousHotkeyScopeState, currentHotkeyScope); }, [setHotkeyScope], ); diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeyCallback.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeyCallback.ts index 92ebc8b89821..6e3d2d102087 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeyCallback.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeyCallback.ts @@ -24,7 +24,7 @@ export const useScopedHotkeyCallback = () => preventDefault?: boolean; }) => { const currentHotkeyScopes = snapshot - .getLoadable(internalHotkeysEnabledScopesState()) + .getLoadable(internalHotkeysEnabledScopesState) .getValue(); if (!currentHotkeyScopes.includes(scope)) { diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeys.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeys.ts index b8059643c4a2..b8c7ff31dadf 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeys.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useScopedHotkeys.ts @@ -22,8 +22,7 @@ export const useScopedHotkeys = ( preventDefault: true, }, ) => { - const [pendingHotkey, setPendingHotkey] = - useRecoilState(pendingHotkeyState()); + const [pendingHotkey, setPendingHotkey] = useRecoilState(pendingHotkeyState); const callScopedHotkeyCallback = useScopedHotkeyCallback(); diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSequenceScopedHotkeys.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSequenceScopedHotkeys.ts index e2a4ead6b0ad..1ab3fe8e04fa 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSequenceScopedHotkeys.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSequenceScopedHotkeys.ts @@ -20,8 +20,7 @@ export const useSequenceHotkeys = ( }, deps: any[] = [], ) => { - const [pendingHotkey, setPendingHotkey] = - useRecoilState(pendingHotkeyState()); + const [pendingHotkey, setPendingHotkey] = useRecoilState(pendingHotkeyState); const callScopedHotkeyCallback = useScopedHotkeyCallback(); diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSetHotkeyScope.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSetHotkeyScope.ts index aee1f213f231..ad890e08b465 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSetHotkeyScope.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/useSetHotkeyScope.ts @@ -26,7 +26,7 @@ export const useSetHotkeyScope = () => ({ snapshot, set }) => async (hotkeyScopeToSet: string, customScopes?: CustomHotkeyScopes) => { const currentHotkeyScope = snapshot - .getLoadable(currentHotkeyScopeState()) + .getLoadable(currentHotkeyScopeState) .getValue(); if (currentHotkeyScope.scope === hotkeyScopeToSet) { @@ -76,8 +76,8 @@ export const useSetHotkeyScope = () => } scopesToSet.push(newHotkeyScope.scope); - set(internalHotkeysEnabledScopesState(), scopesToSet); - set(currentHotkeyScopeState(), newHotkeyScope); + set(internalHotkeysEnabledScopesState, scopesToSet); + set(currentHotkeyScopeState, newHotkeyScope); }, [], ); diff --git a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/__tests__/useClickOutsideListener.test.tsx b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/__tests__/useClickOutsideListener.test.tsx index 5916fa12ad7d..04d2b882544f 100644 --- a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/__tests__/useClickOutsideListener.test.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/__tests__/useClickOutsideListener.test.tsx @@ -15,9 +15,7 @@ describe('useClickOutsideListener', () => { return { useClickOutside: useClickOutsideListener(componentId), - isActivated: useRecoilValue( - getClickOutsideListenerIsActivatedState(), - ), + isActivated: useRecoilValue(getClickOutsideListenerIsActivatedState), }; }, { diff --git a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useClickOutsideListener.ts b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useClickOutsideListener.ts index e1db02e4837c..a03da62510f8 100644 --- a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useClickOutsideListener.ts +++ b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useClickOutsideListener.ts @@ -34,7 +34,7 @@ export const useClickOutsideListener = (componentId: string) => { callback(event); const additionalCallbacks = snapshot - .getLoadable(getClickOutsideListenerCallbacksState()) + .getLoadable(getClickOutsideListenerCallbacksState) .getValue(); additionalCallbacks.forEach((additionalCallback) => { @@ -51,7 +51,7 @@ export const useClickOutsideListener = (componentId: string) => { const toggleClickOutsideListener = useRecoilCallback( ({ set }) => (activated: boolean) => { - set(getClickOutsideListenerIsActivatedState(), activated); + set(getClickOutsideListenerIsActivatedState, activated); }, [getClickOutsideListenerIsActivatedState], ); @@ -60,7 +60,7 @@ export const useClickOutsideListener = (componentId: string) => { ({ set, snapshot }) => ({ callbackFunction, callbackId }: ClickOutsideListenerCallback) => { const existingCallbacks = snapshot - .getLoadable(getClickOutsideListenerCallbacksState()) + .getLoadable(getClickOutsideListenerCallbacksState) .getValue(); const existingCallbackWithSameId = existingCallbacks.find( @@ -74,7 +74,7 @@ export const useClickOutsideListener = (componentId: string) => { }); set( - getClickOutsideListenerCallbacksState(), + getClickOutsideListenerCallbacksState, existingCallbacksWithNewCallback, ); } else { @@ -95,7 +95,7 @@ export const useClickOutsideListener = (componentId: string) => { }; set( - getClickOutsideListenerCallbacksState(), + getClickOutsideListenerCallbacksState, existingCallbacksWithOverwrittenCallback, ); } @@ -107,7 +107,7 @@ export const useClickOutsideListener = (componentId: string) => { ({ set, snapshot }) => ({ callbackId }: { callbackId: string }) => { const existingCallbacks = snapshot - .getLoadable(getClickOutsideListenerCallbacksState()) + .getLoadable(getClickOutsideListenerCallbacksState) .getValue(); const indexOfCallbackToUnsubscribe = existingCallbacks.findIndex( @@ -121,7 +121,7 @@ export const useClickOutsideListener = (componentId: string) => { existingCallbacks.toSpliced(indexOfCallbackToUnsubscribe, 1); set( - getClickOutsideListenerCallbacksState(), + getClickOutsideListenerCallbacksState, newCallbacksWithoutCallbackToUnsubscribe, ); } diff --git a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutsideV2.ts b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutsideV2.ts index e7f178e7d761..287d6b0f8e6d 100644 --- a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutsideV2.ts +++ b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutsideV2.ts @@ -32,7 +32,7 @@ export const useListenClickOutsideV2 = ({ ({ snapshot, set }) => (event: MouseEvent | TouchEvent) => { const clickOutsideListenerIsActivated = snapshot - .getLoadable(getClickOutsideListenerIsActivatedState()) + .getLoadable(getClickOutsideListenerIsActivatedState) .getValue(); const isListening = clickOutsideListenerIsActivated && enabled; @@ -47,7 +47,7 @@ export const useListenClickOutsideV2 = ({ .some((ref) => ref.current?.contains(event.target as Node)); set( - getClickOutsideListenerIsMouseDownInsideState(), + getClickOutsideListenerIsMouseDownInsideState, clickedOnAtLeastOneRef, ); } @@ -84,7 +84,7 @@ export const useListenClickOutsideV2 = ({ }); set( - getClickOutsideListenerIsMouseDownInsideState(), + getClickOutsideListenerIsMouseDownInsideState, clickedOnAtLeastOneRef, ); } @@ -102,7 +102,7 @@ export const useListenClickOutsideV2 = ({ ({ snapshot }) => (event: MouseEvent | TouchEvent) => { const isMouseDownInside = snapshot - .getLoadable(getClickOutsideListenerIsMouseDownInsideState()) + .getLoadable(getClickOutsideListenerIsMouseDownInsideState) .getValue(); if (mode === ClickOutsideMode.compareHTMLRef) { diff --git a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated.ts b/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated.ts deleted file mode 100644 index 89dad50b9498..000000000000 --- a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { RecoilState, SerializableParam } from 'recoil'; - -import { ComponentFamilyStateKey } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateKey'; - -export const getScopedFamilyStateDeprecated = < - StateType, - FamilyKey extends SerializableParam, ->( - recoilState: ( - scopedFamilyKey: ComponentFamilyStateKey, - ) => RecoilState, - scopeId: string, - familyKey: FamilyKey, -) => { - return recoilState({ - scopeId, - familyKey: familyKey || ('' as FamilyKey), - }); -}; diff --git a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedSelectorDeprecated.ts b/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedSelectorDeprecated.ts deleted file mode 100644 index 7ff7d3d9147f..000000000000 --- a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/utils/getScopedSelectorDeprecated.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { RecoilScopedSelector } from '../types/RecoilScopedSelector'; - -export const getScopedSelectorDeprecated = ( - recoilScopedState: RecoilScopedSelector, - scopeId: string, -) => { - return recoilScopedState({ - scopeId, - }); -}; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useListenScroll.test.tsx b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useListenScroll.test.tsx index ccde6fbca899..4d254e0f99c4 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useListenScroll.test.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useListenScroll.test.tsx @@ -24,7 +24,7 @@ describe('useListenScroll', () => { const { result } = renderHook( () => { useListenScroll({ scrollableRef: containerRef }); - const isScrolling = useRecoilValue(isScrollingState()); + const isScrolling = useRecoilValue(isScrollingState); return { isScrolling }; }, diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts index 969f24e0e36e..7607c51fef7a 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts @@ -15,7 +15,7 @@ export const useListenScroll = ({ const hideScrollBarsCallback = useRecoilCallback( ({ snapshot }) => () => { - const isScrolling = snapshot.getLoadable(isScrollingState()).getValue(); + const isScrolling = snapshot.getLoadable(isScrollingState).getValue(); if (!isScrolling) { scrollableRef.current?.classList.remove('scrolling'); @@ -27,13 +27,13 @@ export const useListenScroll = ({ const handleScrollStart = useRecoilCallback( ({ set }) => (event: Event) => { - set(isScrollingState(), true); + set(isScrollingState, true); scrollableRef.current?.classList.add('scrolling'); const target = event.target as HTMLElement; - set(scrollTopState(), target.scrollTop); - set(scrollLeftState(), target.scrollLeft); + set(scrollTopState, target.scrollTop); + set(scrollLeftState, target.scrollLeft); }, [scrollableRef], ); @@ -41,7 +41,7 @@ export const useListenScroll = ({ const handleScrollEnd = useRecoilCallback( ({ set }) => () => { - set(isScrollingState(), false); + set(isScrollingState, false); debounce(hideScrollBarsCallback, 1000)(); }, [hideScrollBarsCallback], diff --git a/packages/twenty-front/src/modules/ui/utilities/state/component-state/utils/extractComponentState.ts b/packages/twenty-front/src/modules/ui/utilities/state/component-state/utils/extractComponentState.ts index c9b6478c2e50..ea797fe77ea7 100644 --- a/packages/twenty-front/src/modules/ui/utilities/state/component-state/utils/extractComponentState.ts +++ b/packages/twenty-front/src/modules/ui/utilities/state/component-state/utils/extractComponentState.ts @@ -8,5 +8,5 @@ export const extractComponentState = ( ) => RecoilState, scopeId: string, ) => { - return () => componentState({ scopeId }); + return componentState({ scopeId }); }; diff --git a/packages/twenty-front/src/modules/ui/utilities/state/utils/createState.ts b/packages/twenty-front/src/modules/ui/utilities/state/utils/createState.ts index b2fdfcdd0cfd..c81d9a86db73 100644 --- a/packages/twenty-front/src/modules/ui/utilities/state/utils/createState.ts +++ b/packages/twenty-front/src/modules/ui/utilities/state/utils/createState.ts @@ -14,5 +14,5 @@ export const createState = ({ default: defaultValue, effects, }); - return () => recoilState; + return recoilState; }; diff --git a/packages/twenty-front/src/modules/users/components/UserProvider.tsx b/packages/twenty-front/src/modules/users/components/UserProvider.tsx index e871755179a5..aa0af98a25d9 100644 --- a/packages/twenty-front/src/modules/users/components/UserProvider.tsx +++ b/packages/twenty-front/src/modules/users/components/UserProvider.tsx @@ -12,11 +12,11 @@ import { isDefined } from '~/utils/isDefined'; export const UserProvider = ({ children }: React.PropsWithChildren) => { const [isLoading, setIsLoading] = useState(true); - const setCurrentUser = useSetRecoilState(currentUserState()); - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); + const setCurrentUser = useSetRecoilState(currentUserState); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const { loading: queryLoading, data: queryData } = useQuery(GET_CURRENT_USER); diff --git a/packages/twenty-front/src/modules/views/components/EditableFilterChip.tsx b/packages/twenty-front/src/modules/views/components/EditableFilterChip.tsx index b054c58fb8de..af75297298a9 100644 --- a/packages/twenty-front/src/modules/views/components/EditableFilterChip.tsx +++ b/packages/twenty-front/src/modules/views/components/EditableFilterChip.tsx @@ -1,10 +1,10 @@ +import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel'; import { useIcons } from '@/ui/display/icon/hooks/useIcons'; import { SortOrFilterChip } from '@/views/components/SortOrFilterChip'; -import { ViewFilter } from '@/views/types/ViewFilter'; type EditableFilterChipProps = { - viewFilter: ViewFilter; + viewFilter: Filter; onRemove: () => void; }; diff --git a/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx b/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx index 0f9ef89b1b64..aa10156cdc03 100644 --- a/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx +++ b/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx @@ -1,18 +1,19 @@ import { useCallback, useEffect } from 'react'; +import { useRecoilValue } from 'recoil'; import { MultipleFiltersDropdownContent } from '@/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; +import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { EditableFilterChip } from '@/views/components/EditableFilterChip'; -import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewFilter } from '@/views/types/ViewFilter'; +import { useCombinedViewFilters } from '@/views/hooks/useCombinedViewFilters'; import { isDefined } from '~/utils/isDefined'; type EditableFilterDropdownButtonProps = { viewFilterDropdownId: string; - viewFilter: ViewFilter; + viewFilter: Filter; hotkeyScope: HotkeyScope; }; @@ -22,7 +23,7 @@ export const EditableFilterDropdownButton = ({ hotkeyScope, }: EditableFilterDropdownButtonProps) => { const { - availableFilterDefinitions, + availableFilterDefinitionsState, setFilterDefinitionUsedInDropdown, setSelectedOperandInDropdown, setSelectedFilter, @@ -30,9 +31,13 @@ export const EditableFilterDropdownButton = ({ filterDropdownId: viewFilterDropdownId, }); + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, + ); + const { closeDropdown } = useDropdown(viewFilterDropdownId); - const { removeViewFilter } = useViewBar(); + const { removeCombinedViewFilter } = useCombinedViewFilters(); useEffect(() => { const filterDefinition = availableFilterDefinitions.find( @@ -57,15 +62,15 @@ export const EditableFilterDropdownButton = ({ const handleRemove = () => { closeDropdown(); - removeViewFilter(viewFilter.fieldMetadataId); + removeCombinedViewFilter(viewFilter.fieldMetadataId); }; const handleDropdownClickOutside = useCallback(() => { const { value, fieldMetadataId } = viewFilter; if (!value) { - removeViewFilter(fieldMetadataId); + removeCombinedViewFilter(fieldMetadataId); } - }, [viewFilter, removeViewFilter]); + }, [viewFilter, removeCombinedViewFilter]); return ( { - const { removeViewSort, upsertViewSort } = useViewBar(); + const { removeCombinedViewSort, upsertCombinedViewSort } = + useCombinedViewSorts(); const handleRemoveClick = () => { - removeViewSort(viewSort.fieldMetadataId); + removeCombinedViewSort(viewSort.fieldMetadataId); }; const handleClick = () => { - upsertViewSort({ + upsertCombinedViewSort({ ...viewSort, direction: viewSort.direction === 'asc' ? 'desc' : 'asc', }); diff --git a/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx b/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx index fe72b24bc0d4..ad9d60800555 100644 --- a/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx @@ -1,38 +1,47 @@ import { useEffect } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { isUndefined } from '@sniptt/guards'; +import { useSetRecoilState } from 'recoil'; -import { useFiltersFromQueryParams } from '@/views/hooks/internal/useFiltersFromQueryParams'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useResetCurrentView } from '@/views/hooks/useResetCurrentView'; export const FilterQueryParamsEffect = () => { - const { hasFiltersQueryParams, getFiltersFromQueryParams } = - useFiltersFromQueryParams(); - const { currentViewFiltersState, onViewFiltersChangeState } = - useViewScopedStates(); - const setCurrentViewFilters = useSetRecoilState(currentViewFiltersState); - const onViewFiltersChange = useRecoilValue(onViewFiltersChangeState); - const { resetViewBar } = useViewBar(); + const { hasFiltersQueryParams, getFiltersFromQueryParams, viewIdQueryParam } = + useViewFromQueryParams(); + const { unsavedToUpsertViewFiltersState, currentViewIdState } = + useViewStates(); + const setUnsavedViewFilter = useSetRecoilState( + unsavedToUpsertViewFiltersState, + ); + const setCurrentViewId = useSetRecoilState(currentViewIdState); + const { resetCurrentView } = useResetCurrentView(); + + useEffect(() => { + if (isUndefined(viewIdQueryParam) || !viewIdQueryParam) { + return; + } + + setCurrentViewId(viewIdQueryParam); + }, [getFiltersFromQueryParams, setCurrentViewId, viewIdQueryParam]); useEffect(() => { if (!hasFiltersQueryParams) return; getFiltersFromQueryParams().then((filtersFromParams) => { if (Array.isArray(filtersFromParams)) { - setCurrentViewFilters(filtersFromParams); - onViewFiltersChange?.(filtersFromParams); + setUnsavedViewFilter(filtersFromParams); } }); return () => { - resetViewBar(); + resetCurrentView(); }; }, [ getFiltersFromQueryParams, hasFiltersQueryParams, - onViewFiltersChange, - resetViewBar, - setCurrentViewFilters, + resetCurrentView, + setUnsavedViewFilter, ]); return null; diff --git a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx index ac8c6da739e0..d4dac54f45a4 100644 --- a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx +++ b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { IconChevronDown, IconPlus } from '@/ui/display/icon'; import { Button } from '@/ui/input/button/components/Button'; @@ -10,9 +10,8 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { UPDATE_VIEW_DROPDOWN_ID } from '@/views/constants/UpdateViewDropdownId'; -import { useViewBar } from '@/views/hooks/useViewBar'; - -import { useViewScopedStates } from '../hooks/internal/useViewScopedStates'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useSaveCurrentViewFiltersAndSorts } from '@/views/hooks/useSaveCurrentViewFiltersAndSorts'; const StyledContainer = styled.div` background: ${({ theme }) => theme.color.blue}; @@ -31,14 +30,11 @@ export const UpdateViewButtonGroup = ({ hotkeyScope, onViewEditModeChange, }: UpdateViewButtonGroupProps) => { - const { updateCurrentView, setViewEditMode } = useViewBar(); - const { canPersistFiltersSelector, canPersistSortsSelector } = - useViewScopedStates(); - - const canPersistFilters = useRecoilValue(canPersistFiltersSelector); - const canPersistSorts = useRecoilValue(canPersistSortsSelector); + const { canPersistViewSelector, viewEditModeState } = useViewStates(); + const { saveCurrentViewFilterAndSorts } = useSaveCurrentViewFiltersAndSorts(); - const canPersistView = canPersistFilters || canPersistSorts; + const setViewEditMode = useSetRecoilState(viewEditModeState); + const canPersistView = useRecoilValue(canPersistViewSelector()); const handleCreateViewButtonClick = useCallback(() => { setViewEditMode('create'); @@ -46,7 +42,7 @@ export const UpdateViewButtonGroup = ({ }, [setViewEditMode, onViewEditModeChange]); const handleViewSubmit = async () => { - await updateCurrentView?.(); + await saveCurrentViewFilterAndSorts(); }; if (!canPersistView) { diff --git a/packages/twenty-front/src/modules/views/components/ViewBar.tsx b/packages/twenty-front/src/modules/views/components/ViewBar.tsx index 2ee4be3f2e1b..2d13fe1ac208 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBar.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBar.tsx @@ -10,12 +10,8 @@ import { FilterQueryParamsEffect } from '@/views/components/FilterQueryParamsEff import { ViewBarEffect } from '@/views/components/ViewBarEffect'; import { ViewBarFilterEffect } from '@/views/components/ViewBarFilterEffect'; import { ViewBarSortEffect } from '@/views/components/ViewBarSortEffect'; -import { useViewBar } from '@/views/hooks/useViewBar'; import { ViewScope } from '@/views/scopes/ViewScope'; -import { ViewField } from '@/views/types/ViewField'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { ViewSort } from '@/views/types/ViewSort'; -import { ViewType } from '@/views/types/ViewType'; +import { GraphQLView } from '@/views/types/GraphQLView'; import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope'; @@ -28,13 +24,7 @@ export type ViewBarProps = { className?: string; optionsDropdownButton: ReactNode; optionsDropdownScopeId: string; - onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; - onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; - onViewFieldsChange?: (fields: ViewField[]) => void | Promise; - onViewTypeChange?: (viewType: ViewType) => void | Promise; - onViewCompactModeChange?: ( - isCompactModeActive: boolean, - ) => void | Promise; + onCurrentViewChange: (view: GraphQLView | undefined) => void | Promise; }; export const ViewBar = ({ @@ -42,18 +32,12 @@ export const ViewBar = ({ className, optionsDropdownButton, optionsDropdownScopeId, - onViewFieldsChange, - onViewFiltersChange, - onViewSortsChange, - onViewTypeChange, - onViewCompactModeChange, + onCurrentViewChange, }: ViewBarProps) => { const { openDropdown: openOptionsDropdownButton } = useDropdown( optionsDropdownScopeId, ); - const { upsertViewSort, upsertViewFilter } = useViewBar({ - viewBarId, - }); + const { objectNamePlural } = useParams(); const filterDropdownId = 'view-filter'; @@ -62,21 +46,11 @@ export const ViewBar = ({ return ( - - - + + + {!!objectNamePlural && } theme.border.color.light}; display: flex; flex-direction: row; - height: 40px; + min-height: 32px; justify-content: space-between; z-index: 4; + padding-top: ${({ theme }) => theme.spacing(1)}; + padding-bottom: ${({ theme }) => theme.spacing(1)}; `; const StyledChipcontainer = styled.div` @@ -35,10 +39,9 @@ const StyledChipcontainer = styled.div` display: flex; flex-direction: row; gap: ${({ theme }) => theme.spacing(1)}; - height: 40px; - justify-content: space-between; + min-height: 32px; margin-left: ${({ theme }) => theme.spacing(2)}; - overflow-x: auto; + flex-wrap: wrap; `; const StyledCancelButton = styled.button` @@ -92,37 +95,35 @@ export const ViewBarDetails = ({ hasFilterButton = false, rightComponent, filterDropdownId, - viewBarId, }: ViewBarDetailsProps) => { const { - currentViewSortsState, - currentViewFiltersState, - canPersistFiltersSelector, - canPersistSortsSelector, + canPersistViewSelector, isViewBarExpandedState, - } = useViewScopedStates(); + availableFilterDefinitionsState, + availableSortDefinitionsState, + } = useViewStates(); - const currentViewSorts = useRecoilValue(currentViewSortsState); - const currentViewFilters = useRecoilValue(currentViewFiltersState); - const canPersistFilters = useRecoilValue(canPersistFiltersSelector); - const canPersistSorts = useRecoilValue(canPersistSortsSelector); - const isViewBarExpanded = useRecoilValue(isViewBarExpandedState); + const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView(); - const { resetViewBar } = useViewBar(); + const isViewBarExpanded = useRecoilValue(isViewBarExpandedState); + const canPersistView = useRecoilValue(canPersistViewSelector()); + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, + ); + const availableSortDefinitions = useRecoilValue( + availableSortDefinitionsState, + ); - const canPersistView = canPersistFilters || canPersistSorts; + const { resetCurrentView } = useResetCurrentView(); const handleCancelClick = () => { - resetViewBar(); + resetCurrentView(); }; - const { upsertViewFilter } = useViewBar({ - viewBarId: viewBarId, - }); - const shouldExpandViewBar = canPersistView || - ((currentViewSorts?.length || currentViewFilters?.length) && + ((currentViewWithCombinedFiltersAndSorts?.viewSorts?.length || + currentViewWithCombinedFiltersAndSorts?.viewFilters?.length) && isViewBarExpanded); if (!shouldExpandViewBar) { @@ -133,23 +134,29 @@ export const ViewBarDetails = ({ - {currentViewSorts?.map((sort) => ( - + {mapViewSortsToSorts( + currentViewWithCombinedFiltersAndSorts?.viewSorts ?? [], + availableSortDefinitions, + ).map((sort) => ( + ))} - {!!currentViewSorts?.length && !!currentViewFilters?.length && ( - - - - )} - {currentViewFilters?.map((viewFilter) => ( + {!!currentViewWithCombinedFiltersAndSorts?.viewSorts?.length && + !!currentViewWithCombinedFiltersAndSorts?.viewFilters?.length && ( + + + + )} + {mapViewFiltersToFilters( + currentViewWithCombinedFiltersAndSorts?.viewFilters ?? [], + availableFilterDefinitions, + ).map((viewFilter) => ( { +export const ViewBarEffect = ({ viewBarId }: ViewBarEffectProps) => { + const { currentViewWithCombinedFiltersAndSorts } = + useGetCurrentView(viewBarId); const { - loadView, - changeViewInUrl, - loadViewFields, - loadViewFilters, - loadViewSorts, - } = useViewBar(); - - const [searchParams] = useSearchParams(); - const currentViewIdFromUrl = searchParams.get('view'); - - const { viewObjectMetadataIdState, viewsState, currentViewIdState } = - useViewScopedStates(); - - const [views, setViews] = useRecoilState(viewsState); - const viewObjectMetadataId = useRecoilValue(viewObjectMetadataIdState); - const setCurrentViewId = useSetRecoilState(currentViewIdState); - - const { records: newViews } = usePrefetchedData( - PrefetchKey.AllViews, - ); - - const newViewsOnCurrentObject = newViews.filter( - (view) => view.objectMetadataId === viewObjectMetadataId, + onCurrentViewChangeState, + currentViewIdState, + availableFilterDefinitionsState, + isPersistingViewFieldsState, + } = useViewStates(viewBarId); + + const [currentViewSnapshot, setCurrentViewSnapshot] = useState< + GraphQLView | undefined + >(undefined); + const onCurrentViewChange = useRecoilValue(onCurrentViewChangeState); + const availableFilterDefinitions = useRecoilValue( + availableFilterDefinitionsState, ); + const isPersistingViewFields = useRecoilValue(isPersistingViewFieldsState); + const [currentViewId, setCurrentViewId] = useRecoilState(currentViewIdState); useEffect(() => { - if (!newViewsOnCurrentObject.length) return; - - if (!isDeeplyEqual(views, newViewsOnCurrentObject)) { - setViews(newViewsOnCurrentObject); + if ( + !isDeeplyEqual( + currentViewWithCombinedFiltersAndSorts, + currentViewSnapshot, + ) + ) { + setCurrentViewSnapshot(currentViewWithCombinedFiltersAndSorts); + + if (isUndefined(currentViewWithCombinedFiltersAndSorts)) { + onCurrentViewChange?.(undefined); + return; + } + + if (!isPersistingViewFields) { + onCurrentViewChange?.(currentViewWithCombinedFiltersAndSorts); + } } - - const currentView = - newViewsOnCurrentObject.find( - (view) => view.id === currentViewIdFromUrl, - ) ?? - newViewsOnCurrentObject[0] ?? - null; - - if (isUndefinedOrNull(currentView)) return; - - setCurrentViewId(currentView.id); - - if (isDefined(currentView?.viewFields)) { - loadViewFields(currentView.viewFields, currentView.id); - loadViewFilters(currentView.viewFilters, currentView.id); - loadViewSorts(currentView.viewSorts, currentView.id); - } - - if (!currentViewIdFromUrl) return changeViewInUrl(currentView.id); }, [ - changeViewInUrl, - currentViewIdFromUrl, - loadViewFields, - loadViewFilters, - loadViewSorts, - newViewsOnCurrentObject, - setCurrentViewId, - setViews, - views, + availableFilterDefinitions, + currentViewSnapshot, + currentViewWithCombinedFiltersAndSorts, + isPersistingViewFields, + onCurrentViewChange, ]); useEffect(() => { - if (!currentViewIdFromUrl || !newViewsOnCurrentObject.length) return; - - loadView(currentViewIdFromUrl); - }, [currentViewIdFromUrl, loadView, newViewsOnCurrentObject]); + if ( + isDefined(currentViewWithCombinedFiltersAndSorts) && + !isDefined(currentViewId) + ) { + setCurrentViewId(currentViewWithCombinedFiltersAndSorts.id); + } + }, [currentViewWithCombinedFiltersAndSorts, currentViewId, setCurrentViewId]); return <>; }; diff --git a/packages/twenty-front/src/modules/views/components/ViewBarFilterEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterEffect.tsx index d496280994a0..1f19e48103da 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarFilterEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterEffect.tsx @@ -4,20 +4,21 @@ import { useRecoilValue } from 'recoil'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useCombinedViewFilters } from '@/views/hooks/useCombinedViewFilters'; import { isDefined } from '~/utils/isDefined'; type ViewBarFilterEffectProps = { filterDropdownId: string; - onFilterSelect?: ((filter: Filter) => void) | undefined; }; export const ViewBarFilterEffect = ({ filterDropdownId, - onFilterSelect, }: ViewBarFilterEffectProps) => { - const { availableFilterDefinitionsState, currentViewFiltersState } = - useViewScopedStates(); + const { availableFilterDefinitionsState, unsavedToUpsertViewFiltersState } = + useViewStates(); + + const { upsertCombinedViewFilter } = useCombinedViewFilters(); const availableFilterDefinitions = useRecoilValue( availableFilterDefinitionsState, @@ -25,32 +26,38 @@ export const ViewBarFilterEffect = ({ const { setAvailableFilterDefinitions, setOnFilterSelect, - filterDefinitionUsedInDropdown, + filterDefinitionUsedInDropdownState, setObjectFilterDropdownSelectedRecordIds, setObjectFilterDropdownSelectedOptionValues, - isObjectFilterDropdownUnfolded, } = useFilterDropdown({ filterDropdownId }); + const filterDefinitionUsedInDropdown = useRecoilValue( + filterDefinitionUsedInDropdownState, + ); + useEffect(() => { if (isDefined(availableFilterDefinitions)) { setAvailableFilterDefinitions(availableFilterDefinitions); } - - if (isDefined(onFilterSelect)) { - setOnFilterSelect(() => onFilterSelect); - } + setOnFilterSelect(() => (filter: Filter | null) => { + if (isDefined(filter)) { + upsertCombinedViewFilter(filter); + } + }); }, [ availableFilterDefinitions, - onFilterSelect, setAvailableFilterDefinitions, setOnFilterSelect, + upsertCombinedViewFilter, ]); - const currentViewFilters = useRecoilValue(currentViewFiltersState); + const unsavedToUpsertViewFilters = useRecoilValue( + unsavedToUpsertViewFiltersState, + ); useEffect(() => { if (filterDefinitionUsedInDropdown?.type === 'RELATION') { - const viewFilterUsedInDropdown = currentViewFilters.find( + const viewFilterUsedInDropdown = unsavedToUpsertViewFilters.find( (filter) => filter.fieldMetadataId === filterDefinitionUsedInDropdown.fieldMetadataId, @@ -64,7 +71,7 @@ export const ViewBarFilterEffect = ({ setObjectFilterDropdownSelectedRecordIds(viewFilterSelectedRecordIds); } else if (filterDefinitionUsedInDropdown?.type === 'SELECT') { - const viewFilterUsedInDropdown = currentViewFilters.find( + const viewFilterUsedInDropdown = unsavedToUpsertViewFilters.find( (filter) => filter.fieldMetadataId === filterDefinitionUsedInDropdown.fieldMetadataId, @@ -82,10 +89,9 @@ export const ViewBarFilterEffect = ({ } }, [ filterDefinitionUsedInDropdown, - currentViewFilters, setObjectFilterDropdownSelectedRecordIds, - isObjectFilterDropdownUnfolded, setObjectFilterDropdownSelectedOptionValues, + unsavedToUpsertViewFilters, ]); return <>; diff --git a/packages/twenty-front/src/modules/views/components/ViewBarSortEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarSortEffect.tsx index eed9b42982e2..0baba6d0b403 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarSortEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarSortEffect.tsx @@ -1,42 +1,52 @@ import { useEffect } from 'react'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown'; import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useCombinedViewSorts } from '@/views/hooks/useCombinedViewSorts'; import { isDefined } from '~/utils/isDefined'; type ViewBarSortEffectProps = { sortDropdownId: string; - onSortSelect?: ((sort: Sort) => void) | undefined; }; export const ViewBarSortEffect = ({ sortDropdownId, - onSortSelect, }: ViewBarSortEffectProps) => { - const { availableSortDefinitionsState } = useViewScopedStates(); + const { availableSortDefinitionsState } = useViewStates(); + const { upsertCombinedViewSort } = useCombinedViewSorts(); const availableSortDefinitions = useRecoilValue( availableSortDefinitionsState, ); - const { setAvailableSortDefinitions, setOnSortSelect } = useSortDropdown({ + const { + availableSortDefinitionsState: availableSortDefinitionsInSortDropdownState, + onSortSelectState, + } = useSortDropdown({ sortDropdownId, }); + const setAvailableSortDefinitionsInSortDropdown = useSetRecoilState( + availableSortDefinitionsInSortDropdownState, + ); + const setOnSortSelect = useSetRecoilState(onSortSelectState); + useEffect(() => { if (isDefined(availableSortDefinitions)) { - setAvailableSortDefinitions(availableSortDefinitions); - } - if (isDefined(onSortSelect)) { - setOnSortSelect(() => onSortSelect); + setAvailableSortDefinitionsInSortDropdown(availableSortDefinitions); } + setOnSortSelect(() => (sort: Sort | null) => { + if (isDefined(sort)) { + upsertCombinedViewSort(sort); + } + }); }, [ availableSortDefinitions, - onSortSelect, - setAvailableSortDefinitions, + setAvailableSortDefinitionsInSortDropdown, setOnSortSelect, + upsertCombinedViewSort, ]); return <>; diff --git a/packages/twenty-front/src/modules/views/components/ViewsDropdownButton.tsx b/packages/twenty-front/src/modules/views/components/ViewsDropdownButton.tsx index d85a344c8948..1ff11b28b4c0 100644 --- a/packages/twenty-front/src/modules/views/components/ViewsDropdownButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewsDropdownButton.tsx @@ -1,7 +1,7 @@ import { MouseEvent } from 'react'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useRecoilCallback, useRecoilValue } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { IconChevronDown, @@ -20,10 +20,11 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MOBILE_VIEWPORT } from '@/ui/theme/constants/MobileViewport'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { VIEWS_DROPDOWN_ID } from '@/views/constants/ViewsDropdownId'; -import { useViewBar } from '@/views/hooks/useViewBar'; +import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; +import { useHandleViews } from '@/views/hooks/useHandleViews'; import { isDefined } from '~/utils/isDefined'; -import { useViewScopedStates } from '../hooks/internal/useViewScopedStates'; +import { useViewStates } from '../hooks/internal/useViewStates'; const StyledBoldDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)` font-weight: ${({ theme }) => theme.font.weight.regular}; @@ -65,18 +66,18 @@ export const ViewsDropdownButton = ({ optionsDropdownScopeId, }: ViewsDropdownButtonProps) => { const theme = useTheme(); - const { removeView, changeViewInUrl } = useViewBar(); - const { viewsState, currentViewSelector, entityCountInCurrentViewState } = - useViewScopedStates(); + const { removeView, selectView } = useHandleViews(); + const { entityCountInCurrentViewState, viewEditModeState } = useViewStates(); + + const { currentViewWithCombinedFiltersAndSorts, viewsOnCurrentObject } = + useGetCurrentView(); - const views = useRecoilValue(viewsState); - const currentView = useRecoilValue(currentViewSelector); const entityCountInCurrentView = useRecoilValue( entityCountInCurrentViewState, ); - const { setViewEditMode, setCurrentViewId, loadView } = useViewBar(); + const setViewEditMode = useSetRecoilState(viewEditModeState); const { isDropdownOpen: isViewsDropdownOpen, @@ -87,14 +88,10 @@ export const ViewsDropdownButton = ({ optionsDropdownScopeId, ); - const handleViewSelect = useRecoilCallback( - () => async (viewId: string) => { - changeViewInUrl(viewId); - loadView(viewId); - closeViewsDropdown(); - }, - [changeViewInUrl, closeViewsDropdown, loadView], - ); + const handleViewSelect = (viewId: string) => { + selectView(viewId); + closeViewsDropdown(); + }; const handleAddViewButtonClick = () => { setViewEditMode('create'); @@ -108,8 +105,7 @@ export const ViewsDropdownButton = ({ viewId: string, ) => { event.stopPropagation(); - changeViewInUrl(viewId); - setCurrentViewId(viewId); + selectView(viewId); setViewEditMode('edit'); onViewEditModeChange?.(); closeViewsDropdown(); @@ -123,11 +119,12 @@ export const ViewsDropdownButton = ({ event.stopPropagation(); await removeView(viewId); + selectView(viewsOnCurrentObject.filter((view) => view.id !== viewId)[0].id); closeViewsDropdown(); }; const { getIcon } = useIcons(); - const CurrentViewIcon = getIcon(currentView?.icon); + const CurrentViewIcon = getIcon(currentViewWithCombinedFiltersAndSorts?.icon); return ( - {currentView && CurrentViewIcon ? ( + {currentViewWithCombinedFiltersAndSorts && CurrentViewIcon ? ( ) : ( )} - {currentView?.name ?? 'All'} + + {currentViewWithCombinedFiltersAndSorts?.name ?? 'All'} + · {entityCountInCurrentView}{' '} @@ -150,16 +149,18 @@ export const ViewsDropdownButton = ({ dropdownComponents={ <> - {views.map((view) => ( + {viewsOnCurrentObject.map((view) => ( ) => - handleEditViewButtonClick(event, view.id), - }, - views.length > 1 + currentViewWithCombinedFiltersAndSorts?.id === view.id + ? { + Icon: IconPencil, + onClick: (event: MouseEvent) => + handleEditViewButtonClick(event, view.id), + } + : null, + viewsOnCurrentObject.length > 1 ? { Icon: IconTrash, onClick: (event: MouseEvent) => diff --git a/packages/twenty-front/src/modules/views/constants/index.ts b/packages/twenty-front/src/modules/views/constants/index.ts deleted file mode 100644 index 932654ac31ab..000000000000 --- a/packages/twenty-front/src/modules/views/constants/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// TODO: find a better pattern than using '' as a fallback -export const UNDEFINED_FAMILY_ITEM_ID = ''; diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx index d0a0de37cdfa..3dabf65e0f99 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx @@ -1,27 +1,11 @@ -import { act } from 'react-dom/test-utils'; -import { MemoryRouter, useSearchParams } from 'react-router-dom'; +import { MemoryRouter } from 'react-router-dom'; import { MockedProvider } from '@apollo/client/testing'; -import { renderHook, waitFor } from '@testing-library/react'; -import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil'; +import { RecoilRoot } from 'recoil'; import { v4 as uuidv4 } from 'uuid'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { generateDeleteOneRecordMutation } from '@/object-record/utils/generateDeleteOneRecordMutation'; -import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; -import { - filterDefinition, - viewFilter, -} from '@/views/hooks/__tests__/useViewBar_ViewFilters.test'; -import { - sortDefinition, - viewSort, -} from '@/views/hooks/__tests__/useViewBar_ViewSorts.test'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; import { ViewScope } from '@/views/scopes/ViewScope'; -import { entityCountInCurrentViewScopedState } from '@/views/states/entityCountInCurrentViewScopedState'; -import { viewEditModeScopedState } from '@/views/states/viewEditModeScopedState'; -import { viewObjectMetadataIdScopeState } from '@/views/states/viewObjectMetadataIdScopeState'; const mockedUuid = 'mocked-uuid'; jest.mock('uuid'); @@ -49,225 +33,19 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => ( > - {children} + {}}> + {children} + ); -const renderHookConfig = { +const _renderHookConfig = { wrapper: Wrapper, }; -const viewBarId = 'viewBarTestId'; +const _viewBarId = 'viewBarTestId'; describe('useViewBar', () => { - it('should set and get current view Id', () => { - const { result } = renderHook( - () => useViewBar({ viewBarId }), - renderHookConfig, - ); - - expect(result.current.scopeId).toBe(viewBarId); - expect(result.current.currentViewId).toBeUndefined(); - - act(() => { - result.current.setCurrentViewId('testId'); - }); - - expect(result.current.currentViewId).toBe('testId'); - }); - - it('should create view and update url params', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - const searchParams = useSearchParams(); - - return { - viewBar, - searchParams, - }; - }, renderHookConfig); - await act(async () => { - await result.current.viewBar.createView('Test View'); - }); - expect(result.current.searchParams[0].get('view')).toBe(mockedUuid); - }); - - it('should delete current view and remove id from params', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - searchParams: useSearchParams(), - }), - renderHookConfig, - ); - - await act(async () => { - await result.current.viewBar.createView('Test View'); - result.current.viewBar.setCurrentViewId(mockedUuid); - }); - expect(result.current.searchParams[0].get('view')).toBe(mockedUuid); - - await act(async () => { - await result.current.viewBar.removeView(mockedUuid); - }); - expect(result.current.searchParams[0].get('view')).toBeNull(); - - const addBookMutationMock = mocks[0].result; - await waitFor(() => expect(addBookMutationMock).toHaveBeenCalled()); - }); - - it('should resetViewBar', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - const { - currentViewFiltersState, - currentViewSortsState, - viewEditModeState, - } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewFilters = useRecoilValue(currentViewFiltersState); - const currentViewSorts = useRecoilValue(currentViewSortsState); - const viewEditMode = useRecoilValue(viewEditModeState); - - return { - viewBar, - currentViewFilters, - currentViewSorts, - viewEditMode, - }; - }, renderHookConfig); - - act(() => { - result.current.viewBar.resetViewBar(); - }); - - expect(result.current.currentViewFilters).toStrictEqual([]); - expect(result.current.currentViewSorts).toStrictEqual([]); - expect(result.current.viewEditMode).toBe('none'); - }); - - it('should handleViewNameSubmit', async () => { - const { result } = renderHook( - () => useViewBar({ viewBarId }), - renderHookConfig, - ); - - await act(async () => { - await result.current.handleViewNameSubmit('New View Name'); - }); - }); - - it('should update edit mode', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - editMode: useRecoilState( - getScopedStateDeprecated(viewEditModeScopedState, viewBarId), - )[0], - }), - renderHookConfig, - ); - - expect(result.current.editMode).toBe('none'); - await act(async () => { - result.current.viewBar.setViewEditMode('create'); - }); - - expect(result.current.editMode).toBe('create'); - await act(async () => { - result.current.viewBar.setViewEditMode('edit'); - }); - - expect(result.current.editMode).toBe('edit'); - }); - - it('should update url param', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - searchParams: useSearchParams(), - }), - renderHookConfig, - ); - expect(result.current.searchParams[0].get('view')).toBeNull(); - await act(async () => { - result.current.viewBar.changeViewInUrl('view1'); - }); - expect(result.current.searchParams[0].get('view')).toBe('view1'); - }); - - it('should update object metadata id', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - metadataId: useRecoilState( - getScopedStateDeprecated(viewObjectMetadataIdScopeState, viewBarId), - )[0], - }), - renderHookConfig, - ); - - expect(result.current.metadataId).toBeUndefined(); - await act(async () => { - result.current.viewBar.setViewObjectMetadataId('newId'); - }); - - expect(result.current.metadataId).toBe('newId'); - }); - - it('should update count in current view', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - count: useRecoilState( - getScopedStateDeprecated( - entityCountInCurrentViewScopedState, - viewBarId, - ), - )[0], - }), - renderHookConfig, - ); - - expect(result.current.count).toBe(0); - await act(async () => { - result.current.viewBar.setEntityCountInCurrentView(1); - }); - - expect(result.current.count).toBe(1); - }); - - it('should loadView', async () => { - const { result } = renderHook( - () => useViewBar({ viewBarId }), - renderHookConfig, - ); - - act(() => { - result.current.loadView(mockedUuid); - }); - }); - - it('should updateCurrentView', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - viewBar.setCurrentViewId(mockedUuid); - - viewBar.setAvailableSortDefinitions([sortDefinition]); - - viewBar.loadViewSorts([viewSort], mockedUuid); - - viewBar.setAvailableFilterDefinitions([filterDefinition]); - - viewBar.loadViewFilters([viewFilter], mockedUuid); - - return { viewBar }; - }, renderHookConfig); - - await act(async () => { - await result.current.viewBar.updateCurrentView(); - }); - }); + it('should set and get current view Id', () => {}); }); diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFields.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFields.test.tsx deleted file mode 100644 index 7097205dc4ea..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFields.test.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { act } from 'react-dom/test-utils'; -import { MemoryRouter } from 'react-router-dom'; -import { gql } from '@apollo/client'; -import { MockedProvider } from '@apollo/client/testing'; -import { renderHook, waitFor } from '@testing-library/react'; -import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil'; - -import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; -import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; -import { getScopedFamilyStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewScope } from '@/views/scopes/ViewScope'; -import { currentViewFieldsScopedFamilyState } from '@/views/states/currentViewFieldsScopedFamilyState'; -import { ViewField } from '@/views/types/ViewField'; - -const fieldMetadataId = '12ecdf87-506f-44a7-98c6-393e5f05b225'; - -const fieldDefinition: ColumnDefinition = { - size: 1, - position: 1, - fieldMetadataId, - label: 'label', - iconName: 'icon', - type: 'TEXT', - metadata: { - placeHolder: 'placeHolder', - fieldName: 'fieldName', - }, -}; -const viewField: ViewField = { - id: '88930a16-685f-493b-a96b-91ca55666bba', - fieldMetadataId, - position: 1, - isVisible: true, - size: 1, - definition: fieldDefinition, -}; - -const viewBarId = 'viewBarTestId'; - -const currentViewId = '23f5dceb-3482-4e3a-9bb4-2f52f2556be9'; - -const mocks = [ - { - request: { - query: gql` - mutation CreateOneViewField($input: ViewFieldCreateInput!) { - createViewField(data: $input) { - __typename - position - isVisible - fieldMetadataId - viewId - id - size - createdAt - updatedAt - } - } - `, - variables: { - input: { - fieldMetadataId, - viewId: currentViewId, - isVisible: true, - size: 1, - position: 1, - }, - }, - }, - result: jest.fn(() => ({ - data: { createViewField: { id: '' } }, - })), - }, -]; - -const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - - - {children} - - - -); - -const renderHookConfig = { - wrapper: Wrapper, -}; - -describe('useViewBar > viewFields', () => { - it('should update current fields', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - currentFields: useRecoilState( - getScopedFamilyStateDeprecated( - currentViewFieldsScopedFamilyState, - viewBarId, - currentViewId, - ), - )[0], - }), - renderHookConfig, - ); - - expect(result.current.currentFields).toStrictEqual([]); - await act(async () => { - result.current.viewBar.setCurrentViewId(currentViewId); - result.current.viewBar.setViewObjectMetadataId('newId'); - result.current.viewBar.persistViewFields([viewField]); - }); - - await waitFor(() => - expect(result.current.currentFields).toEqual([viewField]), - ); - }); - - it('should persist view fields', async () => { - const { result } = renderHook( - () => useViewBar({ viewBarId }), - renderHookConfig, - ); - - await act(async () => { - result.current.setCurrentViewId(currentViewId); - result.current.setViewObjectMetadataId('newId'); - await result.current.persistViewFields([viewField]); - }); - - const persistViewFieldsMutation = mocks[0]; - - await waitFor(() => - expect(persistViewFieldsMutation.result).toHaveBeenCalled(), - ); - }); - - it('should load view fields', async () => { - const currentViewId = 'ac8807fd-0065-436d-bdf6-94333d75af6e'; - - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - const { currentViewFieldsState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewFields = useRecoilValue(currentViewFieldsState); - - return { - viewBar, - currentViewFields, - }; - }, renderHookConfig); - - expect(result.current.currentViewFields).toStrictEqual([]); - - await act(async () => { - result.current.viewBar.setAvailableFieldDefinitions([fieldDefinition]); - - await result.current.viewBar.loadViewFields([viewField], currentViewId); - result.current.viewBar.setCurrentViewId(currentViewId); - }); - - expect(result.current.currentViewFields).toStrictEqual([viewField]); - }); -}); diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFilters.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFilters.test.tsx deleted file mode 100644 index 442e9a872288..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewFilters.test.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { act } from 'react-dom/test-utils'; -import { MemoryRouter } from 'react-router-dom'; -import { MockedProvider } from '@apollo/client/testing'; -import { renderHook } from '@testing-library/react'; -import { RecoilRoot, useRecoilValue } from 'recoil'; - -import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; -import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewScope } from '@/views/scopes/ViewScope'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; - -const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - - - {children} - - - -); -const renderHookConfig = { - wrapper: Wrapper, -}; - -const viewBarId = 'viewBarTestId'; - -export const filterDefinition: FilterDefinition = { - fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5', - label: 'label', - iconName: 'iconName', - type: 'TEXT', -}; - -export const viewFilter: ViewFilter = { - id: 'id', - fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5', - operand: ViewFilterOperand.Is, - value: 'value', - displayValue: 'displayValue', - definition: filterDefinition, -}; - -const currentViewId = '23f5dceb-3482-4e3a-9bb4-2f52f2556be9'; - -describe('useViewBar > viewFilters', () => { - it('should load view filters', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - const { currentViewFiltersState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewFilters = useRecoilValue(currentViewFiltersState); - - return { - viewBar, - currentViewFilters, - }; - }, renderHookConfig); - - expect(result.current.currentViewFilters).toStrictEqual([]); - - await act(async () => { - result.current.viewBar.setAvailableFilterDefinitions([filterDefinition]); - - await result.current.viewBar.loadViewFilters([viewFilter], currentViewId); - result.current.viewBar.setCurrentViewId(currentViewId); - }); - - expect(result.current.currentViewFilters).toStrictEqual([viewFilter]); - }); - - it('should upsertViewFilter', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - viewBar.setAvailableFilterDefinitions([filterDefinition]); - - viewBar.loadViewFilters([viewFilter], currentViewId); - viewBar.setCurrentViewId(currentViewId); - - const { currentViewFiltersState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewFilters = useRecoilValue(currentViewFiltersState); - - return { - viewBar, - currentViewFilters, - }; - }, renderHookConfig); - - expect(result.current.currentViewFilters).toStrictEqual([viewFilter]); - - const newFilters: Filter[] = [ - { - fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5', - value: 'value', - displayValue: 'displayValue', - operand: ViewFilterOperand.IsNot, - definition: { - fieldMetadataId: 'id', - label: 'label', - iconName: 'icon', - type: 'TEXT', - }, - }, - { - fieldMetadataId: 'd9487757-183e-4fa0-a554-a980850cb23d', - value: 'value', - displayValue: 'displayValue', - operand: ViewFilterOperand.Contains, - definition: { - fieldMetadataId: 'id', - label: 'label', - iconName: 'icon', - type: 'TEXT', - }, - }, - ]; - - // upsert an existing filter - act(() => { - result.current.viewBar.upsertViewFilter(newFilters[0]); - }); - - expect(result.current.currentViewFilters).toStrictEqual([ - { ...newFilters[0], id: viewFilter.id }, - ]); - - // upsert a new filter - act(() => { - result.current.viewBar.upsertViewFilter(newFilters[1]); - }); - - // expect currentViewFilters to contain both filters - expect(result.current.currentViewFilters).toStrictEqual([ - { ...newFilters[0], id: viewFilter.id }, - { ...newFilters[1], id: undefined }, - ]); - }); - - it('should remove view filter', () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - viewBar.setAvailableFilterDefinitions([filterDefinition]); - - viewBar.loadViewFilters([viewFilter], currentViewId); - viewBar.setCurrentViewId(currentViewId); - - const { currentViewFiltersState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewFilters = useRecoilValue(currentViewFiltersState); - - return { - viewBar, - currentViewFilters, - }; - }, renderHookConfig); - - expect(result.current.currentViewFilters).toStrictEqual([viewFilter]); - - // remove an existing filter - act(() => { - result.current.viewBar.removeViewFilter(filterDefinition.fieldMetadataId); - }); - - expect(result.current.currentViewFilters).toStrictEqual([]); - }); -}); diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewSorts.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewSorts.test.tsx deleted file mode 100644 index b1a9c4d7a342..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar_ViewSorts.test.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { act } from 'react-dom/test-utils'; -import { MemoryRouter } from 'react-router-dom'; -import { MockedProvider } from '@apollo/client/testing'; -import { renderHook } from '@testing-library/react'; -import { RecoilRoot, useRecoilValue } from 'recoil'; - -import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; -import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewScope } from '@/views/scopes/ViewScope'; -import { ViewSort } from '@/views/types/ViewSort'; - -const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - - - {children} - - - -); -const renderHookConfig = { - wrapper: Wrapper, -}; - -const viewBarId = 'viewBarTestId'; - -export const sortDefinition: SortDefinition = { - fieldMetadataId: '12ecdf87-506f-44a7-98c6-393e5f05b225', - label: 'label', - iconName: 'icon', -}; - -export const viewSort: ViewSort = { - id: '88930a16-685f-493b-a96b-91ca55666bba', - fieldMetadataId: '12ecdf87-506f-44a7-98c6-393e5f05b225', - direction: 'asc', - definition: sortDefinition, -}; - -describe('View Sorts', () => { - const currentViewId = 'ac8807fd-0065-436d-bdf6-94333d75af6e'; - - it('should load view sorts', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - const { currentViewSortsState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewSorts = useRecoilValue(currentViewSortsState); - - return { - viewBar, - currentViewSorts, - }; - }, renderHookConfig); - - expect(result.current.currentViewSorts).toStrictEqual([]); - - await act(async () => { - result.current.viewBar.setAvailableSortDefinitions([sortDefinition]); - - await result.current.viewBar.loadViewSorts([viewSort], currentViewId); - result.current.viewBar.setCurrentViewId(currentViewId); - }); - - expect(result.current.currentViewSorts).toStrictEqual([viewSort]); - }); - - it('should upsertViewSort', async () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - viewBar.setAvailableSortDefinitions([sortDefinition]); - - viewBar.loadViewSorts([viewSort], currentViewId); - viewBar.setCurrentViewId(currentViewId); - - const { currentViewSortsState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewSorts = useRecoilValue(currentViewSortsState); - - return { - viewBar, - currentViewSorts, - }; - }, renderHookConfig); - - expect(result.current.currentViewSorts).toStrictEqual([viewSort]); - - const newSortFieldMetadataId = 'd9487757-183e-4fa0-a554-a980850cb23d'; - - const newSorts: Sort[] = [ - { - fieldMetadataId: viewSort.fieldMetadataId, - direction: 'desc', - definition: sortDefinition, - }, - { - fieldMetadataId: newSortFieldMetadataId, - direction: 'asc', - definition: { - ...sortDefinition, - fieldMetadataId: newSortFieldMetadataId, - }, - }, - ]; - - // upsert an existing sort - act(() => { - result.current.viewBar.upsertViewSort(newSorts[0]); - }); - - expect(result.current.currentViewSorts).toStrictEqual([ - { ...newSorts[0], id: viewSort.id }, - ]); - - // upsert a new sort - act(() => { - result.current.viewBar.upsertViewSort(newSorts[1]); - }); - - // expect currentViewSorts to contain both sorts - expect(result.current.currentViewSorts).toStrictEqual([ - { ...newSorts[0], id: viewSort.id }, - { ...newSorts[1], id: undefined }, - ]); - }); - - it('should remove view sort', () => { - const { result } = renderHook(() => { - const viewBar = useViewBar({ viewBarId }); - - viewBar.setAvailableSortDefinitions([sortDefinition]); - - viewBar.loadViewSorts([viewSort], currentViewId); - viewBar.setCurrentViewId(currentViewId); - - const { currentViewSortsState } = useViewScopedStates({ - viewScopeId: viewBarId, - }); - const currentViewSorts = useRecoilValue(currentViewSortsState); - - return { - viewBar, - currentViewSorts, - }; - }, renderHookConfig); - - expect(result.current.currentViewSorts).toStrictEqual([viewSort]); - - // remove an existing sort - act(() => { - result.current.viewBar.removeViewSort(sortDefinition.fieldMetadataId); - }); - - expect(result.current.currentViewSorts).toStrictEqual([]); - }); -}); diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFieldRecords.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFieldRecords.ts new file mode 100644 index 000000000000..0b7db03d039d --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFieldRecords.ts @@ -0,0 +1,115 @@ +import { useCallback } from 'react'; +import { useApolloClient } from '@apollo/client'; +import { v4 } from 'uuid'; + +import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect'; +import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { ViewField } from '@/views/types/ViewField'; + +export const usePersistViewFieldRecords = () => { + const { + updateOneRecordMutation, + createOneRecordMutation, + getRecordFromCache, + objectMetadataItem, + } = useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.ViewField, + }); + + const { objectMetadataItems } = useObjectMetadataItems(); + + const apolloClient = useApolloClient(); + + const createViewFieldRecords = useCallback( + (viewFieldsToCreate: ViewField[], view: GraphQLView) => { + if (!viewFieldsToCreate.length) return; + return Promise.all( + viewFieldsToCreate.map((viewField) => + apolloClient.mutate({ + mutation: createOneRecordMutation, + variables: { + input: { + fieldMetadataId: viewField.fieldMetadataId, + viewId: view.id, + isVisible: viewField.isVisible, + position: viewField.position, + size: viewField.size, + id: v4(), + }, + }, + update: (cache, { data }) => { + const record = data?.['createViewField']; + if (!record) return; + + triggerCreateRecordsOptimisticEffect({ + cache, + objectMetadataItem, + recordsToCreate: [record], + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + createOneRecordMutation, + objectMetadataItem, + objectMetadataItems, + ], + ); + + const updateViewFieldRecords = useCallback( + (viewFieldsToUpdate: ViewField[]) => { + if (!viewFieldsToUpdate.length) return; + return Promise.all( + viewFieldsToUpdate.map((viewField) => + apolloClient.mutate({ + mutation: updateOneRecordMutation, + variables: { + idToUpdate: viewField.id, + input: { + isVisible: viewField.isVisible, + position: viewField.position, + size: viewField.size, + }, + }, + update: (cache, { data }) => { + const record = data?.['updateViewField']; + if (!record) return; + const cachedRecord = getRecordFromCache(record.id); + + if (!cachedRecord) return; + + triggerUpdateRecordOptimisticEffect({ + cache, + objectMetadataItem, + currentRecord: cachedRecord, + updatedRecord: record, + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + getRecordFromCache, + objectMetadataItem, + objectMetadataItems, + updateOneRecordMutation, + ], + ); + + return { + createViewFieldRecords, + updateViewFieldRecords, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterRecords.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterRecords.ts new file mode 100644 index 000000000000..2a6527c0cf72 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterRecords.ts @@ -0,0 +1,156 @@ +import { useCallback } from 'react'; +import { useApolloClient } from '@apollo/client'; + +import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect'; +import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect'; +import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { ViewFilter } from '@/views/types/ViewFilter'; + +export const usePersistViewFilterRecords = () => { + const { + updateOneRecordMutation, + createOneRecordMutation, + deleteOneRecordMutation, + objectMetadataItem, + getRecordFromCache, + } = useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.ViewFilter, + }); + + const { objectMetadataItems } = useObjectMetadataItems(); + + const apolloClient = useApolloClient(); + + const createViewFilterRecords = useCallback( + (viewFiltersToCreate: ViewFilter[], view: GraphQLView) => { + if (!viewFiltersToCreate.length) return; + + return Promise.all( + viewFiltersToCreate.map((viewFilter) => + apolloClient.mutate({ + mutation: createOneRecordMutation, + variables: { + input: { + fieldMetadataId: viewFilter.fieldMetadataId, + viewId: view.id, + value: viewFilter.value, + displayValue: viewFilter.displayValue, + operand: viewFilter.operand, + }, + }, + update: (cache, { data }) => { + const record = data?.['createViewFilter']; + if (!record) return; + + triggerCreateRecordsOptimisticEffect({ + cache, + objectMetadataItem, + recordsToCreate: [record], + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + createOneRecordMutation, + objectMetadataItem, + objectMetadataItems, + ], + ); + + const updateViewFilterRecords = useCallback( + (viewFiltersToUpdate: ViewFilter[]) => { + if (!viewFiltersToUpdate.length) return; + return Promise.all( + viewFiltersToUpdate.map((viewFilter) => + apolloClient.mutate({ + mutation: updateOneRecordMutation, + variables: { + idToUpdate: viewFilter.id, + input: { + value: viewFilter.value, + displayValue: viewFilter.displayValue, + operand: viewFilter.operand, + }, + }, + update: (cache, { data }) => { + const record = data?.['updateViewFilter']; + if (!record) return; + const cachedRecord = getRecordFromCache(record.id); + + if (!cachedRecord) return; + + triggerUpdateRecordOptimisticEffect({ + cache, + objectMetadataItem, + currentRecord: cachedRecord, + updatedRecord: record, + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + getRecordFromCache, + objectMetadataItem, + objectMetadataItems, + updateOneRecordMutation, + ], + ); + + const deleteViewFilterRecords = useCallback( + (viewFilterIdsToDelete: string[]) => { + if (!viewFilterIdsToDelete.length) return; + return Promise.all( + viewFilterIdsToDelete.map((viewFilterId) => + apolloClient.mutate({ + mutation: deleteOneRecordMutation, + variables: { + idToDelete: viewFilterId, + }, + update: (cache, { data }) => { + const record = data?.['deleteViewFilter']; + + if (!record) return; + + const cachedRecord = getRecordFromCache(record.id, cache); + + if (!cachedRecord) return; + + triggerDeleteRecordsOptimisticEffect({ + cache, + objectMetadataItem, + recordsToDelete: [cachedRecord], + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + deleteOneRecordMutation, + getRecordFromCache, + objectMetadataItem, + objectMetadataItems, + ], + ); + + return { + createViewFilterRecords, + updateViewFilterRecords, + deleteViewFilterRecords, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSortRecords.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSortRecords.ts new file mode 100644 index 000000000000..4c927df23cb4 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSortRecords.ts @@ -0,0 +1,151 @@ +import { useCallback } from 'react'; +import { useApolloClient } from '@apollo/client'; + +import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect'; +import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect'; +import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { ViewSort } from '@/views/types/ViewSort'; + +export const usePersistViewSortRecords = () => { + const { + updateOneRecordMutation, + createOneRecordMutation, + deleteOneRecordMutation, + objectMetadataItem, + getRecordFromCache, + } = useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.ViewSort, + }); + + const { objectMetadataItems } = useObjectMetadataItems(); + + const apolloClient = useApolloClient(); + + const createViewSortRecords = useCallback( + (viewSortsToCreate: ViewSort[], view: GraphQLView) => { + if (!viewSortsToCreate.length) return; + return Promise.all( + viewSortsToCreate.map((viewSort) => + apolloClient.mutate({ + mutation: createOneRecordMutation, + variables: { + input: { + fieldMetadataId: viewSort.fieldMetadataId, + viewId: view.id, + direction: viewSort.direction, + }, + }, + update: (cache, { data }) => { + const record = data?.['createViewSort']; + if (!record) return; + + triggerCreateRecordsOptimisticEffect({ + cache, + objectMetadataItem, + recordsToCreate: [record], + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + createOneRecordMutation, + objectMetadataItem, + objectMetadataItems, + ], + ); + + const updateViewSortRecords = useCallback( + (viewSortsToUpdate: ViewSort[]) => { + if (!viewSortsToUpdate.length) return; + return Promise.all( + viewSortsToUpdate.map((viewSort) => + apolloClient.mutate({ + mutation: updateOneRecordMutation, + variables: { + idToUpdate: viewSort.id, + input: { + direction: viewSort.direction, + }, + }, + update: (cache, { data }) => { + const record = data?.['updateViewSort']; + if (!record) return; + const cachedRecord = getRecordFromCache(record.id); + + if (!cachedRecord) return; + + triggerUpdateRecordOptimisticEffect({ + cache, + objectMetadataItem, + currentRecord: cachedRecord, + updatedRecord: record, + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + getRecordFromCache, + objectMetadataItem, + objectMetadataItems, + updateOneRecordMutation, + ], + ); + + const deleteViewSortRecords = useCallback( + (viewSortIdsToDelete: string[]) => { + if (!viewSortIdsToDelete.length) return; + return Promise.all( + viewSortIdsToDelete.map((viewSortId) => + apolloClient.mutate({ + mutation: deleteOneRecordMutation, + variables: { + idToDelete: viewSortId, + }, + update: (cache, { data }) => { + const record = data?.['deleteViewSort']; + + if (!record) return; + + const cachedRecord = getRecordFromCache(record.id, cache); + + if (!cachedRecord) return; + + triggerDeleteRecordsOptimisticEffect({ + cache, + objectMetadataItem, + recordsToDelete: [cachedRecord], + objectMetadataItems, + }); + }, + }), + ), + ); + }, + [ + apolloClient, + deleteOneRecordMutation, + getRecordFromCache, + objectMetadataItem, + objectMetadataItems, + ], + ); + + return { + createViewSortRecords, + updateViewSortRecords, + deleteViewSortRecords, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewFields.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewFields.ts deleted file mode 100644 index e3d81affda85..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewFields.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Reference, useApolloClient } from '@apollo/client'; -import { useRecoilCallback } from 'recoil'; - -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { ViewField } from '@/views/types/ViewField'; -import { getViewScopedStatesFromSnapshot } from '@/views/utils/getViewScopedStatesFromSnapshot'; -import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot'; - -export const useViewFields = (viewScopeId: string) => { - const { updateOneRecordMutation, createOneRecordMutation } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ViewField, - }); - - const { modifyRecordFromCache } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.View, - }); - - const apolloClient = useApolloClient(); - - const persistViewFields = useRecoilCallback( - ({ snapshot, set }) => - async (viewFieldsToPersist: ViewField[], viewId?: string) => { - const { - viewObjectMetadataId, - currentViewId, - savedViewFieldsByKey, - onViewFieldsChange, - views, - } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - viewId, - }); - - const { - isPersistingViewState, - currentViewFieldsState, - savedViewFieldsState, - } = getViewScopedStatesFromSnapshot({ - snapshot, - viewScopeId, - viewId, - }); - - const viewIdToPersist = viewId ?? currentViewId; - - if (!currentViewId || !savedViewFieldsByKey || !viewObjectMetadataId) { - return; - } - - const _createViewFields = (viewFieldsToCreate: ViewField[]) => { - if (!viewFieldsToCreate.length) { - return; - } - - return Promise.all( - viewFieldsToCreate.map((viewField) => - apolloClient.mutate({ - mutation: createOneRecordMutation, - variables: { - input: { - fieldMetadataId: viewField.fieldMetadataId, - viewId: viewIdToPersist, - isVisible: viewField.isVisible, - size: viewField.size, - position: viewField.position, - }, - }, - }), - ), - ); - }; - - const _updateViewFields = (viewFieldsToUpdate: ViewField[]) => { - if (!viewFieldsToUpdate.length) { - return; - } - - return Promise.all( - viewFieldsToUpdate.map((viewField) => - apolloClient.mutate({ - mutation: updateOneRecordMutation, - variables: { - idToUpdate: viewField.id, - input: { - isVisible: viewField.isVisible, - size: viewField.size, - position: viewField.position, - }, - }, - }), - ), - ); - }; - - const viewFieldsToCreate = viewFieldsToPersist.filter( - (viewField) => !savedViewFieldsByKey[viewField.fieldMetadataId], - ); - - const viewFieldsToUpdate = viewFieldsToPersist.filter( - (viewFieldToPersit) => - savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId] && - (savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId].size !== - viewFieldToPersit.size || - savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId] - .position !== viewFieldToPersit.position || - savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId] - .isVisible !== viewFieldToPersit.isVisible), - ); - - set(isPersistingViewState, true); - - await _createViewFields(viewFieldsToCreate); - - await _updateViewFields(viewFieldsToUpdate); - - set(isPersistingViewState, false); - set(currentViewFieldsState, viewFieldsToPersist); - set(savedViewFieldsState, viewFieldsToPersist); - - const existingView = views.find((view) => view.id === viewIdToPersist); - - if (!existingView) { - return; - } - - modifyRecordFromCache(viewIdToPersist ?? '', { - viewFields: (viewFieldsRef, { readField }) => { - const edges = readField<{ node: Reference }[]>( - 'edges', - viewFieldsRef, - ); - - if (!edges) return viewFieldsRef; - - return { - ...viewFieldsRef, - edges: viewFieldsToPersist.map((viewField) => ({ - node: viewField, - cursor: '', - })), - }; - }, - }); - - onViewFieldsChange?.(viewFieldsToPersist); - }, - [ - viewScopeId, - modifyRecordFromCache, - apolloClient, - createOneRecordMutation, - updateOneRecordMutation, - ], - ); - - return { persistViewFields }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewFilters.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewFilters.ts deleted file mode 100644 index a490c957566e..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewFilters.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { Reference, useApolloClient } from '@apollo/client'; -import { produce } from 'immer'; -import { useRecoilCallback } from 'recoil'; - -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; -import { savedViewFiltersScopedFamilyState } from '@/views/states/savedViewFiltersScopedFamilyState'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot'; - -import { useViewScopedStates } from './useViewScopedStates'; - -export const useViewFilters = (viewScopeId: string) => { - const { - updateOneRecordMutation, - createOneRecordMutation, - deleteOneRecordMutation, - } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ViewFilter, - }); - - const { modifyRecordFromCache } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.View, - }); - - const apolloClient = useApolloClient(); - - const { currentViewFiltersState } = useViewScopedStates({ - viewScopeId: viewScopeId, - }); - - const persistViewFilters = useRecoilCallback( - ({ snapshot, set }) => - async (viewId?: string) => { - const { - currentViewId, - currentViewFilters, - savedViewFiltersByKey, - views, - } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId || !currentViewFilters || !savedViewFiltersByKey) { - return; - } - - const createViewFilters = (viewFiltersToCreate: ViewFilter[]) => { - if (!viewFiltersToCreate.length) return; - - return Promise.all( - viewFiltersToCreate.map((viewFilter) => - apolloClient.mutate({ - mutation: createOneRecordMutation, - variables: { - input: { - fieldMetadataId: viewFilter.fieldMetadataId, - viewId: viewId ?? currentViewId, - value: viewFilter.value, - displayValue: viewFilter.displayValue, - operand: viewFilter.operand, - }, - }, - }), - ), - ); - }; - - const updateViewFilters = (viewFiltersToUpdate: ViewFilter[]) => { - if (!viewFiltersToUpdate.length) return; - - return Promise.all( - viewFiltersToUpdate.map((viewFilter) => - apolloClient.mutate({ - mutation: updateOneRecordMutation, - variables: { - idToUpdate: viewFilter.id, - input: { - value: viewFilter.value, - displayValue: viewFilter.displayValue, - operand: viewFilter.operand, - }, - }, - }), - ), - ); - }; - - const deleteViewFilters = (viewFilterIdsToDelete: string[]) => { - if (!viewFilterIdsToDelete.length) return; - - return Promise.all( - viewFilterIdsToDelete.map((viewFilterId) => - apolloClient.mutate({ - mutation: deleteOneRecordMutation, - variables: { - idToDelete: viewFilterId, - }, - }), - ), - ); - }; - - const filtersToCreate = currentViewFilters.filter( - (filter) => !savedViewFiltersByKey[filter.fieldMetadataId], - ); - await createViewFilters(filtersToCreate); - - const filtersToUpdate = currentViewFilters.filter( - (filter) => - savedViewFiltersByKey[filter.fieldMetadataId] && - (savedViewFiltersByKey[filter.fieldMetadataId].operand !== - filter.operand || - savedViewFiltersByKey[filter.fieldMetadataId].value !== - filter.value), - ); - await updateViewFilters(filtersToUpdate); - - const filterKeys = currentViewFilters.map( - (filter) => filter.fieldMetadataId, - ); - const filterKeysToDelete = Object.keys(savedViewFiltersByKey).filter( - (previousFilterKey) => !filterKeys.includes(previousFilterKey), - ); - const filterIdsToDelete = filterKeysToDelete.map( - (filterKeyToDelete) => - savedViewFiltersByKey[filterKeyToDelete].id ?? '', - ); - await deleteViewFilters(filterIdsToDelete); - set( - savedViewFiltersScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId ?? currentViewId, - }), - currentViewFilters, - ); - - const existingViewId = viewId ?? currentViewId; - const existingView = views.find((view) => view.id === existingViewId); - - if (!existingView) { - return; - } - - modifyRecordFromCache(existingViewId, { - viewFilters: (viewFiltersRef, { readField }) => { - const edges = readField<{ node: Reference }[]>( - 'edges', - viewFiltersRef, - ); - - if (!edges) return viewFiltersRef; - - return { - ...viewFiltersRef, - edges: currentViewFilters.map((viewFilter) => ({ - node: viewFilter, - cursor: '', - })), - }; - }, - }); - }, - [ - apolloClient, - createOneRecordMutation, - deleteOneRecordMutation, - modifyRecordFromCache, - updateOneRecordMutation, - viewScopeId, - ], - ); - - const upsertViewFilter = useRecoilCallback( - ({ snapshot, set }) => - (filterToUpsert: Filter) => { - const { currentViewId, savedViewFiltersByKey, onViewFiltersChange } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId) { - return; - } - - if (!savedViewFiltersByKey) { - return; - } - - const existingSavedFilterId = - savedViewFiltersByKey[filterToUpsert.fieldMetadataId]?.id; - - set(currentViewFiltersState, (filters) => { - const newViewFilters = produce(filters, (filtersDraft) => { - const existingFilterIndex = filtersDraft.findIndex( - (filter) => - filter.fieldMetadataId === filterToUpsert.fieldMetadataId, - ); - - if (existingFilterIndex === -1 && filterToUpsert.value !== '') { - filtersDraft.push({ - ...filterToUpsert, - id: existingSavedFilterId, - }); - return filtersDraft; - } - - filtersDraft[existingFilterIndex] = { - ...filterToUpsert, - id: existingSavedFilterId, - }; - }); - onViewFiltersChange?.(newViewFilters); - return newViewFilters; - }); - }, - [currentViewFiltersState, viewScopeId], - ); - - const removeViewFilter = useRecoilCallback( - ({ snapshot, set }) => - (fieldMetadataId: string) => { - const { currentViewId, currentViewFilters, onViewFiltersChange } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId) { - return; - } - - const newViewFilters = currentViewFilters.filter((filter) => { - return filter.fieldMetadataId !== fieldMetadataId; - }); - set(currentViewFiltersState, newViewFilters); - onViewFiltersChange?.(newViewFilters); - }, - [currentViewFiltersState, viewScopeId], - ); - - return { persistViewFilters, removeViewFilter, upsertViewFilter }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useFiltersFromQueryParams.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts similarity index 89% rename from packages/twenty-front/src/modules/views/hooks/internal/useFiltersFromQueryParams.ts rename to packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts index 2bc335175374..4b7aad26cad3 100644 --- a/packages/twenty-front/src/modules/views/hooks/internal/useFiltersFromQueryParams.ts +++ b/packages/twenty-front/src/modules/views/hooks/internal/useViewFromQueryParams.ts @@ -19,17 +19,20 @@ import { isDefined } from '~/utils/isDefined'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; const filterQueryParamsSchema = z.object({ - filter: z.record( - z.record( - z.nativeEnum(ViewFilterOperand), - z.string().or(z.array(z.string())), - ), - ), + view: z.string().optional(), + filter: z + .record( + z.record( + z.nativeEnum(ViewFilterOperand), + z.string().or(z.array(z.string())), + ), + ) + .optional(), }); export type FilterQueryParams = z.infer; -export const useFiltersFromQueryParams = () => { +export const useViewFromQueryParams = () => { const apolloClient = useApolloClient(); const [searchParams] = useSearchParams(); const { objectNamePlural = '' } = useParams(); @@ -39,15 +42,21 @@ export const useFiltersFromQueryParams = () => { const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular }); const generateFindManyRecordsQuery = useGenerateFindManyRecordsQuery(); - const filterParamsValidation = filterQueryParamsSchema.safeParse( + const queryParamsValidation = filterQueryParamsSchema.safeParse( qs.parse(searchParams.toString()), ); + const filterQueryParams = useMemo( () => - filterParamsValidation.success ? filterParamsValidation.data.filter : {}, - [filterParamsValidation], + queryParamsValidation.success ? queryParamsValidation.data.filter : {}, + [queryParamsValidation], + ); + const viewIdQueryParam = useMemo( + () => queryParamsValidation.success && queryParamsValidation.data.view, + [queryParamsValidation], ); - const hasFiltersQueryParams = filterParamsValidation.success; + + const hasFiltersQueryParams = filterQueryParams; const getFiltersFromQueryParams = useRecoilCallback( ({ snapshot }) => @@ -129,6 +138,7 @@ export const useFiltersFromQueryParams = () => { : filterValueFromURL; return { + __typename: 'ViewFilter', id: `tmp-${[ fieldName, filterOperandFromURL, @@ -140,6 +150,7 @@ export const useFiltersFromQueryParams = () => { displayValue: relationRecordNames?.join(', ') ?? filterValueAsString, definition: filterDefinition, + persistAction: 'NONE', }; }, ), @@ -156,6 +167,7 @@ export const useFiltersFromQueryParams = () => { ); return { + viewIdQueryParam, hasFiltersQueryParams, getFiltersFromQueryParams, }; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts deleted file mode 100644 index ecc4465e9961..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { useRecoilState } from 'recoil'; - -import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; -import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; - -import { UNDEFINED_FAMILY_ITEM_ID } from '../../constants'; -import { ViewScopeInternalContext } from '../../scopes/scope-internal-context/ViewScopeInternalContext'; -import { currentViewIdScopedState } from '../../states/currentViewIdScopedState'; -import { getViewScopedStates } from '../../utils/internal/getViewScopedStates'; - -export const useViewScopedStates = (args?: { viewScopeId?: string }) => { - const { viewScopeId } = args ?? {}; - - const scopeId = useAvailableScopeIdOrThrow( - ViewScopeInternalContext, - viewScopeId, - ); - - // View - const [currentViewId] = useRecoilState( - getScopedStateDeprecated(currentViewIdScopedState, scopeId), - ); - - const viewId = currentViewId ?? UNDEFINED_FAMILY_ITEM_ID; - - const { - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - canPersistFiltersSelector, - canPersistSortsSelector, - currentViewFieldsState, - currentViewFiltersState, - currentViewIdState, - currentViewSelector, - currentViewSortsState, - entityCountInCurrentViewState, - isViewBarExpandedState, - isPersistingViewState, - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - onViewTypeChangeState, - onViewCompactModeChangeState, - savedViewFieldsByKeySelector, - savedViewFieldsState, - savedViewFiltersByKeySelector, - savedViewFiltersState, - savedViewSortsByKeySelector, - savedViewSortsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - viewsState, - } = getViewScopedStates({ - viewScopeId: scopeId, - viewId, - }); - - return { - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - canPersistFiltersSelector, - canPersistSortsSelector, - currentViewFieldsState, - currentViewFiltersState, - currentViewIdState, - currentViewSelector, - currentViewSortsState, - entityCountInCurrentViewState, - isViewBarExpandedState, - isPersistingViewState, - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - onViewTypeChangeState, - onViewCompactModeChangeState, - savedViewFieldsByKeySelector, - savedViewFieldsState, - savedViewFiltersByKeySelector, - savedViewFiltersState, - savedViewSortsByKeySelector, - savedViewSortsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - viewsState, - }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewSorts.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewSorts.ts deleted file mode 100644 index 093e371732e8..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewSorts.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { Reference, useApolloClient } from '@apollo/client'; -import { produce } from 'immer'; -import { useRecoilCallback } from 'recoil'; - -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; -import { savedViewSortsScopedFamilyState } from '@/views/states/savedViewSortsScopedFamilyState'; -import { ViewSort } from '@/views/types/ViewSort'; -import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot'; -import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; - -import { useViewScopedStates } from './useViewScopedStates'; - -export const useViewSorts = (viewScopeId: string) => { - const { - updateOneRecordMutation, - createOneRecordMutation, - deleteOneRecordMutation, - } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ViewSort, - }); - - const { modifyRecordFromCache } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.View, - }); - const apolloClient = useApolloClient(); - - const { currentViewSortsState } = useViewScopedStates({ - viewScopeId: viewScopeId, - }); - - const persistViewSorts = useRecoilCallback( - ({ snapshot, set }) => - async (viewId?: string) => { - const { currentViewId, currentViewSorts, savedViewSortsByKey, views } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId) { - return; - } - - if (isUndefinedOrNull(currentViewSorts)) { - return; - } - if (!savedViewSortsByKey) { - return; - } - - const createViewSorts = (viewSortsToCreate: ViewSort[]) => { - if (!viewSortsToCreate.length) return; - - return Promise.all( - viewSortsToCreate.map((viewSort) => - apolloClient.mutate({ - mutation: createOneRecordMutation, - variables: { - input: { - fieldMetadataId: viewSort.fieldMetadataId, - viewId: viewId ?? currentViewId, - direction: viewSort.direction, - }, - }, - }), - ), - ); - }; - - const updateViewSorts = (viewSortsToUpdate: ViewSort[]) => { - if (!viewSortsToUpdate.length) return; - - return Promise.all( - viewSortsToUpdate.map((viewSort) => - apolloClient.mutate({ - mutation: updateOneRecordMutation, - variables: { - idToUpdate: viewSort.id, - input: { - direction: viewSort.direction, - }, - }, - }), - ), - ); - }; - - const deleteViewSorts = (viewSortIdsToDelete: string[]) => { - if (!viewSortIdsToDelete.length) return; - - return Promise.all( - viewSortIdsToDelete.map((viewSortId) => - apolloClient.mutate({ - mutation: deleteOneRecordMutation, - variables: { - idToDelete: viewSortId, - }, - }), - ), - ); - }; - - const sortsToCreate = currentViewSorts.filter( - (sort) => !savedViewSortsByKey[sort.fieldMetadataId], - ); - - await createViewSorts(sortsToCreate); - - const sortsToUpdate = currentViewSorts.filter( - (sort) => - savedViewSortsByKey[sort.fieldMetadataId] && - savedViewSortsByKey[sort.fieldMetadataId].direction !== - sort.direction, - ); - await updateViewSorts(sortsToUpdate); - - const sortKeys = currentViewSorts.map((sort) => sort.fieldMetadataId); - const sortKeysToDelete = Object.keys(savedViewSortsByKey).filter( - (previousSortKey) => !sortKeys.includes(previousSortKey), - ); - const sortIdsToDelete = sortKeysToDelete.map( - (sortKeyToDelete) => savedViewSortsByKey[sortKeyToDelete].id ?? '', - ); - await deleteViewSorts(sortIdsToDelete); - set( - savedViewSortsScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId ?? currentViewId, - }), - currentViewSorts, - ); - const existingViewId = viewId ?? currentViewId; - const existingView = views.find((view) => view.id === existingViewId); - - if (!existingView) { - return; - } - - modifyRecordFromCache(existingViewId, { - viewSorts: (viewSortsRef, { readField }) => { - const edges = readField<{ node: Reference }[]>( - 'edges', - viewSortsRef, - ); - - if (!edges) return viewSortsRef; - - return { - ...viewSortsRef, - edges: currentViewSorts.map((viewSort) => ({ - node: viewSort, - cursor: '', - })), - }; - }, - }); - }, - [ - apolloClient, - createOneRecordMutation, - deleteOneRecordMutation, - modifyRecordFromCache, - updateOneRecordMutation, - viewScopeId, - ], - ); - - const upsertViewSort = useRecoilCallback( - ({ snapshot, set }) => - (sortToUpsert: Sort) => { - const { currentViewId, onViewSortsChange, savedViewSortsByKey } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId) { - return; - } - - if (!savedViewSortsByKey) { - return; - } - - const existingSavedSortId = - savedViewSortsByKey[sortToUpsert.fieldMetadataId]?.id; - - set(currentViewSortsState, (sorts) => { - const newViewSorts = produce(sorts, (sortsDraft) => { - const existingSortIndex = sortsDraft.findIndex( - (sort) => sort.fieldMetadataId === sortToUpsert.fieldMetadataId, - ); - - if (existingSortIndex === -1) { - sortsDraft.push({ ...sortToUpsert, id: existingSavedSortId }); - return sortsDraft; - } - - sortsDraft[existingSortIndex] = { - ...sortToUpsert, - id: existingSavedSortId, - }; - }); - onViewSortsChange?.(newViewSorts); - return newViewSorts; - }); - }, - [currentViewSortsState, viewScopeId], - ); - - const removeViewSort = useRecoilCallback( - ({ snapshot, set }) => - (fieldMetadataId: string) => { - const { currentViewId, onViewSortsChange, currentViewSorts } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId, - }); - - if (!currentViewId) { - return; - } - - const newViewSorts = currentViewSorts.filter((filter) => { - return filter.fieldMetadataId !== fieldMetadataId; - }); - set(currentViewSortsState, newViewSorts); - onViewSortsChange?.(newViewSorts); - }, - [currentViewSortsState, viewScopeId], - ); - - return { persistViewSorts, upsertViewSort, removeViewSort }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewStates.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewStates.ts new file mode 100644 index 000000000000..f5a1a5307bfb --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/internal/useViewStates.ts @@ -0,0 +1,96 @@ +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; +import { extractComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/extractComponentReadOnlySelector'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; +import { availableFieldDefinitionsComponentState } from '@/views/states/availableFieldDefinitionsComponentState'; +import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState'; +import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState'; +import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState'; +import { entityCountInCurrentViewComponentState } from '@/views/states/entityCountInCurrentViewComponentState'; +import { isCurrentViewKeyIndexComponentState } from '@/views/states/isCurrentViewIndexComponentState'; +import { isPersistingViewFieldsComponentState } from '@/views/states/isPersistingViewFieldsComponentState'; +import { isViewBarExpandedComponentState } from '@/views/states/isViewBarExpandedComponentState'; +import { onCurrentViewChangeComponentState } from '@/views/states/onCurrentViewChangeComponentState'; +import { canPersistViewComponentSelector } from '@/views/states/selectors/canPersistViewComponentSelector'; +import { unsavedToDeleteViewFilterIdsComponentState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentState'; +import { unsavedToDeleteViewSortIdsComponentState } from '@/views/states/unsavedToDeleteViewSortIdsComponentState'; +import { unsavedToUpsertViewFiltersComponentState } from '@/views/states/unsavedToUpsertViewFiltersComponentState'; +import { unsavedToUpsertViewSortsComponentState } from '@/views/states/unsavedToUpsertViewSortsComponentState'; +import { viewEditModeComponentState } from '@/views/states/viewEditModeComponentState'; +import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState'; + +import { ViewScopeInternalContext } from '../../scopes/scope-internal-context/ViewScopeInternalContext'; + +export const useViewStates = (viewComponentId?: string) => { + const componentId = useAvailableScopeIdOrThrow( + ViewScopeInternalContext, + viewComponentId, + ); + + return { + componentId, + currentViewIdState: extractComponentState( + currentViewIdComponentState, + componentId, + ), + availableFieldDefinitionsState: extractComponentState( + availableFieldDefinitionsComponentState, + componentId, + ), + availableFilterDefinitionsState: extractComponentState( + availableFilterDefinitionsComponentState, + componentId, + ), + availableSortDefinitionsState: extractComponentState( + availableSortDefinitionsComponentState, + componentId, + ), + canPersistViewSelector: extractComponentReadOnlySelector( + canPersistViewComponentSelector, + componentId, + ), + isViewBarExpandedState: extractComponentState( + isViewBarExpandedComponentState, + componentId, + ), + onCurrentViewChangeState: extractComponentState( + onCurrentViewChangeComponentState, + componentId, + ), + entityCountInCurrentViewState: extractComponentState( + entityCountInCurrentViewComponentState, + componentId, + ), + viewEditModeState: extractComponentState( + viewEditModeComponentState, + componentId, + ), + viewObjectMetadataIdState: extractComponentState( + viewObjectMetadataIdComponentState, + componentId, + ), + unsavedToUpsertViewFiltersState: extractComponentState( + unsavedToUpsertViewFiltersComponentState, + componentId, + ), + unsavedToUpsertViewSortsState: extractComponentState( + unsavedToUpsertViewSortsComponentState, + componentId, + ), + unsavedToDeleteViewFilterIdsState: extractComponentState( + unsavedToDeleteViewFilterIdsComponentState, + componentId, + ), + unsavedToDeleteViewSortIdsState: extractComponentState( + unsavedToDeleteViewSortIdsComponentState, + componentId, + ), + isPersistingViewFieldsState: extractComponentState( + isPersistingViewFieldsComponentState, + componentId, + ), + isCurrentViewKeyIndexState: extractComponentState( + isCurrentViewKeyIndexComponentState, + componentId, + ), + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViews.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViews.ts deleted file mode 100644 index 8bc05a85a729..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViews.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { useApolloClient } from '@apollo/client'; -import { useRecoilCallback } from 'recoil'; - -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { GraphQLView } from '@/views/types/GraphQLView'; -import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot'; - -export const useViews = (scopeId: string) => { - const { - updateOneRecordMutation: updateOneMutation, - createOneRecordMutation: createOneMutation, - deleteOneRecordMutation: deleteOneMutation, - findManyRecordsQuery: findManyQuery, - } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.View, - }); - - const apolloClient = useApolloClient(); - - const createView = useRecoilCallback( - ({ snapshot }) => - async (view: Pick) => { - const { viewObjectMetadataId, viewType } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - if (!viewObjectMetadataId || !viewType) { - return; - } - await apolloClient.mutate({ - mutation: createOneMutation, - variables: { - input: { - id: view.id, - name: view.name, - objectMetadataId: viewObjectMetadataId, - type: viewType, - }, - }, - refetchQueries: [findManyQuery], - }); - }, - [scopeId, apolloClient, createOneMutation, findManyQuery], - ); - - const updateView = async (view: GraphQLView) => { - await apolloClient.mutate({ - mutation: updateOneMutation, - variables: { - idToUpdate: view.id, - input: { - id: view.id, - name: view.name, - isCompact: view.isCompact, - }, - }, - refetchQueries: [findManyQuery], - }); - }; - - const deleteView = async (viewId: string) => { - await apolloClient.mutate({ - mutation: deleteOneMutation, - variables: { - idToDelete: viewId, - }, - refetchQueries: [findManyQuery], - }); - }; - - return { - createView, - deleteView, - isFetchingViews: false, - updateView, - }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/useCombinedViewFilters.ts b/packages/twenty-front/src/modules/views/hooks/useCombinedViewFilters.ts new file mode 100644 index 000000000000..e3eceeed3ebd --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useCombinedViewFilters.ts @@ -0,0 +1,158 @@ +import { useRecoilCallback } from 'recoil'; +import { v4 } from 'uuid'; + +import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; +import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetViewFromCache } from '@/views/hooks/useGetViewFromCache'; +import { ViewFilter } from '@/views/types/ViewFilter'; +import { isDefined } from '~/utils/isDefined'; + +export const useCombinedViewFilters = (viewBarComponentId?: string) => { + const { + unsavedToUpsertViewFiltersState, + unsavedToDeleteViewFilterIdsState, + currentViewIdState, + } = useViewStates(viewBarComponentId); + + const { getViewFromCache } = useGetViewFromCache(); + + const upsertCombinedViewFilter = useRecoilCallback( + ({ snapshot, set }) => + async (upsertedFilter: Filter) => { + const unsavedToUpsertViewFilters = getSnapshotValue( + snapshot, + unsavedToUpsertViewFiltersState, + ); + + const unsavedToDeleteViewFilterIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewFilterIdsState, + ); + + const currentViewId = getSnapshotValue(snapshot, currentViewIdState); + + if (!currentViewId) { + return; + } + + const currentView = await getViewFromCache(currentViewId); + + if (!currentView) { + return; + } + + const matchingFilterInCurrentView = currentView.viewFilters.find( + (viewFilter) => + viewFilter.fieldMetadataId === upsertedFilter.fieldMetadataId, + ); + + const matchingFilterInUnsavedFilters = unsavedToUpsertViewFilters.find( + (viewFilter) => + viewFilter.fieldMetadataId === upsertedFilter.fieldMetadataId, + ); + + if (isDefined(matchingFilterInUnsavedFilters)) { + const updatedFilters = unsavedToUpsertViewFilters.map((viewFilter) => + viewFilter.id === matchingFilterInUnsavedFilters.id + ? { ...viewFilter, ...upsertedFilter } + : viewFilter, + ); + + set(unsavedToUpsertViewFiltersState, updatedFilters); + return; + } + + if (isDefined(matchingFilterInCurrentView)) { + set(unsavedToUpsertViewFiltersState, [ + ...unsavedToUpsertViewFilters, + { ...matchingFilterInCurrentView, ...upsertedFilter }, + ]); + set( + unsavedToDeleteViewFilterIdsState, + unsavedToDeleteViewFilterIds.filter( + (id) => id !== matchingFilterInCurrentView.id, + ), + ); + return; + } + + set(unsavedToUpsertViewFiltersState, [ + ...unsavedToUpsertViewFilters, + { + ...upsertedFilter, + id: v4(), + __typename: 'ViewFilter', + } satisfies ViewFilter, + ]); + }, + [ + currentViewIdState, + getViewFromCache, + unsavedToDeleteViewFilterIdsState, + unsavedToUpsertViewFiltersState, + ], + ); + const removeCombinedViewFilter = useRecoilCallback( + ({ snapshot, set }) => + async (fieldMetadataId: string) => { + const unsavedToUpsertViewFilters = getSnapshotValue( + snapshot, + unsavedToUpsertViewFiltersState, + ); + + const unsavedToDeleteViewFilterIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewFilterIdsState, + ); + + const currentViewId = getSnapshotValue(snapshot, currentViewIdState); + + if (!currentViewId) { + return; + } + + const currentView = await getViewFromCache(currentViewId); + + if (!currentView) { + return; + } + + const matchingFilterInCurrentView = currentView.viewFilters.find( + (viewFilter) => viewFilter.fieldMetadataId === fieldMetadataId, + ); + + const matchingFilterInUnsavedFilters = unsavedToUpsertViewFilters.find( + (viewFilter) => viewFilter.fieldMetadataId === fieldMetadataId, + ); + + if (isDefined(matchingFilterInUnsavedFilters)) { + set( + unsavedToUpsertViewFiltersState, + unsavedToUpsertViewFilters.filter( + (viewFilter) => viewFilter.fieldMetadataId !== fieldMetadataId, + ), + ); + } + + if (isDefined(matchingFilterInCurrentView)) { + set(unsavedToDeleteViewFilterIdsState, [ + ...new Set([ + ...unsavedToDeleteViewFilterIds, + matchingFilterInCurrentView.id, + ]), + ]); + } + }, + [ + currentViewIdState, + getViewFromCache, + unsavedToDeleteViewFilterIdsState, + unsavedToUpsertViewFiltersState, + ], + ); + return { + upsertCombinedViewFilter, + removeCombinedViewFilter, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useCombinedViewSorts.ts b/packages/twenty-front/src/modules/views/hooks/useCombinedViewSorts.ts new file mode 100644 index 000000000000..6f08d77b1715 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useCombinedViewSorts.ts @@ -0,0 +1,159 @@ +import { useRecoilCallback } from 'recoil'; +import { v4 } from 'uuid'; + +import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; +import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetViewFromCache } from '@/views/hooks/useGetViewFromCache'; +import { ViewSort } from '@/views/types/ViewSort'; +import { isDefined } from '~/utils/isDefined'; + +export const useCombinedViewSorts = (viewBarComponentId?: string) => { + const { + unsavedToUpsertViewSortsState, + unsavedToDeleteViewSortIdsState, + currentViewIdState, + } = useViewStates(viewBarComponentId); + + const { getViewFromCache } = useGetViewFromCache(); + + const upsertCombinedViewSort = useRecoilCallback( + ({ snapshot, set }) => + async (upsertedSort: Sort) => { + const unsavedToUpsertViewSorts = getSnapshotValue( + snapshot, + unsavedToUpsertViewSortsState, + ); + + const unsavedToDeleteViewSortIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewSortIdsState, + ); + + const currentViewId = getSnapshotValue(snapshot, currentViewIdState); + + if (!currentViewId) { + return; + } + + const currentView = await getViewFromCache(currentViewId); + + if (!currentView) { + return; + } + + const matchingSortInCurrentView = currentView.viewSorts.find( + (viewSort) => + viewSort.fieldMetadataId === upsertedSort.fieldMetadataId, + ); + + const matchingSortInUnsavedSorts = unsavedToUpsertViewSorts.find( + (viewSort) => + viewSort.fieldMetadataId === upsertedSort.fieldMetadataId, + ); + + if (isDefined(matchingSortInUnsavedSorts)) { + const updatedSorts = unsavedToUpsertViewSorts.map((viewSort) => + viewSort.id === matchingSortInUnsavedSorts.id + ? { ...viewSort, ...upsertedSort } + : viewSort, + ); + + set(unsavedToUpsertViewSortsState, updatedSorts); + return; + } + + if (isDefined(matchingSortInCurrentView)) { + set(unsavedToUpsertViewSortsState, [ + ...unsavedToUpsertViewSorts, + { ...matchingSortInCurrentView, ...upsertedSort }, + ]); + set( + unsavedToDeleteViewSortIdsState, + unsavedToDeleteViewSortIds.filter( + (id) => id !== matchingSortInCurrentView.id, + ), + ); + return; + } + + set(unsavedToUpsertViewSortsState, [ + ...unsavedToUpsertViewSorts, + { + ...upsertedSort, + id: v4(), + __typename: 'ViewSort', + } satisfies ViewSort, + ]); + }, + [ + currentViewIdState, + getViewFromCache, + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + ], + ); + const removeCombinedViewSort = useRecoilCallback( + ({ snapshot, set }) => + async (fieldMetadataId: string) => { + const unsavedToUpsertViewSorts = getSnapshotValue( + snapshot, + unsavedToUpsertViewSortsState, + ); + + const unsavedToDeleteViewSortIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewSortIdsState, + ); + + const currentViewId = getSnapshotValue(snapshot, currentViewIdState); + + if (!currentViewId) { + return; + } + + const currentView = await getViewFromCache(currentViewId); + + if (!currentView) { + return; + } + + const matchingSortInCurrentView = currentView.viewSorts.find( + (viewSort) => viewSort.fieldMetadataId === fieldMetadataId, + ); + + const matchingSortInUnsavedSorts = unsavedToUpsertViewSorts.find( + (viewSort) => viewSort.fieldMetadataId === fieldMetadataId, + ); + + if (isDefined(matchingSortInUnsavedSorts)) { + set( + unsavedToUpsertViewSortsState, + unsavedToUpsertViewSorts.filter( + (viewSort) => viewSort.fieldMetadataId !== fieldMetadataId, + ), + ); + return; + } + + if (isDefined(matchingSortInCurrentView)) { + set(unsavedToDeleteViewSortIdsState, [ + ...new Set([ + ...unsavedToDeleteViewSortIds, + matchingSortInCurrentView.id, + ]), + ]); + } + }, + [ + currentViewIdState, + getViewFromCache, + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + ], + ); + return { + upsertCombinedViewSort, + removeCombinedViewSort, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useGetCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useGetCurrentView.ts new file mode 100644 index 000000000000..e95a4f2cf2b1 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useGetCurrentView.ts @@ -0,0 +1,107 @@ +import { useEffect } from 'react'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; + +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { ViewScopeInternalContext } from '@/views/scopes/scope-internal-context/ViewScopeInternalContext'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { combinedViewFilters } from '@/views/utils/combinedViewFilters'; +import { combinedViewSorts } from '@/views/utils/combinedViewSorts'; +import { isDefined } from '~/utils/isDefined'; + +export const useGetCurrentView = (viewBarComponentId?: string) => { + const componentId = useAvailableScopeIdOrThrow( + ViewScopeInternalContext, + viewBarComponentId, + ); + + const { records: views } = usePrefetchedData( + PrefetchKey.AllViews, + ); + + const { + currentViewIdState, + viewObjectMetadataIdState, + unsavedToUpsertViewFiltersState, + unsavedToDeleteViewFilterIdsState, + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + isCurrentViewKeyIndexState, + } = useViewStates(componentId); + + const currentViewId = useRecoilValue(currentViewIdState); + const viewObjectMetadataId = useRecoilValue(viewObjectMetadataIdState); + const setIsCurrentViewKeyIndex = useSetRecoilState( + isCurrentViewKeyIndexState, + ); + + const currentViewFromCurrentViewId = views.find( + (view) => view.id === currentViewId, + ); + const indexView = views.find( + (view) => + view.key === 'INDEX' && view.objectMetadataId === viewObjectMetadataId, + ); + + const currentView = currentViewId ? currentViewFromCurrentViewId : indexView; + + useEffect(() => { + setIsCurrentViewKeyIndex(currentView?.key === 'INDEX'); + }, [currentView, setIsCurrentViewKeyIndex]); + + const viewsOnCurrentObject = views + .filter((view) => view.objectMetadataId === viewObjectMetadataId) + .map((view) => ({ + id: view.id, + name: view.name, + type: view.type, + key: view.key, + objectMetadataId: view.objectMetadataId, + icon: view.icon, + })); + + const unsavedToUpsertViewFilters = useRecoilValue( + unsavedToUpsertViewFiltersState, + ); + const unsavedToUpsertViewSorts = useRecoilValue( + unsavedToUpsertViewSortsState, + ); + const unsavedToDeleteViewFilterIds = useRecoilValue( + unsavedToDeleteViewFilterIdsState, + ); + const unsavedToDeleteViewSortIds = useRecoilValue( + unsavedToDeleteViewSortIdsState, + ); + + if (!isDefined(currentView)) { + return { + componentId, + currentViewWithSavedFiltersAndSorts: undefined, + currentViewWithCombinedFiltersAndSorts: undefined, + viewsOnCurrentObject: viewsOnCurrentObject ?? [], + }; + } + + const currentViewWithCombinedFiltersAndSorts = { + ...currentView, + viewFilters: combinedViewFilters( + currentView.viewFilters, + unsavedToUpsertViewFilters, + unsavedToDeleteViewFilterIds, + ), + viewSorts: combinedViewSorts( + currentView.viewSorts, + unsavedToUpsertViewSorts, + unsavedToDeleteViewSortIds, + ), + }; + + return { + componentId, + currentViewWithSavedFiltersAndSorts: currentView, + currentViewWithCombinedFiltersAndSorts, + viewsOnCurrentObject: viewsOnCurrentObject ?? [], + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useGetViewFromCache.ts b/packages/twenty-front/src/modules/views/hooks/useGetViewFromCache.ts new file mode 100644 index 000000000000..b39e23380022 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useGetViewFromCache.ts @@ -0,0 +1,48 @@ +import { useCallback } from 'react'; +import { useApolloClient } from '@apollo/client'; + +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; + +export const useGetViewFromCache = () => { + const client = useApolloClient(); + const cache = client.cache; + + const { getRecordFromCache } = useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.View, + }); + + const getViewFromCache = useCallback( + async (viewId: string) => { + // Todo Fix typing once we have figured out record connections + const viewWithConnections = getRecordFromCache(viewId, cache); + + if (isUndefinedOrNull(viewWithConnections)) { + return; + } + + const view = { + ...viewWithConnections, + viewFilters: viewWithConnections.viewFilters?.edges.map( + (edge: ObjectRecordEdge) => edge.node, + ), + viewSorts: viewWithConnections.viewSorts?.edges.map( + (edge: ObjectRecordEdge) => edge.node, + ), + viewFields: viewWithConnections.viewFields?.edges.map( + (edge: ObjectRecordEdge) => edge.node, + ), + } as GraphQLView; + + return view; + }, + [cache, getRecordFromCache], + ); + + return { + getViewFromCache, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useHandleViews.ts b/packages/twenty-front/src/modules/views/hooks/useHandleViews.ts new file mode 100644 index 000000000000..2d24279f907b --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useHandleViews.ts @@ -0,0 +1,130 @@ +import { useCallback } from 'react'; +import { useSearchParams } from 'react-router-dom'; +import { useRecoilCallback } from 'recoil'; +import { v4 } from 'uuid'; + +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; +import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; +import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; +import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; +import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetViewFromCache } from '@/views/hooks/useGetViewFromCache'; +import { useResetCurrentView } from '@/views/hooks/useResetCurrentView'; +import { GraphQLView } from '@/views/types/GraphQLView'; +import { isDefined } from '~/utils/isDefined'; +import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; + +export const useHandleViews = (viewBarComponentId?: string) => { + const { resetCurrentView } = useResetCurrentView(viewBarComponentId); + + const { currentViewIdState } = useViewStates(viewBarComponentId); + + const { getViewFromCache } = useGetViewFromCache(); + + const { deleteOneRecord } = useDeleteOneRecord({ + objectNameSingular: CoreObjectNameSingular.View, + }); + + const { createOneRecord } = useCreateOneRecord({ + objectNameSingular: CoreObjectNameSingular.View, + }); + + const { updateOneRecord } = useUpdateOneRecord({ + objectNameSingular: CoreObjectNameSingular.View, + }); + + const { createViewFieldRecords } = usePersistViewFieldRecords(); + + const createViewFromCurrent = useRecoilCallback(() => () => {}, []); + + const [_, setSearchParams] = useSearchParams(); + + const removeView = useRecoilCallback( + () => async (viewId: string) => { + await deleteOneRecord(viewId); + }, + [deleteOneRecord], + ); + + const createEmptyView = useRecoilCallback( + ({ snapshot }) => + async (id: string, name: string) => { + const currentViewId = getSnapshotValue(snapshot, currentViewIdState); + + if (!isDefined(currentViewId)) { + return; + } + + const view = await getViewFromCache(currentViewId); + + if (!isDefined(view)) { + return; + } + + const newView = await createOneRecord({ + id: id ?? v4(), + name: name, + objectMetadataId: view.objectMetadataId, + type: view.type, + }); + + if (isUndefinedOrNull(newView)) { + throw new Error('Failed to create view'); + } + + await createViewFieldRecords(view.viewFields, newView); + }, + [ + createOneRecord, + createViewFieldRecords, + currentViewIdState, + getViewFromCache, + ], + ); + + const changeViewInUrl = useCallback( + (viewId: string) => { + setSearchParams((previousSearchParams) => { + previousSearchParams.set('view', viewId); + return previousSearchParams; + }); + }, + [setSearchParams], + ); + + const selectView = useRecoilCallback( + ({ set }) => + async (viewId: string) => { + set(currentViewIdState, viewId); + changeViewInUrl(viewId); + resetCurrentView(); + }, + [changeViewInUrl, currentViewIdState, resetCurrentView], + ); + + const updateCurrentView = useRecoilCallback( + ({ snapshot }) => + async (view: Partial) => { + const currentViewId = snapshot + .getLoadable(currentViewIdState) + .getValue(); + if (isDefined(currentViewId)) { + await updateOneRecord({ + idToUpdate: currentViewId, + updateOneRecordInput: view, + }); + } + }, + [currentViewIdState, updateOneRecord], + ); + + return { + selectView, + updateCurrentView, + removeView, + createEmptyView, + createViewFromCurrent, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useInitViewBar.ts b/packages/twenty-front/src/modules/views/hooks/useInitViewBar.ts new file mode 100644 index 000000000000..e81802846868 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useInitViewBar.ts @@ -0,0 +1,31 @@ +import { useSetRecoilState } from 'recoil'; + +import { useViewStates } from '@/views/hooks/internal/useViewStates'; + +export const useInitViewBar = (viewBarComponentId?: string) => { + const { + availableFieldDefinitionsState, + availableSortDefinitionsState, + availableFilterDefinitionsState, + viewObjectMetadataIdState, + } = useViewStates(viewBarComponentId); + + const setAvailableFieldDefinitions = useSetRecoilState( + availableFieldDefinitionsState, + ); + const setAvailableSortDefinitions = useSetRecoilState( + availableSortDefinitionsState, + ); + const setAvailableFilterDefinitions = useSetRecoilState( + availableFilterDefinitionsState, + ); + + const setViewObjectMetadataId = useSetRecoilState(viewObjectMetadataIdState); + + return { + setAvailableFieldDefinitions, + setAvailableSortDefinitions, + setAvailableFilterDefinitions, + setViewObjectMetadataId, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useResetCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useResetCurrentView.ts new file mode 100644 index 000000000000..d188580ca355 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useResetCurrentView.ts @@ -0,0 +1,32 @@ +import { useRecoilCallback } from 'recoil'; + +import { useViewStates } from '@/views/hooks/internal/useViewStates'; + +export const useResetCurrentView = (viewBarComponentId?: string) => { + const { + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + unsavedToDeleteViewFilterIdsState, + unsavedToUpsertViewFiltersState, + } = useViewStates(viewBarComponentId); + + const resetCurrentView = useRecoilCallback( + ({ set }) => + async () => { + set(unsavedToDeleteViewFilterIdsState, []); + set(unsavedToDeleteViewSortIdsState, []); + set(unsavedToUpsertViewFiltersState, []); + set(unsavedToUpsertViewSortsState, []); + }, + [ + unsavedToDeleteViewFilterIdsState, + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewFiltersState, + unsavedToUpsertViewSortsState, + ], + ); + + return { + resetCurrentView, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts new file mode 100644 index 000000000000..fed1518f1f18 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts @@ -0,0 +1,87 @@ +import { useRecoilCallback } from 'recoil'; + +import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetViewFromCache } from '@/views/hooks/useGetViewFromCache'; +import { ViewField } from '@/views/types/ViewField'; +import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { isDefined } from '~/utils/isDefined'; +import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; + +export const useSaveCurrentViewFields = (viewBarComponentId?: string) => { + const { createViewFieldRecords, updateViewFieldRecords } = + usePersistViewFieldRecords(); + + const { getViewFromCache } = useGetViewFromCache(); + + const { isPersistingViewFieldsState, currentViewIdState } = + useViewStates(viewBarComponentId); + + const saveViewFields = useRecoilCallback( + ({ set, snapshot }) => + async (fields: ViewField[]) => { + const currentViewId = snapshot + .getLoadable(currentViewIdState) + .getValue(); + + if (!currentViewId) { + return; + } + + set(isPersistingViewFieldsState, true); + const view = await getViewFromCache(currentViewId); + + if (isUndefinedOrNull(view)) { + return; + } + + const viewFieldsToUpdate = fields + .map((field) => { + const existingField = view.viewFields.find( + (viewField) => viewField.id === field.id, + ); + + if (isUndefinedOrNull(existingField)) { + return undefined; + } + if ( + isDeeplyEqual( + { + position: existingField.position, + size: existingField.size, + isVisible: existingField.isVisible, + }, + { + position: field.position, + size: field.size, + isVisible: field.isVisible, + }, + ) + ) { + return undefined; + } + return field; + }) + .filter(isDefined); + + const viewFieldsToCreate = fields.filter((field) => !field.id); + + await Promise.all([ + createViewFieldRecords(viewFieldsToCreate, view), + updateViewFieldRecords(viewFieldsToUpdate), + ]); + set(isPersistingViewFieldsState, false); + }, + [ + createViewFieldRecords, + currentViewIdState, + getViewFromCache, + isPersistingViewFieldsState, + updateViewFieldRecords, + ], + ); + + return { + saveViewFields, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFiltersAndSorts.ts b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFiltersAndSorts.ts new file mode 100644 index 000000000000..f351dc1c3982 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFiltersAndSorts.ts @@ -0,0 +1,147 @@ +import { useRecoilCallback } from 'recoil'; + +import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; +import { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilterRecords'; +import { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSortRecords'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetViewFromCache } from '@/views/hooks/useGetViewFromCache'; +import { useResetCurrentView } from '@/views/hooks/useResetCurrentView'; +import { isDefined } from '~/utils/isDefined'; +import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; + +export const useSaveCurrentViewFiltersAndSorts = ( + viewBarComponentId?: string, +) => { + const { getViewFromCache } = useGetViewFromCache(); + + const { + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + unsavedToDeleteViewFilterIdsState, + unsavedToUpsertViewFiltersState, + currentViewIdState, + } = useViewStates(viewBarComponentId); + + const { + createViewSortRecords, + updateViewSortRecords, + deleteViewSortRecords, + } = usePersistViewSortRecords(); + + const { + createViewFilterRecords, + updateViewFilterRecords, + deleteViewFilterRecords, + } = usePersistViewFilterRecords(); + + const { resetCurrentView } = useResetCurrentView(viewBarComponentId); + + const saveViewSorts = useRecoilCallback( + ({ snapshot }) => + async (viewId: string) => { + const unsavedToDeleteViewSortIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewSortIdsState, + ); + + const unsavedToUpsertViewSorts = getSnapshotValue( + snapshot, + unsavedToUpsertViewSortsState, + ); + + const view = await getViewFromCache(viewId); + + if (isUndefinedOrNull(view)) { + return; + } + + const viewSortsToCreate = unsavedToUpsertViewSorts.filter( + (viewSort) => + !view.viewSorts.some( + (vf) => vf.fieldMetadataId === viewSort.fieldMetadataId, + ), + ); + + const viewSortsToUpdate = unsavedToUpsertViewSorts.filter((viewSort) => + view.viewSorts.some((vf) => vf.id === viewSort.id), + ); + + await createViewSortRecords(viewSortsToCreate, view); + await updateViewSortRecords(viewSortsToUpdate); + await deleteViewSortRecords(unsavedToDeleteViewSortIds); + }, + [ + createViewSortRecords, + deleteViewSortRecords, + getViewFromCache, + unsavedToDeleteViewSortIdsState, + unsavedToUpsertViewSortsState, + updateViewSortRecords, + ], + ); + + const saveViewFilters = useRecoilCallback( + ({ snapshot }) => + async (viewId: string) => { + const unsavedToDeleteViewFilterIds = getSnapshotValue( + snapshot, + unsavedToDeleteViewFilterIdsState, + ); + + const unsavedToUpsertViewFilters = getSnapshotValue( + snapshot, + unsavedToUpsertViewFiltersState, + ); + + const view = await getViewFromCache(viewId); + + if (isUndefinedOrNull(view)) { + return; + } + + const viewFiltersToCreate = unsavedToUpsertViewFilters.filter( + (viewFilter) => + !view.viewFilters.some((vf) => vf.id === viewFilter.id), + ); + + const viewFiltersToUpdate = unsavedToUpsertViewFilters.filter( + (viewFilter) => + view.viewFilters.some((vf) => vf.id === viewFilter.id), + ); + + await createViewFilterRecords(viewFiltersToCreate, view); + await updateViewFilterRecords(viewFiltersToUpdate); + await deleteViewFilterRecords(unsavedToDeleteViewFilterIds); + }, + [ + createViewFilterRecords, + deleteViewFilterRecords, + getViewFromCache, + unsavedToDeleteViewFilterIdsState, + unsavedToUpsertViewFiltersState, + updateViewFilterRecords, + ], + ); + + const saveCurrentViewFilterAndSorts = useRecoilCallback( + ({ snapshot }) => + async () => { + const currentViewId = snapshot + .getLoadable(currentViewIdState) + .getValue(); + + if (!isDefined(currentViewId)) { + return; + } + + await saveViewFilters(currentViewId); + await saveViewSorts(currentViewId); + resetCurrentView(); + }, + [currentViewIdState, resetCurrentView, saveViewFilters, saveViewSorts], + ); + + return { + saveCurrentViewFilterAndSorts, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useSetRecordCountInCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useSetRecordCountInCurrentView.ts new file mode 100644 index 000000000000..8deeece5a1a5 --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useSetRecordCountInCurrentView.ts @@ -0,0 +1,15 @@ +import { useSetRecoilState } from 'recoil'; + +import { useViewStates } from '@/views/hooks/internal/useViewStates'; + +export const useSetRecordCountInCurrentView = (viewBarComponentId?: string) => { + const { entityCountInCurrentViewState } = useViewStates(viewBarComponentId); + + const setEntityCountInCurrentView = useSetRecoilState( + entityCountInCurrentViewState, + ); + + return { + setRecordCountInCurrentView: setEntityCountInCurrentView, + }; +}; diff --git a/packages/twenty-front/src/modules/views/hooks/useViewBar.ts b/packages/twenty-front/src/modules/views/hooks/useViewBar.ts deleted file mode 100644 index ae114e12d958..000000000000 --- a/packages/twenty-front/src/modules/views/hooks/useViewBar.ts +++ /dev/null @@ -1,441 +0,0 @@ -import { useCallback } from 'react'; -import { useSearchParams } from 'react-router-dom'; -import { isNonEmptyString } from '@sniptt/guards'; -import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil'; -import { v4 } from 'uuid'; - -import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; -import { ViewField } from '@/views/types/ViewField'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { ViewSort } from '@/views/types/ViewSort'; -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -import { isDefined } from '~/utils/isDefined'; -import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; - -import { ViewScopeInternalContext } from '../scopes/scope-internal-context/ViewScopeInternalContext'; -import { currentViewFieldsScopedFamilyState } from '../states/currentViewFieldsScopedFamilyState'; -import { currentViewFiltersScopedFamilyState } from '../states/currentViewFiltersScopedFamilyState'; -import { currentViewSortsScopedFamilyState } from '../states/currentViewSortsScopedFamilyState'; -import { getViewScopedStatesFromSnapshot } from '../utils/getViewScopedStatesFromSnapshot'; -import { getViewScopedStateValuesFromSnapshot } from '../utils/getViewScopedStateValuesFromSnapshot'; - -import { useViewFields } from './internal/useViewFields'; -import { useViewFilters } from './internal/useViewFilters'; -import { useViews } from './internal/useViews'; -import { useViewScopedStates } from './internal/useViewScopedStates'; -import { useViewSorts } from './internal/useViewSorts'; - -type UseViewProps = { - viewBarId?: string; -}; - -export const useViewBar = (props?: UseViewProps) => { - const scopeId = useAvailableScopeIdOrThrow( - ViewScopeInternalContext, - props?.viewBarId, - ); - - const { - currentViewFiltersState, - currentViewIdState, - currentViewSortsState, - viewEditModeState, - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - entityCountInCurrentViewState, - viewObjectMetadataIdState, - } = useViewScopedStates({ - viewScopeId: scopeId, - }); - - const { persistViewSorts, upsertViewSort, removeViewSort } = - useViewSorts(scopeId); - const { persistViewFilters, upsertViewFilter, removeViewFilter } = - useViewFilters(scopeId); - const { persistViewFields } = useViewFields(scopeId); - const { - createView: internalCreateView, - updateView: internalUpdateView, - deleteView: internalDeleteView, - } = useViews(scopeId); - - const [currentViewId, setCurrentViewId] = useRecoilState(currentViewIdState); - - const setAvailableFieldDefinitions = useSetRecoilState( - availableFieldDefinitionsState, - ); - - const setAvailableSortDefinitions = useSetRecoilState( - availableSortDefinitionsState, - ); - - const setAvailableFilterDefinitions = useSetRecoilState( - availableFilterDefinitionsState, - ); - - const setEntityCountInCurrentView = useSetRecoilState( - entityCountInCurrentViewState, - ); - - const setViewEditMode = useSetRecoilState(viewEditModeState); - const setViewObjectMetadataId = useSetRecoilState(viewObjectMetadataIdState); - - const [_, setSearchParams] = useSearchParams(); - - const changeViewInUrl = useCallback( - (viewId: string) => { - setSearchParams((previousSearchParams) => { - previousSearchParams.set('view', viewId); - return previousSearchParams; - }); - }, - [setSearchParams], - ); - - const loadViewFields = useRecoilCallback( - ({ snapshot, set }) => - async (viewFields: ViewField[], currentViewId: string) => { - const { - availableFieldDefinitions, - onViewFieldsChange, - savedViewFields, - isPersistingView, - } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - const { savedViewFieldsState, currentViewFieldsState } = - getViewScopedStatesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - if (isUndefinedOrNull(availableFieldDefinitions)) { - return; - } - - const queriedViewFields = viewFields.filter(isDefined); - - if (isPersistingView) { - return; - } - - if (!isDeeplyEqual(savedViewFields, queriedViewFields)) { - set(currentViewFieldsState, queriedViewFields); - set(savedViewFieldsState, queriedViewFields); - } - - onViewFieldsChange?.(queriedViewFields); - }, - [scopeId], - ); - - const loadViewFilters = useRecoilCallback( - ({ snapshot, set }) => - async (viewFilters: ViewFilter[], currentViewId: string) => { - const { - availableFilterDefinitions, - savedViewFilters, - onViewFiltersChange, - } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - const { savedViewFiltersState, currentViewFiltersState } = - getViewScopedStatesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - if (isUndefinedOrNull(availableFilterDefinitions)) { - return; - } - - const queriedViewFilters = viewFilters - .map((viewFilter) => { - const availableFilterDefinition = availableFilterDefinitions.find( - (filterDefinition) => - filterDefinition.fieldMetadataId === viewFilter.fieldMetadataId, - ); - - if (!availableFilterDefinition) return null; - - return { - ...viewFilter, - displayValue: viewFilter.displayValue ?? viewFilter.value, - definition: availableFilterDefinition, - }; - }) - .filter(isDefined); - - if (!isDeeplyEqual(savedViewFilters, queriedViewFilters)) { - set(savedViewFiltersState, queriedViewFilters); - set(currentViewFiltersState, queriedViewFilters); - } - onViewFiltersChange?.(queriedViewFilters); - }, - [scopeId], - ); - - const loadViewSorts = useRecoilCallback( - ({ snapshot, set }) => - async (viewSorts: Required[], currentViewId: string) => { - const { availableSortDefinitions, savedViewSorts, onViewSortsChange } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - const { savedViewSortsState, currentViewSortsState } = - getViewScopedStatesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId: currentViewId, - }); - - if (!availableSortDefinitions || !currentViewId) { - return; - } - - const queriedViewSorts = viewSorts - .map((viewSort) => { - const availableSortDefinition = availableSortDefinitions.find( - (sort) => sort.fieldMetadataId === viewSort.fieldMetadataId, - ); - - if (!availableSortDefinition) return null; - - return { - id: viewSort.id, - fieldMetadataId: viewSort.fieldMetadataId, - direction: viewSort.direction, - definition: availableSortDefinition, - }; - }) - .filter(isDefined); - - if (!isDeeplyEqual(savedViewSorts, queriedViewSorts)) { - set(savedViewSortsState, queriedViewSorts); - set(currentViewSortsState, queriedViewSorts); - } - onViewSortsChange?.(queriedViewSorts); - }, - [scopeId], - ); - - const loadView = useRecoilCallback( - ({ snapshot }) => - (viewId: string) => { - setCurrentViewId?.(viewId); - - const { currentView, onViewTypeChange, onViewCompactModeChange } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId, - }); - - if (!currentView) { - return; - } - - onViewTypeChange?.(currentView.type); - onViewCompactModeChange?.(currentView.isCompact); - loadViewFields(currentView.viewFields, viewId); - loadViewFilters(currentView.viewFilters, viewId); - loadViewSorts(currentView.viewSorts, viewId); - }, - [setCurrentViewId, scopeId, loadViewFields, loadViewFilters, loadViewSorts], - ); - - const resetViewBar = useRecoilCallback( - ({ snapshot, set }) => - () => { - const { - savedViewFilters, - savedViewSorts, - onViewFiltersChange, - onViewSortsChange, - } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - if (isDefined(savedViewFilters)) { - set(currentViewFiltersState, savedViewFilters); - onViewFiltersChange?.(savedViewFilters); - } - if (isDefined(savedViewSorts)) { - set(currentViewSortsState, savedViewSorts); - onViewSortsChange?.(savedViewSorts); - } - - set(viewEditModeState, 'none'); - }, - [ - currentViewFiltersState, - currentViewSortsState, - scopeId, - viewEditModeState, - ], - ); - - const createView = useRecoilCallback( - ({ snapshot, set }) => - async (name: string) => { - const newViewId = v4(); - await internalCreateView({ id: newViewId, name }); - - const { currentViewFields, currentViewFilters, currentViewSorts } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - set( - currentViewFieldsScopedFamilyState({ scopeId, familyKey: newViewId }), - currentViewFields, - ); - - set( - currentViewFiltersScopedFamilyState({ - scopeId, - familyKey: newViewId, - }), - currentViewFilters, - ); - - set( - currentViewSortsScopedFamilyState({ - scopeId, - familyKey: newViewId, - }), - currentViewSorts, - ); - - await persistViewFields(currentViewFields, newViewId); - await persistViewFilters(newViewId); - await persistViewSorts(newViewId); - - changeViewInUrl(newViewId); - }, - [ - changeViewInUrl, - internalCreateView, - persistViewFields, - persistViewFilters, - persistViewSorts, - scopeId, - ], - ); - - const updateCurrentView = async () => { - await persistViewFilters(); - await persistViewSorts(); - }; - - const removeView = useRecoilCallback( - ({ set, snapshot }) => - async (viewIdToDelete: string) => { - const { currentViewId } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - const { currentViewIdState, viewsState } = - getViewScopedStatesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - if (currentViewId === viewIdToDelete) { - set(currentViewIdState, undefined); - } - - set(viewsState, (previousViews) => - previousViews.filter((view) => view.id !== viewIdToDelete), - ); - - internalDeleteView(viewIdToDelete); - - if (currentViewId === viewIdToDelete) { - setSearchParams(); - } - }, - [internalDeleteView, scopeId, setSearchParams], - ); - - const handleViewNameSubmit = useRecoilCallback( - ({ snapshot }) => - async (name?: string) => { - if (!name) { - return; - } - - const { viewEditMode, currentView } = - getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - }); - - if (!currentView) { - return; - } - - if (viewEditMode === 'create' && isNonEmptyString(name)) { - await createView(name); - - // Temporary to force refetch - await internalUpdateView({ - ...currentView, - }); - } else { - await internalUpdateView({ - ...currentView, - name, - }); - } - }, - [createView, internalUpdateView, scopeId], - ); - - return { - scopeId, - currentViewId, - - setCurrentViewId, - updateCurrentView, - createView, - removeView, - resetViewBar, - handleViewNameSubmit, - - setViewEditMode, - setViewObjectMetadataId, - setEntityCountInCurrentView, - setAvailableFieldDefinitions, - - setAvailableSortDefinitions, - upsertViewSort, - removeViewSort, - - setAvailableFilterDefinitions, - upsertViewFilter, - removeViewFilter, - - persistViewFields, - changeViewInUrl, - loadView, - loadViewFields, - loadViewFilters, - loadViewSorts, - }; -}; diff --git a/packages/twenty-front/src/modules/views/hooks/useViewBarEditMode.ts b/packages/twenty-front/src/modules/views/hooks/useViewBarEditMode.ts new file mode 100644 index 000000000000..b24c2e74617a --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useViewBarEditMode.ts @@ -0,0 +1,14 @@ +import { useRecoilState } from 'recoil'; + +import { useViewStates } from '@/views/hooks/internal/useViewStates'; + +export const useViewBarEditMode = (viewBarComponentId?: string) => { + const { viewEditModeState } = useViewStates(viewBarComponentId); + + const [viewEditMode, setViewEditMode] = useRecoilState(viewEditModeState); + + return { + viewEditMode, + setViewEditMode, + }; +}; diff --git a/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx b/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx index 2f83a182384d..e70372fab5a8 100644 --- a/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx +++ b/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx @@ -1,10 +1,6 @@ import { ReactNode } from 'react'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { ViewSort } from '@/views/types/ViewSort'; -import { ViewType } from '@/views/types/ViewType'; - -import { ViewField } from '../types/ViewField'; +import { GraphQLView } from '@/views/types/GraphQLView'; import { ViewScopeInitEffect } from './init-effect/ViewScopeInitEffect'; import { ViewScopeInternalContext } from './scope-internal-context/ViewScopeInternalContext'; @@ -12,23 +8,13 @@ import { ViewScopeInternalContext } from './scope-internal-context/ViewScopeInte type ViewScopeProps = { children: ReactNode; viewScopeId: string; - onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; - onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; - onViewFieldsChange?: (fields: ViewField[]) => void | Promise; - onViewTypeChange?: (viewType: ViewType) => void | Promise; - onViewCompactModeChange?: ( - isCompactModeActive: boolean, - ) => void | Promise; + onCurrentViewChange: (view: GraphQLView | undefined) => void | Promise; }; export const ViewScope = ({ children, viewScopeId, - onViewSortsChange, - onViewFiltersChange, - onViewFieldsChange, - onViewTypeChange, - onViewCompactModeChange, + onCurrentViewChange, }: ViewScopeProps) => { return ( {children} diff --git a/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx b/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx index 2452eab20d84..330c270d8fd8 100644 --- a/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx +++ b/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx @@ -1,64 +1,24 @@ import { useEffect } from 'react'; import { useSetRecoilState } from 'recoil'; -import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; -import { ViewField } from '@/views/types/ViewField'; -import { ViewFilter } from '@/views/types/ViewFilter'; -import { ViewSort } from '@/views/types/ViewSort'; -import { ViewType } from '@/views/types/ViewType'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { GraphQLView } from '@/views/types/GraphQLView'; type ViewScopeInitEffectProps = { viewScopeId: string; - onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; - onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; - onViewFieldsChange?: (fields: ViewField[]) => void | Promise; - onViewTypeChange?: (viewType: ViewType) => void | Promise; - onViewCompactModeChange?: ( - isCompactModeActive: boolean, - ) => void | Promise; + onCurrentViewChange: (view: GraphQLView | undefined) => void | Promise; }; export const ViewScopeInitEffect = ({ - onViewSortsChange, - onViewFiltersChange, - onViewFieldsChange, - onViewTypeChange, - onViewCompactModeChange, + onCurrentViewChange, }: ViewScopeInitEffectProps) => { - const { - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - onViewTypeChangeState, - onViewCompactModeChangeState, - } = useViewScopedStates(); + const { onCurrentViewChangeState } = useViewStates(); - const setOnViewSortsChange = useSetRecoilState(onViewSortsChangeState); - const setOnViewFiltersChange = useSetRecoilState(onViewFiltersChangeState); - const setOnViewFieldsChange = useSetRecoilState(onViewFieldsChangeState); - const setOnViewTypeChange = useSetRecoilState(onViewTypeChangeState); - const setOnViewCompactModeChange = useSetRecoilState( - onViewCompactModeChangeState, - ); + const setOnCurrentViewChange = useSetRecoilState(onCurrentViewChangeState); useEffect(() => { - setOnViewSortsChange(() => onViewSortsChange); - setOnViewFiltersChange(() => onViewFiltersChange); - setOnViewFieldsChange(() => onViewFieldsChange); - setOnViewTypeChange(() => onViewTypeChange); - setOnViewCompactModeChange(() => onViewCompactModeChange); - }, [ - onViewCompactModeChange, - onViewFieldsChange, - onViewFiltersChange, - onViewSortsChange, - onViewTypeChange, - setOnViewCompactModeChange, - setOnViewFieldsChange, - setOnViewFiltersChange, - setOnViewSortsChange, - setOnViewTypeChange, - ]); + setOnCurrentViewChange(() => onCurrentViewChange); + }, [onCurrentViewChange, setOnCurrentViewChange]); return <>; }; diff --git a/packages/twenty-front/src/modules/views/states/availableFieldDefinitionsScopedState.ts b/packages/twenty-front/src/modules/views/states/availableFieldDefinitionsComponentState.ts similarity index 72% rename from packages/twenty-front/src/modules/views/states/availableFieldDefinitionsScopedState.ts rename to packages/twenty-front/src/modules/views/states/availableFieldDefinitionsComponentState.ts index 39e08739fabe..9f11648305d5 100644 --- a/packages/twenty-front/src/modules/views/states/availableFieldDefinitionsScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/availableFieldDefinitionsComponentState.ts @@ -2,9 +2,9 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const availableFieldDefinitionsScopedState = createComponentState< +export const availableFieldDefinitionsComponentState = createComponentState< ColumnDefinition[] >({ - key: 'availableFieldDefinitionsScopedState', + key: 'availableFieldDefinitionsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/views/states/availableFilterDefinitionsScopedState.ts b/packages/twenty-front/src/modules/views/states/availableFilterDefinitionsComponentState.ts similarity index 66% rename from packages/twenty-front/src/modules/views/states/availableFilterDefinitionsScopedState.ts rename to packages/twenty-front/src/modules/views/states/availableFilterDefinitionsComponentState.ts index 8433868e1b12..9a3f649ea491 100644 --- a/packages/twenty-front/src/modules/views/states/availableFilterDefinitionsScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/availableFilterDefinitionsComponentState.ts @@ -1,9 +1,9 @@ import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const availableFilterDefinitionsScopedState = createComponentState< +export const availableFilterDefinitionsComponentState = createComponentState< FilterDefinition[] >({ - key: 'availableFilterDefinitionsScopedState', + key: 'availableFilterDefinitionsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/views/states/availableSortDefinitionsScopedState.ts b/packages/twenty-front/src/modules/views/states/availableSortDefinitionsComponentState.ts similarity index 66% rename from packages/twenty-front/src/modules/views/states/availableSortDefinitionsScopedState.ts rename to packages/twenty-front/src/modules/views/states/availableSortDefinitionsComponentState.ts index ad93c3092577..9281f1d75780 100644 --- a/packages/twenty-front/src/modules/views/states/availableSortDefinitionsScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/availableSortDefinitionsComponentState.ts @@ -1,9 +1,9 @@ import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition'; import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const availableSortDefinitionsScopedState = createComponentState< +export const availableSortDefinitionsComponentState = createComponentState< SortDefinition[] >({ - key: 'availableSortDefinitionsScopedState', + key: 'availableSortDefinitionsComponentState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/views/states/currentViewFieldsScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/currentViewFieldsScopedFamilyState.ts deleted file mode 100644 index 2e73a4f2a5fc..000000000000 --- a/packages/twenty-front/src/modules/views/states/currentViewFieldsScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewField } from '../types/ViewField'; - -export const currentViewFieldsScopedFamilyState = createComponentFamilyState< - ViewField[], - string ->({ - key: 'currentViewFieldsScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/currentViewFiltersScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/currentViewFiltersScopedFamilyState.ts deleted file mode 100644 index 8365c3a021b0..000000000000 --- a/packages/twenty-front/src/modules/views/states/currentViewFiltersScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewFilter } from '../types/ViewFilter'; - -export const currentViewFiltersScopedFamilyState = createComponentFamilyState< - ViewFilter[], - string ->({ - key: 'currentViewFiltersScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/currentViewIdScopedState.ts b/packages/twenty-front/src/modules/views/states/currentViewIdComponentState.ts similarity index 60% rename from packages/twenty-front/src/modules/views/states/currentViewIdScopedState.ts rename to packages/twenty-front/src/modules/views/states/currentViewIdComponentState.ts index 806a02384ef5..799ba48005b3 100644 --- a/packages/twenty-front/src/modules/views/states/currentViewIdScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/currentViewIdComponentState.ts @@ -1,8 +1,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const currentViewIdScopedState = createComponentState< +export const currentViewIdComponentState = createComponentState< string | undefined >({ - key: 'currentViewIdScopedState', + key: 'currentViewIdComponentState', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/views/states/currentViewSortsScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/currentViewSortsScopedFamilyState.ts deleted file mode 100644 index bb209e6d01f7..000000000000 --- a/packages/twenty-front/src/modules/views/states/currentViewSortsScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewSort } from '../types/ViewSort'; - -export const currentViewSortsScopedFamilyState = createComponentFamilyState< - ViewSort[], - string ->({ - key: 'currentViewSortsScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewComponentState.ts b/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewComponentState.ts new file mode 100644 index 000000000000..02a42b251b9d --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewComponentState.ts @@ -0,0 +1,7 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const entityCountInCurrentViewComponentState = + createComponentState({ + key: 'entityCountInCurrentViewComponentState', + defaultValue: 0, + }); diff --git a/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewScopedState.ts b/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewScopedState.ts deleted file mode 100644 index e78260b1e676..000000000000 --- a/packages/twenty-front/src/modules/views/states/entityCountInCurrentViewScopedState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; - -export const entityCountInCurrentViewScopedState = createComponentState( - { - key: 'entityCountInCurrentViewScopedState', - defaultValue: 0, - }, -); diff --git a/packages/twenty-front/src/modules/views/states/isCurrentViewIndexComponentState.ts b/packages/twenty-front/src/modules/views/states/isCurrentViewIndexComponentState.ts new file mode 100644 index 000000000000..ee3252d3680d --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/isCurrentViewIndexComponentState.ts @@ -0,0 +1,7 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const isCurrentViewKeyIndexComponentState = + createComponentState({ + key: 'isCurrentViewKeyIndexComponentState', + defaultValue: true, + }); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedScopedState.ts b/packages/twenty-front/src/modules/views/states/isPersistingViewFieldsComponentState.ts similarity index 55% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedScopedState.ts rename to packages/twenty-front/src/modules/views/states/isPersistingViewFieldsComponentState.ts index 5fc86fa88913..60cfdd2c0562 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/states/isObjectFilterDropdownOperandSelectUnfoldedScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/isPersistingViewFieldsComponentState.ts @@ -1,7 +1,7 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const isObjectFilterDropdownOperandSelectUnfoldedScopedState = +export const isPersistingViewFieldsComponentState = createComponentState({ - key: 'isObjectFilterDropdownOperandSelectUnfoldedScopedState', + key: 'isPersistingViewFieldsComponentState', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/views/states/isPersistingViewScopedState.ts b/packages/twenty-front/src/modules/views/states/isPersistingViewScopedState.ts deleted file mode 100644 index ad648dc44ec4..000000000000 --- a/packages/twenty-front/src/modules/views/states/isPersistingViewScopedState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; - -export const isPersistingViewScopedState = createComponentState({ - key: 'isPersistingViewScopedState', - defaultValue: false, -}); diff --git a/packages/twenty-front/src/modules/views/states/isViewBarExpandedScopedState.ts b/packages/twenty-front/src/modules/views/states/isViewBarExpandedComponentState.ts similarity index 51% rename from packages/twenty-front/src/modules/views/states/isViewBarExpandedScopedState.ts rename to packages/twenty-front/src/modules/views/states/isViewBarExpandedComponentState.ts index c809b40872b6..9742ce77e350 100644 --- a/packages/twenty-front/src/modules/views/states/isViewBarExpandedScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/isViewBarExpandedComponentState.ts @@ -1,6 +1,6 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const isViewBarExpandedScopedState = createComponentState({ - key: 'isViewBarExpandedScopedState', +export const isViewBarExpandedComponentState = createComponentState({ + key: 'isViewBarExpandedComponentState', defaultValue: true, }); diff --git a/packages/twenty-front/src/modules/views/states/noneScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/noneScopedFamilyState.ts deleted file mode 100644 index 8e8f45838c3d..000000000000 --- a/packages/twenty-front/src/modules/views/states/noneScopedFamilyState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -export const noneScopedFamilyState = createComponentFamilyState({ - key: 'noneScopedFamilyState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/views/states/onCurrentViewChangeComponentState.ts b/packages/twenty-front/src/modules/views/states/onCurrentViewChangeComponentState.ts new file mode 100644 index 000000000000..06b503c486b6 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/onCurrentViewChangeComponentState.ts @@ -0,0 +1,9 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; +import { GraphQLView } from '@/views/types/GraphQLView'; + +export const onCurrentViewChangeComponentState = createComponentState< + ((view: GraphQLView | undefined) => void | Promise) | undefined +>({ + key: 'onCurrentViewChangeComponentState', + defaultValue: undefined, +}); diff --git a/packages/twenty-front/src/modules/views/states/onViewCompactModeChangeScopeState.ts b/packages/twenty-front/src/modules/views/states/onViewCompactModeChangeScopeState.ts deleted file mode 100644 index 267682f96b42..000000000000 --- a/packages/twenty-front/src/modules/views/states/onViewCompactModeChangeScopeState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; - -export const onViewCompactModeChangeScopeState = createComponentState< - ((isCompactModeActive: boolean) => void | Promise) | undefined ->({ - key: 'onViewCompactModeChangeScopeState', - defaultValue: undefined, -}); diff --git a/packages/twenty-front/src/modules/views/states/onViewFieldsChangeScopedState.ts b/packages/twenty-front/src/modules/views/states/onViewFieldsChangeScopedState.ts deleted file mode 100644 index e7e002f35a1e..000000000000 --- a/packages/twenty-front/src/modules/views/states/onViewFieldsChangeScopedState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; - -import { ViewField } from '../types/ViewField'; - -export const onViewFieldsChangeScopedState = createComponentState< - ((fields: ViewField[]) => void | Promise) | undefined ->({ - key: 'onViewFieldsChangeScopedState', - defaultValue: undefined, -}); diff --git a/packages/twenty-front/src/modules/views/states/onViewFiltersChangeScopedState.ts b/packages/twenty-front/src/modules/views/states/onViewFiltersChangeScopedState.ts deleted file mode 100644 index 2e16b7ab4814..000000000000 --- a/packages/twenty-front/src/modules/views/states/onViewFiltersChangeScopedState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -import { ViewFilter } from '@/views/types/ViewFilter'; - -export const onViewFiltersChangeScopedState = createComponentState< - ((filters: ViewFilter[]) => void | Promise) | undefined ->({ - key: 'onViewFiltersChangeScopedState', - defaultValue: undefined, -}); diff --git a/packages/twenty-front/src/modules/views/states/onViewSortsChangeScopedState.ts b/packages/twenty-front/src/modules/views/states/onViewSortsChangeScopedState.ts deleted file mode 100644 index 551c165de644..000000000000 --- a/packages/twenty-front/src/modules/views/states/onViewSortsChangeScopedState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -import { ViewSort } from '@/views/types/ViewSort'; - -export const onViewSortsChangeScopedState = createComponentState< - ((sorts: ViewSort[]) => void | Promise) | undefined ->({ - key: 'onViewSortsChangeScopedState', - defaultValue: undefined, -}); diff --git a/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts b/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts deleted file mode 100644 index b48c3f29e859..000000000000 --- a/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -import { ViewType } from '@/views/types/ViewType'; - -export const onViewTypeChangeScopedState = createComponentState< - ((viewType: ViewType) => void | Promise) | undefined ->({ - key: 'onViewTypeChangeScopedState', - defaultValue: undefined, -}); diff --git a/packages/twenty-front/src/modules/views/states/savedViewFieldsScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/savedViewFieldsScopedFamilyState.ts deleted file mode 100644 index d0fd3ddac4a8..000000000000 --- a/packages/twenty-front/src/modules/views/states/savedViewFieldsScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewField } from '../types/ViewField'; - -export const savedViewFieldsScopedFamilyState = createComponentFamilyState< - ViewField[], - string ->({ - key: 'savedViewFieldsScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/savedViewFiltersScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/savedViewFiltersScopedFamilyState.ts deleted file mode 100644 index cc90fa73de22..000000000000 --- a/packages/twenty-front/src/modules/views/states/savedViewFiltersScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewFilter } from '../types/ViewFilter'; - -export const savedViewFiltersScopedFamilyState = createComponentFamilyState< - ViewFilter[], - string ->({ - key: 'savedViewFiltersScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/savedViewSortsScopedFamilyState.ts b/packages/twenty-front/src/modules/views/states/savedViewSortsScopedFamilyState.ts deleted file mode 100644 index a6d0eceb55a8..000000000000 --- a/packages/twenty-front/src/modules/views/states/savedViewSortsScopedFamilyState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState'; - -import { ViewSort } from '../types/ViewSort'; - -export const savedViewSortsScopedFamilyState = createComponentFamilyState< - ViewSort[], - string ->({ - key: 'savedViewSortsScopedFamilyState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/canPersistViewComponentSelector.ts b/packages/twenty-front/src/modules/views/states/selectors/canPersistViewComponentSelector.ts new file mode 100644 index 000000000000..2d28c5735993 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/selectors/canPersistViewComponentSelector.ts @@ -0,0 +1,21 @@ +import { selectorFamily } from 'recoil'; + +import { unsavedToDeleteViewFilterIdsComponentState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentState'; +import { unsavedToDeleteViewSortIdsComponentState } from '@/views/states/unsavedToDeleteViewSortIdsComponentState'; +import { unsavedToUpsertViewFiltersComponentState } from '@/views/states/unsavedToUpsertViewFiltersComponentState'; +import { unsavedToUpsertViewSortsComponentState } from '@/views/states/unsavedToUpsertViewSortsComponentState'; + +export const canPersistViewComponentSelector = selectorFamily({ + key: 'canPersistViewComponentSelector', + get: + ({ scopeId }: { scopeId: string }) => + ({ get }) => { + return ( + get(unsavedToUpsertViewFiltersComponentState({ scopeId })).length > 0 || + get(unsavedToUpsertViewSortsComponentState({ scopeId })).length > 0 || + get(unsavedToDeleteViewFilterIdsComponentState({ scopeId })).length > + 0 || + get(unsavedToDeleteViewSortIdsComponentState({ scopeId })).length > 0 + ); + }, +}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/canPersistViewFiltersScopedFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/canPersistViewFiltersScopedFamilySelector.ts deleted file mode 100644 index b13e6041d30d..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/canPersistViewFiltersScopedFamilySelector.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; - -import { currentViewFiltersScopedFamilyState } from '../currentViewFiltersScopedFamilyState'; -import { savedViewFiltersScopedFamilyState } from '../savedViewFiltersScopedFamilyState'; - -export const canPersistViewFiltersScopedFamilySelector = selectorFamily({ - key: 'canPersistFiltersScopedFamilySelector', - get: - ({ viewScopeId, viewId }: { viewScopeId: string; viewId?: string }) => - ({ get }) => { - if (!viewId) { - return; - } - - return !isDeeplyEqual( - get( - savedViewFiltersScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId, - }), - ), - get( - currentViewFiltersScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId, - }), - ), - ); - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/canPersistViewSortsScopedFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/canPersistViewSortsScopedFamilySelector.ts deleted file mode 100644 index 37020a7d1b22..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/canPersistViewSortsScopedFamilySelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; - -import { currentViewSortsScopedFamilyState } from '../currentViewSortsScopedFamilyState'; -import { savedViewSortsScopedFamilyState } from '../savedViewSortsScopedFamilyState'; - -export const canPersistViewSortsScopedFamilySelector = selectorFamily({ - key: 'canPersistSortsScopedFamilySelector', - get: - ({ viewScopeId, viewId }: { viewScopeId: string; viewId?: string }) => - ({ get }) => { - if (!viewId) { - return; - } - return !isDeeplyEqual( - get( - savedViewSortsScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId, - }), - ), - get( - currentViewSortsScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId, - }), - ), - ); - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/canResetViewComponentSelector.ts b/packages/twenty-front/src/modules/views/states/selectors/canResetViewComponentSelector.ts new file mode 100644 index 000000000000..5ad2bd408d5c --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/selectors/canResetViewComponentSelector.ts @@ -0,0 +1,22 @@ +import { selectorFamily } from 'recoil'; + +import { unsavedToDeleteViewFilterIdsComponentState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentState'; +import { unsavedToDeleteViewSortIdsComponentState } from '@/views/states/unsavedToDeleteViewSortIdsComponentState'; +import { unsavedToUpsertViewFiltersComponentState } from '@/views/states/unsavedToUpsertViewFiltersComponentState'; +import { unsavedToUpsertViewSortsComponentState } from '@/views/states/unsavedToUpsertViewSortsComponentState'; + +export const canResetViewComponentSelector = selectorFamily({ + key: 'canResetViewComponentSelector', + get: + ({ scopeId }: { scopeId: string }) => + ({ get }) => { + return ( + get(unsavedToUpsertViewFiltersComponentState({ scopeId })).length === + 0 && + get(unsavedToUpsertViewSortsComponentState({ scopeId })).length === 0 && + get(unsavedToDeleteViewFilterIdsComponentState({ scopeId })).length === + 0 && + get(unsavedToDeleteViewSortIdsComponentState({ scopeId })).length === 0 + ); + }, +}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/currentViewComponentSelector.ts b/packages/twenty-front/src/modules/views/states/selectors/currentViewComponentSelector.ts deleted file mode 100644 index 7f8770d6c932..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/currentViewComponentSelector.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector'; -import { GraphQLView } from '@/views/types/GraphQLView'; - -import { currentViewIdScopedState } from '../currentViewIdScopedState'; - -import { viewsByIdScopedSelector } from './viewsByIdScopedSelector'; - -export const currentViewComponentSelector = createComponentReadOnlySelector< - GraphQLView | undefined ->({ - key: 'currentViewScopedSelector', - get: - ({ scopeId }: { scopeId: string }) => - ({ get }) => { - const currentViewId = get(currentViewIdScopedState({ scopeId: scopeId })); - - return currentViewId - ? get(viewsByIdScopedSelector(scopeId))[currentViewId] - : undefined; - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/savedViewFieldByKeyScopedFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/savedViewFieldByKeyScopedFamilySelector.ts deleted file mode 100644 index fc56e7fdeef9..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/savedViewFieldByKeyScopedFamilySelector.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { ViewField } from '@/views/types/ViewField'; - -import { savedViewFieldsScopedFamilyState } from '../savedViewFieldsScopedFamilyState'; - -export const savedViewFieldByKeyScopedFamilySelector = selectorFamily({ - key: 'savedViewFieldByKeyScopedFamilySelector', - get: - ({ - viewScopeId, - viewId, - }: { - viewScopeId: string; - viewId: string | undefined; - }) => - ({ get }) => { - if (viewId === undefined) { - return undefined; - } - - return get( - savedViewFieldsScopedFamilyState({ - scopeId: viewScopeId, - familyKey: viewId, - }), - ).reduce>( - (result, column) => ({ ...result, [column.fieldMetadataId]: column }), - {}, - ); - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector.ts deleted file mode 100644 index 235d5375f666..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { ViewFilter } from '@/views/types/ViewFilter'; - -import { savedViewFiltersScopedFamilyState } from '../savedViewFiltersScopedFamilyState'; - -export const savedViewFiltersByKeyScopedFamilySelector = selectorFamily({ - key: 'savedViewFiltersByKeyScopedFamilySelector', - get: - ({ scopeId, viewId }: { scopeId: string; viewId: string | undefined }) => - ({ get }) => { - if (viewId === undefined) { - return undefined; - } - return get( - savedViewFiltersScopedFamilyState({ - scopeId: scopeId, - familyKey: viewId, - }), - ).reduce>( - (result, filter) => ({ ...result, [filter.fieldMetadataId]: filter }), - {}, - ); - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsByKeyScopedFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsByKeyScopedFamilySelector.ts deleted file mode 100644 index 2348464d40d6..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsByKeyScopedFamilySelector.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { ViewSort } from '@/views/types/ViewSort'; - -import { savedViewSortsScopedFamilyState } from '../savedViewSortsScopedFamilyState'; - -export const savedViewSortsByKeyScopedFamilySelector = selectorFamily({ - key: 'savedViewSortsByKeyScopedFamilySelector', - get: - ({ scopeId, viewId }: { scopeId: string; viewId: string | undefined }) => - ({ get }) => { - if (viewId === undefined) { - return undefined; - } - return get( - savedViewSortsScopedFamilyState({ - scopeId: scopeId, - familyKey: viewId, - }), - ).reduce>( - (result, sort) => ({ ...result, [sort.fieldMetadataId]: sort }), - {}, - ); - }, -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsFamilySelector.ts b/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsFamilySelector.ts deleted file mode 100644 index ee0a98353048..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/savedViewSortsFamilySelector.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { savedViewSortsScopedFamilyState } from '../savedViewSortsScopedFamilyState'; - -export const savedViewSortsFamilySelector = selectorFamily({ - key: 'savedViewSortsFamilySelector', - get: - ({ scopeId, viewId }: { scopeId: string; viewId: string }) => - ({ get }) => - get( - savedViewSortsScopedFamilyState({ - scopeId: scopeId, - familyKey: viewId, - }), - ), -}); diff --git a/packages/twenty-front/src/modules/views/states/selectors/viewsByIdScopedSelector.ts b/packages/twenty-front/src/modules/views/states/selectors/viewsByIdScopedSelector.ts deleted file mode 100644 index 0ec9d8919202..000000000000 --- a/packages/twenty-front/src/modules/views/states/selectors/viewsByIdScopedSelector.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { selectorFamily } from 'recoil'; - -import { GraphQLView } from '@/views/types/GraphQLView'; - -import { viewsScopedState } from '../viewsScopedState'; - -export const viewsByIdScopedSelector = selectorFamily< - Record, - string ->({ - key: 'viewsByIdScopedSelector', - get: - (scopeId) => - ({ get }) => - get(viewsScopedState({ scopeId: scopeId })).reduce< - Record - >((result, view) => ({ ...result, [view.id]: view }), {}), -}); diff --git a/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewFilterIdsComponentState.ts b/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewFilterIdsComponentState.ts new file mode 100644 index 000000000000..60b89afbbb1c --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewFilterIdsComponentState.ts @@ -0,0 +1,8 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const unsavedToDeleteViewFilterIdsComponentState = createComponentState< + string[] +>({ + key: 'unsavedToDeleteViewFilterIdsComponentState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewSortIdsComponentState.ts b/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewSortIdsComponentState.ts new file mode 100644 index 000000000000..bb44082bf807 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/unsavedToDeleteViewSortIdsComponentState.ts @@ -0,0 +1,8 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const unsavedToDeleteViewSortIdsComponentState = createComponentState< + string[] +>({ + key: 'unsavedToDeleteViewSortIdsComponentState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewFiltersComponentState.ts b/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewFiltersComponentState.ts new file mode 100644 index 000000000000..108ad0847910 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewFiltersComponentState.ts @@ -0,0 +1,10 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +import { ViewFilter } from '../types/ViewFilter'; + +export const unsavedToUpsertViewFiltersComponentState = createComponentState< + ViewFilter[] +>({ + key: 'unsavedToUpsertViewFiltersComponentState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewSortsComponentState.ts b/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewSortsComponentState.ts new file mode 100644 index 000000000000..57fa5f0b9af9 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/unsavedToUpsertViewSortsComponentState.ts @@ -0,0 +1,10 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +import { ViewSort } from '../types/ViewSort'; + +export const unsavedToUpsertViewSortsComponentState = createComponentState< + ViewSort[] +>({ + key: 'unsavedToUpsertViewSortsComponentState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/views/states/viewEditModeScopedState.ts b/packages/twenty-front/src/modules/views/states/viewEditModeComponentState.ts similarity index 62% rename from packages/twenty-front/src/modules/views/states/viewEditModeScopedState.ts rename to packages/twenty-front/src/modules/views/states/viewEditModeComponentState.ts index 638502faf422..ffd30511a3c4 100644 --- a/packages/twenty-front/src/modules/views/states/viewEditModeScopedState.ts +++ b/packages/twenty-front/src/modules/views/states/viewEditModeComponentState.ts @@ -1,8 +1,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const viewEditModeScopedState = createComponentState< +export const viewEditModeComponentState = createComponentState< 'none' | 'edit' | 'create' >({ - key: 'viewEditModeScopedState', + key: 'viewEditModeComponentState', defaultValue: 'none', }); diff --git a/packages/twenty-front/src/modules/views/states/viewObjectMetadataIdScopeState.ts b/packages/twenty-front/src/modules/views/states/viewObjectMetadataIdComponentState.ts similarity index 57% rename from packages/twenty-front/src/modules/views/states/viewObjectMetadataIdScopeState.ts rename to packages/twenty-front/src/modules/views/states/viewObjectMetadataIdComponentState.ts index 12e397f558b6..a20cbb9016fb 100644 --- a/packages/twenty-front/src/modules/views/states/viewObjectMetadataIdScopeState.ts +++ b/packages/twenty-front/src/modules/views/states/viewObjectMetadataIdComponentState.ts @@ -1,8 +1,8 @@ import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -export const viewObjectMetadataIdScopeState = createComponentState< +export const viewObjectMetadataIdComponentState = createComponentState< string | undefined >({ - key: 'viewObjectMetadataIdScopeState', + key: 'viewObjectMetadataIdComponentState', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/views/states/viewTypeScopedState.ts b/packages/twenty-front/src/modules/views/states/viewTypeScopedState.ts deleted file mode 100644 index 899166dd8bb7..000000000000 --- a/packages/twenty-front/src/modules/views/states/viewTypeScopedState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; - -import { ViewType } from '../types/ViewType'; - -export const viewTypeScopedState = createComponentState({ - key: 'viewTypeScopedState', - defaultValue: ViewType.Table, -}); diff --git a/packages/twenty-front/src/modules/views/states/viewsScopedState.ts b/packages/twenty-front/src/modules/views/states/viewsScopedState.ts deleted file mode 100644 index 6186528b8365..000000000000 --- a/packages/twenty-front/src/modules/views/states/viewsScopedState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; -import { GraphQLView } from '@/views/types/GraphQLView'; - -export const viewsScopedState = createComponentState({ - key: 'viewsScopedState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/views/types/ViewField.ts b/packages/twenty-front/src/modules/views/types/ViewField.ts index 0e1d44bb4f87..708f2b034385 100644 --- a/packages/twenty-front/src/modules/views/types/ViewField.ts +++ b/packages/twenty-front/src/modules/views/types/ViewField.ts @@ -3,6 +3,7 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; export type ViewField = { + __typename: 'ViewField'; id: string; fieldMetadataId: string; position: number; diff --git a/packages/twenty-front/src/modules/views/types/ViewFilter.ts b/packages/twenty-front/src/modules/views/types/ViewFilter.ts index 793357ce7c47..1a21b111f071 100644 --- a/packages/twenty-front/src/modules/views/types/ViewFilter.ts +++ b/packages/twenty-front/src/modules/views/types/ViewFilter.ts @@ -1,12 +1,13 @@ -import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; - import { ViewFilterOperand } from './ViewFilterOperand'; export type ViewFilter = { + __typename: 'ViewFilter'; id: string; fieldMetadataId: string; operand: ViewFilterOperand; value: string; displayValue: string; - definition: FilterDefinition; + createdAt?: string; + updatedAt?: string; + viewId?: string; }; diff --git a/packages/twenty-front/src/modules/views/types/ViewSort.ts b/packages/twenty-front/src/modules/views/types/ViewSort.ts index c88aaa13a5fe..67d48fc59e27 100644 --- a/packages/twenty-front/src/modules/views/types/ViewSort.ts +++ b/packages/twenty-front/src/modules/views/types/ViewSort.ts @@ -1,9 +1,8 @@ -import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition'; import { SortDirection } from '@/object-record/object-sort-dropdown/types/SortDirection'; export type ViewSort = { + __typename: 'ViewSort'; id: string; fieldMetadataId: string; direction: SortDirection; - definition: SortDefinition; }; diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/viewMapFunctions.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/viewMapFunctions.test.ts index da0a27668421..a1c0b58193ca 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/viewMapFunctions.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/viewMapFunctions.test.ts @@ -12,7 +12,7 @@ import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; const baseDefinition = { - fieldMetadataId: 'fieldMetadataId', + fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', label: 'label', iconName: 'iconName', }; @@ -21,20 +21,22 @@ describe('mapViewSortsToSorts', () => { it('should map each ViewSort object to a corresponding Sort object', () => { const viewSorts: ViewSort[] = [ { + __typename: 'ViewSort', id: 'id', - fieldMetadataId: 'fieldMetadataId', + fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', direction: 'asc', - definition: baseDefinition, }, ]; const expectedSorts: Sort[] = [ { - fieldMetadataId: 'fieldMetadataId', + fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', direction: 'asc', definition: baseDefinition, }, ]; - expect(mapViewSortsToSorts(viewSorts)).toEqual(expectedSorts); + expect(mapViewSortsToSorts(viewSorts, [baseDefinition])).toEqual( + expectedSorts, + ); }); }); @@ -42,20 +44,17 @@ describe('mapViewFiltersToFilters', () => { it('should map each ViewFilter object to a corresponding Filter object', () => { const viewFilters: ViewFilter[] = [ { + __typename: 'ViewFilter', id: 'id', - fieldMetadataId: '1', + fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', value: 'testValue', displayValue: 'Test Display Value', operand: ViewFilterOperand.Is, - definition: { - ...baseDefinition, - type: 'FULL_NAME', - }, }, ]; const expectedFilters: Filter[] = [ { - fieldMetadataId: '1', + fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', value: 'testValue', displayValue: 'Test Display Value', operand: ViewFilterOperand.Is, @@ -65,7 +64,14 @@ describe('mapViewFiltersToFilters', () => { }, }, ]; - expect(mapViewFiltersToFilters(viewFilters)).toEqual(expectedFilters); + expect( + mapViewFiltersToFilters(viewFilters, [ + { + ...baseDefinition, + type: 'FULL_NAME', + }, + ]), + ).toEqual(expectedFilters); }); }); @@ -73,6 +79,7 @@ describe('mapViewFieldsToColumnDefinitions', () => { it('should map visible ViewFields to ColumnDefinitions and filter out missing fieldMetadata', () => { const viewFields: ViewField[] = [ { + __typename: 'ViewField', id: '1', fieldMetadataId: '1', position: 1, @@ -92,6 +99,7 @@ describe('mapViewFieldsToColumnDefinitions', () => { }, }, { + __typename: 'ViewField', id: '2', fieldMetadataId: '2', position: 2, @@ -111,6 +119,7 @@ describe('mapViewFieldsToColumnDefinitions', () => { }, }, { + __typename: 'ViewField', id: '3', fieldMetadataId: '3', position: 3, @@ -209,13 +218,16 @@ describe('mapColumnDefinitionsToViewFields', () => { const expectedViewFields = [ { + __typename: 'ViewField', id: 'custom-id-1', fieldMetadataId: 1, position: 1, isVisible: true, definition: columnDefinitions[0], + size: undefined, }, { + __typename: 'ViewField', id: '', fieldMetadataId: 2, position: 2, diff --git a/packages/twenty-front/src/modules/views/utils/combinedViewFilters.ts b/packages/twenty-front/src/modules/views/utils/combinedViewFilters.ts new file mode 100644 index 000000000000..ac33a83f396c --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/combinedViewFilters.ts @@ -0,0 +1,34 @@ +import { ViewFilter } from '@/views/types/ViewFilter'; + +export const combinedViewFilters = ( + viewFilter: ViewFilter[], + toUpsertViewFilters: ViewFilter[], + toDeleteViewFilterIds: string[], +): ViewFilter[] => { + const toCreateViewFilters = toUpsertViewFilters.filter( + (toUpsertViewFilter) => + !viewFilter.some((viewFilter) => viewFilter.id === toUpsertViewFilter.id), + ); + + const toUpdateViewFilters = toUpsertViewFilters.filter((toUpsertViewFilter) => + viewFilter.some((viewFilter) => viewFilter.id === toUpsertViewFilter.id), + ); + + const combinedViewFilters = viewFilter + .filter((viewFilter) => !toDeleteViewFilterIds.includes(viewFilter.id)) + .map((viewFilter) => { + const toUpdateViewFilter = toUpdateViewFilters.find( + (toUpdateViewFilter) => toUpdateViewFilter.id === viewFilter.id, + ); + + return toUpdateViewFilter ?? viewFilter; + }) + .concat(toCreateViewFilters); + + return Object.values( + combinedViewFilters.reduce( + (acc, obj) => ({ ...acc, [obj.fieldMetadataId]: obj }), + {}, + ), + ); +}; diff --git a/packages/twenty-front/src/modules/views/utils/combinedViewSorts.ts b/packages/twenty-front/src/modules/views/utils/combinedViewSorts.ts new file mode 100644 index 000000000000..c0fad726aa99 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/combinedViewSorts.ts @@ -0,0 +1,34 @@ +import { ViewSort } from '@/views/types/ViewSort'; + +export const combinedViewSorts = ( + viewSort: ViewSort[], + toUpsertViewSorts: ViewSort[], + toDeleteViewSortIds: string[], +): ViewSort[] => { + const toCreateViewSorts = toUpsertViewSorts.filter( + (toUpsertViewSort) => + !viewSort.some((viewSort) => viewSort.id === toUpsertViewSort.id), + ); + + const toUpdateViewSorts = toUpsertViewSorts.filter((toUpsertViewSort) => + viewSort.some((viewSort) => viewSort.id === toUpsertViewSort.id), + ); + + const combinedViewSorts = viewSort + .filter((viewSort) => !toDeleteViewSortIds.includes(viewSort.id)) + .map((viewSort) => { + const toUpdateViewSort = toUpdateViewSorts.find( + (toUpdateViewSort) => toUpdateViewSort.id === viewSort.id, + ); + + return toUpdateViewSort ?? viewSort; + }) + .concat(toCreateViewSorts); + + return Object.values( + combinedViewSorts.reduce( + (acc, obj) => ({ ...acc, [obj.fieldMetadataId]: obj }), + {}, + ), + ); +}; diff --git a/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts b/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts deleted file mode 100644 index 3d7b749f0173..000000000000 --- a/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Snapshot } from 'recoil'; - -import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; -import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; - -import { UNDEFINED_FAMILY_ITEM_ID } from '../constants'; -import { currentViewIdScopedState } from '../states/currentViewIdScopedState'; - -import { getViewScopedStates } from './internal/getViewScopedStates'; - -export const getViewScopedStateValuesFromSnapshot = ({ - snapshot, - viewScopeId, - viewId, -}: { - snapshot: Snapshot; - viewScopeId: string; - viewId?: string; -}) => { - const currentViewId = getSnapshotValue( - snapshot, - getScopedStateDeprecated(currentViewIdScopedState, viewScopeId), - ); - - const familyItemId = viewId ?? currentViewId ?? UNDEFINED_FAMILY_ITEM_ID; - - const { - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - canPersistFiltersSelector, - canPersistSortsSelector, - currentViewFieldsState, - currentViewFiltersState, - currentViewIdState, - currentViewSelector, - currentViewSortsState, - entityCountInCurrentViewState, - isViewBarExpandedState, - isPersistingViewState, - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - onViewTypeChangeState, - onViewCompactModeChangeState, - savedViewFieldsByKeySelector, - savedViewFieldsState, - savedViewFiltersByKeySelector, - savedViewFiltersState, - savedViewSortsByKeySelector, - savedViewSortsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - viewsState, - } = getViewScopedStates({ - viewScopeId, - viewId: familyItemId, - }); - - return { - availableFieldDefinitions: getSnapshotValue( - snapshot, - availableFieldDefinitionsState, - ), - availableFilterDefinitions: getSnapshotValue( - snapshot, - availableFilterDefinitionsState, - ), - availableSortDefinitions: getSnapshotValue( - snapshot, - availableSortDefinitionsState, - ), - canPersistFilters: getSnapshotValue(snapshot, canPersistFiltersSelector), - canPersistSorts: getSnapshotValue(snapshot, canPersistSortsSelector), - currentViewFields: getSnapshotValue(snapshot, currentViewFieldsState), - currentViewFilters: getSnapshotValue(snapshot, currentViewFiltersState), - currentViewId: getSnapshotValue(snapshot, currentViewIdState), - currentView: getSnapshotValue(snapshot, currentViewSelector), - currentViewSorts: getSnapshotValue(snapshot, currentViewSortsState), - entityCountInCurrentView: getSnapshotValue( - snapshot, - entityCountInCurrentViewState, - ), - isViewBarExpanded: getSnapshotValue(snapshot, isViewBarExpandedState), - isPersistingView: getSnapshotValue(snapshot, isPersistingViewState), - onViewFieldsChange: getSnapshotValue(snapshot, onViewFieldsChangeState), - onViewFiltersChange: getSnapshotValue(snapshot, onViewFiltersChangeState), - onViewSortsChange: getSnapshotValue(snapshot, onViewSortsChangeState), - onViewTypeChange: getSnapshotValue(snapshot, onViewTypeChangeState), - onViewCompactModeChange: getSnapshotValue( - snapshot, - onViewCompactModeChangeState, - ), - savedViewFieldsByKey: getSnapshotValue( - snapshot, - savedViewFieldsByKeySelector, - ), - savedViewFields: getSnapshotValue(snapshot, savedViewFieldsState), - savedViewFiltersByKey: getSnapshotValue( - snapshot, - savedViewFiltersByKeySelector, - ), - savedViewFilters: getSnapshotValue(snapshot, savedViewFiltersState), - savedViewSortsByKey: getSnapshotValue( - snapshot, - savedViewSortsByKeySelector, - ), - savedViewSorts: getSnapshotValue(snapshot, savedViewSortsState), - viewEditMode: getSnapshotValue(snapshot, viewEditModeState), - viewObjectMetadataId: getSnapshotValue(snapshot, viewObjectMetadataIdState), - viewType: getSnapshotValue(snapshot, viewTypeState), - views: getSnapshotValue(snapshot, viewsState), - }; -}; diff --git a/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts b/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts deleted file mode 100644 index b6b9f0ea5ad8..000000000000 --- a/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Snapshot } from 'recoil'; - -import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; -import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; - -import { UNDEFINED_FAMILY_ITEM_ID } from '../constants'; -import { currentViewIdScopedState } from '../states/currentViewIdScopedState'; - -import { getViewScopedStates } from './internal/getViewScopedStates'; - -export const getViewScopedStatesFromSnapshot = ({ - snapshot, - viewScopeId, - viewId, -}: { - snapshot: Snapshot; - viewScopeId: string; - viewId?: string; -}) => { - const currentViewId = getSnapshotValue( - snapshot, - getScopedStateDeprecated(currentViewIdScopedState, viewScopeId), - ); - - const usedViewId = viewId ?? currentViewId ?? UNDEFINED_FAMILY_ITEM_ID; - - const { - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - canPersistFiltersSelector, - canPersistSortsSelector, - currentViewFieldsState, - currentViewFiltersState, - currentViewIdState, - currentViewSelector, - currentViewSortsState, - entityCountInCurrentViewState, - isViewBarExpandedState, - isPersistingViewState, - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - savedViewFieldsByKeySelector, - savedViewFieldsState, - savedViewFiltersByKeySelector, - savedViewFiltersState, - savedViewSortsByKeySelector, - savedViewSortsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - viewsState, - } = getViewScopedStates({ - viewScopeId, - viewId: usedViewId, - }); - - return { - availableFieldDefinitionsState, - availableFilterDefinitionsState, - availableSortDefinitionsState, - canPersistFiltersReadOnlyState: canPersistFiltersSelector, - canPersistSortsReadOnlyState: canPersistSortsSelector, - currentViewFieldsState, - currentViewFiltersState, - currentViewIdState, - currentViewSelector, - currentViewSortsState, - entityCountInCurrentViewState, - isViewBarExpandedState, - isPersistingViewState, - onViewFieldsChangeState, - onViewFiltersChangeState, - onViewSortsChangeState, - savedViewFieldsByKeyReadOnlyState: savedViewFieldsByKeySelector, - savedViewFieldsState, - savedViewFiltersByKeyReadOnlyState: savedViewFiltersByKeySelector, - savedViewFiltersState, - savedViewSortsByKeyReadOnlyState: savedViewSortsByKeySelector, - savedViewSortsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - viewsState, - }; -}; diff --git a/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts b/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts deleted file mode 100644 index 5e3d5f29b3b8..000000000000 --- a/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { getScopedFamilyStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated'; -import { getScopedSelectorDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedSelectorDeprecated'; -import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; -import { currentViewIdScopedState } from '@/views/states/currentViewIdScopedState'; -import { isPersistingViewScopedState } from '@/views/states/isPersistingViewScopedState'; -import { onViewCompactModeChangeScopeState } from '@/views/states/onViewCompactModeChangeScopeState'; -import { onViewTypeChangeScopedState } from '@/views/states/onViewTypeChangeScopedState'; -import { currentViewComponentSelector } from '@/views/states/selectors/currentViewComponentSelector'; -import { savedViewFieldByKeyScopedFamilySelector } from '@/views/states/selectors/savedViewFieldByKeyScopedFamilySelector'; - -import { availableFieldDefinitionsScopedState } from '../../states/availableFieldDefinitionsScopedState'; -import { availableFilterDefinitionsScopedState } from '../../states/availableFilterDefinitionsScopedState'; -import { availableSortDefinitionsScopedState } from '../../states/availableSortDefinitionsScopedState'; -import { currentViewFieldsScopedFamilyState } from '../../states/currentViewFieldsScopedFamilyState'; -import { currentViewFiltersScopedFamilyState } from '../../states/currentViewFiltersScopedFamilyState'; -import { currentViewSortsScopedFamilyState } from '../../states/currentViewSortsScopedFamilyState'; -import { entityCountInCurrentViewScopedState } from '../../states/entityCountInCurrentViewScopedState'; -import { isViewBarExpandedScopedState } from '../../states/isViewBarExpandedScopedState'; -import { onViewFieldsChangeScopedState } from '../../states/onViewFieldsChangeScopedState'; -import { onViewFiltersChangeScopedState } from '../../states/onViewFiltersChangeScopedState'; -import { onViewSortsChangeScopedState } from '../../states/onViewSortsChangeScopedState'; -import { savedViewFieldsScopedFamilyState } from '../../states/savedViewFieldsScopedFamilyState'; -import { savedViewFiltersScopedFamilyState } from '../../states/savedViewFiltersScopedFamilyState'; -import { savedViewSortsScopedFamilyState } from '../../states/savedViewSortsScopedFamilyState'; -import { canPersistViewFiltersScopedFamilySelector } from '../../states/selectors/canPersistViewFiltersScopedFamilySelector'; -import { canPersistViewSortsScopedFamilySelector } from '../../states/selectors/canPersistViewSortsScopedFamilySelector'; -import { savedViewFiltersByKeyScopedFamilySelector } from '../../states/selectors/savedViewFiltersByKeyScopedFamilySelector'; -import { savedViewSortsByKeyScopedFamilySelector } from '../../states/selectors/savedViewSortsByKeyScopedFamilySelector'; -import { viewEditModeScopedState } from '../../states/viewEditModeScopedState'; -import { viewObjectMetadataIdScopeState } from '../../states/viewObjectMetadataIdScopeState'; -import { viewsScopedState } from '../../states/viewsScopedState'; -import { viewTypeScopedState } from '../../states/viewTypeScopedState'; - -export const getViewScopedStates = ({ - viewScopeId, - viewId, -}: { - viewScopeId: string; - viewId: string; -}) => { - const viewEditModeState = getScopedStateDeprecated( - viewEditModeScopedState, - viewScopeId, - ); - - const viewsState = getScopedStateDeprecated(viewsScopedState, viewScopeId); - - const viewObjectMetadataIdState = getScopedStateDeprecated( - viewObjectMetadataIdScopeState, - viewScopeId, - ); - - const viewTypeState = getScopedStateDeprecated( - viewTypeScopedState, - viewScopeId, - ); - - const entityCountInCurrentViewState = getScopedStateDeprecated( - entityCountInCurrentViewScopedState, - viewScopeId, - ); - - const isViewBarExpandedState = getScopedStateDeprecated( - isViewBarExpandedScopedState, - viewScopeId, - ); - - const isPersistingViewState = getScopedStateDeprecated( - isPersistingViewScopedState, - viewScopeId, - ); - - // ViewSorts - const currentViewSortsState = getScopedFamilyStateDeprecated( - currentViewSortsScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewSortsState = getScopedFamilyStateDeprecated( - savedViewSortsScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewSortsByKeySelector = savedViewSortsByKeyScopedFamilySelector({ - scopeId: viewScopeId, - viewId: viewId, - }); - - const availableSortDefinitionsState = getScopedStateDeprecated( - availableSortDefinitionsScopedState, - viewScopeId, - ); - - const canPersistSortsSelector = canPersistViewSortsScopedFamilySelector({ - viewScopeId: viewScopeId, - viewId: viewId, - }); - - // ViewFilters - const currentViewFiltersState = getScopedFamilyStateDeprecated( - currentViewFiltersScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewFiltersState = getScopedFamilyStateDeprecated( - savedViewFiltersScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewFiltersByKeySelector = - savedViewFiltersByKeyScopedFamilySelector({ - scopeId: viewScopeId, - viewId: viewId, - }); - - const availableFilterDefinitionsState = getScopedStateDeprecated( - availableFilterDefinitionsScopedState, - viewScopeId, - ); - - const canPersistFiltersSelector = canPersistViewFiltersScopedFamilySelector({ - viewScopeId: viewScopeId, - viewId: viewId, - }); - - // ViewFields - const availableFieldDefinitionsState = getScopedStateDeprecated( - availableFieldDefinitionsScopedState, - viewScopeId, - ); - - const currentViewFieldsState = getScopedFamilyStateDeprecated( - currentViewFieldsScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewFieldsState = getScopedFamilyStateDeprecated( - savedViewFieldsScopedFamilyState, - viewScopeId, - viewId, - ); - - const savedViewFieldsByKeySelector = savedViewFieldByKeyScopedFamilySelector({ - viewScopeId, - viewId, - }); - - // ViewChangeHandlers - const onViewSortsChangeState = getScopedStateDeprecated( - onViewSortsChangeScopedState, - viewScopeId, - ); - - const onViewFiltersChangeState = getScopedStateDeprecated( - onViewFiltersChangeScopedState, - viewScopeId, - ); - - const onViewFieldsChangeState = getScopedStateDeprecated( - onViewFieldsChangeScopedState, - viewScopeId, - ); - - const onViewTypeChangeState = getScopedStateDeprecated( - onViewTypeChangeScopedState, - viewScopeId, - ); - - const onViewCompactModeChangeState = getScopedStateDeprecated( - onViewCompactModeChangeScopeState, - viewScopeId, - ); - - const currentViewIdState = getScopedStateDeprecated( - currentViewIdScopedState, - viewScopeId, - ); - - const currentViewSelector = getScopedSelectorDeprecated( - currentViewComponentSelector, - viewScopeId, - ); - - return { - currentViewIdState, - currentViewSelector, - - isViewBarExpandedState, - isPersistingViewState, - - viewsState, - viewEditModeState, - viewObjectMetadataIdState, - viewTypeState, - entityCountInCurrentViewState, - - availableSortDefinitionsState, - currentViewSortsState, - savedViewSortsState, - savedViewSortsByKeySelector, - canPersistSortsSelector, - - availableFilterDefinitionsState, - currentViewFiltersState, - savedViewFiltersState, - savedViewFiltersByKeySelector, - canPersistFiltersSelector, - - availableFieldDefinitionsState, - currentViewFieldsState, - savedViewFieldsByKeySelector, - savedViewFieldsState, - - onViewSortsChangeState, - onViewFiltersChangeState, - onViewFieldsChangeState, - onViewTypeChangeState, - onViewCompactModeChangeState, - }; -}; diff --git a/packages/twenty-front/src/modules/views/utils/mapBoardFieldDefinitionsToViewFields.ts b/packages/twenty-front/src/modules/views/utils/mapBoardFieldDefinitionsToViewFields.ts index bf183ca0f8cc..873187cb0f73 100644 --- a/packages/twenty-front/src/modules/views/utils/mapBoardFieldDefinitionsToViewFields.ts +++ b/packages/twenty-front/src/modules/views/utils/mapBoardFieldDefinitionsToViewFields.ts @@ -1,5 +1,3 @@ -import { v4 } from 'uuid'; - import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { ViewField } from '@/views/types/ViewField'; @@ -9,7 +7,8 @@ export const mapBoardFieldDefinitionsToViewFields = ( ): ViewField[] => { return fieldsDefinitions.map( (fieldDefinition): ViewField => ({ - id: fieldDefinition.viewFieldId || v4(), + __typename: 'ViewField', + id: fieldDefinition.viewFieldId || '', fieldMetadataId: fieldDefinition.fieldMetadataId, size: 0, position: fieldDefinition.position, diff --git a/packages/twenty-front/src/modules/views/utils/mapColumnDefinitionToViewField.ts b/packages/twenty-front/src/modules/views/utils/mapColumnDefinitionToViewField.ts index 833c1a65b6e7..7b00889bbded 100644 --- a/packages/twenty-front/src/modules/views/utils/mapColumnDefinitionToViewField.ts +++ b/packages/twenty-front/src/modules/views/utils/mapColumnDefinitionToViewField.ts @@ -7,6 +7,7 @@ export const mapColumnDefinitionsToViewFields = ( columnDefinitions: ColumnDefinition[], ): ViewField[] => { return columnDefinitions.map((columnDefinition) => ({ + __typename: 'ViewField', id: columnDefinition.viewFieldId || '', fieldMetadataId: columnDefinition.fieldMetadataId, position: columnDefinition.position, diff --git a/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts b/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts index 8cca29540688..4df8f1e993fb 100644 --- a/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts +++ b/packages/twenty-front/src/modules/views/utils/mapViewFiltersToFilters.ts @@ -1,17 +1,29 @@ import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; +import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; +import { isDefined } from '~/utils/isDefined'; import { ViewFilter } from '../types/ViewFilter'; export const mapViewFiltersToFilters = ( viewFilters: ViewFilter[], + availableFilterDefinitions: FilterDefinition[], ): Filter[] => { - return viewFilters.map((viewFilter) => { - return { - fieldMetadataId: viewFilter.fieldMetadataId, - value: viewFilter.value, - displayValue: viewFilter.displayValue, - operand: viewFilter.operand, - definition: viewFilter.definition, - }; - }); + return viewFilters + .map((viewFilter) => { + const availableFilterDefinition = availableFilterDefinitions.find( + (filterDefinition) => + filterDefinition.fieldMetadataId === viewFilter.fieldMetadataId, + ); + + if (!availableFilterDefinition) return null; + + return { + fieldMetadataId: viewFilter.fieldMetadataId, + value: viewFilter.value, + displayValue: viewFilter.displayValue, + operand: viewFilter.operand, + definition: availableFilterDefinition, + }; + }) + .filter(isDefined); }; diff --git a/packages/twenty-front/src/modules/views/utils/mapViewSortsToSorts.ts b/packages/twenty-front/src/modules/views/utils/mapViewSortsToSorts.ts index 7ceec1a62242..34e8c2f07c4f 100644 --- a/packages/twenty-front/src/modules/views/utils/mapViewSortsToSorts.ts +++ b/packages/twenty-front/src/modules/views/utils/mapViewSortsToSorts.ts @@ -1,13 +1,26 @@ import { Sort } from '@/object-record/object-sort-dropdown/types/Sort'; +import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition'; +import { isDefined } from '~/utils/isDefined'; import { ViewSort } from '../types/ViewSort'; -export const mapViewSortsToSorts = (viewSorts: ViewSort[]): Sort[] => { - return viewSorts.map((viewSort) => { - return { - fieldMetadataId: viewSort.fieldMetadataId, - direction: viewSort.direction, - definition: viewSort.definition, - }; - }); +export const mapViewSortsToSorts = ( + viewSorts: ViewSort[], + availableSortDefinitions: SortDefinition[], +): Sort[] => { + return viewSorts + .map((viewSort) => { + const availableSortDefinition = availableSortDefinitions.find( + (sortDefinition) => + sortDefinition.fieldMetadataId === viewSort.fieldMetadataId, + ); + + if (!availableSortDefinition) return null; + return { + fieldMetadataId: viewSort.fieldMetadataId, + direction: viewSort.direction, + definition: availableSortDefinition, + }; + }) + .filter(isDefined); }; diff --git a/packages/twenty-front/src/modules/workspace/hooks/useIsFeatureEnabled.ts b/packages/twenty-front/src/modules/workspace/hooks/useIsFeatureEnabled.ts index ac3786d375d8..31906107de82 100644 --- a/packages/twenty-front/src/modules/workspace/hooks/useIsFeatureEnabled.ts +++ b/packages/twenty-front/src/modules/workspace/hooks/useIsFeatureEnabled.ts @@ -4,7 +4,7 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { FeatureFlagKey } from '@/workspace/types/FeatureFlagKey'; export const useIsFeatureEnabled = (featureKey: FeatureFlagKey) => { - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const featureFlag = currentWorkspace?.featureFlags?.find( (flag) => flag.key === featureKey, diff --git a/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx b/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx index 235eefd8dfc2..2cb36de502e1 100644 --- a/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx +++ b/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx @@ -43,7 +43,7 @@ const StyledBenefitsContainer = styled.div` `; export const ChooseYourPlan = () => { - const billing = useRecoilValue(billingState()); + const billing = useRecoilValue(billingState); const [planSelected, setPlanSelected] = useState('month'); diff --git a/packages/twenty-front/src/pages/auth/CreateProfile.tsx b/packages/twenty-front/src/pages/auth/CreateProfile.tsx index 554c14beabda..edbaa99bcfcf 100644 --- a/packages/twenty-front/src/pages/auth/CreateProfile.tsx +++ b/packages/twenty-front/src/pages/auth/CreateProfile.tsx @@ -58,7 +58,7 @@ export const CreateProfile = () => { const { enqueueSnackBar } = useSnackBar(); const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); const { updateOneRecord } = useUpdateOneRecord({ diff --git a/packages/twenty-front/src/pages/auth/VerifyEffect.tsx b/packages/twenty-front/src/pages/auth/VerifyEffect.tsx index c4ba1c21b7f1..cda60b1bc447 100644 --- a/packages/twenty-front/src/pages/auth/VerifyEffect.tsx +++ b/packages/twenty-front/src/pages/auth/VerifyEffect.tsx @@ -10,7 +10,7 @@ import { AppPath } from '@/types/AppPath'; export const VerifyEffect = () => { const [searchParams] = useSearchParams(); const loginToken = searchParams.get('loginToken'); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); const isLogged = useIsLogged(); const navigate = useNavigate(); diff --git a/packages/twenty-front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx b/packages/twenty-front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx index 1d1fe2f84172..61d2f8316fb8 100644 --- a/packages/twenty-front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx +++ b/packages/twenty-front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx @@ -21,7 +21,7 @@ const meta: Meta = { component: CreateWorkspace, decorators: [ (Story) => { - const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState()); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); setCurrentWorkspace(mockedOnboardingUsersData[1].defaultWorkspace); return ; }, diff --git a/packages/twenty-front/src/pages/impersonate/ImpersonateEffect.tsx b/packages/twenty-front/src/pages/impersonate/ImpersonateEffect.tsx index d8973a776fad..897ab095fc2f 100644 --- a/packages/twenty-front/src/pages/impersonate/ImpersonateEffect.tsx +++ b/packages/twenty-front/src/pages/impersonate/ImpersonateEffect.tsx @@ -14,8 +14,8 @@ export const ImpersonateEffect = () => { const navigate = useNavigate(); const { userId } = useParams(); - const [currentUser, setCurrentUser] = useRecoilState(currentUserState()); - const setTokenPair = useSetRecoilState(tokenPairState()); + const [currentUser, setCurrentUser] = useRecoilState(currentUserState); + const setTokenPair = useSetRecoilState(tokenPairState); const [impersonate] = useImpersonateMutation(); diff --git a/packages/twenty-front/src/pages/object-record/RecordIndexPageHeader.tsx b/packages/twenty-front/src/pages/object-record/RecordIndexPageHeader.tsx index 0ea96ca435df..fd24ab76f1b3 100644 --- a/packages/twenty-front/src/pages/object-record/RecordIndexPageHeader.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordIndexPageHeader.tsx @@ -27,7 +27,7 @@ export const RecordIndexPageHeader = ({ findObjectMetadataItemByNamePlural(objectNamePlural)?.icon, ); - const recordIndexViewType = useRecoilValue(recordIndexViewTypeState()); + const recordIndexViewType = useRecoilValue(recordIndexViewTypeState); return ( diff --git a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx index 48345f869ec1..bd63e8978ab5 100644 --- a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx @@ -42,8 +42,8 @@ export const SettingsWorkspaceMembers = () => { const { deleteOneRecord: deleteOneWorkspaceMember } = useDeleteOneRecord({ objectNameSingular: CoreObjectNameSingular.WorkspaceMember, }); - const currentWorkspace = useRecoilValue(currentWorkspaceState()); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspace = useRecoilValue(currentWorkspaceState); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const handleRemoveWorkspaceMember = async (workspaceMemberId: string) => { await deleteOneWorkspaceMember?.(workspaceMemberId); diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx index 6b66c48261a1..72576db59f1f 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx @@ -14,7 +14,7 @@ import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { SettingsAccountLoader } from '~/pages/settings/accounts/SettingsAccountLoader'; export const SettingsAccounts = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { records: accounts, loading } = useFindManyRecords({ objectNameSingular: 'connectedAccount', diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx index d4960b0731bb..8fb0cb66e118 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx @@ -21,7 +21,7 @@ import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; import { mockedConnectedAccounts } from '~/testing/mock-data/accounts'; export const SettingsAccountsCalendars = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { records: _accounts } = useFindManyRecords({ objectNameSingular: CoreObjectNameSingular.ConnectedAccount, filter: { diff --git a/packages/twenty-front/src/pages/tasks/TasksEffect.tsx b/packages/twenty-front/src/pages/tasks/TasksEffect.tsx index 5c503edcd0eb..c3d5e2daf743 100644 --- a/packages/twenty-front/src/pages/tasks/TasksEffect.tsx +++ b/packages/twenty-front/src/pages/tasks/TasksEffect.tsx @@ -13,7 +13,7 @@ type TasksEffectProps = { }; export const TasksEffect = ({ filterDropdownId }: TasksEffectProps) => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState()); + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const { setSelectedFilter, setAvailableFilterDefinitions, diff --git a/packages/twenty-front/src/testing/decorators/ObjectMetadataItemsDecorator.tsx b/packages/twenty-front/src/testing/decorators/ObjectMetadataItemsDecorator.tsx index ec961a8700f4..a657c9953803 100644 --- a/packages/twenty-front/src/testing/decorators/ObjectMetadataItemsDecorator.tsx +++ b/packages/twenty-front/src/testing/decorators/ObjectMetadataItemsDecorator.tsx @@ -8,9 +8,9 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; export const ObjectMetadataItemsDecorator: Decorator = (Story) => { - const objectMetadataItems = useRecoilValue(objectMetadataItemsState()); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState(), + currentWorkspaceMemberState, ); useEffect( diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts index 37429daf75ab..85c4b0ca6601 100644 --- a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts +++ b/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import groupBy from 'lodash.groupBy'; +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'; diff --git a/yarn.lock b/yarn.lock index f8806b2b7af7..bfb3bdf8a68d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33367,6 +33367,13 @@ __metadata: languageName: node linkType: hard +"lodash.groupby@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.groupby@npm:4.6.0" + checksum: 3d136cad438ad6c3a078984ef60e057a3498b1312aa3621b00246ecb99e8f2c4d447e2815460db7a0b661a4fe4e2eeee96c84cb661a824bad04b6cf1f7bc6e9b + languageName: node + linkType: hard + "lodash.includes@npm:^4.3.0": version: 4.3.0 resolution: "lodash.includes@npm:4.3.0" @@ -46010,6 +46017,7 @@ __metadata: libphonenumber-js: "npm:^1.10.26" lodash.camelcase: "npm:^4.3.0" lodash.debounce: "npm:^4.0.8" + lodash.groupby: "npm:^4.6.0" lodash.isempty: "npm:^4.4.0" lodash.isequal: "npm:^4.5.0" lodash.isobject: "npm:^3.0.2" From 352192a63f7bd18f760d8b6493b825b45940eb0c Mon Sep 17 00:00:00 2001 From: Anoop P <44577841+anoopw3bdev@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:55:05 +0530 Subject: [PATCH 31/44] fix: add missing package lodash.groupby (#4579) * fix: add missing package * fix: typo in case From da12710fe99cd2e89faddf90d1b6c97c4f301d4a Mon Sep 17 00:00:00 2001 From: Aditya Pimpalkar Date: Wed, 20 Mar 2024 13:43:41 +0000 Subject: [PATCH 32/44] feat: multi-workspace (frontend) (#4232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * select workspace component * generateJWT mutation * workspaces state and hooks * requested changes * mutation fix * requested changes * user workpsace delete call * migration to drop and createt user workspace * revert select props * add DropdownMenu * seperate multi-workspace dropdown as component * Signup button displayed accurately * update seed data for multi-workspace * lint fix * lint fix * css fix * lint fix * state fix * isDefined check * refactor * add default workspace constants for logo and name * update migration * lint fix * isInviteMode check on sign-in/up * removeWorkspaceMember mutation * import fixes * prop name fix * backfill migration * handle edge cases * refactor * remove migration query * delete user on no-workspace found condition * emit workspaceMember.deleted * Fix event class and unrelated fix linked to a previously missing dependency * Edit migration (I did it in prod manually) * Revert changes * Fix tests * Fix conflicts --------- Co-authored-by: Félix Malfait --- package.json | 1 + .../twenty-front/src/generated/graphql.tsx | 100 ++++++++++++- .../auth/graphql/mutations/generateJWT.ts | 11 ++ .../src/modules/auth/hooks/useAuth.ts | 12 ++ .../sign-in-up/components/SignInUpForm.tsx | 5 +- .../auth/sign-in-up/hooks/useSignInUp.tsx | 27 ++-- .../src/modules/auth/states/workspaces.ts | 9 ++ .../MultiWorkspaceDropdownButton.tsx | 124 ++++++++++++++++ .../components/NavigationDrawerHeader.tsx | 21 ++- .../constants/DefaultWorkspaceLogo.ts | 2 + .../constants/DefaultWorkspaceName.ts | 1 + .../constants/MulitWorkspaceDropdownId.ts | 1 + .../hooks/useWorkspaceSwitching.ts | 38 +++++ .../types/NavigationDrawerHotKeyScope.ts | 3 + .../modules/users/components/UserProvider.tsx | 17 ++- .../graphql/fragments/userQueryFragment.ts | 8 ++ .../data-seed-dev-workspace.command.ts | 133 ++++++++++-------- .../typeorm-seeds/core/userWorkspaces.ts | 34 ++++- .../database/typeorm-seeds/core/workspaces.ts | 45 ++++-- .../workspace/workspaceMember.ts | 63 +++++++-- .../1707778127558-addUserWorkspaces.ts | 4 - ...88-updateUserWorkspaceColumnConstraints.ts | 44 ++++++ .../utils/__tests__/fields.utils.spec.ts | 4 +- .../user/services/user.service.spec.ts | 5 + .../modules/user/services/user.service.ts | 5 + .../services/workspace.service.spec.ts | 4 +- .../workspace/services/workspace.service.ts | 120 +++++++++++++++- .../modules/workspace/workspace.module.ts | 11 +- yarn.lock | 10 ++ 29 files changed, 727 insertions(+), 135 deletions(-) create mode 100644 packages/twenty-front/src/modules/auth/graphql/mutations/generateJWT.ts create mode 100644 packages/twenty-front/src/modules/auth/states/workspaces.ts create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo.ts create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName.ts create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/constants/MulitWorkspaceDropdownId.ts create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching.ts create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/types/NavigationDrawerHotKeyScope.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/1709680520888-updateUserWorkspaceColumnConstraints.ts diff --git a/package.json b/package.json index da21618c9743..f7e14be3a000 100644 --- a/package.json +++ b/package.json @@ -230,6 +230,7 @@ "@types/js-cookie": "^3.0.3", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.debounce": "^4.0.7", + "@types/lodash.groupby": "^4.6.9", "@types/lodash.isempty": "^4.4.7", "@types/lodash.isequal": "^4.5.7", "@types/lodash.isobject": "^3.0.7", diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 43192e2bc9ab..1c89af101e9b 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -254,6 +254,7 @@ export type Mutation = { generateJWT: AuthTokens; generateTransientToken: TransientToken; impersonate: Verify; + removeWorkspaceMember: Scalars['String']; renewToken: AuthTokens; signUp: LoginToken; track: Analytics; @@ -311,6 +312,11 @@ export type MutationImpersonateArgs = { }; +export type MutationRemoveWorkspaceMemberArgs = { + memberId: Scalars['String']; +}; + + export type MutationRenewTokenArgs = { refreshToken: Scalars['String']; }; @@ -953,6 +959,13 @@ export type GenerateApiKeyTokenMutationVariables = Exact<{ export type GenerateApiKeyTokenMutation = { __typename?: 'Mutation', generateApiKeyToken: { __typename?: 'ApiKeyToken', token: string } }; +export type GenerateJwtMutationVariables = Exact<{ + workspaceId: Scalars['String']; +}>; + + +export type GenerateJwtMutation = { __typename?: 'Mutation', generateJWT: { __typename?: 'AuthTokens', tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; + export type GenerateTransientTokenMutationVariables = Exact<{ [key: string]: never; }>; @@ -963,7 +976,7 @@ export type ImpersonateMutationVariables = Exact<{ }>; -export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; export type RenewTokenMutationVariables = Exact<{ refreshToken: Scalars['String']; @@ -994,7 +1007,7 @@ export type VerifyMutationVariables = Exact<{ }>; -export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; export type CheckUserExistsQueryVariables = Exact<{ email: Scalars['String']; @@ -1053,7 +1066,7 @@ export type UploadImageMutationVariables = Exact<{ export type UploadImageMutation = { __typename?: 'Mutation', uploadImage: string }; -export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }; +export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }; export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>; @@ -1072,6 +1085,13 @@ export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', status: string } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null } | null }> } }; +export type RemoveWorkspaceMemberMutationVariables = Exact<{ + memberId: Scalars['String']; +}>; + + +export type RemoveWorkspaceMemberMutation = { __typename?: 'Mutation', removeWorkspaceMember: string }; + export type ActivateWorkspaceMutationVariables = Exact<{ input: ActivateWorkspaceInput; }>; @@ -1232,6 +1252,14 @@ export const UserQueryFragmentFragmentDoc = gql` workspaceId } } + workspaces { + workspace { + id + logo + displayName + domainName + } + } } `; export const GetTimelineCalendarEventsFromCompanyIdDocument = gql` @@ -1535,6 +1563,41 @@ export function useGenerateApiKeyTokenMutation(baseOptions?: Apollo.MutationHook export type GenerateApiKeyTokenMutationHookResult = ReturnType; export type GenerateApiKeyTokenMutationResult = Apollo.MutationResult; export type GenerateApiKeyTokenMutationOptions = Apollo.BaseMutationOptions; +export const GenerateJwtDocument = gql` + mutation GenerateJWT($workspaceId: String!) { + generateJWT(workspaceId: $workspaceId) { + tokens { + ...AuthTokensFragment + } + } +} + ${AuthTokensFragmentFragmentDoc}`; +export type GenerateJwtMutationFn = Apollo.MutationFunction; + +/** + * __useGenerateJwtMutation__ + * + * To run a mutation, you first call `useGenerateJwtMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useGenerateJwtMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [generateJwtMutation, { data, loading, error }] = useGenerateJwtMutation({ + * variables: { + * workspaceId: // value for 'workspaceId' + * }, + * }); + */ +export function useGenerateJwtMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(GenerateJwtDocument, options); + } +export type GenerateJwtMutationHookResult = ReturnType; +export type GenerateJwtMutationResult = Apollo.MutationResult; +export type GenerateJwtMutationOptions = Apollo.BaseMutationOptions; export const GenerateTransientTokenDocument = gql` mutation generateTransientToken { generateTransientToken { @@ -2202,6 +2265,37 @@ export function useGetCurrentUserLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt export type GetCurrentUserQueryHookResult = ReturnType; export type GetCurrentUserLazyQueryHookResult = ReturnType; export type GetCurrentUserQueryResult = Apollo.QueryResult; +export const RemoveWorkspaceMemberDocument = gql` + mutation RemoveWorkspaceMember($memberId: String!) { + removeWorkspaceMember(memberId: $memberId) +} + `; +export type RemoveWorkspaceMemberMutationFn = Apollo.MutationFunction; + +/** + * __useRemoveWorkspaceMemberMutation__ + * + * To run a mutation, you first call `useRemoveWorkspaceMemberMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useRemoveWorkspaceMemberMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [removeWorkspaceMemberMutation, { data, loading, error }] = useRemoveWorkspaceMemberMutation({ + * variables: { + * memberId: // value for 'memberId' + * }, + * }); + */ +export function useRemoveWorkspaceMemberMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(RemoveWorkspaceMemberDocument, options); + } +export type RemoveWorkspaceMemberMutationHookResult = ReturnType; +export type RemoveWorkspaceMemberMutationResult = Apollo.MutationResult; +export type RemoveWorkspaceMemberMutationOptions = Apollo.BaseMutationOptions; export const ActivateWorkspaceDocument = gql` mutation ActivateWorkspace($input: ActivateWorkspaceInput!) { activateWorkspace(data: $input) { diff --git a/packages/twenty-front/src/modules/auth/graphql/mutations/generateJWT.ts b/packages/twenty-front/src/modules/auth/graphql/mutations/generateJWT.ts new file mode 100644 index 000000000000..7f7d19ae71be --- /dev/null +++ b/packages/twenty-front/src/modules/auth/graphql/mutations/generateJWT.ts @@ -0,0 +1,11 @@ +import { gql } from '@apollo/client'; + +export const GENERATE_JWT = gql` + mutation GenerateJWT($workspaceId: String!) { + generateJWT(workspaceId: $workspaceId) { + tokens { + ...AuthTokensFragment + } + } + } +`; diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index a39d49bcd19b..5f6e97ea77e6 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -11,6 +11,7 @@ import { import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState'; +import { workspacesState } from '@/auth/states/workspaces'; import { authProvidersState } from '@/client-config/states/authProvidersState'; import { billingState } from '@/client-config/states/billingState'; import { isDebugModeState } from '@/client-config/states/isDebugModeState'; @@ -40,6 +41,7 @@ export const useAuth = () => { const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState); + const setWorkspaces = useSetRecoilState(workspacesState); const [challenge] = useChallengeMutation(); const [signUp] = useSignUpMutation(); @@ -101,6 +103,15 @@ export const useAuth = () => { } const workspace = user.defaultWorkspace ?? null; setCurrentWorkspace(workspace); + if (isDefined(verifyResult.data?.verify.user.workspaces)) { + const validWorkspaces = verifyResult.data?.verify.user.workspaces + .filter( + ({ workspace }) => workspace !== null && workspace !== undefined, + ) + .map((validWorkspace) => validWorkspace.workspace!); + + setWorkspaces(validWorkspaces); + } return { user, workspaceMember, @@ -114,6 +125,7 @@ export const useAuth = () => { setCurrentUser, setCurrentWorkspaceMember, setCurrentWorkspace, + setWorkspaces, ], ); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx index bc1997f2d483..6b2c5f2362cd 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx @@ -54,6 +54,7 @@ export const SignInUpForm = () => { const { form } = useSignInUpForm(); const { + isInviteMode, signInUpStep, signInUpMode, continueWithCredentials, @@ -89,14 +90,14 @@ export const SignInUpForm = () => { }, [signInUpMode, signInUpStep]); const title = useMemo(() => { - if (signInUpMode === SignInUpMode.Invite) { + if (isInviteMode) { return `Join ${workspace?.displayName ?? ''} team`; } return signInUpMode === SignInUpMode.SignIn ? 'Sign in to Twenty' : 'Sign up to Twenty'; - }, [signInUpMode, workspace?.displayName]); + }, [signInUpMode, workspace?.displayName, isInviteMode]); const theme = useTheme(); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx index cbc4d5192b08..5433e8f0d2be 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx @@ -15,7 +15,6 @@ import { useAuth } from '../../hooks/useAuth'; export enum SignInUpMode { SignIn = 'sign-in', SignUp = 'sign-up', - Invite = 'invite', } export enum SignInUpStep { @@ -33,15 +32,13 @@ export const useSignInUp = (form: UseFormReturn) => { const { navigateAfterSignInUp } = useNavigateAfterSignInUp(); + const [isInviteMode] = useState(() => isMatchingLocation(AppPath.Invite)); + const [signInUpStep, setSignInUpStep] = useState( SignInUpStep.Init, ); const [signInUpMode, setSignInUpMode] = useState(() => { - if (isMatchingLocation(AppPath.Invite)) { - return SignInUpMode.Invite; - } - return isMatchingLocation(AppPath.SignIn) ? SignInUpMode.SignIn : SignInUpMode.SignUp; @@ -72,24 +69,14 @@ export const useSignInUp = (form: UseFormReturn) => { }, onCompleted: (data) => { if (data?.checkUserExists.exists) { - isMatchingLocation(AppPath.Invite) - ? setSignInUpMode(SignInUpMode.Invite) - : setSignInUpMode(SignInUpMode.SignIn); + setSignInUpMode(SignInUpMode.SignIn); } else { - isMatchingLocation(AppPath.Invite) - ? setSignInUpMode(SignInUpMode.Invite) - : setSignInUpMode(SignInUpMode.SignUp); + setSignInUpMode(SignInUpMode.SignUp); } setSignInUpStep(SignInUpStep.Password); }, }); - }, [ - isMatchingLocation, - setSignInUpStep, - checkUserExistsQuery, - form, - setSignInUpMode, - ]); + }, [setSignInUpStep, checkUserExistsQuery, form, setSignInUpMode]); const submitCredentials: SubmitHandler = useCallback( async (data) => { @@ -102,7 +89,7 @@ export const useSignInUp = (form: UseFormReturn) => { workspace: currentWorkspace, workspaceMember: currentWorkspaceMember, } = - signInUpMode === SignInUpMode.SignIn + signInUpMode === SignInUpMode.SignIn && !isInviteMode ? await signInWithCredentials( data.email.toLowerCase().trim(), data.password, @@ -122,6 +109,7 @@ export const useSignInUp = (form: UseFormReturn) => { }, [ signInUpMode, + isInviteMode, signInWithCredentials, signUpWithCredentials, workspaceInviteHash, @@ -156,6 +144,7 @@ export const useSignInUp = (form: UseFormReturn) => { ); return { + isInviteMode, signInUpStep, signInUpMode, continueWithCredentials, diff --git a/packages/twenty-front/src/modules/auth/states/workspaces.ts b/packages/twenty-front/src/modules/auth/states/workspaces.ts new file mode 100644 index 000000000000..dc0be614a72b --- /dev/null +++ b/packages/twenty-front/src/modules/auth/states/workspaces.ts @@ -0,0 +1,9 @@ +import { createState } from '@/ui/utilities/state/utils/createState'; +import { Workspace } from '~/generated/graphql'; + +export type Workspaces = Pick; + +export const workspacesState = createState({ + key: 'workspacesState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx new file mode 100644 index 000000000000..04e3217db7de --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton.tsx @@ -0,0 +1,124 @@ +import { useState } from 'react'; +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { useRecoilValue } from 'recoil'; + +import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { Workspaces } from '@/auth/states/workspaces'; +import { IconChevronDown } from '@/ui/display/icon'; +import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; +import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; +import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar'; +import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo'; +import { MULTI_WORKSPACE_DROPDOWN_ID } from '@/ui/navigation/navigation-drawer/constants/MulitWorkspaceDropdownId'; +import { useWorkspaceSwitching } from '@/ui/navigation/navigation-drawer/hooks/useWorkspaceSwitching'; +import { NavigationDrawerHotKeyScope } from '@/ui/navigation/navigation-drawer/types/NavigationDrawerHotKeyScope'; + +const StyledLogo = styled.div<{ logo: string }>` + background: url(${({ logo }) => logo}); + background-position: center; + background-size: cover; + border-radius: ${({ theme }) => theme.border.radius.xs}; + height: 16px; + width: 16px; +`; + +const StyledContainer = styled.div` + align-items: center; + cursor: pointer; + color: ${({ theme }) => theme.font.color.primary}; + border-radius: ${({ theme }) => theme.border.radius.sm}; + border: 1px solid transparent; + display: flex; + justify-content: space-between; + height: ${({ theme }) => theme.spacing(7)}; + padding: 0 ${({ theme }) => theme.spacing(2)}; + width: 100%; + + &:hover { + background-color: ${({ theme }) => theme.background.transparent.lighter}; + border: 1px solid ${({ theme }) => theme.border.color.medium}; + } +`; + +const StyledLabel = styled.div` + align-items: center; + display: flex; + gap: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledIconChevronDown = styled(IconChevronDown)<{ disabled?: boolean }>` + color: ${({ disabled, theme }) => + disabled ? theme.font.color.extraLight : theme.font.color.tertiary}; +`; + +type MultiWorkspaceDropdownButtonProps = { + workspaces: Workspaces[]; +}; + +export const MultiWorkspaceDropdownButton = ({ + workspaces, +}: MultiWorkspaceDropdownButtonProps) => { + const theme = useTheme(); + const currentWorkspace = useRecoilValue(currentWorkspaceState); + + const [isMultiWorkspaceDropdownOpen, setToggleMultiWorkspaceDropdown] = + useState(false); + + const { switchWorkspace } = useWorkspaceSwitching(); + + const { closeDropdown } = useDropdown(MULTI_WORKSPACE_DROPDOWN_ID); + + const handleChange = async (workspaceId: string) => { + setToggleMultiWorkspaceDropdown(!isMultiWorkspaceDropdownOpen); + closeDropdown(); + await switchWorkspace(workspaceId); + }; + + return ( + + + {currentWorkspace?.displayName ?? ''} + + + } + dropdownComponents={ + + {workspaces.map((workspace) => ( + + } + selected={currentWorkspace?.id === workspace.id} + onClick={() => handleChange(workspace.id)} + /> + ))} + + } + /> + ); +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx index 568fbb4b6b85..eae27e8c73d3 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx @@ -1,5 +1,10 @@ import styled from '@emotion/styled'; +import { useRecoilValue } from 'recoil'; +import { workspacesState } from '@/auth/states/workspaces'; +import { MultiWorkspaceDropdownButton } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdownButton'; +import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo'; +import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { NavigationDrawerCollapseButton } from './NavigationDrawerCollapseButton'; @@ -44,16 +49,24 @@ type NavigationDrawerHeaderProps = { }; export const NavigationDrawerHeader = ({ - name = 'Twenty', - logo = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACb0lEQVR4nO2VO4taQRTHr3AblbjxEVlwCwVhg7BoqqCIjy/gAyyFWNlYBOxsfH0KuxgQGwXRUkGuL2S7i1barGAgiwbdW93SnGOc4BonPiKahf3DwXFmuP/fPM4ZlvmlTxAhCBdzHnEQWYiv7Mr4C3NeuVYhQYDPzOUUQgDLBQGcLHNhvQK8DACPx8PTxiqVyvISG43GbyaT6Qfpn06n0m63e/tPAPF4vJ1MJu8kEsnWTCkWi1yr1RKGw+GDRqPBOTfr44vFQvD7/Q/lcpmaaVQAr9fLp1IpO22c47hGOBz+MB6PH+Vy+VYDAL8qlUoGtVotzOfzq4MAgsHgE/6KojiQyWR/bKVSqbSszHFM8Pl8z1YK48JsNltCOBwOnrYLO+8AAIjb+nHbycoTiUQfDJ7tFq4YAHiVSmXBxcD41u8flQU8z7fhzO0r83atVns3Go3u9Xr9x0O/RQXo9/tsIBBg6vX606a52Wz+bZ7P5/WwG29gxSJzhKgA6XTaDoFNF+krFAocmC//4yWEcSf2wTm7mCO19xFgSsKOLI16vV7b7XY7mRNoLwA0JymJ5uQIzgIAuX5PzDElT2m+E8BqtQ4ymcx7Yq7T6a6ZE4sKgOadTucaCwkxp1UzlEKh0GDxIXOwDWHAdi6Xe3swQDQa/Q7mywoolUpvsaptymazDWKxmBHTlWXZm405BFZoNpuGgwEmk4mE2SGtVivii4f1AO7J3ZopkQCQj7Ar1FeRChCJRJzVapX6DKNIfSc1Ax+wtQWQ55h6bH8FWDfYV4fO3wlwDr0C/BcADYiTPCxHqIEA2QsCZAkAKnRGkMbKN/sTX5YHPQ1e7SkAAAAASUVORK5CYII=', + name = DEFAULT_WORKSPACE_NAME, + logo = DEFAULT_WORKSPACE_LOGO, showCollapseButton, }: NavigationDrawerHeaderProps) => { const isMobile = useIsMobile(); + const workspaces = useRecoilValue(workspacesState); return ( - - {name} + {workspaces !== null && workspaces.length > 1 ? ( + + ) : ( + <> + + {name} + + )} + {!isMobile && ( { + const navigate = useNavigate(); + const setTokenPair = useSetRecoilState(tokenPairState); + const [generateJWT] = useGenerateJwtMutation(); + const currentWorkspace = useRecoilValue(currentWorkspaceState); + + const switchWorkspace = async (workspaceId: string) => { + if (currentWorkspace?.id === workspaceId) return; + const jwt = await generateJWT({ + variables: { + workspaceId, + }, + }); + + if (isDefined(jwt.errors)) { + throw jwt.errors; + } + + if (!isDefined(jwt.data?.generateJWT)) { + throw new Error('could not create token'); + } + + const { tokens } = jwt.data.generateJWT; + setTokenPair(tokens); + navigate(`/objects/companies`); + window.location.reload(); + }; + + return { switchWorkspace }; +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/types/NavigationDrawerHotKeyScope.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/types/NavigationDrawerHotKeyScope.ts new file mode 100644 index 000000000000..834b5d50ea56 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/types/NavigationDrawerHotKeyScope.ts @@ -0,0 +1,3 @@ +export enum NavigationDrawerHotKeyScope { + MultiWorkspaceDropdownButton = 'multi-workspace-dropdown', +} diff --git a/packages/twenty-front/src/modules/users/components/UserProvider.tsx b/packages/twenty-front/src/modules/users/components/UserProvider.tsx index aa0af98a25d9..43e5f04e617e 100644 --- a/packages/twenty-front/src/modules/users/components/UserProvider.tsx +++ b/packages/twenty-front/src/modules/users/components/UserProvider.tsx @@ -1,10 +1,11 @@ -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useQuery } from '@apollo/client'; import { useSetRecoilState } from 'recoil'; import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { Workspaces, workspacesState } from '@/auth/states/workspaces'; import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser'; import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; import { isDefined } from '~/utils/isDefined'; @@ -14,6 +15,7 @@ export const UserProvider = ({ children }: React.PropsWithChildren) => { const setCurrentUser = useSetRecoilState(currentUserState); const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); + const setWorkspaces = useSetRecoilState(workspacesState); const setCurrentWorkspaceMember = useSetRecoilState( currentWorkspaceMemberState, @@ -36,12 +38,25 @@ export const UserProvider = ({ children }: React.PropsWithChildren) => { colorScheme: (workspaceMember.colorScheme as ColorScheme) ?? 'Light', }); } + if (isDefined(queryData?.currentUser?.workspaces)) { + const validWorkspaces = queryData.currentUser.workspaces.filter( + (obj: any) => obj.workspace !== null && obj.workspace !== undefined, + ); + const workspaces: Workspaces[] = []; + validWorkspaces.forEach((validWorkspace: any) => { + const workspace = validWorkspace.workspace! as Workspaces; + workspaces.push(workspace); + }); + + setWorkspaces(workspaces); + } }, [ setCurrentUser, isLoading, queryLoading, setCurrentWorkspace, setCurrentWorkspaceMember, + setWorkspaces, queryData?.currentUser, ]); diff --git a/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts b/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts index a19b5ff18f16..bd02380fae6b 100644 --- a/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts +++ b/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts @@ -34,5 +34,13 @@ export const USER_QUERY_FRAGMENT = gql` workspaceId } } + workspaces { + workspace { + id + logo + displayName + domainName + } + } } `; diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index b038227318ec..97a012d18cfa 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -15,6 +15,10 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { + SeedAppleWorkspaceId, + SeedTwentyWorkspaceId, +} from 'src/database/typeorm-seeds/core/workspaces'; // TODO: implement dry-run @Command({ @@ -23,7 +27,7 @@ import { EnvironmentService } from 'src/engine/integrations/environment/environm 'Seed workspace with initial data. This command is intended for development only.', }) export class DataSeedWorkspaceCommand extends CommandRunner { - workspaceId = '20202020-1c25-4d02-bf25-6aeccf7ea419'; + workspaceIds = [SeedAppleWorkspaceId, SeedTwentyWorkspaceId]; constructor( private readonly environmentService: EnvironmentService, @@ -45,79 +49,88 @@ export class DataSeedWorkspaceCommand extends CommandRunner { schema: 'core', }); - await dataSource.initialize(); + for (const workspaceId of this.workspaceIds) { + await dataSource.initialize(); - await seedCoreSchema(dataSource, this.workspaceId); + await seedCoreSchema(dataSource, workspaceId); - await dataSource.destroy(); + await dataSource.destroy(); - const schemaName = - await this.workspaceDataSourceService.createWorkspaceDBSchema( - this.workspaceId, - ); + const schemaName = + await this.workspaceDataSourceService.createWorkspaceDBSchema( + workspaceId, + ); - const dataSourceMetadata = - await this.dataSourceService.createDataSourceMetadata( - this.workspaceId, - schemaName, - ); + const dataSourceMetadata = + await this.dataSourceService.createDataSourceMetadata( + workspaceId, + schemaName, + ); - await this.workspaceSyncMetadataService.synchronize({ - workspaceId: this.workspaceId, - dataSourceId: dataSourceMetadata.id, - }); + await this.workspaceSyncMetadataService.synchronize({ + workspaceId: workspaceId, + dataSourceId: dataSourceMetadata.id, + }); + } } catch (error) { console.error(error); return; } - const dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( - this.workspaceId, - ); - - const workspaceDataSource = - await this.typeORMService.connectToDataSource(dataSourceMetadata); + for (const workspaceId of this.workspaceIds) { + const dataSourceMetadata = + await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( + workspaceId, + ); - if (!workspaceDataSource) { - throw new Error('Could not connect to workspace data source'); - } + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); + + if (!workspaceDataSource) { + throw new Error('Could not connect to workspace data source'); + } + + try { + const objectMetadata = + await this.objectMetadataService.findManyWithinWorkspace(workspaceId); + const objectMetadataMap = objectMetadata.reduce((acc, object) => { + acc[object.nameSingular] = { + id: object.id, + fields: object.fields.reduce((acc, field) => { + acc[field.name] = field.id; + + return acc; + }, {}), + }; + + return acc; + }, {}); + + await seedCompanies(workspaceDataSource, dataSourceMetadata.schema); + await seedPeople(workspaceDataSource, dataSourceMetadata.schema); + await seedPipelineStep(workspaceDataSource, dataSourceMetadata.schema); + await seedOpportunity(workspaceDataSource, dataSourceMetadata.schema); + await seedCalendarEvents( + workspaceDataSource, + dataSourceMetadata.schema, + ); - try { - const objectMetadata = - await this.objectMetadataService.findManyWithinWorkspace( - this.workspaceId, + await seedViews( + workspaceDataSource, + dataSourceMetadata.schema, + objectMetadataMap, ); - const objectMetadataMap = objectMetadata.reduce((acc, object) => { - acc[object.nameSingular] = { - id: object.id, - fields: object.fields.reduce((acc, field) => { - acc[field.name] = field.id; - - return acc; - }, {}), - }; - - return acc; - }, {}); - - await seedCompanies(workspaceDataSource, dataSourceMetadata.schema); - await seedPeople(workspaceDataSource, dataSourceMetadata.schema); - await seedPipelineStep(workspaceDataSource, dataSourceMetadata.schema); - await seedOpportunity(workspaceDataSource, dataSourceMetadata.schema); - await seedCalendarEvents(workspaceDataSource, dataSourceMetadata.schema); - - await seedViews( - workspaceDataSource, - dataSourceMetadata.schema, - objectMetadataMap, - ); - await seedWorkspaceMember(workspaceDataSource, dataSourceMetadata.schema); - } catch (error) { - console.error(error); - } + await seedWorkspaceMember( + workspaceDataSource, + dataSourceMetadata.schema, + workspaceId, + ); + } catch (error) { + console.error(error); + } - await this.typeORMService.disconnectFromDataSource(dataSourceMetadata.id); + await this.typeORMService.disconnectFromDataSource(dataSourceMetadata.id); + } } } diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts b/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts index 39b2771825d9..f3902d95c580 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts @@ -1,5 +1,11 @@ import { DataSource } from 'typeorm'; +import { + SeedAppleWorkspaceId, + SeedTwentyWorkspaceId, +} from 'src/database/typeorm-seeds/core/workspaces'; +import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; + // import { SeedWorkspaceId } from 'src/database/typeorm-seeds/core/workspaces'; const tableName = 'userWorkspace'; @@ -15,12 +21,10 @@ export const seedUserWorkspaces = async ( schemaName: string, workspaceId: string, ) => { - await workspaceDataSource - .createQueryBuilder() - .insert() - .into(`${schemaName}.${tableName}`, ['userId', 'workspaceId']) - .orIgnore() - .values([ + let userWorkspaces: Pick[] = []; + + if (workspaceId === SeedAppleWorkspaceId) { + userWorkspaces = [ { userId: SeedUserIds.Tim, workspaceId, @@ -33,7 +37,23 @@ export const seedUserWorkspaces = async ( userId: SeedUserIds.Phil, workspaceId, }, - ]) + ]; + } + + if (workspaceId === SeedTwentyWorkspaceId) { + userWorkspaces = [ + { + userId: SeedUserIds.Tim, + workspaceId, + }, + ]; + } + await workspaceDataSource + .createQueryBuilder() + .insert() + .into(`${schemaName}.${tableName}`, ['userId', 'workspaceId']) + .orIgnore() + .values(userWorkspaces) .execute(); }; diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts b/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts index 0cef73330157..75513e5ccb54 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts @@ -1,14 +1,46 @@ import { DataSource } from 'typeorm'; +import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; + const tableName = 'workspace'; -export const SeedWorkspaceId = '20202020-1c25-4d02-bf25-6aeccf7ea419'; +export const SeedAppleWorkspaceId = '20202020-1c25-4d02-bf25-6aeccf7ea419'; +export const SeedTwentyWorkspaceId = '3b8e6458-5fc1-4e63-8563-008ccddaa6db'; export const seedWorkspaces = async ( workspaceDataSource: DataSource, schemaName: string, workspaceId: string, ) => { + const workspaces: { + [key: string]: Pick< + Workspace, + | 'id' + | 'displayName' + | 'domainName' + | 'inviteHash' + | 'logo' + | 'subscriptionStatus' + >; + } = { + [SeedAppleWorkspaceId]: { + id: workspaceId, + displayName: 'Apple', + domainName: 'apple.dev', + inviteHash: 'apple.dev-invite-hash', + logo: 'data:image/png;base64,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', + subscriptionStatus: 'incomplete', + }, + [SeedTwentyWorkspaceId]: { + id: workspaceId, + displayName: 'Twenty', + domainName: 'twenty.dev', + inviteHash: 'twenty.dev-invite-hash', + logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACb0lEQVR4nO2VO4taQRTHr3AblbjxEVlwCwVhg7BoqqCIjy/gAyyFWNlYBOxsfH0KuxgQGwXRUkGuL2S7i1barGAgiwbdW93SnGOc4BonPiKahf3DwXFmuP/fPM4ZlvmlTxAhCBdzHnEQWYiv7Mr4C3NeuVYhQYDPzOUUQgDLBQGcLHNhvQK8DACPx8PTxiqVyvISG43GbyaT6Qfpn06n0m63e/tPAPF4vJ1MJu8kEsnWTCkWi1yr1RKGw+GDRqPBOTfr44vFQvD7/Q/lcpmaaVQAr9fLp1IpO22c47hGOBz+MB6PH+Vy+VYDAL8qlUoGtVotzOfzq4MAgsHgE/6KojiQyWR/bKVSqbSszHFM8Pl8z1YK48JsNltCOBwOnrYLO+8AAIjb+nHbycoTiUQfDJ7tFq4YAHiVSmXBxcD41u8flQU8z7fhzO0r83atVns3Go3u9Xr9x0O/RQXo9/tsIBBg6vX606a52Wz+bZ7P5/WwG29gxSJzhKgA6XTaDoFNF+krFAocmC//4yWEcSf2wTm7mCO19xFgSsKOLI16vV7b7XY7mRNoLwA0JymJ5uQIzgIAuX5PzDElT2m+E8BqtQ4ymcx7Yq7T6a6ZE4sKgOadTucaCwkxp1UzlEKh0GDxIXOwDWHAdi6Xe3swQDQa/Q7mywoolUpvsaptymazDWKxmBHTlWXZm405BFZoNpuGgwEmk4mE2SGtVivii4f1AO7J3ZopkQCQj7Ar1FeRChCJRJzVapX6DKNIfSc1Ax+wtQWQ55h6bH8FWDfYV4fO3wlwDr0C/BcADYiTPCxHqIEA2QsCZAkAKnRGkMbKN/sTX5YHPQ1e7SkAAAAASUVORK5CYII=', + subscriptionStatus: 'incomplete', + }, + }; + await workspaceDataSource .createQueryBuilder() .insert() @@ -21,16 +53,7 @@ export const seedWorkspaces = async ( 'subscriptionStatus', ]) .orIgnore() - .values([ - { - id: workspaceId, - displayName: 'Apple', - domainName: 'apple.dev', - inviteHash: 'apple.dev-invite-hash', - logo: 'data:image/png;base64,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', - subscriptionStatus: 'incomplete', - }, - ]) + .values(workspaces[workspaceId]) .execute(); }; diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts index 2f0054e87a04..643238873678 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts @@ -1,6 +1,11 @@ import { DataSource } from 'typeorm'; import { SeedUserIds } from 'src/database/typeorm-seeds/core/users'; +import { + SeedAppleWorkspaceId, + SeedTwentyWorkspaceId, +} from 'src/database/typeorm-seeds/core/workspaces'; +import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; const tableName = 'workspaceMember'; @@ -10,24 +15,25 @@ const WorkspaceMemberIds = { Phil: '20202020-1553-45c6-a028-5a9064cce07f', }; +type WorkspaceMembers = Pick< + WorkspaceMember, + 'id' | 'locale' | 'colorScheme' +> & { + nameFirstName: string; + nameLastName: string; + userEmail: string; + userId: string; +}; + export const seedWorkspaceMember = async ( workspaceDataSource: DataSource, schemaName: string, + workspaceId: string, ) => { - await workspaceDataSource - .createQueryBuilder() - .insert() - .into(`${schemaName}.${tableName}`, [ - 'id', - 'nameFirstName', - 'nameLastName', - 'locale', - 'colorScheme', - 'userEmail', - 'userId', - ]) - .orIgnore() - .values([ + let workspaceMembers: WorkspaceMembers[] = []; + + if (workspaceId === SeedAppleWorkspaceId) { + workspaceMembers = [ { id: WorkspaceMemberIds.Tim, nameFirstName: 'Tim', @@ -55,6 +61,35 @@ export const seedWorkspaceMember = async ( userEmail: 'phil.schiler@apple.dev', userId: SeedUserIds.Phil, }, + ]; + } + + if (workspaceId === SeedTwentyWorkspaceId) { + workspaceMembers = [ + { + id: WorkspaceMemberIds.Tim, + nameFirstName: 'Tim', + nameLastName: 'Apple', + locale: 'en', + colorScheme: 'Light', + userEmail: 'tim@apple.dev', + userId: SeedUserIds.Tim, + }, + ]; + } + await workspaceDataSource + .createQueryBuilder() + .insert() + .into(`${schemaName}.${tableName}`, [ + 'id', + 'nameFirstName', + 'nameLastName', + 'locale', + 'colorScheme', + 'userEmail', + 'userId', ]) + .orIgnore() + .values(workspaceMembers) .execute(); }; diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/1707778127558-addUserWorkspaces.ts b/packages/twenty-server/src/database/typeorm/core/migrations/1707778127558-addUserWorkspaces.ts index e0e0b2013b3f..b509cbca5790 100644 --- a/packages/twenty-server/src/database/typeorm/core/migrations/1707778127558-addUserWorkspaces.ts +++ b/packages/twenty-server/src/database/typeorm/core/migrations/1707778127558-addUserWorkspaces.ts @@ -14,10 +14,6 @@ export class AddUserWorkspaces1707778127558 implements MigrationInterface { "deletedAt" TIMESTAMP )`, ); - - await queryRunner.query( - `ALTER TABLE "core"."user" DROP CONSTRAINT "FK_2ec910029395fa7655621c88908"`, - ); } public async down(): Promise {} diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/1709680520888-updateUserWorkspaceColumnConstraints.ts b/packages/twenty-server/src/database/typeorm/core/migrations/1709680520888-updateUserWorkspaceColumnConstraints.ts new file mode 100644 index 000000000000..abaab0034311 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/1709680520888-updateUserWorkspaceColumnConstraints.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class updateUserWorkspaceColumnConstraints1709680520888 + implements MigrationInterface +{ + name = 'updateUserWorkspaceColumnConstraints1709680520888'; + + public async up(queryRunner: QueryRunner): Promise { + // ----------------- WARNING ------------------------ + // Dropping constraints and adding them back is NOT a recommended and should be AVOIDED, + // since it can affect data integrity and cause downtime and unintentional data loss. + await queryRunner.query( + `ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "userWorkspace_userId_fkey"`, + ); + + await queryRunner.query( + `ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "userWorkspace_workspaceId_fkey"`, + ); + + await queryRunner.query( + `ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "FK_cb488f32c6a0827b938edadf221"`, + ); + + await queryRunner.query( + `ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "FK_37fdc7357af701e595c5c3a9bd6"`, + ); + + await queryRunner.query(` + ALTER TABLE "core"."userWorkspace" + ADD CONSTRAINT "FK_37fdc7357af701e595c5c3a9bd6" + FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") + ON DELETE CASCADE ON UPDATE NO ACTION + `); + + await queryRunner.query(` + ALTER TABLE "core"."userWorkspace" + ADD CONSTRAINT "FK_cb488f32c6a0827b938edadf221" + FOREIGN KEY ("userId") REFERENCES "core"."user"("id") + ON DELETE CASCADE ON UPDATE NO ACTION + `); + } + + public async down(): Promise {} +} diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts index 474a1a203b52..5408accb6c60 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts @@ -20,7 +20,9 @@ describe('FieldUtils', () => { checkFields(objectMetadataItemMock, ['fieldNumber']), ).not.toThrow(); - expect(() => checkFields(objectMetadataItemMock, ['wrongField'])).toThrow(); + expect(() => + checkFields(objectMetadataItemMock, ['wrongField']), + ).toThrow(); expect(() => checkFields(objectMetadataItemMock, ['fieldNumber', 'wrongField']), diff --git a/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts b/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts index 010a7c6992d6..9ad7b8ef41ec 100644 --- a/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts @@ -4,6 +4,7 @@ import { getRepositoryToken } from '@nestjs/typeorm'; import { User } from 'src/engine/modules/user/user.entity'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; +import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; import { UserService } from './user.service'; @@ -18,6 +19,10 @@ describe('UserService', () => { provide: getRepositoryToken(User, 'core'), useValue: {}, }, + { + provide: getRepositoryToken(UserWorkspace, 'core'), + useValue: {}, + }, { provide: DataSourceService, useValue: {}, diff --git a/packages/twenty-server/src/engine/modules/user/services/user.service.ts b/packages/twenty-server/src/engine/modules/user/services/user.service.ts index f4c76ff842ab..59f139875396 100644 --- a/packages/twenty-server/src/engine/modules/user/services/user.service.ts +++ b/packages/twenty-server/src/engine/modules/user/services/user.service.ts @@ -8,12 +8,15 @@ import { User } from 'src/engine/modules/user/user.entity'; import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; +import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; export class UserService extends TypeOrmQueryService { constructor( @InjectRepository(User, 'core') private readonly userRepository: Repository, + @InjectRepository(UserWorkspace, 'core') + private readonly userWorkspaceRepository: Repository, private readonly dataSourceService: DataSourceService, private readonly typeORMService: TypeORMService, ) { @@ -104,6 +107,8 @@ export class UserService extends TypeOrmQueryService { `DELETE FROM ${dataSourceMetadata.schema}."workspaceMember" WHERE "userId" = '${userId}'`, ); + await this.userWorkspaceRepository.delete({ userId }); + await this.userRepository.delete(user.id); return user; diff --git a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts b/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts index 1f6961f6c8c5..af996f78e2cd 100644 --- a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts +++ b/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts @@ -2,11 +2,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; import { User } from 'src/engine/modules/user/user.entity'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; +import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { BillingService } from 'src/engine/modules/billing/billing.service'; import { WorkspaceService } from './workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts b/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts index 2e32aa5fe7e0..a87bdf26a732 100644 --- a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts +++ b/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts @@ -6,13 +6,13 @@ import assert from 'assert'; import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { Repository } from 'typeorm'; -import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; -import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { User } from 'src/engine/modules/user/user.entity'; +import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; import { BillingService } from 'src/engine/modules/billing/billing.service'; +import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; export class WorkspaceService extends TypeOrmQueryService { constructor( @@ -70,4 +70,118 @@ export class WorkspaceService extends TypeOrmQueryService { .find() .then((workspaces) => workspaces.map((workspace) => workspace.id)); } + + private async reassignDefaultWorkspace( + currentWorkspaceId: string, + user: User, + worskpaces: UserWorkspace[], + ) { + // We'll filter all user workspaces without the one which its getting removed from + const filteredUserWorkspaces = worskpaces.filter( + (workspace) => workspace.workspaceId !== currentWorkspaceId, + ); + + // Loop over each workspace in the filteredUserWorkspaces array and check if it currently exists in + // the database + for (let index = 0; index < filteredUserWorkspaces.length; index++) { + const userWorkspace = filteredUserWorkspaces[index]; + + const nextWorkspace = await this.workspaceRepository.findOneBy({ + id: userWorkspace.workspaceId, + }); + + if (nextWorkspace) { + await this.userRepository.save({ + id: user.id, + defaultWorkspace: nextWorkspace, + updatedAt: new Date().toISOString(), + }); + break; + } + + // if no workspaces are valid then we delete the user + if (index === filteredUserWorkspaces.length - 1) { + await this.userRepository.delete({ id: user.id }); + } + } + } + + /* + async removeWorkspaceMember(workspaceId: string, memberId: string) { + const dataSourceMetadata = + await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( + workspaceId, + ); + + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); + + // using "SELECT *" here because we will need the corresponding members userId later + const [workspaceMember] = await workspaceDataSource?.query( + `SELECT * FROM ${dataSourceMetadata.schema}."workspaceMember" WHERE "id" = '${memberId}'`, + ); + + if (!workspaceMember) { + throw new NotFoundException('Member not found.'); + } + + await workspaceDataSource?.query( + `DELETE FROM ${dataSourceMetadata.schema}."workspaceMember" WHERE "id" = '${memberId}'`, + ); + + const workspaceMemberUser = await this.userRepository.findOne({ + where: { + id: workspaceMember.userId, + }, + relations: ['defaultWorkspace'], + }); + + if (!workspaceMemberUser) { + throw new NotFoundException('User not found'); + } + + const userWorkspaces = await this.userWorkspaceRepository.find({ + where: { userId: workspaceMemberUser.id }, + relations: ['workspace'], + }); + + // We want to check if we the user has signed up to more than one workspace + if (userWorkspaces.length > 1) { + // We neeed to check if the workspace that its getting removed from is its default workspace, if it is then + // change the default workspace to point to the next workspace available. + if (workspaceMemberUser.defaultWorkspace.id === workspaceId) { + await this.reassignDefaultWorkspace( + workspaceId, + workspaceMemberUser, + userWorkspaces, + ); + } + // if its not the default workspace then simply delete the user-workspace mapping + await this.userWorkspaceRepository.delete({ + userId: workspaceMemberUser.id, + workspaceId, + }); + } else { + await this.userWorkspaceRepository.delete({ + userId: workspaceMemberUser.id, + }); + + // After deleting the user-workspace mapping, we have a condition where we have the users default workspace points to a + // workspace which it doesnt have access to. So we delete the user. + await this.userRepository.delete({ id: workspaceMemberUser.id }); + } + + const payload = + new ObjectRecordDeleteEvent(); + + payload.workspaceId = workspaceId; + payload.details = { + before: workspaceMember, + }; + + this.eventEmitter.emit('workspaceMember.deleted', payload); + + return memberId; + } + */ } diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts b/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts index a2fa95f2316d..e636e051cce3 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts +++ b/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts @@ -6,15 +6,16 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { WorkspaceResolver } from 'src/engine/modules/workspace/workspace.resolver'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { BillingModule } from 'src/engine/modules/billing/billing.module'; import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; -import { BillingModule } from 'src/engine/modules/billing/billing.module'; +import { User } from 'src/engine/modules/user/user.entity'; +import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; -import { Workspace } from './workspace.entity'; import { workspaceAutoResolverOpts } from './workspace.auto-resolver-opts'; +import { Workspace } from './workspace.entity'; import { WorkspaceService } from './services/workspace.service'; @@ -31,6 +32,8 @@ import { WorkspaceService } from './services/workspace.service'; ), UserWorkspaceModule, WorkspaceManagerModule, + DataSourceModule, + TypeORMModule, ], services: [WorkspaceService], resolvers: workspaceAutoResolverOpts, diff --git a/yarn.lock b/yarn.lock index bfb3bdf8a68d..9bc8d86202da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16560,6 +16560,15 @@ __metadata: languageName: node linkType: hard +"@types/lodash.groupby@npm:^4.6.9": + version: 4.6.9 + resolution: "@types/lodash.groupby@npm:4.6.9" + dependencies: + "@types/lodash": "npm:*" + checksum: 1302531f76da99cc8f1bbd486a8c7048a833352b12c39eb5b2ded01173dd5fff76f2c7ace04f08b51c55840271170f1cfbffe4e454dde8597c3ee996e70d4e11 + languageName: node + linkType: hard + "@types/lodash.isempty@npm:^4.4.7": version: 4.4.9 resolution: "@types/lodash.isempty@npm:4.4.9" @@ -45916,6 +45925,7 @@ __metadata: "@types/js-cookie": "npm:^3.0.3" "@types/lodash.camelcase": "npm:^4.3.7" "@types/lodash.debounce": "npm:^4.0.7" + "@types/lodash.groupby": "npm:^4.6.9" "@types/lodash.isempty": "npm:^4.4.7" "@types/lodash.isequal": "npm:^4.5.7" "@types/lodash.isobject": "npm:^3.0.7" From e5c1309e8ca14e05badab4fe7b0262db0074a95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20M?= Date: Wed, 20 Mar 2024 16:23:46 +0100 Subject: [PATCH 33/44] feat: wip server folder structure (#4573) * feat: wip server folder structure * fix: merge * fix: wrong merge * fix: remove unused file * fix: comment * fix: lint * fix: merge * fix: remove console.log * fix: metadata graphql arguments broken --- packages/twenty-server/.env.example | 1 + packages/twenty-server/package.json | 3 +- ...0.8.patch => @nestjs+graphql+12.1.1.patch} | 14 +- packages/twenty-server/src/app.module.ts | 38 ++- packages/twenty-server/src/app.service.ts | 8 - packages/twenty-server/src/command/command.ts | 2 +- .../data-seed-dev-workspace.command.ts | 4 +- .../commands/database-command.module.ts | 6 +- .../typeorm-seeds/core/feature-flags.ts | 2 +- .../typeorm-seeds/core/userWorkspaces.ts | 2 +- .../database/typeorm-seeds/core/workspaces.ts | 2 +- .../database/typeorm-seeds/workspace/views.ts | 2 +- .../workspace/workspaceMember.ts | 2 +- .../database/typeorm/core/core.datasource.ts | 2 +- .../typeorm/metadata/metadata.datasource.ts | 2 +- .../src/database/typeorm/typeorm.service.ts | 16 +- .../graphql-config.module.ts | 11 - .../field-metadata/composite-types/index.ts | 19 -- .../interfaces/field-metadata.interface.ts | 25 -- .../factories/factories.ts | 7 - .../__mocks__/object-metadata-item.mock.ts | 4 +- .../__tests__/workspace.factory.spec.ts | 14 +- .../api/graphql/core-graphql-api.module.ts | 23 +- .../factories/create-context.factory.ts | 4 +- .../graphql-config}/factories/index.ts | 0 .../graphql-config/graphql-config.module.ts | 11 + .../graphql-config}/graphql-config.service.ts | 22 +- .../graphql-config}/hooks/use-throttler.ts | 2 +- .../interfaces/graphql-context.interface.ts | 4 +- .../graphql/metadata-graphql-api.module.ts} | 21 +- .../api/graphql}/metadata.module-factory.ts | 8 +- .../workspace-query-builder-options.mock.ts | 2 +- .../factories/args-alias.factory.ts | 2 +- .../factories/args-string.factory.ts | 2 +- .../factories/field-alias.factory.ts | 2 +- .../factories/fields-string.factory.ts | 4 +- .../find-duplicates-query.factory.ts | 2 +- .../factories/relation-field-alias.factory.ts | 8 +- ...rkspace-query-builder-options.interface.ts | 4 +- .../workspace-query-builder.module.ts | 2 +- .../query-runner-args.factory.spec.ts | 4 +- .../factories/query-result-getters.factory.ts | 4 +- .../factories/query-runner-args.factory.ts | 4 +- .../query-runner-option.interface.ts | 4 +- .../jobs/call-webhook-jobs.job.ts | 6 +- .../jobs/save-event-to-db.job.ts | 2 +- .../listeners/entity-events-to-db.listener.ts | 2 +- .../listeners/record-position.listener.ts | 2 +- .../record-position-backfill-service.ts | 2 +- .../workspace-query-runner.module.ts | 6 +- .../workspace-query-runner.service.ts | 4 +- ...te-quick-action-on-one-resolver.factory.ts | 2 +- .../workspace-resolver-builder.module.ts | 2 +- .../workspace-resolver.factory.ts | 2 +- .../connection-type-definition.factory.ts | 2 +- .../factories/connection-type.factory.ts | 2 +- .../factories/edge-type-definition.factory.ts | 2 +- .../factories/edge-type.factory.ts | 2 +- .../factories/enum-type-definition.factory.ts | 8 +- .../extend-object-type-definition.factory.ts | 4 +- .../filter-type-definition.factory.ts | 2 +- .../factories/filter-type.factory.ts | 6 +- .../input-type-definition.factory.ts | 4 +- .../factories/input-type.factory.ts | 4 +- .../factories/mutation-type.factory.ts | 2 +- .../object-type-definition.factory.ts | 4 +- .../order-by-type-definition.factory.ts | 2 +- .../factories/order-by-type.factory.ts | 4 +- .../factories/output-type.factory.ts | 4 +- .../factories/query-type.factory.ts | 2 +- .../factories/relation-type.factory.ts | 6 +- .../factories/root-type.factory.ts | 2 +- .../interfaces/param-metadata.interface.ts | 2 +- ...kspace-schema-builder-context.interface.ts | 4 +- .../services/type-mapper.service.ts | 2 +- .../storages/type-definitions.storage.ts | 4 +- .../type-definitions.generator.ts | 12 +- .../__tests__/get-field-metadata-type.spec.ts | 2 +- .../utils/__tests__/get-resolver-args.spec.ts | 2 +- .../utils/get-field-metadata-type.util.ts | 2 +- .../utils/get-resolver-args.util.ts | 2 +- .../utils/object-contains-relation-field.ts | 2 +- .../workspace-graphql-schema.factory.ts | 2 +- .../workspace-schema-builder.module.ts | 4 +- .../workspace-schema-storage.module.ts | 4 +- .../workspace-schema-storage.service.ts | 4 +- ...factory.ts => workspace-schema.factory.ts} | 6 +- .../rest/__tests__/api-rest.service.spec.ts | 2 +- .../api-rest-query-builder.factory.spec.ts | 4 +- .../api-rest-query-builder.factory.ts | 6 +- .../api-rest-query-builder.module.ts | 4 +- .../format-field-values.utils.spec.ts | 2 +- .../filter-utils/format-field-values.utils.ts | 2 +- .../utils/__tests__/fields.utils.spec.ts | 2 +- .../utils/fields.utils.ts | 2 +- ...p-field-metadata-to-graphql-query.utils.ts | 4 +- .../src/engine/api/rest/api-rest.module.ts | 2 +- .../src/engine/api/rest/api-rest.service.ts | 2 +- .../engine/api/rest/metadata-rest.service.ts | 2 +- .../settings/interfaces/settings.interface.ts | 2 +- .../analytics/analytics.entity.ts | 0 .../analytics/analytics.module.ts | 0 .../analytics/analytics.resolver.spec.ts | 0 .../analytics/analytics.resolver.ts | 4 +- .../analytics/analytics.service.spec.ts | 0 .../analytics/analytics.service.ts | 4 +- .../analytics/dto/create-analytics.input.ts | 0 .../auth/auth.module.ts | 30 +-- .../auth/auth.resolver.spec.ts | 8 +- .../auth/auth.resolver.ts | 26 +- .../auth/auth.util.ts | 0 .../google-apis-auth.controller.ts | 10 +- .../controllers/google-auth.controller.ts | 14 +- .../google-gmail-auth.controller.ts | 10 +- .../verify-auth.controller.spec.ts | 4 +- .../controllers/verify-auth.controller.ts | 8 +- .../auth/dto/api-key-token.input.ts | 0 .../auth/dto/challenge.input.ts | 0 .../dto/email-password-reset-link.entity.ts | 0 .../dto/email-password-reset-link.input.ts | 0 .../auth/dto/generate-jwt.input.ts | 0 .../auth/dto/impersonate.input.ts | 0 .../auth/dto/invalidate-password.entity.ts | 0 .../auth/dto/login-token.entity.ts | 0 .../auth/dto/password-reset-token.input.ts | 0 .../auth/dto/refresh-token.input.ts | 0 .../auth/dto/save-connected-account.ts | 0 .../auth/dto/sign-up.input.ts | 0 .../auth/dto/token.entity.ts | 0 .../auth/dto/transient-token.entity.ts | 0 .../update-password-via-reset-token.input.ts | 0 .../auth/dto/update-password.entity.ts | 0 .../auth/dto/user-exists.entity.ts | 0 .../auth/dto/user-exists.input.ts | 0 .../validate-password-reset-token.entity.ts | 0 .../validate-password-reset-token.input.ts | 0 .../auth/dto/verify.entity.ts | 2 +- .../auth/dto/verify.input.ts | 0 .../dto/workspace-invite-hash-valid.entity.ts | 0 .../auth/dto/workspace-invite-hash.input.ts | 0 .../auth/guards/google-apis-oauth.guard.ts | 0 .../google-apis-provider-enabled.guard.ts | 2 +- .../google-gmail-provider-enabled.guard.ts | 2 +- .../auth/guards/google-oauth.guard.ts | 0 .../guards/google-provider-enabled.guard.ts | 2 +- .../auth/services/auth.service.spec.ts | 8 +- .../auth/services/auth.service.ts | 20 +- .../auth/services/google-apis.service.ts | 6 +- .../auth/services/sign-up.service.spec.ts | 10 +- .../auth/services/sign-up.service.ts | 12 +- .../auth/services/token.service.spec.ts | 8 +- .../auth/services/token.service.ts | 18 +- .../strategies/google-apis.auth.strategy.ts | 0 .../auth/strategies/google.auth.strategy.ts | 0 .../auth/strategies/jwt.auth.strategy.ts | 6 +- .../core-modules/auth/types/jwt-data.type.ts | 7 + .../billing/billing.controller.ts | 4 +- .../core-modules/billing/billing.module.ts | 27 +++ .../billing/billing.resolver.ts | 14 +- .../billing/billing.service.ts | 14 +- .../billing/dto/billing-session.input.ts | 0 .../billing/dto/checkout-session.input.ts | 0 .../billing/dto/product-price.entity.ts | 0 .../billing/dto/product-prices.entity.ts | 2 +- .../billing/dto/product.input.ts | 2 +- .../billing/dto/session.entity.ts | 0 .../billing-subscription-item.entity.ts | 2 +- .../entities/billing-subscription.entity.ts | 4 +- .../billing/jobs/update-subscription.job.ts | 6 +- .../billing-workspace-member.listener.ts | 2 +- .../billing/stripe/stripe.module.ts | 2 +- .../billing/stripe/stripe.service.ts | 2 +- .../calendar/constants/calendar.constants.ts | 0 .../timeline-calendar-event-attendee.dto.ts | 0 .../dtos/timeline-calendar-event.dto.ts | 2 +- ...timeline-calendar-events-with-total.dto.ts | 2 +- .../timeline-calendar-event.module.ts | 7 +- .../timeline-calendar-event.resolver.ts | 14 +- .../timeline-calendar-event.service.ts | 8 +- .../client-config/client-config.entity.ts | 0 .../client-config/client-config.module.ts | 0 .../client-config.resolver.spec.ts | 0 .../client-config/client-config.resolver.ts | 0 .../engine/core-modules/core-engine.module.ts | 44 ++++ .../feature-flag/feature-flag.entity.ts | 2 +- .../feature-flag/feature-flag.module.ts | 2 +- .../interfaces/feature-flag-map.interface.ts | 3 + .../file/controllers/file.controller.spec.ts | 4 +- .../file/controllers/file.controller.ts | 6 +- .../file/file-upload/file-upload.module.ts | 4 +- .../resolvers/file-upload.resolver.spec.ts | 2 +- .../resolvers/file-upload.resolver.ts | 4 +- .../services/file-upload.service.spec.ts | 0 .../services/file-upload.service.ts | 2 +- .../file/file.module.ts | 6 +- .../file/file.utils.ts | 0 .../file/guards/file-path-guard.ts | 2 +- .../file/interfaces/file-folder.interface.ts | 0 .../resolvers/file-upload.resolver.spec.ts | 27 +++ .../file/resolvers/file-upload.resolver.ts | 57 +++++ .../file/services/file.service.spec.ts | 0 .../file/services/file.service.ts | 0 .../health/health.controller.spec.ts | 2 +- .../health/health.controller.ts | 0 .../health/health.module.ts | 2 +- .../constants/messaging.constants.ts | 0 .../dtos/timeline-thread-participant.dto.ts | 0 .../messaging/dtos/timeline-thread.dto.ts | 2 +- .../dtos/timeline-threads-with-total.dto.ts | 2 +- .../messaging/timeline-messaging.module.ts | 6 +- .../messaging/timeline-messaging.resolver.ts | 12 +- .../messaging/timeline-messaging.service.ts | 4 +- .../open-api/open-api.controller.ts | 2 +- .../core-modules/open-api/open-api.module.ts | 13 + .../open-api/open-api.service.spec.ts | 6 +- .../open-api/open-api.service.ts | 20 +- .../utils/__tests__/components.utils.spec.ts | 4 +- .../utils/__tests__/parameters.utils.spec.ts | 2 +- .../open-api/utils/base-schema.utils.ts | 2 +- .../open-api/utils/components.utils.ts | 6 +- .../utils/compute-schema-tags.utils.ts | 2 +- .../open-api/utils/computeWebhooks.utils.ts | 2 +- .../utils/get-error-responses.utils.ts | 0 .../open-api/utils/parameters.utils.ts | 0 .../open-api/utils/path.utils.ts | 6 +- .../open-api/utils/request-body.utils.ts | 2 +- .../open-api/utils/responses.utils.ts | 2 +- .../quick-actions/intelligence.service.ts | 2 +- .../interfaces/company.interface.ts | 0 .../quick-actions/quick-actions.module.ts | 4 +- .../quick-actions/quick-actions.service.ts | 4 +- .../dtos/create-refresh-token.input.ts | 0 .../before-create-one-refresh-token.hook.ts | 2 +- .../refresh-token.auto-resolver-opts.ts | 0 .../refresh-token/refresh-token.entity.ts | 2 +- .../refresh-token/refresh-token.module.ts | 0 .../services/refresh-token.service.spec.ts | 2 +- .../services/refresh-token.service.ts | 2 +- .../user-workspace/user-workspace.entity.ts | 4 +- .../user-workspace/user-workspace.module.ts | 6 +- .../user-workspace/user-workspace.service.ts | 6 +- .../user/dtos/workspace-member.dto.ts | 0 .../user/services/user.service.spec.ts | 6 +- .../user/services/user.service.ts | 10 +- .../user/user.auto-resolver-opts.ts | 2 +- .../user/user.entity.ts | 8 +- .../user/user.module.ts | 12 +- .../user/user.resolver.ts | 10 +- .../dtos/activate-workspace-input.ts | 0 .../workspace/dtos/update-workspace-input.ts | 0 .../services/workspace.service.spec.ts | 10 +- .../workspace/services/workspace.service.ts | 12 +- .../workspace/workspace.auto-resolver-opts.ts | 2 +- .../workspace/workspace.entity.ts | 8 +- .../workspace/workspace.module.ts | 16 +- .../workspace/workspace.resolver.ts | 14 +- .../is-valid-metadata-name.decorator.ts} | 2 +- .../environment/environment-variables.ts | 21 +- .../environment/environment.default.ts | 79 ------ .../types/object-record.base.event.ts | 2 +- .../hooks/use-exception-handler.hook.ts | 4 +- .../hooks/use-sentry-tracing.ts | 2 +- .../integrations/message-queue/jobs.module.ts | 20 +- .../data-source/data-source.entity.ts | 2 +- .../data-source/data-source.module.ts | 0 .../data-source/data-source.service.ts | 0 .../currency.composite-type.ts | 8 +- .../full-name.composite-type.ts | 8 +- .../field-metadata/composite-types/index.ts | 19 ++ .../composite-types/link.composite-type.ts | 8 +- .../field-metadata/dtos/create-field.input.ts | 2 +- .../dtos/default-value.input.ts | 0 .../field-metadata/dtos/field-metadata.dto.ts | 18 +- .../field-metadata/dtos/options.input.ts | 2 +- .../dtos/relation-definition.dto.ts | 6 +- .../field-metadata/dtos/update-field.input.ts | 2 +- .../field-metadata/field-metadata.entity.ts | 12 +- .../field-metadata/field-metadata.module.ts | 16 +- .../field-metadata/field-metadata.resolver.ts | 12 +- .../field-metadata/field-metadata.service.ts | 26 +- .../hooks/before-delete-one-field.hook.ts | 4 +- .../field-metadata-default-value.interface.ts | 4 +- .../field-metadata-options.interface.ts | 4 +- ...ld-metadata-target-column-map.interface.ts | 2 +- .../interfaces/field-metadata.interface.ts | 25 ++ .../interfaces/object-metadata.interface.ts | 0 .../interfaces/relation-metadata.interface.ts | 2 +- .../utils/__tests__/generate-nullable.spec.ts | 4 +- .../generate-target-column-map.spec.ts | 4 +- .../__tests__/serialize-default-value.spec.ts | 2 +- ...lidate-default-value-based-on-type.spec.ts | 4 +- .../utils/generate-default-value.ts | 4 +- .../field-metadata/utils/generate-nullable.ts | 2 +- .../utils/generate-rating-optionts.util.ts | 2 +- .../utils/generate-target-column-map.util.ts | 6 +- .../is-composite-field-metadata-type.util.ts | 2 +- .../utils/is-enum-field-metadata-type.util.ts | 2 +- .../utils/serialize-default-value.ts | 4 +- .../serialize-type-default-value.util.ts | 2 +- .../validate-default-value-for-type.util.ts | 6 +- .../utils/validate-options-for-type.util.ts | 6 +- ...-field-metadata-default-value.validator.ts | 8 +- .../is-field-metadata-options.validator.ts | 8 +- .../is-valid-graphql-enum-name.validator.ts | 0 .../metadata-engine.module.ts | 27 +++ .../dtos/create-object.input.ts | 8 +- .../dtos/delete-object.input.ts | 2 +- .../dtos/object-metadata.dto.ts | 4 +- .../dtos/update-object.input.ts | 8 +- .../hooks/before-create-one-object.hook.ts | 2 +- .../hooks/before-delete-one-object.hook.ts | 2 +- .../hooks/before-update-one-object.hook.ts | 8 +- .../object-metadata/object-metadata.entity.ts | 8 +- .../object-metadata/object-metadata.module.ts | 10 +- .../object-metadata.resolver.ts | 8 +- .../object-metadata.service.ts | 16 +- .../dtos/create-relation.input.ts | 4 +- .../dtos/relation-metadata.dto.ts | 6 +- .../hooks/before-create-one-relation.hook.ts | 2 +- .../hooks/before-delete-one-field.hook.ts | 2 +- .../relation-metadata.entity.ts | 6 +- .../relation-metadata.module.ts | 6 +- .../relation-metadata.service.ts | 20 +- .../types/relation-to-delete.ts | 0 ...e-relation-foreign-key-column-name.util.ts | 2 +- ...on-foreign-key-field-metadata-name.util.ts | 0 .../workspace-cache-version.entity.ts | 0 .../workspace-cache-version.module.ts | 4 +- .../workspace-cache-version.service.ts | 2 +- .../factories/basic-column-action.factory.ts | 16 +- .../column-action-abstract.factory.ts | 10 +- .../factories/enum-column-action.factory.ts | 14 +- .../factories/factories.ts | 7 + ...rkspace-column-action-factory.interface.ts | 8 +- ...rkspace-column-action-options.interface.ts | 0 ...field-metadata-type-to-column-type.util.ts | 2 +- .../utils/generate-migration-name.util.ts | 0 .../workspace-migration.entity.ts | 2 +- .../workspace-migration.factory.ts | 18 +- .../workspace-migration.module.ts | 4 +- .../workspace-migration.service.ts | 0 .../modules/auth/types/jwt-data.type.ts | 7 - .../engine/modules/billing/billing.module.ts | 27 --- .../engine/modules/engine-modules.module.ts | 44 ---- .../interfaces/feature-flag-map.interface.ts | 3 - .../modules/open-api/open-api.module.ts | 13 - ...regate-by-workspace-context-id.strategy.ts | 38 +++ .../deduce-relation-direction.spec.ts | 8 +- .../utils/compute-object-target-table.util.ts | 2 +- .../utils/create-custom-column-name.util.ts | 0 .../utils/deduce-relation-direction.util.ts | 4 +- .../engine/utils/get-resolver-name.util.ts | 2 +- .../utils/global-exception-handler.util.ts | 2 +- .../utils/graphql-errors.util.ts | 0 .../is-relation-field-metadata-type.util.ts | 2 +- .../workspace-datasource.module.ts | 2 +- .../workspace-datasource.service.ts | 4 +- .../demo-objects-prefill-data.ts | 2 +- .../demo-objects-prefill-data/view.ts | 2 +- .../standard-objects-prefill-data.ts | 2 +- .../standard-objects-prefill-data/view.ts | 2 +- .../delete-incomplete-workspaces.command.ts | 6 +- .../crons/clean-inactive-workspace.job.ts | 10 +- .../workspace-cleaner.module.ts | 6 +- .../fixer/abstract-workspace.fixer.ts | 4 +- .../fixer/workspace-default-value.fixer.ts | 6 +- .../fixer/workspace-nullable.fixer.ts | 4 +- .../workspace-target-column-map.fixer.ts | 12 +- .../fixer/workspace-type.fixer.ts | 4 +- .../workspace-health-issue.interface.ts | 6 +- .../services/database-structure.service.ts | 10 +- .../services/field-metadata-health.service.ts | 18 +- .../object-metadata-health.service.ts | 2 +- .../relation-metadata.health.service.ts | 10 +- .../services/workspace-fix.service.ts | 4 +- .../compute-composite-field-metadata.util.ts | 4 +- ...p-field-metadata-type-to-data-type.util.ts | 2 +- .../workspace-health.module.ts | 4 +- .../workspace-health.service.ts | 6 +- .../workspace-manager.module.ts | 6 +- .../workspace-manager.service.ts | 8 +- .../workspace-migration-field.factory.ts | 10 +- .../workspace-migration-object.factory.ts | 10 +- .../workspace-migration-relation.factory.ts | 8 +- .../workspace-migration-builder.module.ts | 2 +- .../workspace-migration-enum.service.ts | 4 +- .../workspace-migration-type.service.ts | 2 +- ...vert-on-delete-action-to-on-delete.util.ts | 2 +- .../workspace-migration-runner.module.ts | 4 +- .../workspace-migration-runner.service.ts | 6 +- .../commands/add-standard-id.command.ts | 4 +- .../services/sync-workspace-logger.service.ts | 2 +- .../sync-workspace-metadata.command.ts | 4 +- ...workspace-sync-metadata-commands.module.ts | 4 +- .../comparators/workspace-field.comparator.ts | 4 +- .../workspace-object.comparator.ts | 2 +- .../workspace-relation.comparator.ts | 2 +- .../custom-objects/custom.object-metadata.ts | 4 +- .../dynamic-field-metadata.interface.ts | 2 +- .../decorators/field-metadata.decorator.ts | 8 +- .../decorators/relation-metadata.decorator.ts | 2 +- .../factories/feature-flags.factory.ts | 4 +- .../factories/standard-field.factory.ts | 2 +- .../factories/standard-object.factory.ts | 2 +- .../factories/standard-relation.factory.ts | 6 +- .../interfaces/comparator.interface.ts | 4 +- .../interfaces/mapped-metadata.interface.ts | 4 +- ...puted-relation-field-metadata.interface.ts | 4 +- .../reflect-field-metadata.interface.ts | 10 +- .../reflect-relation-metadata.interface.ts | 2 +- .../workspace-metadata-updater.service.ts | 8 +- .../workspace-sync-field-metadata.service.ts | 6 +- .../workspace-sync-object-metadata.service.ts | 6 +- ...orkspace-sync-relation-metadata.service.ts | 8 +- .../standard-objects/base.object-metadata.ts | 2 +- .../storage/workspace-sync.storage.ts | 6 +- .../utils/compute-standard-object.util.ts | 6 +- .../utils/sync-metadata.util.spec.ts | 4 +- .../workspace-sync-metadata.module.ts | 10 +- .../workspace-sync-metadata.service.ts | 2 +- packages/twenty-server/src/main.ts | 6 +- .../activity-target.object-metadata.ts | 2 +- .../activity.object-metadata.ts | 4 +- .../comment.object-metadata.ts | 2 +- .../api-key.object-metadata.ts | 2 +- .../attachment.object-metadata.ts | 2 +- .../google-calendar-full-sync.module.ts | 2 +- .../google-calendar-full-sync.service.ts | 2 +- ...annel-event-association.object-metadata.ts | 4 +- .../calendar-channel.object-metadata.ts | 6 +- ...calendar-event-attendee.object-metadata.ts | 2 +- .../calendar-event.object-metadata.ts | 6 +- .../company.object-metadata.ts | 8 +- .../blocklist.object-metadata.ts | 2 +- .../connected-account.object-metadata.ts | 6 +- .../standard-objects/event.object-metadata.ts | 4 +- .../favorite.object-metadata.ts | 2 +- .../fetch-all-workspaces-messages.job.ts | 4 +- .../messaging-connected-account.listener.ts | 2 +- .../src/modules/messaging/messaging.module.ts | 3 +- .../gmail-full-sync/gmail-full-sync.module.ts | 2 +- .../gmail-full-sync.service.ts | 2 +- .../gmail-partial-sync.module.ts | 2 +- .../gmail-partial-sync.service.ts | 2 +- .../services/message/message.service.ts | 10 +- ...nel-message-association.object-metadata.ts | 2 +- .../message-channel.object-metadata.ts | 4 +- .../message-participant.object-metadata.ts | 2 +- .../message-thread.object-metadata.ts | 4 +- .../message.object-metadata.ts | 4 +- .../opportunity.object-metadata.ts | 6 +- .../person.object-metadata.ts | 8 +- .../pipeline-step.object-metadata.ts | 4 +- .../view-field.object-metadata.ts | 2 +- .../view-filter.object-metadata.ts | 2 +- .../view-sort.object-metadata.ts | 2 +- .../standard-objects/view.object-metadata.ts | 4 +- .../webhook.object-metadata.ts | 2 +- .../workspace-member.object-metadata.ts | 6 +- .../src/queue-worker/queue-worker.ts | 2 +- yarn.lock | 229 ++++++++---------- 461 files changed, 1396 insertions(+), 1322 deletions(-) rename packages/twenty-server/patches/{@nestjs+graphql+12.0.8.patch => @nestjs+graphql+12.1.1.patch} (80%) delete mode 100644 packages/twenty-server/src/app.service.ts delete mode 100644 packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts delete mode 100644 packages/twenty-server/src/engine-metadata/field-metadata/composite-types/index.ts delete mode 100644 packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata.interface.ts delete mode 100644 packages/twenty-server/src/engine-metadata/workspace-migration/factories/factories.ts rename packages/twenty-server/src/{engine-graphql-config => engine/api/graphql/graphql-config}/factories/create-context.factory.ts (76%) rename packages/twenty-server/src/{engine-graphql-config => engine/api/graphql/graphql-config}/factories/index.ts (100%) create mode 100644 packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts rename packages/twenty-server/src/{engine-graphql-config => engine/api/graphql/graphql-config}/graphql-config.service.ts (87%) rename packages/twenty-server/src/{engine-graphql-config => engine/api/graphql/graphql-config}/hooks/use-throttler.ts (96%) rename packages/twenty-server/src/{engine-graphql-config => engine/api/graphql/graphql-config}/interfaces/graphql-context.interface.ts (56%) rename packages/twenty-server/src/{engine-metadata/metadata.module.ts => engine/api/graphql/metadata-graphql-api.module.ts} (51%) rename packages/twenty-server/src/{engine-metadata => engine/api/graphql}/metadata.module-factory.ts (82%) rename packages/twenty-server/src/engine/api/graphql/{workspace.factory.ts => workspace-schema.factory.ts} (94%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.module.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.resolver.spec.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.resolver.ts (88%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.service.spec.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/analytics.service.ts (91%) rename packages/twenty-server/src/engine/{modules => core-modules}/analytics/dto/create-analytics.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/auth.module.ts (53%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/auth.resolver.spec.ts (77%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/auth.resolver.ts (83%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/auth.util.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/controllers/google-apis-auth.controller.ts (77%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/controllers/google-auth.controller.ts (76%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/controllers/google-gmail-auth.controller.ts (77%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/controllers/verify-auth.controller.spec.ts (80%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/controllers/verify-auth.controller.ts (61%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/api-key-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/challenge.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/email-password-reset-link.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/email-password-reset-link.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/generate-jwt.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/impersonate.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/invalidate-password.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/login-token.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/password-reset-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/refresh-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/save-connected-account.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/sign-up.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/token.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/transient-token.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/update-password-via-reset-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/update-password.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/user-exists.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/user-exists.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/validate-password-reset-token.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/validate-password-reset-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/verify.entity.ts (76%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/verify.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/workspace-invite-hash-valid.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/dto/workspace-invite-hash.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/guards/google-apis-oauth.guard.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/guards/google-apis-provider-enabled.guard.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/guards/google-gmail-provider-enabled.guard.ts (86%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/guards/google-oauth.guard.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/guards/google-provider-enabled.guard.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/auth.service.spec.ts (82%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/auth.service.ts (86%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/google-apis.service.ts (94%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/sign-up.service.spec.ts (72%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/sign-up.service.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/token.service.spec.ts (80%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/services/token.service.ts (94%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/strategies/google-apis.auth.strategy.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/strategies/google.auth.strategy.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/auth/strategies/jwt.auth.strategy.ts (91%) create mode 100644 packages/twenty-server/src/engine/core-modules/auth/types/jwt-data.type.ts rename packages/twenty-server/src/engine/{modules => core-modules}/billing/billing.controller.ts (90%) create mode 100644 packages/twenty-server/src/engine/core-modules/billing/billing.module.ts rename packages/twenty-server/src/engine/{modules => core-modules}/billing/billing.resolver.ts (80%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/billing.service.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/billing-session.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/checkout-session.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/product-price.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/product-prices.entity.ts (71%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/product.input.ts (73%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/dto/session.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/entities/billing-subscription-item.entity.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/entities/billing-subscription.entity.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/jobs/update-subscription.job.ts (84%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/listeners/billing-workspace-member.listener.ts (94%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/stripe/stripe.module.ts (62%) rename packages/twenty-server/src/engine/{modules => core-modules}/billing/stripe/stripe.service.ts (97%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/constants/calendar.constants.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/dtos/timeline-calendar-event-attendee.dto.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/dtos/timeline-calendar-event.dto.ts (88%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/dtos/timeline-calendar-events-with-total.dto.ts (74%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/timeline-calendar-event.module.ts (53%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/timeline-calendar-event.resolver.ts (81%) rename packages/twenty-server/src/engine/{modules => core-modules}/calendar/timeline-calendar-event.service.ts (95%) rename packages/twenty-server/src/engine/{modules => core-modules}/client-config/client-config.entity.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/client-config/client-config.module.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/client-config/client-config.resolver.spec.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/client-config/client-config.resolver.ts (100%) create mode 100644 packages/twenty-server/src/engine/core-modules/core-engine.module.ts rename packages/twenty-server/src/engine/{modules => core-modules}/feature-flag/feature-flag.entity.ts (93%) rename packages/twenty-server/src/engine/{modules => core-modules}/feature-flag/feature-flag.module.ts (85%) create mode 100644 packages/twenty-server/src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface.ts rename packages/twenty-server/src/engine/{modules => core-modules}/file/controllers/file.controller.spec.ts (82%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/controllers/file.controller.ts (79%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file-upload/file-upload.module.ts (58%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file-upload/resolvers/file-upload.resolver.spec.ts (84%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file-upload/resolvers/file-upload.resolver.ts (88%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file-upload/services/file-upload.service.spec.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file-upload/services/file-upload.service.ts (96%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file.module.ts (64%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/file.utils.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/guards/file-path-guard.ts (93%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/interfaces/file-folder.interface.ts (100%) create mode 100644 packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.spec.ts create mode 100644 packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.ts rename packages/twenty-server/src/engine/{modules => core-modules}/file/services/file.service.spec.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/file/services/file.service.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/health/health.controller.spec.ts (89%) rename packages/twenty-server/src/engine/{modules => core-modules}/health/health.controller.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/health/health.module.ts (70%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/constants/messaging.constants.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/dtos/timeline-thread-participant.dto.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/dtos/timeline-thread.dto.ts (83%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/dtos/timeline-threads-with-total.dto.ts (74%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/timeline-messaging.module.ts (54%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/timeline-messaging.resolver.ts (80%) rename packages/twenty-server/src/engine/{modules => core-modules}/messaging/timeline-messaging.service.ts (98%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/open-api.controller.ts (88%) create mode 100644 packages/twenty-server/src/engine/core-modules/open-api/open-api.module.ts rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/open-api.service.spec.ts (73%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/open-api.service.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/__tests__/components.utils.spec.ts (83%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/__tests__/parameters.utils.spec.ts (98%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/base-schema.utils.ts (93%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/components.utils.ts (97%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/compute-schema-tags.utils.ts (80%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/computeWebhooks.utils.ts (95%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/get-error-responses.utils.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/parameters.utils.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/path.utils.ts (93%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/request-body.utils.ts (77%) rename packages/twenty-server/src/engine/{modules => core-modules}/open-api/utils/responses.utils.ts (97%) rename packages/twenty-server/src/engine/{modules => core-modules}/quick-actions/intelligence.service.ts (93%) rename packages/twenty-server/src/engine/{modules => core-modules}/quick-actions/interfaces/company.interface.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/quick-actions/quick-actions.module.ts (69%) rename packages/twenty-server/src/engine/{modules => core-modules}/quick-actions/quick-actions.service.ts (95%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/dtos/create-refresh-token.input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/hooks/before-create-one-refresh-token.hook.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/refresh-token.auto-resolver-opts.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/refresh-token.entity.ts (94%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/refresh-token.module.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/services/refresh-token.service.spec.ts (88%) rename packages/twenty-server/src/engine/{modules => core-modules}/refresh-token/services/refresh-token.service.ts (62%) rename packages/twenty-server/src/engine/{modules => core-modules}/user-workspace/user-workspace.entity.ts (89%) rename packages/twenty-server/src/engine/{modules => core-modules}/user-workspace/user-workspace.module.ts (72%) rename packages/twenty-server/src/engine/{modules => core-modules}/user-workspace/user-workspace.service.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/dtos/workspace-member.dto.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/services/user.service.spec.ts (78%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/services/user.service.ts (88%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/user.auto-resolver-opts.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/user.entity.ts (84%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/user.module.ts (63%) rename packages/twenty-server/src/engine/{modules => core-modules}/user/user.resolver.ts (87%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/dtos/activate-workspace-input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/dtos/update-workspace-input.ts (100%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/services/workspace.service.spec.ts (74%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/services/workspace.service.ts (92%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/workspace.auto-resolver-opts.ts (89%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/workspace.entity.ts (84%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/workspace.module.ts (62%) rename packages/twenty-server/src/engine/{modules => core-modules}/workspace/workspace.resolver.ts (82%) rename packages/twenty-server/src/{engine-metadata/decorators/is-valid-name.decorator.ts => engine/decorators/metadata/is-valid-metadata-name.decorator.ts} (89%) delete mode 100644 packages/twenty-server/src/engine/integrations/environment/environment.default.ts rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/data-source/data-source.entity.ts (89%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/data-source/data-source.module.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/data-source/data-source.service.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/composite-types/currency.composite-type.ts (81%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/composite-types/full-name.composite-type.ts (81%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/composite-types/link.composite-type.ts (80%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/create-field.input.ts (84%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/default-value.input.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/field-metadata.dto.ts (69%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/options.input.ts (76%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/relation-definition.dto.ts (76%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/dtos/update-field.input.ts (88%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/field-metadata.entity.ts (76%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/field-metadata.module.ts (71%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/field-metadata.resolver.ts (67%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/field-metadata.service.ts (90%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/hooks/before-delete-one-field.hook.ts (86%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/interfaces/field-metadata-default-value.interface.ts (94%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/interfaces/field-metadata-options.interface.ts (79%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/interfaces/field-metadata-target-column-map.interface.ts (91%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface.ts rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/interfaces/object-metadata.interface.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/interfaces/relation-metadata.interface.ts (83%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/__tests__/generate-nullable.spec.ts (85%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/__tests__/generate-target-column-map.spec.ts (81%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/__tests__/serialize-default-value.spec.ts (92%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts (95%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/generate-default-value.ts (71%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/generate-nullable.ts (75%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/generate-rating-optionts.util.ts (79%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/generate-target-column-map.util.ts (83%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/is-composite-field-metadata-type.util.ts (75%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/is-enum-field-metadata-type.util.ts (79%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/serialize-default-value.ts (85%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/serialize-type-default-value.util.ts (68%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/validate-default-value-for-type.util.ts (88%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/utils/validate-options-for-type.util.ts (82%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/validators/is-field-metadata-default-value.validator.ts (73%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/validators/is-field-metadata-options.validator.ts (72%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/field-metadata/validators/is-valid-graphql-enum-name.validator.ts (100%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/dtos/create-object.input.ts (78%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/dtos/delete-object.input.ts (71%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/dtos/object-metadata.dto.ts (84%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/dtos/update-object.input.ts (79%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/hooks/before-create-one-object.hook.ts (90%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/hooks/before-delete-one-object.hook.ts (91%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/hooks/before-update-one-object.hook.ts (90%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/object-metadata.entity.ts (83%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/object-metadata.module.ts (79%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/object-metadata.resolver.ts (62%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/object-metadata/object-metadata.service.ts (97%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/dtos/create-relation.input.ts (84%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/dtos/relation-metadata.dto.ts (78%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/hooks/before-create-one-relation.hook.ts (84%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/hooks/before-delete-one-field.hook.ts (91%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/relation-metadata.entity.ts (85%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/relation-metadata.module.ts (83%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/relation-metadata.service.ts (89%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/types/relation-to-delete.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts (77%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-cache-version/workspace-cache-version.entity.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-cache-version/workspace-cache-version.module.ts (55%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-cache-version/workspace-cache-version.service.ts (88%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/factories/basic-column-action.factory.ts (77%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/factories/column-action-abstract.factory.ts (76%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/factories/enum-column-action.factory.ts (82%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/factories.ts rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/interfaces/workspace-column-action-factory.interface.ts (52%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/interfaces/workspace-column-action-options.interface.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/utils/field-metadata-type-to-column-type.util.ts (91%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/utils/generate-migration-name.util.ts (100%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/workspace-migration.entity.ts (95%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/workspace-migration.factory.ts (83%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/workspace-migration.module.ts (70%) rename packages/twenty-server/src/{engine-metadata => engine/metadata-modules}/workspace-migration/workspace-migration.service.ts (100%) delete mode 100644 packages/twenty-server/src/engine/modules/auth/types/jwt-data.type.ts delete mode 100644 packages/twenty-server/src/engine/modules/billing/billing.module.ts delete mode 100644 packages/twenty-server/src/engine/modules/engine-modules.module.ts delete mode 100644 packages/twenty-server/src/engine/modules/feature-flag/interfaces/feature-flag-map.interface.ts delete mode 100644 packages/twenty-server/src/engine/modules/open-api/open-api.module.ts create mode 100644 packages/twenty-server/src/engine/strategies/aggregate-by-workspace-context-id.strategy.ts rename packages/twenty-server/src/{engine-metadata => engine}/utils/create-custom-column-name.util.ts (100%) rename packages/twenty-server/src/engine/{filters => }/utils/global-exception-handler.util.ts (97%) rename packages/twenty-server/src/engine/{filters => }/utils/graphql-errors.util.ts (100%) diff --git a/packages/twenty-server/.env.example b/packages/twenty-server/.env.example index d8e3f31fb00e..4959f2e8207f 100644 --- a/packages/twenty-server/.env.example +++ b/packages/twenty-server/.env.example @@ -14,6 +14,7 @@ SIGN_IN_PREFILLED=true # ———————— Optional ———————— # PORT=3000 # DEBUG_MODE=true +# DEBUG_PORT=9000 # ACCESS_TOKEN_EXPIRES_IN=30m # LOGIN_TOKEN_EXPIRES_IN=15m # API_TOKEN_EXPIRES_IN=1000y diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index b5c913daee80..2309ebe441cc 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -36,12 +36,13 @@ "@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga+nestjs+2.1.0.patch", "@nestjs/cache-manager": "^2.2.1", "@nestjs/devtools-integration": "^0.1.6", - "@nestjs/graphql": "patch:@nestjs/graphql@12.0.8#./patches/@nestjs+graphql+12.0.8.patch", + "@nestjs/graphql": "patch:@nestjs/graphql@12.1.1#./patches/@nestjs+graphql+12.1.1.patch", "@ptc-org/nestjs-query-graphql": "patch:@ptc-org/nestjs-query-graphql@4.2.0#./patches/@ptc-org+nestjs-query-graphql+4.2.0.patch", "cache-manager": "^5.4.0", "cache-manager-redis-yet": "^4.1.2", "class-validator": "patch:class-validator@0.14.0#./patches/class-validator+0.14.0.patch", "graphql-middleware": "^6.1.35", + "jwt-decode": "^4.0.0", "passport": "^0.7.0", "psl": "^1.9.0" }, diff --git a/packages/twenty-server/patches/@nestjs+graphql+12.0.8.patch b/packages/twenty-server/patches/@nestjs+graphql+12.1.1.patch similarity index 80% rename from packages/twenty-server/patches/@nestjs+graphql+12.0.8.patch rename to packages/twenty-server/patches/@nestjs+graphql+12.1.1.patch index c69764b78837..47643c5b6fb3 100644 --- a/packages/twenty-server/patches/@nestjs+graphql+12.0.8.patch +++ b/packages/twenty-server/patches/@nestjs+graphql+12.1.1.patch @@ -1,8 +1,8 @@ diff --git a/dist/schema-builder/graphql-schema.factory.js b/dist/schema-builder/graphql-schema.factory.js -index 787bcbc..1c825bd 100644 +index f349a6e..425815c 100644 --- a/dist/schema-builder/graphql-schema.factory.js +++ b/dist/schema-builder/graphql-schema.factory.js -@@ -32,6 +32,7 @@ let GraphQLSchemaFactory = exports.GraphQLSchemaFactory = GraphQLSchemaFactory_1 +@@ -32,6 +32,7 @@ let GraphQLSchemaFactory = GraphQLSchemaFactory_1 = class GraphQLSchemaFactory { else { options = scalarsOrOptions; } @@ -11,10 +11,10 @@ index 787bcbc..1c825bd 100644 type_metadata_storage_1.TypeMetadataStorage.compile(options.orphanedTypes); this.typeDefinitionsGenerator.generate(options); diff --git a/dist/schema-builder/storages/type-definitions.storage.js b/dist/schema-builder/storages/type-definitions.storage.js -index d100444..158c592 100644 +index a19dee7..466ee86 100644 --- a/dist/schema-builder/storages/type-definitions.storage.js +++ b/dist/schema-builder/storages/type-definitions.storage.js -@@ -81,6 +81,10 @@ let TypeDefinitionsStorage = exports.TypeDefinitionsStorage = class TypeDefiniti +@@ -81,6 +81,10 @@ let TypeDefinitionsStorage = class TypeDefinitionsStorage { } return; } @@ -23,13 +23,13 @@ index d100444..158c592 100644 + this.outputTypeDefinitionsLinks = null; + } }; + exports.TypeDefinitionsStorage = TypeDefinitionsStorage; exports.TypeDefinitionsStorage = TypeDefinitionsStorage = tslib_1.__decorate([ - (0, common_1.Injectable)() diff --git a/dist/schema-builder/type-definitions.generator.js b/dist/schema-builder/type-definitions.generator.js -index eb6bcfd..4fbc1ae 100644 +index d5423f1..701a3b2 100644 --- a/dist/schema-builder/type-definitions.generator.js +++ b/dist/schema-builder/type-definitions.generator.js -@@ -26,6 +26,9 @@ let TypeDefinitionsGenerator = exports.TypeDefinitionsGenerator = class TypeDefi +@@ -26,6 +26,9 @@ let TypeDefinitionsGenerator = class TypeDefinitionsGenerator { this.generateObjectTypeDefs(options); this.generateInputTypeDefs(options); } diff --git a/packages/twenty-server/src/app.module.ts b/packages/twenty-server/src/app.module.ts index 04025def2de0..24c9e07f60fc 100644 --- a/packages/twenty-server/src/app.module.ts +++ b/packages/twenty-server/src/app.module.ts @@ -1,40 +1,54 @@ import { DynamicModule, Module } from '@nestjs/common'; -import { GraphQLModule } from '@nestjs/graphql'; import { ConfigModule } from '@nestjs/config'; import { ServeStaticModule } from '@nestjs/serve-static'; +import { DevtoolsModule } from '@nestjs/devtools-integration'; +import { GraphQLModule } from '@nestjs/graphql'; import { existsSync } from 'fs'; import { join } from 'path'; -import { YogaDriver, YogaDriverConfig } from '@graphql-yoga/nestjs'; +import { YogaDriverConfig, YogaDriver } from '@graphql-yoga/nestjs'; -import { GraphQLConfigService } from 'src/engine-graphql-config/graphql-config.service'; import { ApiRestModule } from 'src/engine/api/rest/api-rest.module'; import { ModulesModule } from 'src/modules/modules.module'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; +import { CoreGraphQLApiModule } from 'src/engine/api/graphql/core-graphql-api.module'; +import { MetadataGraphQLApiModule } from 'src/engine/api/graphql/metadata-graphql-api.module'; +import { GraphQLConfigModule } from 'src/engine/api/graphql/graphql-config/graphql-config.module'; +import { GraphQLConfigService } from 'src/engine/api/graphql/graphql-config/graphql-config.service'; -import { EngineModulesModule } from './engine/modules/engine-modules.module'; +import { CoreEngineModule } from './engine/core-modules/core-engine.module'; import { IntegrationsModule } from './engine/integrations/integrations.module'; -import { CoreGraphqlApiModule } from './engine/api/graphql/core-graphql-api.module'; -import { GraphQLConfigModule } from './engine-graphql-config/graphql-config.module'; @Module({ imports: [ - // DevtoolsModule.register({ - // http: process.env.NODE_ENV !== 'production', - // }), + // Nest.js devtools, use devtools.nestjs.com to debug + DevtoolsModule.registerAsync({ + useFactory: (environmentService: EnvironmentService) => ({ + http: environmentService.get('DEBUG_MODE'), + port: environmentService.get('DEBUG_PORT'), + }), + inject: [EnvironmentService], + }), ConfigModule.forRoot({ isGlobal: true, }), GraphQLModule.forRootAsync({ driver: YogaDriver, - imports: [EngineModulesModule, GraphQLConfigModule], + imports: [CoreEngineModule, GraphQLConfigModule], useClass: GraphQLConfigService, }), + // Integrations module, contains all the integrations with other services IntegrationsModule, - EngineModulesModule, + // Core engine module, contains all the core modules + CoreEngineModule, + // Modules module, contains all business logic modules ModulesModule, + // Api modules + CoreGraphQLApiModule, + MetadataGraphQLApiModule, ApiRestModule, - CoreGraphqlApiModule, + // Conditional modules ...AppModule.getConditionalModules(), ], }) diff --git a/packages/twenty-server/src/app.service.ts b/packages/twenty-server/src/app.service.ts deleted file mode 100644 index 2849c691283e..000000000000 --- a/packages/twenty-server/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - health(): string { - return 'Healthy!'; - } -} diff --git a/packages/twenty-server/src/command/command.ts b/packages/twenty-server/src/command/command.ts index b73377d6bd54..2ebc22bdedfb 100644 --- a/packages/twenty-server/src/command/command.ts +++ b/packages/twenty-server/src/command/command.ts @@ -2,7 +2,7 @@ import { ConfigService } from '@nestjs/config'; import { CommandFactory } from 'nest-commander'; -import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; +import { filterException } from 'src/engine/utils/global-exception-handler.util'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { LoggerService } from 'src/engine/integrations/logger/logger.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index 97a012d18cfa..0a8ec622e022 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -1,7 +1,7 @@ import { Command, CommandRunner } from 'nest-commander'; import { DataSource } from 'typeorm'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { seedCompanies } from 'src/database/typeorm-seeds/workspace/companies'; import { seedViews } from 'src/database/typeorm-seeds/workspace/views'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; @@ -10,7 +10,7 @@ import { seedPipelineStep } from 'src/database/typeorm-seeds/workspace/pipeline- import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/workspaceMember'; import { seedPeople } from 'src/database/typeorm-seeds/workspace/people'; import { seedCoreSchema } from 'src/database/typeorm-seeds/core'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events'; diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index a99e511e67f8..1e85f0309a86 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -2,13 +2,13 @@ import { Module } from '@nestjs/common'; import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { WorkspaceModule } from 'src/engine/modules/workspace/workspace.module'; +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { StartDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command'; import { StopDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command'; import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command'; diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts index 98a4ce34b491..9e5cbd752644 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts @@ -1,6 +1,6 @@ import { DataSource } from 'typeorm'; -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; const tableName = 'featureFlag'; diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts b/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts index f3902d95c580..754f6b41f823 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/userWorkspaces.ts @@ -4,7 +4,7 @@ import { SeedAppleWorkspaceId, SeedTwentyWorkspaceId, } from 'src/database/typeorm-seeds/core/workspaces'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; // import { SeedWorkspaceId } from 'src/database/typeorm-seeds/core/workspaces'; diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts b/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts index 75513e5ccb54..83314b575a1d 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/workspaces.ts @@ -1,6 +1,6 @@ import { DataSource } from 'typeorm'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; const tableName = 'workspace'; diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts index db118df5f20f..f3846bb2d500 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts @@ -1,6 +1,6 @@ import { DataSource } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export const seedViews = async ( workspaceDataSource: DataSource, diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts index 643238873678..7d686c130567 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts @@ -5,7 +5,7 @@ import { SeedAppleWorkspaceId, SeedTwentyWorkspaceId, } from 'src/database/typeorm-seeds/core/workspaces'; -import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; +import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto'; const tableName = 'workspaceMember'; diff --git a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts index 0d2bbbcddb32..751442c65770 100644 --- a/packages/twenty-server/src/database/typeorm/core/core.datasource.ts +++ b/packages/twenty-server/src/database/typeorm/core/core.datasource.ts @@ -11,7 +11,7 @@ export const typeORMCoreModuleOptions: TypeOrmModuleOptions = { type: 'postgres', logging: ['error'], schema: 'core', - entities: ['dist/src/engine/modules/**/*.entity{.ts,.js}'], + entities: ['dist/src/engine/core-modules/**/*.entity{.ts,.js}'], synchronize: false, migrationsRun: false, migrationsTableName: '_typeorm_migrations', diff --git a/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts b/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts index 408f047bea24..b6fb0018ddfb 100644 --- a/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts +++ b/packages/twenty-server/src/database/typeorm/metadata/metadata.datasource.ts @@ -11,7 +11,7 @@ export const typeORMMetadataModuleOptions: TypeOrmModuleOptions = { type: 'postgres', logging: ['error'], schema: 'metadata', - entities: ['dist/src/engine-metadata/**/*.entity{.ts,.js}'], + entities: ['dist/src/engine/metadata-modules/**/*.entity{.ts,.js}'], synchronize: false, migrationsRun: false, migrationsTableName: '_typeorm_migrations', diff --git a/packages/twenty-server/src/database/typeorm/typeorm.service.ts b/packages/twenty-server/src/database/typeorm/typeorm.service.ts index 595e0a3d929c..675c7c1f19f5 100644 --- a/packages/twenty-server/src/database/typeorm/typeorm.service.ts +++ b/packages/twenty-server/src/database/typeorm/typeorm.service.ts @@ -3,14 +3,14 @@ import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; -import { BillingSubscriptionItem } from 'src/engine/modules/billing/entities/billing-subscription-item.entity'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; @Injectable() export class TypeORMService implements OnModuleInit, OnModuleDestroy { diff --git a/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts b/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts deleted file mode 100644 index 4106ae69a2f6..000000000000 --- a/packages/twenty-server/src/engine-graphql-config/graphql-config.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { EngineModulesModule } from 'src/engine/modules/engine-modules.module'; -import { graphQLFactories } from 'src/engine-graphql-config/factories'; - -@Module({ - imports: [EngineModulesModule], - providers: [...graphQLFactories], - exports: [...graphQLFactories], -}) -export class GraphQLConfigModule {} diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/index.ts b/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/index.ts deleted file mode 100644 index 5ea08efd56f7..000000000000 --- a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; - -import { currencyFields } from 'src/engine-metadata/field-metadata/composite-types/currency.composite-type'; -import { fullNameFields } from 'src/engine-metadata/field-metadata/composite-types/full-name.composite-type'; -import { linkFields } from 'src/engine-metadata/field-metadata/composite-types/link.composite-type'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; - -export type CompositeFieldsDefinitionFunction = ( - fieldMetadata?: FieldMetadataInterface, -) => FieldMetadataInterface[]; - -export const compositeDefinitions = new Map< - string, - CompositeFieldsDefinitionFunction ->([ - [FieldMetadataType.LINK, linkFields], - [FieldMetadataType.CURRENCY, currencyFields], - [FieldMetadataType.FULL_NAME, fullNameFields], -]); diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata.interface.ts b/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata.interface.ts deleted file mode 100644 index 6991e1113159..000000000000 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata.interface.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { FieldMetadataTargetColumnMap } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; - -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; - -export interface FieldMetadataInterface< - T extends FieldMetadataType | 'default' = 'default', -> { - id: string; - type: FieldMetadataType; - name: string; - label: string; - targetColumnMap: FieldMetadataTargetColumnMap; - defaultValue?: FieldMetadataDefaultValue; - options?: FieldMetadataOptions; - objectMetadataId: string; - workspaceId?: string; - description?: string; - isNullable?: boolean; - fromRelationMetadata?: RelationMetadataEntity; - toRelationMetadata?: RelationMetadataEntity; - isCustom?: boolean; -} diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/factories.ts b/packages/twenty-server/src/engine-metadata/workspace-migration/factories/factories.ts deleted file mode 100644 index 9248ffcaa127..000000000000 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/factories.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BasicColumnActionFactory } from 'src/engine-metadata/workspace-migration/factories/basic-column-action.factory'; -import { EnumColumnActionFactory } from 'src/engine-metadata/workspace-migration/factories/enum-column-action.factory'; - -export const workspaceColumnActionFactories = [ - BasicColumnActionFactory, - EnumColumnActionFactory, -]; diff --git a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index 04860d38203b..77c1fd5f2cbe 100644 --- a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export const fieldNumberMock = { name: 'fieldNumber', diff --git a/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts index 3883c85e178a..29fde8f18e39 100644 --- a/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/__tests__/workspace.factory.spec.ts @@ -1,20 +1,20 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory'; import { WorkspaceGraphQLSchemaFactory } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; -import { WorkspaceFactory } from 'src/engine/api/graphql/workspace.factory'; +import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory'; -describe('WorkspaceFactory', () => { - let service: WorkspaceFactory; +describe('WorkspaceSchemaFactory', () => { + let service: WorkspaceSchemaFactory; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ - WorkspaceFactory, + WorkspaceSchemaFactory, { provide: DataSourceService, useValue: {}, @@ -42,7 +42,7 @@ describe('WorkspaceFactory', () => { ], }).compile(); - service = module.get(WorkspaceFactory); + service = module.get(WorkspaceSchemaFactory); }); it('should be defined', () => { diff --git a/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts index 8bbcda974521..0ea069944d22 100644 --- a/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts @@ -1,25 +1,28 @@ import { Module } from '@nestjs/common'; -import { MetadataModule } from 'src/engine-metadata/metadata.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; import { WorkspaceSchemaStorageModule } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; import { WorkspaceSchemaBuilderModule } from 'src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module'; import { WorkspaceResolverBuilderModule } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module'; +import { MetadataEngineModule } from 'src/engine/metadata-modules/metadata-engine.module'; -import { WorkspaceFactory } from './workspace.factory'; +import { WorkspaceSchemaFactory } from './workspace-schema.factory'; @Module({ imports: [ - MetadataModule, - DataSourceModule, - ObjectMetadataModule, + // TODO: Seems like it's breaking /metadata query and mutation arguments + // we should investigate this issue + // GraphQLModule.forRootAsync({ + // driver: YogaDriver, + // imports: [CoreEngineModule, GraphQLConfigModule], + // useClass: GraphQLConfigService, + // }), + MetadataEngineModule, WorkspaceSchemaBuilderModule, WorkspaceResolverBuilderModule, WorkspaceSchemaStorageModule, ], - providers: [WorkspaceFactory, ScalarsExplorerService], - exports: [WorkspaceFactory], + providers: [WorkspaceSchemaFactory, ScalarsExplorerService], + exports: [WorkspaceSchemaFactory], }) -export class CoreGraphqlApiModule {} +export class CoreGraphQLApiModule {} diff --git a/packages/twenty-server/src/engine-graphql-config/factories/create-context.factory.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/factories/create-context.factory.ts similarity index 76% rename from packages/twenty-server/src/engine-graphql-config/factories/create-context.factory.ts rename to packages/twenty-server/src/engine/api/graphql/graphql-config/factories/create-context.factory.ts index 0e7e3e58879d..0071474e0bae 100644 --- a/packages/twenty-server/src/engine-graphql-config/factories/create-context.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-config/factories/create-context.factory.ts @@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common'; import { YogaDriverServerContext } from '@graphql-yoga/nestjs'; -import { GraphQLContext } from 'src/engine-graphql-config/interfaces/graphql-context.interface'; +import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; @Injectable() export class CreateContextFactory { diff --git a/packages/twenty-server/src/engine-graphql-config/factories/index.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/factories/index.ts similarity index 100% rename from packages/twenty-server/src/engine-graphql-config/factories/index.ts rename to packages/twenty-server/src/engine/api/graphql/graphql-config/factories/index.ts diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts new file mode 100644 index 000000000000..01bf03a9a3fa --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module'; +import { graphQLFactories } from 'src/engine/api/graphql/graphql-config/factories'; + +@Module({ + imports: [CoreEngineModule], + providers: [...graphQLFactories], + exports: [...graphQLFactories], +}) +export class GraphQLConfigModule {} diff --git a/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.service.ts similarity index 87% rename from packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts rename to packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.service.ts index fb9212e3671c..8c1044376b24 100644 --- a/packages/twenty-server/src/engine-graphql-config/graphql-config.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.service.ts @@ -12,18 +12,18 @@ import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken'; import { GraphQLSchemaWithContext, YogaInitialContext } from 'graphql-yoga'; import * as Sentry from '@sentry/node'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { EngineModulesModule } from 'src/engine/modules/engine-modules.module'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { WorkspaceFactory } from 'src/engine/api/graphql/workspace.factory'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; -import { handleExceptionAndConvertToGraphQLError } from 'src/engine/filters/utils/global-exception-handler.util'; +import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util'; import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { useExceptionHandler } from 'src/engine/integrations/exception-handler/hooks/use-exception-handler.hook'; -import { User } from 'src/engine/modules/user/user.entity'; -import { useThrottler } from 'src/engine-graphql-config/hooks/use-throttler'; -import { JwtData } from 'src/engine/modules/auth/types/jwt-data.type'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler'; +import { JwtData } from 'src/engine/core-modules/auth/types/jwt-data.type'; import { useSentryTracing } from 'src/engine/integrations/exception-handler/hooks/use-sentry-tracing'; import { CreateContextFactory } from './factories/create-context.factory'; @@ -67,7 +67,7 @@ export class GraphQLConfigService const config: YogaDriverConfig = { context: (context) => this.createContextFactory.create(context), autoSchemaFile: true, - include: [EngineModulesModule], + include: [CoreEngineModule], conditionalSchema: async (context) => { let user: User | undefined; let workspace: Workspace | undefined; @@ -148,9 +148,9 @@ export class GraphQLConfigService // Register the request in the contextId this.moduleRef.registerRequestByContextId(context.req, contextId); - // Resolve the WorkspaceFactory for the contextId + // Resolve the WorkspaceSchemaFactory for the contextId const workspaceFactory = await this.moduleRef.resolve( - WorkspaceFactory, + WorkspaceSchemaFactory, contextId, { strict: false, diff --git a/packages/twenty-server/src/engine-graphql-config/hooks/use-throttler.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/hooks/use-throttler.ts similarity index 96% rename from packages/twenty-server/src/engine-graphql-config/hooks/use-throttler.ts rename to packages/twenty-server/src/engine/api/graphql/graphql-config/hooks/use-throttler.ts index ffafe4f81086..6959ef8f2b3b 100644 --- a/packages/twenty-server/src/engine-graphql-config/hooks/use-throttler.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-config/hooks/use-throttler.ts @@ -3,7 +3,7 @@ import { getGraphQLRateLimiter } from 'graphql-rate-limit'; import { Plugin } from '@envelop/core'; import { useOnResolve } from '@envelop/on-resolve'; -import { GraphQLContext } from 'src/engine-graphql-config/graphql-config.service'; +import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/graphql-config.service'; export class UnauthenticatedError extends Error {} diff --git a/packages/twenty-server/src/engine-graphql-config/interfaces/graphql-context.interface.ts b/packages/twenty-server/src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface.ts similarity index 56% rename from packages/twenty-server/src/engine-graphql-config/interfaces/graphql-context.interface.ts rename to packages/twenty-server/src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface.ts index eb7d254238a0..fcfd7aae5ae4 100644 --- a/packages/twenty-server/src/engine-graphql-config/interfaces/graphql-context.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface.ts @@ -1,7 +1,7 @@ import { YogaDriverServerContext } from '@graphql-yoga/nestjs'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; export interface GraphQLContext extends YogaDriverServerContext<'express'> { user?: User; diff --git a/packages/twenty-server/src/engine-metadata/metadata.module.ts b/packages/twenty-server/src/engine/api/graphql/metadata-graphql-api.module.ts similarity index 51% rename from packages/twenty-server/src/engine-metadata/metadata.module.ts rename to packages/twenty-server/src/engine/api/graphql/metadata-graphql-api.module.ts index 8702088754c2..5bfadcee7417 100644 --- a/packages/twenty-server/src/engine-metadata/metadata.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/metadata-graphql-api.module.ts @@ -4,17 +4,13 @@ import { GraphQLModule } from '@nestjs/graphql'; import { YogaDriverConfig, YogaDriver } from '@graphql-yoga/nestjs'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; -import { metadataModuleFactory } from 'src/engine-metadata/metadata.module-factory'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; +import { metadataModuleFactory } from 'src/engine/api/graphql/metadata.module-factory'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; -import { GraphQLConfigModule } from 'src/engine-graphql-config/graphql-config.module'; -import { CreateContextFactory } from 'src/engine-graphql-config/factories/create-context.factory'; - -import { DataSourceModule } from './data-source/data-source.module'; -import { FieldMetadataModule } from './field-metadata/field-metadata.module'; -import { ObjectMetadataModule } from './object-metadata/object-metadata.module'; -import { RelationMetadataModule } from './relation-metadata/relation-metadata.module'; +import { GraphQLConfigModule } from 'src/engine/api/graphql/graphql-config/graphql-config.module'; +import { CreateContextFactory } from 'src/engine/api/graphql/graphql-config/factories/create-context.factory'; +import { MetadataEngineModule } from 'src/engine/metadata-modules/metadata-engine.module'; @Module({ imports: [ @@ -28,12 +24,9 @@ import { RelationMetadataModule } from './relation-metadata/relation-metadata.mo CreateContextFactory, ], }), - DataSourceModule, - FieldMetadataModule, - ObjectMetadataModule, + MetadataEngineModule, WorkspaceMigrationRunnerModule, WorkspaceMigrationModule, - RelationMetadataModule, ], }) -export class MetadataModule {} +export class MetadataGraphQLApiModule {} diff --git a/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts b/packages/twenty-server/src/engine/api/graphql/metadata.module-factory.ts similarity index 82% rename from packages/twenty-server/src/engine-metadata/metadata.module-factory.ts rename to packages/twenty-server/src/engine/api/graphql/metadata.module-factory.ts index a11c05e71d4f..7252a43f64ad 100644 --- a/packages/twenty-server/src/engine-metadata/metadata.module-factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/metadata.module-factory.ts @@ -1,12 +1,12 @@ import { YogaDriverConfig } from '@graphql-yoga/nestjs'; import GraphQLJSON from 'graphql-type-json'; -import { CreateContextFactory } from 'src/engine-graphql-config/factories/create-context.factory'; +import { CreateContextFactory } from 'src/engine/api/graphql/graphql-config/factories/create-context.factory'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { useExceptionHandler } from 'src/engine/integrations/exception-handler/hooks/use-exception-handler.hook'; -import { useThrottler } from 'src/engine-graphql-config/hooks/use-throttler'; -import { MetadataModule } from 'src/engine-metadata/metadata.module'; +import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler'; +import { MetadataGraphQLApiModule } from 'src/engine/api/graphql/metadata-graphql-api.module'; import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util'; export const metadataModuleFactory = async ( @@ -19,7 +19,7 @@ export const metadataModuleFactory = async ( return createContextFactory.create(context); }, autoSchemaFile: true, - include: [MetadataModule], + include: [MetadataGraphQLApiModule], renderGraphiQL() { return renderApolloPlayground({ path: 'metadata' }); }, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts index 1f1f4fdb8006..98ec7e5d4290 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/__mocks__/workspace-query-builder-options.mock.ts @@ -1,6 +1,6 @@ import { GraphQLResolveInfo } from 'graphql'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts index a31cb422dcee..ca0a8b857219 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; @Injectable() export class ArgsAliasFactory { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts index df11f1611bbc..d28c124868a3 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-string.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts index ff0afdf47972..547c8704a127 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts @@ -1,6 +1,6 @@ import { Injectable, Logger } from '@nestjs/common'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; @Injectable() export class FieldAliasFactory { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts index 2dfc3eba88a6..e3ae2dfde33f 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory.ts @@ -4,8 +4,8 @@ import { GraphQLResolveInfo } from 'graphql'; import graphqlFields from 'graphql-fields'; import isEmpty from 'lodash.isempty'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts index c8f8bff1366e..5da08ed1a910 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/find-duplicates-query.factory.ts @@ -5,7 +5,7 @@ import isEmpty from 'lodash.isempty'; import { WorkspaceQueryBuilderOptions } from 'src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface'; import { RecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; import { FindDuplicatesResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts index c58b071ad268..113f2af43ca5 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/relation-field-alias.factory.ts @@ -2,17 +2,17 @@ import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; import { GraphQLResolveInfo } from 'graphql'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { deduceRelationDirection, RelationDirection, } from 'src/engine/utils/deduce-relation-direction.util'; import { getFieldArgumentsByKey } from 'src/engine/api/graphql/workspace-query-builder/utils/get-field-arguments-by-key.util'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { FieldsStringFactory } from './fields-string.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts index 15d5af79966e..4f1ace4a8013 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/interfaces/workspace-query-builder-options.interface.ts @@ -1,7 +1,7 @@ import { GraphQLResolveInfo } from 'graphql'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; export interface WorkspaceQueryBuilderOptions { objectMetadataItem: ObjectMetadataInterface; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts index 0325af39e03d..46367dd98e71 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { FieldsStringFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/fields-string.factory'; import { RecordPositionQueryFactory } from 'src/engine/api/graphql/workspace-query-builder/factories/record-position-query.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts index ea9076a2c9cc..7569a35728e8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/__tests__/query-runner-args.factory.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RecordPositionFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/record-position.factory'; describe('QueryRunnerArgsFactory', () => { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts index 6ea3a300ea92..5c61aeb099d5 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory.ts @@ -3,10 +3,10 @@ import { Injectable } from '@nestjs/common'; import { addMilliseconds } from 'date-fns'; import ms from 'ms'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; @Injectable() export class QueryResultGettersFactory { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts index 8bc5df46320b..f5c2d80c272b 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts @@ -1,9 +1,9 @@ import { Injectable } from '@nestjs/common'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RecordPositionFactory } from './record-position.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts index 9a94a9d71982..13b462a04cbe 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface.ts @@ -1,7 +1,7 @@ import { GraphQLResolveInfo } from 'graphql'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; export interface WorkspaceQueryRunnerOptions { workspaceId: string; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts index c05e094e47db..46b4eed29df3 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job.ts @@ -1,11 +1,11 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts index 44fbad59c54d..82cab4e27859 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; export type SaveEventToDbJobData = { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts index 6f6b25f8d699..f13047daf9db 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts @@ -14,7 +14,7 @@ import { import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @Injectable() export class EntityEventsToDbListener { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts index 8e3a23916e02..9d9ea3803f33 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts index a8fb36582c0c..42242d086730 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index b9feb83faac8..f2dcdd20397c 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -6,9 +6,9 @@ import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/works import { WorkspacePreQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module'; import { workspaceQueryRunnerFactories } from 'src/engine/api/graphql/workspace-query-runner/factories'; import { RecordPositionListener } from 'src/engine/api/graphql/workspace-query-runner/listeners/record-position.listener'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { WorkspaceQueryRunnerService } from './workspace-query-runner.service'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index 1088f2ad7592..dd9ae0f08b7e 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -25,7 +25,7 @@ import { UpdateManyResolverArgs, UpdateOneResolverArgs, } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { WorkspaceQueryBuilderFactory } from 'src/engine/api/graphql/workspace-query-builder/workspace-query-builder.factory'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; @@ -43,7 +43,7 @@ import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/t import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { NotFoundError } from 'src/engine/filters/utils/graphql-errors.util'; +import { NotFoundError } from 'src/engine/utils/graphql-errors.util'; import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory'; import { QueryResultGettersFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts index 6ab4c61be6e4..3968ed760b3a 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory.ts @@ -12,7 +12,7 @@ import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; -import { QuickActionsService } from 'src/engine/modules/quick-actions/quick-actions.service'; +import { QuickActionsService } from 'src/engine/core-modules/quick-actions/quick-actions.service'; @Injectable() export class ExecuteQuickActionOnOneResolverFactory diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts index 3cbef4cf4c00..85a84f17a647 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module'; -import { QuickActionsModule } from 'src/engine/modules/quick-actions/quick-actions.module'; +import { QuickActionsModule } from 'src/engine/core-modules/quick-actions/quick-actions.module'; import { WorkspaceResolverFactory } from './workspace-resolver.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts index 8e2a548d897c..a0071bea7bbc 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { IResolvers } from '@graphql-tools/utils'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts index ef9d88548052..e309d4c38421 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type-definition.factory.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLInt, GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts index 41919c7157a7..d6400e7cb0d8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/connection-type.factory.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { TypeMapperService, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts index 877a6e9b22d3..154684e97a34 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type-definition.factory.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts index ea1bdaafdbd3..30ddfd0166a9 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/edge-type.factory.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { TypeMapperService, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts index def7d1095a48..de77733d6151 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory.ts @@ -3,15 +3,15 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLEnumType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; import { FieldMetadataComplexOption, FieldMetadataDefaultOption, -} from 'src/engine-metadata/field-metadata/dtos/options.input'; -import { isEnumFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util'; +} from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; +import { isEnumFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util'; export interface EnumTypeDefinition { target: string; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts index 98766740b62a..1e2b9c5634e7 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/extend-object-type-definition.factory.ts @@ -7,7 +7,7 @@ import { } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { objectContainsRelationField } from 'src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field'; @@ -17,7 +17,7 @@ import { RelationDirection, deduceRelationDirection, } from 'src/engine/utils/deduce-relation-direction.util'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { RelationTypeFactory } from './relation-type.factory'; import { ArgsFactory } from './args.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts index c2c558e5d554..5a545f05810b 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type-definition.factory.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts index 19477e8cb30e..98fd306f8b60 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/filter-type.factory.ts @@ -8,15 +8,15 @@ import { } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; -import { isEnumFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; +import { isEnumFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util'; import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts index 9511b44280a2..6908bc9f3fb8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { InputTypeFactory } from './input-type.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts index 7a5a5e10f743..d1bd5f248957 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/input-type.factory.ts @@ -3,14 +3,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLInputType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts index dbcb506cd74b..b19e73898b18 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/mutation-type.factory.ts @@ -4,7 +4,7 @@ import { GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { WorkspaceResolverBuilderMutationMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { ObjectTypeName, RootTypeFactory } from './root-type.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts index 343df7faae9f..9974139b89d3 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory.ts @@ -3,11 +3,11 @@ import { Injectable } from '@nestjs/common'; import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { OutputTypeFactory } from './output-type.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts index 0b10df54c1a8..2ea6d00c0c5d 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type-definition.factory.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { GraphQLInputFieldConfigMap, GraphQLInputObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { pascalCase } from 'src/utils/pascal-case'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts index d452538a26a7..0ab71f514082 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/order-by-type.factory.ts @@ -3,14 +3,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLInputType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { InputTypeDefinitionKind } from './input-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts index 7ba617ebfc86..9a10ef836cf0 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/output-type.factory.ts @@ -3,14 +3,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { TypeMapperService, TypeOptions, } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { ObjectTypeDefinitionKind } from './object-type-definition.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts index 2275cdca3441..59ce2e0f455f 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/query-type.factory.ts @@ -4,7 +4,7 @@ import { GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { WorkspaceResolverBuilderQueryMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { ObjectTypeName, RootTypeFactory } from './root-type.factory'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts index c4a68a6b2d1b..2c5fbea0bba1 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/relation-type.factory.ts @@ -2,10 +2,10 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLOutputType } from 'graphql'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { RelationMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/relation-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { RelationMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { RelationDirection } from 'src/engine/utils/deduce-relation-direction.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts index b5ec65507924..66a031420ab8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/factories/root-type.factory.ts @@ -4,7 +4,7 @@ import { GraphQLFieldConfigMap, GraphQLObjectType } from 'graphql'; import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { TypeDefinitionsStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage'; import { getResolverName } from 'src/engine/utils/get-resolver-name.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts index d117c560eebf..8a4071d6ca78 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface.ts @@ -1,5 +1,5 @@ import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export interface ArgMetadata { kind?: InputTypeDefinitionKind; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts index 8da8a2c0bfe3..1cbf69aef60d 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface.ts @@ -1,5 +1,5 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; export interface WorkspaceSchemaBuilderContext { workspaceId: string; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index 32a8c0b7c6d9..6b072c2dfc91 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -22,7 +22,7 @@ import { NumberScalarMode, } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { UUIDFilterType, StringFilterType, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts index 9e539bc5d44a..2d89820e16b3 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/type-definitions.storage.ts @@ -6,7 +6,7 @@ import { GraphQLObjectType, } from 'graphql'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { EnumTypeDefinition } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; import { InputTypeDefinition, @@ -18,7 +18,7 @@ import { } from 'src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory'; // Must be scoped on REQUEST level -@Injectable({ scope: Scope.REQUEST }) +@Injectable({ scope: Scope.REQUEST, durable: true }) export class TypeDefinitionsStorage { private readonly enumTypeDefinitions = new Map(); private readonly objectTypeDefinitions = new Map< diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts index 595db1c6bd63..8eb4ca3eae04 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts @@ -1,13 +1,13 @@ import { Injectable, Logger } from '@nestjs/common'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { customTableDefaultColumns } from 'src/engine/workspace-manager/workspace-migration-runner/utils/custom-table-default-column.util'; -import { fullNameObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/full-name.composite-type'; -import { currencyObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/currency.composite-type'; -import { linkObjectDefinition } from 'src/engine-metadata/field-metadata/composite-types/link.composite-type'; +import { fullNameObjectDefinition } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; +import { currencyObjectDefinition } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type'; +import { linkObjectDefinition } from 'src/engine/metadata-modules/field-metadata/composite-types/link.composite-type'; import { EnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; import { TypeDefinitionsStorage } from './storages/type-definitions.storage'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts index 459140af68dc..a2c311d3e783 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-field-metadata-type.spec.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { getFieldMetadataType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util'; describe('getFieldMetadataType', () => { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts index 60d569aa815b..3d4763054035 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/__tests__/get-resolver-args.spec.ts @@ -1,6 +1,6 @@ import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; import { getResolverArgs } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts index 025309f21c33..4784ff27c479 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-field-metadata-type.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; const typeOrmTypeMapping = new Map([ ['uuid', FieldMetadataType.UUID], diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts index 8d1dc4537912..0f99bc0db570 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util.ts @@ -1,7 +1,7 @@ import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { ArgMetadata } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory'; export const getResolverArgs = ( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts index b705b2bb4bb1..e842e4219678 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/object-contains-relation-field.ts @@ -1,4 +1,4 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts index eb25eaa1d664..6d1708db0aa0 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { GraphQLSchema } from 'graphql'; import { WorkspaceResolverBuilderMethods } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { TypeDefinitionsGenerator } from './type-definitions.generator'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts index cdcecb83c5fa..f4be416d1fc6 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; -import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { TypeDefinitionsGenerator } from './type-definitions.generator'; import { WorkspaceGraphQLSchemaFactory } from './workspace-graphql-schema.factory'; @@ -18,7 +17,6 @@ import { TypeMapperService } from './services/type-mapper.service'; TypeDefinitionsStorage, TypeMapperService, WorkspaceGraphQLSchemaFactory, - JwtAuthGuard, ], exports: [WorkspaceGraphQLSchemaFactory], }) diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts index a24c410f48b0..bd57d9db28b8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { WorkspaceCacheVersionModule } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; @Module({ diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts index 0ab8433db156..6733aa8bd132 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service.ts @@ -2,8 +2,8 @@ import { Inject, Injectable } from '@nestjs/common'; import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service'; import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceCacheVersionService } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.service'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; @Injectable() export class WorkspaceSchemaStorageService { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts similarity index 94% rename from packages/twenty-server/src/engine/api/graphql/workspace.factory.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts index 2951eaf5ee9b..608e7a952a6a 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema.factory.ts @@ -4,16 +4,16 @@ import { GraphQLSchema, printSchema } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { gql } from 'graphql-tag'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { WorkspaceSchemaStorageService } from 'src/engine/api/graphql/workspace-schema-storage/workspace-schema-storage.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars-explorer.service'; import { WorkspaceGraphQLSchemaFactory } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/factories/factories'; import { WorkspaceResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory'; @Injectable() -export class WorkspaceFactory { +export class WorkspaceSchemaFactory { constructor( private readonly dataSourceService: DataSourceService, private readonly objectMetadataService: ObjectMetadataService, diff --git a/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts index 3427d320ed0f..83ed4dadfd9c 100644 --- a/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/__tests__/api-rest.service.spec.ts @@ -3,7 +3,7 @@ import { HttpService } from '@nestjs/axios'; import { ApiRestService } from 'src/engine/api/rest/api-rest.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; describe('ApiRestService', () => { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts index 3ba006091928..579786a214af 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/__tests__/api-rest-query-builder.factory.spec.ts @@ -10,8 +10,8 @@ import { DeleteVariablesFactory } from 'src/engine/api/rest/api-rest-query-build import { CreateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-variables.factory'; import { UpdateVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-variables.factory'; import { GetVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; describe('ApiRestQueryBuilderFactory', () => { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts index 74bfe7e0908b..e6df92853c71 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory.ts @@ -3,8 +3,8 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { Request } from 'express'; import { DeleteQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/delete-query.factory'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { CreateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/create-query.factory'; import { UpdateQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/update-query.factory'; import { FindOneQueryFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/find-one-query.factory'; @@ -15,7 +15,7 @@ import { UpdateVariablesFactory } from 'src/engine/api/rest/api-rest-query-build import { GetVariablesFactory } from 'src/engine/api/rest/api-rest-query-builder/factories/get-variables.factory'; import { parsePath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; import { computeDepth } from 'src/engine/api/rest/api-rest-query-builder/utils/compute-depth.utils'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts index f647be1d6332..d4c09f901561 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module.ts @@ -2,8 +2,8 @@ import { Module } from '@nestjs/common'; import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; import { apiRestQueryBuilderFactories } from 'src/engine/api/rest/api-rest-query-builder/factories/factories'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; @Module({ imports: [ObjectMetadataModule, AuthModule], diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts index f012684d762f..22ad6baa6544 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/__tests__/format-field-values.utils.spec.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { formatFieldValue } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils'; describe('formatFieldValue', () => { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts index 5a7c1e976df0..4271970ce1d2 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/format-field-values.utils.ts @@ -1,6 +1,6 @@ import { BadRequestException } from '@nestjs/common'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldValue } from 'src/engine/api/rest/types/api-rest-field-value.type'; export const formatFieldValue = ( diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts index 5408accb6c60..fc0e2bc44cbb 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/__tests__/fields.utils.spec.ts @@ -3,7 +3,7 @@ import { checkFields, getFieldType, } from 'src/engine/api/rest/api-rest-query-builder/utils/fields.utils'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; describe('FieldUtils', () => { describe('getFieldType', () => { diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts index 13a28bb7c592..2e1e82ec32b3 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/fields.utils.ts @@ -1,6 +1,6 @@ import { BadRequestException } from '@nestjs/common'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export const getFieldType = ( diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts index 6be2967c0a03..ed8eeb216588 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; const DEFAULT_DEPTH_VALUE = 2; diff --git a/packages/twenty-server/src/engine/api/rest/api-rest.module.ts b/packages/twenty-server/src/engine/api/rest/api-rest.module.ts index f064ac0cfcb3..79f492733e9f 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest.module.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.module.ts @@ -4,7 +4,7 @@ import { HttpModule } from '@nestjs/axios'; import { ApiRestController } from 'src/engine/api/rest/api-rest.controller'; import { ApiRestService } from 'src/engine/api/rest/api-rest.service'; import { ApiRestQueryBuilderModule } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.module'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { ApiRestMetadataController } from 'src/engine/api/rest/metadata-rest.controller'; import { ApiRestMetadataService } from 'src/engine/api/rest/metadata-rest.service'; diff --git a/packages/twenty-server/src/engine/api/rest/api-rest.service.ts b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts index 7d89c20f521c..4db2893f3082 100644 --- a/packages/twenty-server/src/engine/api/rest/api-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/api-rest.service.ts @@ -5,7 +5,7 @@ import { Request } from 'express'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { ApiRestResponse } from 'src/engine/api/rest/types/api-rest-response.type'; import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; import { getServerUrl } from 'src/utils/get-server-url'; diff --git a/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts index 8a4b61be5f96..3c6ea223d4ff 100644 --- a/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts +++ b/packages/twenty-server/src/engine/api/rest/metadata-rest.service.ts @@ -4,7 +4,7 @@ import { HttpService } from '@nestjs/axios'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-builder/api-rest-query-builder.factory'; import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { parseMetadataPath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; import { capitalize } from 'src/utils/capitalize'; import { getServerUrl } from 'src/utils/get-server-url'; diff --git a/packages/twenty-server/src/engine/constants/settings/interfaces/settings.interface.ts b/packages/twenty-server/src/engine/constants/settings/interfaces/settings.interface.ts index 9f659e0ddb3c..9a5ddf5d9c75 100644 --- a/packages/twenty-server/src/engine/constants/settings/interfaces/settings.interface.ts +++ b/packages/twenty-server/src/engine/constants/settings/interfaces/settings.interface.ts @@ -1,4 +1,4 @@ -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { ShortCropSize } from 'src/utils/image'; diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.entity.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/analytics/analytics.entity.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.entity.ts diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.module.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.module.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/analytics/analytics.module.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.module.ts diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.resolver.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/analytics/analytics.resolver.spec.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.resolver.spec.ts diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.resolver.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.resolver.ts index 999b347dc029..c62f30e0eb9b 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/analytics/analytics.resolver.ts @@ -6,8 +6,8 @@ import { Request } from 'express'; import { OptionalJwtAuthGuard } from 'src/engine/guards/optional-jwt.auth.guard'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { AnalyticsService } from './analytics.service'; import { Analytics } from './analytics.entity'; diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.service.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/analytics/analytics.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.service.spec.ts diff --git a/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts b/packages/twenty-server/src/engine/core-modules/analytics/analytics.service.ts similarity index 91% rename from packages/twenty-server/src/engine/modules/analytics/analytics.service.ts rename to packages/twenty-server/src/engine/core-modules/analytics/analytics.service.ts index dfb9477a05b9..0992f2d1d625 100644 --- a/packages/twenty-server/src/engine/modules/analytics/analytics.service.ts +++ b/packages/twenty-server/src/engine/core-modules/analytics/analytics.service.ts @@ -5,8 +5,8 @@ import { Request } from 'express'; import { anonymize } from 'src/utils/anonymize'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { CreateAnalyticsInput } from './dto/create-analytics.input'; diff --git a/packages/twenty-server/src/engine/modules/analytics/dto/create-analytics.input.ts b/packages/twenty-server/src/engine/core-modules/analytics/dto/create-analytics.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/analytics/dto/create-analytics.input.ts rename to packages/twenty-server/src/engine/core-modules/analytics/dto/create-analytics.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/auth.module.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts similarity index 53% rename from packages/twenty-server/src/engine/modules/auth/auth.module.ts rename to packages/twenty-server/src/engine/core-modules/auth/auth.module.ts index a33776122ba4..ded002b079cc 100644 --- a/packages/twenty-server/src/engine/modules/auth/auth.module.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts @@ -5,23 +5,23 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { HttpModule } from '@nestjs/axios'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { UserModule } from 'src/engine/modules/user/user.module'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { UserModule } from 'src/engine/core-modules/user/user.module'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { GoogleAuthController } from 'src/engine/modules/auth/controllers/google-auth.controller'; -import { GoogleAPIsAuthController } from 'src/engine/modules/auth/controllers/google-apis-auth.controller'; -import { VerifyAuthController } from 'src/engine/modules/auth/controllers/verify-auth.controller'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; -import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; -import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; -import { GoogleGmailAuthController } from 'src/engine/modules/auth/controllers/google-gmail-auth.controller'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; +import { GoogleAuthController } from 'src/engine/core-modules/auth/controllers/google-auth.controller'; +import { GoogleAPIsAuthController } from 'src/engine/core-modules/auth/controllers/google-apis-auth.controller'; +import { VerifyAuthController } from 'src/engine/core-modules/auth/controllers/verify-auth.controller'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service'; +import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; +import { SignUpService } from 'src/engine/core-modules/auth/services/sign-up.service'; +import { GoogleGmailAuthController } from 'src/engine/core-modules/auth/controllers/google-gmail-auth.controller'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module'; import { AuthResolver } from './auth.resolver'; diff --git a/packages/twenty-server/src/engine/modules/auth/auth.resolver.spec.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.spec.ts similarity index 77% rename from packages/twenty-server/src/engine/modules/auth/auth.resolver.spec.ts rename to packages/twenty-server/src/engine/core-modules/auth/auth.resolver.spec.ts index 0057cb7ea414..4edcf14796cf 100644 --- a/packages/twenty-server/src/engine/modules/auth/auth.resolver.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { UserService } from 'src/engine/modules/user/services/user.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { AuthResolver } from './auth.resolver'; diff --git a/packages/twenty-server/src/engine/modules/auth/auth.resolver.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts similarity index 83% rename from packages/twenty-server/src/engine/modules/auth/auth.resolver.ts rename to packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts index 01eab3d8561f..6cd86e1354b4 100644 --- a/packages/twenty-server/src/engine/modules/auth/auth.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts @@ -13,20 +13,20 @@ import { Repository } from 'typeorm'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { assert } from 'src/utils/assert'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { User } from 'src/engine/modules/user/user.entity'; -import { ApiKeyTokenInput } from 'src/engine/modules/auth/dto/api-key-token.input'; -import { ValidatePasswordResetToken } from 'src/engine/modules/auth/dto/validate-password-reset-token.entity'; -import { TransientToken } from 'src/engine/modules/auth/dto/transient-token.entity'; -import { UserService } from 'src/engine/modules/user/services/user.service'; -import { ValidatePasswordResetTokenInput } from 'src/engine/modules/auth/dto/validate-password-reset-token.input'; -import { UpdatePasswordViaResetTokenInput } from 'src/engine/modules/auth/dto/update-password-via-reset-token.input'; -import { EmailPasswordResetLink } from 'src/engine/modules/auth/dto/email-password-reset-link.entity'; -import { InvalidatePassword } from 'src/engine/modules/auth/dto/invalidate-password.entity'; -import { EmailPasswordResetLinkInput } from 'src/engine/modules/auth/dto/email-password-reset-link.input'; -import { GenerateJwtInput } from 'src/engine/modules/auth/dto/generate-jwt.input'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { ApiKeyTokenInput } from 'src/engine/core-modules/auth/dto/api-key-token.input'; +import { ValidatePasswordResetToken } from 'src/engine/core-modules/auth/dto/validate-password-reset-token.entity'; +import { TransientToken } from 'src/engine/core-modules/auth/dto/transient-token.entity'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; +import { ValidatePasswordResetTokenInput } from 'src/engine/core-modules/auth/dto/validate-password-reset-token.input'; +import { UpdatePasswordViaResetTokenInput } from 'src/engine/core-modules/auth/dto/update-password-via-reset-token.input'; +import { EmailPasswordResetLink } from 'src/engine/core-modules/auth/dto/email-password-reset-link.entity'; +import { InvalidatePassword } from 'src/engine/core-modules/auth/dto/invalidate-password.entity'; +import { EmailPasswordResetLinkInput } from 'src/engine/core-modules/auth/dto/email-password-reset-link.input'; +import { GenerateJwtInput } from 'src/engine/core-modules/auth/dto/generate-jwt.input'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; import { ApiKeyToken, AuthTokens } from './dto/token.entity'; import { TokenService } from './services/token.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/auth.util.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.util.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/auth.util.ts rename to packages/twenty-server/src/engine/core-modules/auth/auth.util.ts diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-apis-auth.controller.ts similarity index 77% rename from packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts rename to packages/twenty-server/src/engine/core-modules/auth/controllers/google-apis-auth.controller.ts index 7cdb6279e814..9ae6f4c707dd 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-apis-auth.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-apis-auth.controller.ts @@ -2,11 +2,11 @@ import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; -import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-apis-provider-enabled.guard'; -import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis-oauth.guard'; -import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; -import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { GoogleAPIsProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard'; +import { GoogleAPIsOauthGuard } from 'src/engine/core-modules/auth/guards/google-apis-oauth.guard'; +import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy'; +import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Controller('auth/google-apis') diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts similarity index 76% rename from packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts rename to packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts index df736e6fa234..99aeeefeb504 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-auth.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts @@ -4,13 +4,13 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Response } from 'express'; import { Repository } from 'typeorm'; -import { GoogleRequest } from 'src/engine/modules/auth/strategies/google.auth.strategy'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { GoogleProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-provider-enabled.guard'; -import { GoogleOauthGuard } from 'src/engine/modules/auth/guards/google-oauth.guard'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { AuthService } from 'src/engine/modules/auth/services/auth.service'; +import { GoogleRequest } from 'src/engine/core-modules/auth/strategies/google.auth.strategy'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { GoogleProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/google-provider-enabled.guard'; +import { GoogleOauthGuard } from 'src/engine/core-modules/auth/guards/google-oauth.guard'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { AuthService } from 'src/engine/core-modules/auth/services/auth.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-gmail-auth.controller.ts similarity index 77% rename from packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts rename to packages/twenty-server/src/engine/core-modules/auth/controllers/google-gmail-auth.controller.ts index a5cc294aa20c..03df019d601f 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/google-gmail-auth.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-gmail-auth.controller.ts @@ -2,11 +2,11 @@ import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; -import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis-oauth.guard'; -import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-apis-provider-enabled.guard'; -import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; +import { GoogleAPIsOauthGuard } from 'src/engine/core-modules/auth/guards/google-apis-oauth.guard'; +import { GoogleAPIsProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard'; +import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-apis.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Controller('auth/google-gmail') diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.spec.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.spec.ts similarity index 80% rename from packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.spec.ts rename to packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.spec.ts index 8c205fc57de1..0aef1bea10d2 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { AuthService } from 'src/engine/modules/auth/services/auth.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { AuthService } from 'src/engine/core-modules/auth/services/auth.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { VerifyAuthController } from './verify-auth.controller'; diff --git a/packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.ts similarity index 61% rename from packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.ts rename to packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.ts index 5bedbe9e7883..68d680845011 100644 --- a/packages/twenty-server/src/engine/modules/auth/controllers/verify-auth.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/verify-auth.controller.ts @@ -1,9 +1,9 @@ import { Body, Controller, Post } from '@nestjs/common'; -import { AuthService } from 'src/engine/modules/auth/services/auth.service'; -import { VerifyInput } from 'src/engine/modules/auth/dto/verify.input'; -import { Verify } from 'src/engine/modules/auth/dto/verify.entity'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { AuthService } from 'src/engine/core-modules/auth/services/auth.service'; +import { VerifyInput } from 'src/engine/core-modules/auth/dto/verify.input'; +import { Verify } from 'src/engine/core-modules/auth/dto/verify.entity'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; @Controller('auth/verify') export class VerifyAuthController { diff --git a/packages/twenty-server/src/engine/modules/auth/dto/api-key-token.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/api-key-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/api-key-token.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/api-key-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/challenge.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/challenge.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/challenge.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/challenge.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/email-password-reset-link.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/email-password-reset-link.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/email-password-reset-link.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/email-password-reset-link.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/email-password-reset-link.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/email-password-reset-link.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/email-password-reset-link.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/email-password-reset-link.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/generate-jwt.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/generate-jwt.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/generate-jwt.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/generate-jwt.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/impersonate.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/impersonate.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/impersonate.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/impersonate.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/invalidate-password.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/invalidate-password.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/invalidate-password.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/invalidate-password.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/login-token.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/login-token.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/login-token.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/login-token.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/password-reset-token.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/password-reset-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/password-reset-token.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/password-reset-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/refresh-token.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/refresh-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/refresh-token.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/refresh-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/save-connected-account.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/save-connected-account.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/save-connected-account.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/save-connected-account.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/sign-up.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/sign-up.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/sign-up.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/sign-up.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/token.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/token.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/token.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/token.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/transient-token.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/transient-token.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/transient-token.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/transient-token.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/update-password-via-reset-token.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/update-password-via-reset-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/update-password-via-reset-token.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/update-password-via-reset-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/update-password.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/update-password.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/update-password.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/update-password.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/user-exists.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/user-exists.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/user-exists.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/user-exists.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/user-exists.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/user-exists.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/user-exists.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/user-exists.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/validate-password-reset-token.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/validate-password-reset-token.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/validate-password-reset-token.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/validate-password-reset-token.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/validate-password-reset-token.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/validate-password-reset-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/validate-password-reset-token.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/validate-password-reset-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/verify.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/verify.entity.ts similarity index 76% rename from packages/twenty-server/src/engine/modules/auth/dto/verify.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/verify.entity.ts index 2ad7b1aa977d..5dc9b2ff0104 100644 --- a/packages/twenty-server/src/engine/modules/auth/dto/verify.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/dto/verify.entity.ts @@ -1,6 +1,6 @@ import { Field, ObjectType } from '@nestjs/graphql'; -import { User } from 'src/engine/modules/user/user.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { AuthTokens } from './token.entity'; diff --git a/packages/twenty-server/src/engine/modules/auth/dto/verify.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/verify.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/verify.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/verify.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/workspace-invite-hash-valid.entity.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/workspace-invite-hash-valid.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/workspace-invite-hash-valid.entity.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/workspace-invite-hash-valid.entity.ts diff --git a/packages/twenty-server/src/engine/modules/auth/dto/workspace-invite-hash.input.ts b/packages/twenty-server/src/engine/core-modules/auth/dto/workspace-invite-hash.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/dto/workspace-invite-hash.input.ts rename to packages/twenty-server/src/engine/core-modules/auth/dto/workspace-invite-hash.input.ts diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-apis-oauth.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-apis-oauth.guard.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/guards/google-apis-oauth.guard.ts rename to packages/twenty-server/src/engine/core-modules/auth/guards/google-apis-oauth.guard.ts diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts rename to packages/twenty-server/src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard.ts index 50792c44d026..23b4a0b986f7 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-apis-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/guards/google-apis-provider-enabled.guard.ts @@ -2,7 +2,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; -import { GoogleAPIsStrategy } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; +import { GoogleAPIsStrategy } from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-gmail-provider-enabled.guard.ts similarity index 86% rename from packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts rename to packages/twenty-server/src/engine/core-modules/auth/guards/google-gmail-provider-enabled.guard.ts index a6c88275d4c9..2956601f29f9 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-gmail-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/guards/google-gmail-provider-enabled.guard.ts @@ -2,7 +2,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; -import { GoogleAPIsStrategy } from 'src/engine/modules/auth/strategies/google-apis.auth.strategy'; +import { GoogleAPIsStrategy } from 'src/engine/core-modules/auth/strategies/google-apis.auth.strategy'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-oauth.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/guards/google-oauth.guard.ts rename to packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts diff --git a/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-provider-enabled.guard.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts rename to packages/twenty-server/src/engine/core-modules/auth/guards/google-provider-enabled.guard.ts index feedac845fed..f1a7eaf55620 100644 --- a/packages/twenty-server/src/engine/modules/auth/guards/google-provider-enabled.guard.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/guards/google-provider-enabled.guard.ts @@ -3,7 +3,7 @@ import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { GoogleStrategy } from 'src/engine/modules/auth/strategies/google.auth.strategy'; +import { GoogleStrategy } from 'src/engine/core-modules/auth/strategies/google.auth.strategy'; @Injectable() export class GoogleProviderEnabledGuard implements CanActivate { diff --git a/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.spec.ts similarity index 82% rename from packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/auth.service.spec.ts index 70ce4b8ebcb8..4a6b6ad51080 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/auth.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.spec.ts @@ -1,13 +1,13 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { UserService } from 'src/engine/modules/user/services/user.service'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { EmailService } from 'src/engine/integrations/email/email.service'; -import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; +import { SignUpService } from 'src/engine/core-modules/auth/services/sign-up.service'; import { AuthService } from './auth.service'; import { TokenService } from './token.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts similarity index 86% rename from packages/twenty-server/src/engine/modules/auth/services/auth.service.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts index ad16d1d4f8ad..0a158e5dd55d 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/auth.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts @@ -10,23 +10,23 @@ import { Repository } from 'typeorm'; import { render } from '@react-email/components'; import { PasswordUpdateNotifyEmail } from 'twenty-emails'; -import { ChallengeInput } from 'src/engine/modules/auth/dto/challenge.input'; +import { ChallengeInput } from 'src/engine/core-modules/auth/dto/challenge.input'; import { assert } from 'src/utils/assert'; import { PASSWORD_REGEX, compareHash, hashPassword, -} from 'src/engine/modules/auth/auth.util'; -import { Verify } from 'src/engine/modules/auth/dto/verify.entity'; -import { UserExists } from 'src/engine/modules/auth/dto/user-exists.entity'; -import { WorkspaceInviteHashValid } from 'src/engine/modules/auth/dto/workspace-invite-hash-valid.entity'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { UserService } from 'src/engine/modules/user/services/user.service'; +} from 'src/engine/core-modules/auth/auth.util'; +import { Verify } from 'src/engine/core-modules/auth/dto/verify.entity'; +import { UserExists } from 'src/engine/core-modules/auth/dto/user-exists.entity'; +import { WorkspaceInviteHashValid } from 'src/engine/core-modules/auth/dto/workspace-invite-hash-valid.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { EmailService } from 'src/engine/integrations/email/email.service'; -import { UpdatePassword } from 'src/engine/modules/auth/dto/update-password.entity'; -import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; +import { UpdatePassword } from 'src/engine/core-modules/auth/dto/update-password.entity'; +import { SignUpService } from 'src/engine/core-modules/auth/services/sign-up.service'; import { TokenService } from './token.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/google-apis.service.ts similarity index 94% rename from packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/google-apis.service.ts index 19fd0aab175e..93d0eb502706 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/google-apis.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/google-apis.service.ts @@ -4,9 +4,9 @@ import { InjectRepository } from '@nestjs/typeorm'; import { v4 } from 'uuid'; import { Repository } from 'typeorm'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { SaveConnectedAccountInput } from 'src/engine/modules/auth/dto/save-connected-account'; +import { SaveConnectedAccountInput } from 'src/engine/core-modules/auth/dto/save-connected-account'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { @@ -21,7 +21,7 @@ import { EnvironmentService } from 'src/engine/integrations/environment/environm import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @Injectable() export class GoogleAPIsService { diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts b/packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.spec.ts similarity index 72% rename from packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.spec.ts index af3b2ea6cca9..f453ce7f6eaf 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.spec.ts @@ -2,12 +2,12 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { HttpService } from '@nestjs/axios'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { SignUpService } from 'src/engine/modules/auth/services/sign-up.service'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { SignUpService } from 'src/engine/core-modules/auth/services/sign-up.service'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; describe('SignUpService', () => { let service: SignUpService; diff --git a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.ts index 9c49e61be7b8..71f0b390cff1 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/sign-up.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/sign-up.service.ts @@ -10,19 +10,19 @@ import { Repository } from 'typeorm'; import { v4 } from 'uuid'; import FileType from 'file-type'; -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { assert } from 'src/utils/assert'; import { PASSWORD_REGEX, hashPassword, -} from 'src/engine/modules/auth/auth.util'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +} from 'src/engine/core-modules/auth/auth.util'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { getImageBufferFromUrl } from 'src/utils/image'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; export type SignUpServiceInput = { email: string; diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts b/packages/twenty-server/src/engine/core-modules/auth/services/token.service.spec.ts similarity index 80% rename from packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/token.service.spec.ts index 697359de9afa..fdcad03f6ae1 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/token.service.spec.ts @@ -3,11 +3,11 @@ import { JwtService } from '@nestjs/jwt'; import { getRepositoryToken } from '@nestjs/typeorm'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; -import { User } from 'src/engine/modules/user/user.entity'; -import { JwtAuthStrategy } from 'src/engine/modules/auth/strategies/jwt.auth.strategy'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { JwtAuthStrategy } from 'src/engine/core-modules/auth/strategies/jwt.auth.strategy'; import { EmailService } from 'src/engine/integrations/email/email.service'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { TokenService } from './token.service'; diff --git a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/token.service.ts similarity index 94% rename from packages/twenty-server/src/engine/modules/auth/services/token.service.ts rename to packages/twenty-server/src/engine/core-modules/auth/services/token.service.ts index 76ac9e9d7001..2ab049d23b81 100644 --- a/packages/twenty-server/src/engine/modules/auth/services/token.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/token.service.ts @@ -24,23 +24,23 @@ import { PasswordResetLinkEmail } from 'twenty-emails'; import { JwtAuthStrategy, JwtPayload, -} from 'src/engine/modules/auth/strategies/jwt.auth.strategy'; +} from 'src/engine/core-modules/auth/strategies/jwt.auth.strategy'; import { assert } from 'src/utils/assert'; import { ApiKeyToken, AuthToken, AuthTokens, PasswordResetToken, -} from 'src/engine/modules/auth/dto/token.entity'; +} from 'src/engine/core-modules/auth/dto/token.entity'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { User } from 'src/engine/modules/user/user.entity'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; -import { ValidatePasswordResetToken } from 'src/engine/modules/auth/dto/validate-password-reset-token.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; +import { ValidatePasswordResetToken } from 'src/engine/core-modules/auth/dto/validate-password-reset-token.entity'; import { EmailService } from 'src/engine/integrations/email/email.service'; -import { InvalidatePassword } from 'src/engine/modules/auth/dto/invalidate-password.entity'; -import { EmailPasswordResetLink } from 'src/engine/modules/auth/dto/email-password-reset-link.entity'; -import { JwtData } from 'src/engine/modules/auth/types/jwt-data.type'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { InvalidatePassword } from 'src/engine/core-modules/auth/dto/invalidate-password.entity'; +import { EmailPasswordResetLink } from 'src/engine/core-modules/auth/dto/email-password-reset-link.entity'; +import { JwtData } from 'src/engine/core-modules/auth/types/jwt-data.type'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; @Injectable() export class TokenService { diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/google-apis.auth.strategy.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/strategies/google-apis.auth.strategy.ts rename to packages/twenty-server/src/engine/core-modules/auth/strategies/google-apis.auth.strategy.ts diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/auth/strategies/google.auth.strategy.ts rename to packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts diff --git a/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts similarity index 91% rename from packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts rename to packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts index f097a6513b7c..8e1b7b6e2f6e 100644 --- a/packages/twenty-server/src/engine/modules/auth/strategies/jwt.auth.strategy.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts @@ -11,10 +11,10 @@ import { Repository } from 'typeorm'; import { assert } from 'src/utils/assert'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; export type JwtPayload = { sub: string; workspaceId: string; jti?: string }; export type PassportUser = { user?: User; workspace: Workspace }; diff --git a/packages/twenty-server/src/engine/core-modules/auth/types/jwt-data.type.ts b/packages/twenty-server/src/engine/core-modules/auth/types/jwt-data.type.ts new file mode 100644 index 000000000000..3c24db8de86d --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/auth/types/jwt-data.type.ts @@ -0,0 +1,7 @@ +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; + +export type JwtData = { + user?: User | undefined; + workspace: Workspace; +}; diff --git a/packages/twenty-server/src/engine/modules/billing/billing.controller.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.controller.ts similarity index 90% rename from packages/twenty-server/src/engine/modules/billing/billing.controller.ts rename to packages/twenty-server/src/engine/core-modules/billing/billing.controller.ts index 0587eb45f97a..775604f7d295 100644 --- a/packages/twenty-server/src/engine/modules/billing/billing.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.controller.ts @@ -13,8 +13,8 @@ import { Response } from 'express'; import { BillingService, WebhookEvent, -} from 'src/engine/modules/billing/billing.service'; -import { StripeService } from 'src/engine/modules/billing/stripe/stripe.service'; +} from 'src/engine/core-modules/billing/billing.service'; +import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service'; @Controller('billing') export class BillingController { diff --git a/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts new file mode 100644 index 000000000000..4be921b78c04 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts @@ -0,0 +1,27 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { BillingController } from 'src/engine/core-modules/billing/billing.controller'; +import { BillingService } from 'src/engine/core-modules/billing/billing.service'; +import { StripeModule } from 'src/engine/core-modules/billing/stripe/stripe.module'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { BillingResolver } from 'src/engine/core-modules/billing/billing.resolver'; +import { BillingWorkspaceMemberListener } from 'src/engine/core-modules/billing/listeners/billing-workspace-member.listener'; +import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; + +@Module({ + imports: [ + StripeModule, + UserWorkspaceModule, + TypeOrmModule.forFeature( + [BillingSubscription, BillingSubscriptionItem, Workspace], + 'core', + ), + ], + controllers: [BillingController], + providers: [BillingService, BillingResolver, BillingWorkspaceMemberListener], + exports: [BillingService], +}) +export class BillingModule {} diff --git a/packages/twenty-server/src/engine/modules/billing/billing.resolver.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts similarity index 80% rename from packages/twenty-server/src/engine/modules/billing/billing.resolver.ts rename to packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts index e031d6d9020a..0050a6576695 100644 --- a/packages/twenty-server/src/engine/modules/billing/billing.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts @@ -4,16 +4,16 @@ import { UseGuards } from '@nestjs/common'; import { AvailableProduct, BillingService, -} from 'src/engine/modules/billing/billing.service'; -import { ProductInput } from 'src/engine/modules/billing/dto/product.input'; +} from 'src/engine/core-modules/billing/billing.service'; +import { ProductInput } from 'src/engine/core-modules/billing/dto/product.input'; import { assert } from 'src/utils/assert'; -import { ProductPricesEntity } from 'src/engine/modules/billing/dto/product-prices.entity'; +import { ProductPricesEntity } from 'src/engine/core-modules/billing/dto/product-prices.entity'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; -import { User } from 'src/engine/modules/user/user.entity'; -import { CheckoutSessionInput } from 'src/engine/modules/billing/dto/checkout-session.input'; -import { SessionEntity } from 'src/engine/modules/billing/dto/session.entity'; -import { BillingSessionInput } from 'src/engine/modules/billing/dto/billing-session.input'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { CheckoutSessionInput } from 'src/engine/core-modules/billing/dto/checkout-session.input'; +import { SessionEntity } from 'src/engine/core-modules/billing/dto/session.entity'; +import { BillingSessionInput } from 'src/engine/core-modules/billing/dto/billing-session.input'; @Resolver() export class BillingResolver { diff --git a/packages/twenty-server/src/engine/modules/billing/billing.service.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/billing/billing.service.ts rename to packages/twenty-server/src/engine/core-modules/billing/billing.service.ts index b15c0f3d6cfe..f95580085cab 100644 --- a/packages/twenty-server/src/engine/modules/billing/billing.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts @@ -5,14 +5,14 @@ import Stripe from 'stripe'; import { Not, Repository } from 'typeorm'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { StripeService } from 'src/engine/modules/billing/stripe/stripe.service'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; -import { BillingSubscriptionItem } from 'src/engine/modules/billing/entities/billing-subscription-item.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { ProductPriceEntity } from 'src/engine/modules/billing/dto/product-price.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { ProductPriceEntity } from 'src/engine/core-modules/billing/dto/product-price.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { assert } from 'src/utils/assert'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; export enum AvailableProduct { BasePlan = 'base-plan', diff --git a/packages/twenty-server/src/engine/modules/billing/dto/billing-session.input.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/billing-session.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/billing/dto/billing-session.input.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/billing-session.input.ts diff --git a/packages/twenty-server/src/engine/modules/billing/dto/checkout-session.input.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/checkout-session.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/billing/dto/checkout-session.input.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/checkout-session.input.ts diff --git a/packages/twenty-server/src/engine/modules/billing/dto/product-price.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/product-price.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/billing/dto/product-price.entity.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/product-price.entity.ts diff --git a/packages/twenty-server/src/engine/modules/billing/dto/product-prices.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/product-prices.entity.ts similarity index 71% rename from packages/twenty-server/src/engine/modules/billing/dto/product-prices.entity.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/product-prices.entity.ts index 16a7011b8780..02efc4174929 100644 --- a/packages/twenty-server/src/engine/modules/billing/dto/product-prices.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/dto/product-prices.entity.ts @@ -1,6 +1,6 @@ import { Field, Int, ObjectType } from '@nestjs/graphql'; -import { ProductPriceEntity } from 'src/engine/modules/billing/dto/product-price.entity'; +import { ProductPriceEntity } from 'src/engine/core-modules/billing/dto/product-price.entity'; @ObjectType() export class ProductPricesEntity { diff --git a/packages/twenty-server/src/engine/modules/billing/dto/product.input.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/product.input.ts similarity index 73% rename from packages/twenty-server/src/engine/modules/billing/dto/product.input.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/product.input.ts index d13058c9fe1c..089d18ba0e05 100644 --- a/packages/twenty-server/src/engine/modules/billing/dto/product.input.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/dto/product.input.ts @@ -2,7 +2,7 @@ import { ArgsType, Field } from '@nestjs/graphql'; import { IsNotEmpty, IsString } from 'class-validator'; -import { AvailableProduct } from 'src/engine/modules/billing/billing.service'; +import { AvailableProduct } from 'src/engine/core-modules/billing/billing.service'; @ArgsType() export class ProductInput { diff --git a/packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/session.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/billing/dto/session.entity.ts rename to packages/twenty-server/src/engine/core-modules/billing/dto/session.entity.ts diff --git a/packages/twenty-server/src/engine/modules/billing/entities/billing-subscription-item.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription-item.entity.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/billing/entities/billing-subscription-item.entity.ts rename to packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription-item.entity.ts index 871f2a1b34c5..648d0ade5b8c 100644 --- a/packages/twenty-server/src/engine/modules/billing/entities/billing-subscription-item.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription-item.entity.ts @@ -8,7 +8,7 @@ import { UpdateDateColumn, } from 'typeorm'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; @Entity({ name: 'billingSubscriptionItem', schema: 'core' }) @Unique('IndexOnBillingSubscriptionIdAndStripeProductIdUnique', [ diff --git a/packages/twenty-server/src/engine/modules/billing/entities/billing-subscription.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/billing/entities/billing-subscription.entity.ts rename to packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts index 48b47f123cac..4a6a7c046d20 100644 --- a/packages/twenty-server/src/engine/modules/billing/entities/billing-subscription.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts @@ -13,8 +13,8 @@ import { import Stripe from 'stripe'; import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { BillingSubscriptionItem } from 'src/engine/modules/billing/entities/billing-subscription-item.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; @Entity({ name: 'billingSubscription', schema: 'core' }) @ObjectType('BillingSubscription') diff --git a/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts b/packages/twenty-server/src/engine/core-modules/billing/jobs/update-subscription.job.ts similarity index 84% rename from packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts rename to packages/twenty-server/src/engine/core-modules/billing/jobs/update-subscription.job.ts index 486d289fd398..8dc74ab6c66f 100644 --- a/packages/twenty-server/src/engine/modules/billing/jobs/update-subscription.job.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/jobs/update-subscription.job.ts @@ -2,9 +2,9 @@ import { Injectable, Logger } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; -import { StripeService } from 'src/engine/modules/billing/stripe/stripe.service'; +import { BillingService } from 'src/engine/core-modules/billing/billing.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; +import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service'; export type UpdateSubscriptionJobData = { workspaceId: string }; @Injectable() export class UpdateSubscriptionJob diff --git a/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts b/packages/twenty-server/src/engine/core-modules/billing/listeners/billing-workspace-member.listener.ts similarity index 94% rename from packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts rename to packages/twenty-server/src/engine/core-modules/billing/listeners/billing-workspace-member.listener.ts index e9f982c4f7f1..e31a7b592806 100644 --- a/packages/twenty-server/src/engine/modules/billing/listeners/billing-workspace-member.listener.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/listeners/billing-workspace-member.listener.ts @@ -8,7 +8,7 @@ import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/stan import { UpdateSubscriptionJob, UpdateSubscriptionJobData, -} from 'src/engine/modules/billing/jobs/update-subscription.job'; +} from 'src/engine/core-modules/billing/jobs/update-subscription.job'; @Injectable() export class BillingWorkspaceMemberListener { diff --git a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.module.ts b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.module.ts similarity index 62% rename from packages/twenty-server/src/engine/modules/billing/stripe/stripe.module.ts rename to packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.module.ts index 83eb8ec2814e..31d456008301 100644 --- a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.module.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { StripeService } from 'src/engine/modules/billing/stripe/stripe.service'; +import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service'; @Module({ providers: [StripeService], diff --git a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts similarity index 97% rename from packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts rename to packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts index c4e0cefec547..be72dda1a4d3 100644 --- a/packages/twenty-server/src/engine/modules/billing/stripe/stripe.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common'; import Stripe from 'stripe'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { User } from 'src/engine/modules/user/user.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; @Injectable() export class StripeService { diff --git a/packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts b/packages/twenty-server/src/engine/core-modules/calendar/constants/calendar.constants.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/calendar/constants/calendar.constants.ts rename to packages/twenty-server/src/engine/core-modules/calendar/constants/calendar.constants.ts diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts b/packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts rename to packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-event-attendee.dto.ts diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts b/packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts rename to packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto.ts index 3d276f72e15f..1ae7f9d75929 100644 --- a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-event.dto.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto.ts @@ -1,6 +1,6 @@ import { ObjectType, ID, Field, registerEnumType } from '@nestjs/graphql'; -import { TimelineCalendarEventAttendee } from 'src/engine/modules/calendar/dtos/timeline-calendar-event-attendee.dto'; +import { TimelineCalendarEventAttendee } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event-attendee.dto'; export enum TimelineCalendarEventVisibility { METADATA = 'METADATA', diff --git a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts b/packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts similarity index 74% rename from packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts rename to packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts index 4b879c380df4..10dd32a45c0a 100644 --- a/packages/twenty-server/src/engine/modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto.ts @@ -1,6 +1,6 @@ import { Field, Int, ObjectType } from '@nestjs/graphql'; -import { TimelineCalendarEvent } from 'src/engine/modules/calendar/dtos/timeline-calendar-event.dto'; +import { TimelineCalendarEvent } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto'; @ObjectType('TimelineCalendarEventsWithTotal') export class TimelineCalendarEventsWithTotal { diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.module.ts similarity index 53% rename from packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts rename to packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.module.ts index 7b658e1720e8..917b4ee644c8 100644 --- a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.module.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.module.ts @@ -1,9 +1,10 @@ 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'; +import { UserModule } from 'src/engine/core-modules/user/user.module'; +import { TimelineCalendarEventResolver } from 'src/engine/core-modules/calendar/timeline-calendar-event.resolver'; +import { TimelineCalendarEventService } from 'src/engine/core-modules/calendar/timeline-calendar-event.service'; + @Module({ imports: [WorkspaceDataSourceModule, UserModule], exports: [], diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.resolver.ts similarity index 81% rename from packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts rename to packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.resolver.ts index 1e9e176dc64c..36f88baee32e 100644 --- a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.resolver.ts @@ -11,16 +11,16 @@ import { import { Max } from 'class-validator'; -import { User } from 'src/engine/modules/user/user.entity'; +import { User } from 'src/engine/core-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'; +import { TIMELINE_CALENDAR_EVENTS_MAX_PAGE_SIZE } from 'src/engine/core-modules/calendar/constants/calendar.constants'; +import { TimelineCalendarEventsWithTotal } from 'src/engine/core-modules/calendar/dtos/timeline-calendar-events-with-total.dto'; +import { TimelineCalendarEventService } from 'src/engine/core-modules/calendar/timeline-calendar-event.service'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { NotFoundError } from 'src/engine/utils/graphql-errors.util'; @ArgsType() class GetTimelineCalendarEventsFromPersonIdArgs { diff --git a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts similarity index 95% rename from packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts rename to packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts index 85c4b0ca6601..d492cbfe258a 100644 --- a/packages/twenty-server/src/engine/modules/calendar/timeline-calendar-event.service.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts @@ -2,13 +2,13 @@ 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 { TIMELINE_CALENDAR_EVENTS_DEFAULT_PAGE_SIZE } from 'src/engine/core-modules/calendar/constants/calendar.constants'; +import { TimelineCalendarEventAttendee } from 'src/engine/core-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'; +} from 'src/engine/core-modules/calendar/dtos/timeline-calendar-event.dto'; +import { TimelineCalendarEventsWithTotal } from 'src/engine/core-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'; diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts b/packages/twenty-server/src/engine/core-modules/client-config/client-config.entity.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/client-config/client-config.entity.ts rename to packages/twenty-server/src/engine/core-modules/client-config/client-config.entity.ts diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.module.ts b/packages/twenty-server/src/engine/core-modules/client-config/client-config.module.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/client-config/client-config.module.ts rename to packages/twenty-server/src/engine/core-modules/client-config/client-config.module.ts diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts b/packages/twenty-server/src/engine/core-modules/client-config/client-config.resolver.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/client-config/client-config.resolver.spec.ts rename to packages/twenty-server/src/engine/core-modules/client-config/client-config.resolver.spec.ts diff --git a/packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts b/packages/twenty-server/src/engine/core-modules/client-config/client-config.resolver.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/client-config/client-config.resolver.ts rename to packages/twenty-server/src/engine/core-modules/client-config/client-config.resolver.ts diff --git a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts new file mode 100644 index 000000000000..c61f55b2f886 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts @@ -0,0 +1,44 @@ +import { Module } from '@nestjs/common'; + +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; +import { UserModule } from 'src/engine/core-modules/user/user.module'; +import { RefreshTokenModule } from 'src/engine/core-modules/refresh-token/refresh-token.module'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; +import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module'; +import { TimelineMessagingModule } from 'src/engine/core-modules/messaging/timeline-messaging.module'; +import { TimelineCalendarEventModule } from 'src/engine/core-modules/calendar/timeline-calendar-event.module'; +import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; +import { HealthModule } from 'src/engine/core-modules/health/health.module'; + +import { AnalyticsModule } from './analytics/analytics.module'; +import { FileModule } from './file/file.module'; +import { ClientConfigModule } from './client-config/client-config.module'; + +@Module({ + imports: [ + HealthModule, + AnalyticsModule, + AuthModule, + BillingModule, + ClientConfigModule, + FeatureFlagModule, + FileModule, + OpenApiModule, + RefreshTokenModule, + TimelineMessagingModule, + TimelineCalendarEventModule, + UserModule, + WorkspaceModule, + ], + exports: [ + AnalyticsModule, + AuthModule, + FeatureFlagModule, + TimelineMessagingModule, + TimelineCalendarEventModule, + UserModule, + WorkspaceModule, + ], +}) +export class CoreEngineModule {} diff --git a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts b/packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.entity.ts similarity index 93% rename from packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts rename to packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.entity.ts index a3ae8c2635e8..ae54bcb4f90e 100644 --- a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.entity.ts @@ -11,7 +11,7 @@ import { } from 'typeorm'; import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; export enum FeatureFlagKeys { IsBlocklistEnabled = 'IS_BLOCKLIST_ENABLED', diff --git a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.module.ts b/packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.module.ts similarity index 85% rename from packages/twenty-server/src/engine/modules/feature-flag/feature-flag.module.ts rename to packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.module.ts index 7dddd338d405..0b0f9bbd25ad 100644 --- a/packages/twenty-server/src/engine/modules/feature-flag/feature-flag.module.ts +++ b/packages/twenty-server/src/engine/core-modules/feature-flag/feature-flag.module.ts @@ -4,7 +4,7 @@ import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @Module({ imports: [ diff --git a/packages/twenty-server/src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface.ts b/packages/twenty-server/src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface.ts new file mode 100644 index 000000000000..11c8cc4bbe53 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface.ts @@ -0,0 +1,3 @@ +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; + +export type FeatureFlagMap = Record<`${FeatureFlagKeys}`, boolean>; diff --git a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts b/packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.spec.ts similarity index 82% rename from packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts rename to packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.spec.ts index 7005425ab333..295c89b1b1b0 100644 --- a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { CanActivate } from '@nestjs/common'; -import { FileService } from 'src/engine/modules/file/services/file.service'; -import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; +import { FileService } from 'src/engine/core-modules/file/services/file.service'; +import { FilePathGuard } from 'src/engine/core-modules/file/guards/file-path-guard'; import { FileController } from './file.controller'; diff --git a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts b/packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.ts similarity index 79% rename from packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts rename to packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.ts index ad3547de41d0..39f2b8c70cf4 100644 --- a/packages/twenty-server/src/engine/modules/file/controllers/file.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/file/controllers/file.controller.ts @@ -2,12 +2,12 @@ import { Controller, Get, Param, Res, UseGuards } from '@nestjs/common'; import { Response } from 'express'; -import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; +import { FilePathGuard } from 'src/engine/core-modules/file/guards/file-path-guard'; import { checkFilePath, checkFilename, -} from 'src/engine/modules/file/file.utils'; -import { FileService } from 'src/engine/modules/file/services/file.service'; +} from 'src/engine/core-modules/file/file.utils'; +import { FileService } from 'src/engine/core-modules/file/services/file.service'; // TODO: Add cookie authentication @Controller('files') diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts similarity index 58% rename from packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts rename to packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts index 4c27162db784..5af72bd7a210 100644 --- a/packages/twenty-server/src/engine/modules/file/file-upload/file-upload.module.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/file-upload.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { FileUploadResolver } from 'src/engine/modules/file/file-upload/resolvers/file-upload.resolver'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +import { FileUploadResolver } from 'src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; @Module({ providers: [FileUploadService, FileUploadResolver, EnvironmentService], diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.spec.ts similarity index 84% rename from packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts rename to packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.spec.ts index 242907bee04d..5a62ebdc4ff4 100644 --- a/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; import { FileUploadResolver } from './file-upload.resolver'; diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts rename to packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts index 8b4a1f1a4553..1541bb63e39f 100644 --- a/packages/twenty-server/src/engine/modules/file/file-upload/resolvers/file-upload.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts @@ -3,9 +3,9 @@ import { UseGuards } from '@nestjs/common'; import { GraphQLUpload, FileUpload } from 'graphql-upload'; -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.spec.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.spec.ts diff --git a/packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts similarity index 96% rename from packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.ts rename to packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts index 10d70bf08597..f4fd71850abb 100644 --- a/packages/twenty-server/src/engine/modules/file/file-upload/services/file-upload.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/services/file-upload.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import sharp from 'sharp'; import { v4 as uuidV4 } from 'uuid'; -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { getCropSize } from 'src/utils/image'; import { settings } from 'src/engine/constants/settings'; diff --git a/packages/twenty-server/src/engine/modules/file/file.module.ts b/packages/twenty-server/src/engine/core-modules/file/file.module.ts similarity index 64% rename from packages/twenty-server/src/engine/modules/file/file.module.ts rename to packages/twenty-server/src/engine/core-modules/file/file.module.ts index dfbed11bf12b..521cde04bdad 100644 --- a/packages/twenty-server/src/engine/modules/file/file.module.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file.module.ts @@ -1,9 +1,9 @@ import { Module } from '@nestjs/common'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { FilePathGuard } from 'src/engine/modules/file/guards/file-path-guard'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; -import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; +import { FilePathGuard } from 'src/engine/core-modules/file/guards/file-path-guard'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module'; import { FileService } from './services/file.service'; import { FileController } from './controllers/file.controller'; diff --git a/packages/twenty-server/src/engine/modules/file/file.utils.ts b/packages/twenty-server/src/engine/core-modules/file/file.utils.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/file.utils.ts rename to packages/twenty-server/src/engine/core-modules/file/file.utils.ts diff --git a/packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts b/packages/twenty-server/src/engine/core-modules/file/guards/file-path-guard.ts similarity index 93% rename from packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts rename to packages/twenty-server/src/engine/core-modules/file/guards/file-path-guard.ts index 93ede5dc7c9b..98891647314d 100644 --- a/packages/twenty-server/src/engine/modules/file/guards/file-path-guard.ts +++ b/packages/twenty-server/src/engine/core-modules/file/guards/file-path-guard.ts @@ -7,7 +7,7 @@ import { } from '@nestjs/common'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; @Injectable() export class FilePathGuard implements CanActivate { diff --git a/packages/twenty-server/src/engine/modules/file/interfaces/file-folder.interface.ts b/packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/interfaces/file-folder.interface.ts rename to packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts diff --git a/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.spec.ts b/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.spec.ts new file mode 100644 index 000000000000..5a62ebdc4ff4 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.spec.ts @@ -0,0 +1,27 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; + +import { FileUploadResolver } from './file-upload.resolver'; + +describe('FileUploadResolver', () => { + let resolver: FileUploadResolver; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + FileUploadResolver, + { + provide: FileUploadService, + useValue: {}, + }, + ], + }).compile(); + + resolver = module.get(FileUploadResolver); + }); + + it('should be defined', () => { + expect(resolver).toBeDefined(); + }); +}); diff --git a/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.ts b/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.ts new file mode 100644 index 000000000000..1541bb63e39f --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/file/resolvers/file-upload.resolver.ts @@ -0,0 +1,57 @@ +import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { UseGuards } from '@nestjs/common'; + +import { GraphQLUpload, FileUpload } from 'graphql-upload'; + +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; + +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; +import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; +import { streamToBuffer } from 'src/utils/stream-to-buffer'; +import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; + +@UseGuards(JwtAuthGuard, DemoEnvGuard) +@Resolver() +export class FileUploadResolver { + constructor(private readonly fileUploadService: FileUploadService) {} + + @Mutation(() => String) + async uploadFile( + @Args({ name: 'file', type: () => GraphQLUpload }) + { createReadStream, filename, mimetype }: FileUpload, + @Args('fileFolder', { type: () => FileFolder, nullable: true }) + fileFolder: FileFolder, + ): Promise { + const stream = createReadStream(); + const buffer = await streamToBuffer(stream); + + const { path } = await this.fileUploadService.uploadFile({ + file: buffer, + filename, + mimeType: mimetype, + fileFolder, + }); + + return path; + } + + @Mutation(() => String) + async uploadImage( + @Args({ name: 'file', type: () => GraphQLUpload }) + { createReadStream, filename, mimetype }: FileUpload, + @Args('fileFolder', { type: () => FileFolder, nullable: true }) + fileFolder: FileFolder, + ): Promise { + const stream = createReadStream(); + const buffer = await streamToBuffer(stream); + + const { paths } = await this.fileUploadService.uploadImage({ + file: buffer, + filename, + mimeType: mimetype, + fileFolder, + }); + + return paths[0]; + } +} diff --git a/packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts b/packages/twenty-server/src/engine/core-modules/file/services/file.service.spec.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/services/file.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/file/services/file.service.spec.ts diff --git a/packages/twenty-server/src/engine/modules/file/services/file.service.ts b/packages/twenty-server/src/engine/core-modules/file/services/file.service.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/file/services/file.service.ts rename to packages/twenty-server/src/engine/core-modules/file/services/file.service.ts diff --git a/packages/twenty-server/src/engine/modules/health/health.controller.spec.ts b/packages/twenty-server/src/engine/core-modules/health/health.controller.spec.ts similarity index 89% rename from packages/twenty-server/src/engine/modules/health/health.controller.spec.ts rename to packages/twenty-server/src/engine/core-modules/health/health.controller.spec.ts index db20ad6a92b4..9ee2a50c4a4b 100644 --- a/packages/twenty-server/src/engine/modules/health/health.controller.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/health/health.controller.spec.ts @@ -1,7 +1,7 @@ import { HealthCheckService, HttpHealthIndicator } from '@nestjs/terminus'; import { Test, TestingModule } from '@nestjs/testing'; -import { HealthController } from 'src/engine/modules/health/health.controller'; +import { HealthController } from 'src/engine/core-modules/health/health.controller'; describe('HealthController', () => { let healthController: HealthController; diff --git a/packages/twenty-server/src/engine/modules/health/health.controller.ts b/packages/twenty-server/src/engine/core-modules/health/health.controller.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/health/health.controller.ts rename to packages/twenty-server/src/engine/core-modules/health/health.controller.ts diff --git a/packages/twenty-server/src/engine/modules/health/health.module.ts b/packages/twenty-server/src/engine/core-modules/health/health.module.ts similarity index 70% rename from packages/twenty-server/src/engine/modules/health/health.module.ts rename to packages/twenty-server/src/engine/core-modules/health/health.module.ts index ad4b13483e3a..fa099ef52dbc 100644 --- a/packages/twenty-server/src/engine/modules/health/health.module.ts +++ b/packages/twenty-server/src/engine/core-modules/health/health.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { TerminusModule } from '@nestjs/terminus'; -import { HealthController } from 'src/engine/modules/health/health.controller'; +import { HealthController } from 'src/engine/core-modules/health/health.controller'; @Module({ imports: [TerminusModule], diff --git a/packages/twenty-server/src/engine/modules/messaging/constants/messaging.constants.ts b/packages/twenty-server/src/engine/core-modules/messaging/constants/messaging.constants.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/messaging/constants/messaging.constants.ts rename to packages/twenty-server/src/engine/core-modules/messaging/constants/messaging.constants.ts diff --git a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread-participant.dto.ts b/packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread-participant.dto.ts rename to packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto.ts diff --git a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts b/packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-thread.dto.ts similarity index 83% rename from packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts rename to packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-thread.dto.ts index 811ea2b96479..f8b9e881a048 100644 --- a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-thread.dto.ts +++ b/packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-thread.dto.ts @@ -1,6 +1,6 @@ import { ObjectType, Field, ID } from '@nestjs/graphql'; -import { TimelineThreadParticipant } from 'src/engine/modules/messaging/dtos/timeline-thread-participant.dto'; +import { TimelineThreadParticipant } from 'src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto'; @ObjectType('TimelineThread') export class TimelineThread { diff --git a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-threads-with-total.dto.ts b/packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto.ts similarity index 74% rename from packages/twenty-server/src/engine/modules/messaging/dtos/timeline-threads-with-total.dto.ts rename to packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto.ts index 0d87ed7a7ff3..3cdafcf23252 100644 --- a/packages/twenty-server/src/engine/modules/messaging/dtos/timeline-threads-with-total.dto.ts +++ b/packages/twenty-server/src/engine/core-modules/messaging/dtos/timeline-threads-with-total.dto.ts @@ -1,6 +1,6 @@ import { Field, Int, ObjectType } from '@nestjs/graphql'; -import { TimelineThread } from 'src/engine/modules/messaging/dtos/timeline-thread.dto'; +import { TimelineThread } from 'src/engine/core-modules/messaging/dtos/timeline-thread.dto'; @ObjectType('TimelineThreadsWithTotal') export class TimelineThreadsWithTotal { diff --git a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.module.ts b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.module.ts similarity index 54% rename from packages/twenty-server/src/engine/modules/messaging/timeline-messaging.module.ts rename to packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.module.ts index dcfc287a9120..275f7f0df151 100644 --- a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.module.ts +++ b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.module.ts @@ -1,9 +1,9 @@ import { Module } from '@nestjs/common'; -import { TimelineMessagingResolver } from 'src/engine/modules/messaging/timeline-messaging.resolver'; -import { TimelineMessagingService } from 'src/engine/modules/messaging/timeline-messaging.service'; +import { TimelineMessagingResolver } from 'src/engine/core-modules/messaging/timeline-messaging.resolver'; +import { TimelineMessagingService } from 'src/engine/core-modules/messaging/timeline-messaging.service'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { UserModule } from 'src/engine/modules/user/user.module'; +import { UserModule } from 'src/engine/core-modules/user/user.module'; @Module({ imports: [WorkspaceDataSourceModule, UserModule], exports: [], diff --git a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.resolver.ts b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.resolver.ts similarity index 80% rename from packages/twenty-server/src/engine/modules/messaging/timeline-messaging.resolver.ts rename to packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.resolver.ts index 299bc65ec6c7..504951138529 100644 --- a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.resolver.ts @@ -12,14 +12,14 @@ import { UseGuards } from '@nestjs/common'; import { Max } from 'class-validator'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { TimelineMessagingService } from 'src/engine/modules/messaging/timeline-messaging.service'; -import { TIMELINE_THREADS_MAX_PAGE_SIZE } from 'src/engine/modules/messaging/constants/messaging.constants'; -import { TimelineThreadsWithTotal } from 'src/engine/modules/messaging/dtos/timeline-threads-with-total.dto'; +import { TimelineMessagingService } from 'src/engine/core-modules/messaging/timeline-messaging.service'; +import { TIMELINE_THREADS_MAX_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 { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; -import { UserService } from 'src/engine/modules/user/services/user.service'; -import { User } from 'src/engine/modules/user/user.entity'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; @ArgsType() class GetTimelineThreadsFromPersonIdArgs { diff --git a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.service.ts b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.service.ts similarity index 98% rename from packages/twenty-server/src/engine/modules/messaging/timeline-messaging.service.ts rename to packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.service.ts index 542b4f5f1341..9b962cae849b 100644 --- a/packages/twenty-server/src/engine/modules/messaging/timeline-messaging.service.ts +++ b/packages/twenty-server/src/engine/core-modules/messaging/timeline-messaging.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; -import { TIMELINE_THREADS_DEFAULT_PAGE_SIZE } from 'src/engine/modules/messaging/constants/messaging.constants'; -import { TimelineThreadsWithTotal } from 'src/engine/modules/messaging/dtos/timeline-threads-with-total.dto'; +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 { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; type TimelineThreadParticipant = { diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.controller.ts b/packages/twenty-server/src/engine/core-modules/open-api/open-api.controller.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/open-api/open-api.controller.ts rename to packages/twenty-server/src/engine/core-modules/open-api/open-api.controller.ts index 103d0e27fe67..53c614869176 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/open-api.controller.ts @@ -2,7 +2,7 @@ import { Controller, Get, Req, Res } from '@nestjs/common'; import { Request, Response } from 'express'; -import { OpenApiService } from 'src/engine/modules/open-api/open-api.service'; +import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service'; @Controller('open-api') export class OpenApiController { diff --git a/packages/twenty-server/src/engine/core-modules/open-api/open-api.module.ts b/packages/twenty-server/src/engine/core-modules/open-api/open-api.module.ts new file mode 100644 index 000000000000..69cc16f97a96 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/open-api/open-api.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; + +import { OpenApiController } from 'src/engine/core-modules/open-api/open-api.controller'; +import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service'; +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; + +@Module({ + imports: [ObjectMetadataModule, AuthModule], + controllers: [OpenApiController], + providers: [OpenApiService], +}) +export class OpenApiModule {} diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.spec.ts similarity index 73% rename from packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/open-api/open-api.service.spec.ts index eb277a13511f..b2252b0c6810 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { OpenApiService } from 'src/engine/modules/open-api/open-api.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; +import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; describe('OpenApiService', () => { diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/open-api/open-api.service.ts rename to packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts index bc0b9d38872f..58fe617ca9cc 100644 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.service.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts @@ -3,28 +3,28 @@ import { Injectable } from '@nestjs/common'; import { Request } from 'express'; import { OpenAPIV3_1 } from 'openapi-types'; -import { TokenService } from 'src/engine/modules/auth/services/token.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { baseSchema } from 'src/engine/modules/open-api/utils/base-schema.utils'; +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { baseSchema } from 'src/engine/core-modules/open-api/utils/base-schema.utils'; import { computeManyResultPath, computeSingleResultPath, -} from 'src/engine/modules/open-api/utils/path.utils'; -import { getErrorResponses } from 'src/engine/modules/open-api/utils/get-error-responses.utils'; +} from 'src/engine/core-modules/open-api/utils/path.utils'; +import { getErrorResponses } from 'src/engine/core-modules/open-api/utils/get-error-responses.utils'; import { computeMetadataSchemaComponents, computeParameterComponents, computeSchemaComponents, -} from 'src/engine/modules/open-api/utils/components.utils'; -import { computeSchemaTags } from 'src/engine/modules/open-api/utils/compute-schema-tags.utils'; -import { computeWebhooks } from 'src/engine/modules/open-api/utils/computeWebhooks.utils'; +} from 'src/engine/core-modules/open-api/utils/components.utils'; +import { computeSchemaTags } from 'src/engine/core-modules/open-api/utils/compute-schema-tags.utils'; +import { computeWebhooks } from 'src/engine/core-modules/open-api/utils/computeWebhooks.utils'; import { capitalize } from 'src/utils/capitalize'; import { getDeleteResponse200, getManyResultResponse200, getSingleResultSuccessResponse, -} from 'src/engine/modules/open-api/utils/responses.utils'; -import { getRequestBody } from 'src/engine/modules/open-api/utils/request-body.utils'; +} from 'src/engine/core-modules/open-api/utils/responses.utils'; +import { getRequestBody } from 'src/engine/core-modules/open-api/utils/request-body.utils'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { getServerUrl } from 'src/utils/get-server-url'; diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts similarity index 83% rename from packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts index 5995f0a0e93a..b4440db8eb85 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts @@ -1,6 +1,6 @@ -import { computeSchemaComponents } from 'src/engine/modules/open-api/utils/components.utils'; +import { computeSchemaComponents } from 'src/engine/core-modules/open-api/utils/components.utils'; import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; describe('computeSchemaComponents', () => { it('should compute schema components', () => { diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/parameters.utils.spec.ts similarity index 98% rename from packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/parameters.utils.spec.ts index b5d496a07227..06c4684c9a4d 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/__tests__/parameters.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/parameters.utils.spec.ts @@ -7,7 +7,7 @@ import { computeLastCursorParameters, computeLimitParameters, computeOrderByParameters, -} from 'src/engine/modules/open-api/utils/parameters.utils'; +} from 'src/engine/core-modules/open-api/utils/parameters.utils'; import { DEFAULT_ORDER_DIRECTION } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/order-by-input.factory'; import { FilterComparators } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-base-filter.utils'; import { Conjunctions } from 'src/engine/api/rest/api-rest-query-builder/factories/input-factories/filter-utils/parse-filter.utils'; diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/base-schema.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/base-schema.utils.ts similarity index 93% rename from packages/twenty-server/src/engine/modules/open-api/utils/base-schema.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/base-schema.utils.ts index 328fcee35d0f..d506d6fb6cf0 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/base-schema.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/base-schema.utils.ts @@ -1,6 +1,6 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { computeOpenApiPath } from 'src/engine/modules/open-api/utils/path.utils'; +import { computeOpenApiPath } from 'src/engine/core-modules/open-api/utils/path.utils'; export const baseSchema = ( schemaName: 'core' | 'metadata', diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts similarity index 97% rename from packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index 7fc94e5233da..487156e6b9d2 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -1,7 +1,7 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; import { computeDepthParameters, @@ -10,7 +10,7 @@ import { computeLastCursorParameters, computeLimitParameters, computeOrderByParameters, -} from 'src/engine/modules/open-api/utils/parameters.utils'; +} from 'src/engine/core-modules/open-api/utils/parameters.utils'; type Property = OpenAPIV3_1.SchemaObject; diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/compute-schema-tags.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/compute-schema-tags.utils.ts similarity index 80% rename from packages/twenty-server/src/engine/modules/open-api/utils/compute-schema-tags.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/compute-schema-tags.utils.ts index d18742912f41..e303157a321c 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/compute-schema-tags.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/compute-schema-tags.utils.ts @@ -1,6 +1,6 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; export const computeSchemaTags = ( diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/computeWebhooks.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/computeWebhooks.utils.ts similarity index 95% rename from packages/twenty-server/src/engine/modules/open-api/utils/computeWebhooks.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/computeWebhooks.utils.ts index 0f13450fa48f..c7a2483c002b 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/computeWebhooks.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/computeWebhooks.utils.ts @@ -1,6 +1,6 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; export const computeWebhooks = ( diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/get-error-responses.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/get-error-responses.utils.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/open-api/utils/get-error-responses.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/get-error-responses.utils.ts diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/parameters.utils.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/open-api/utils/parameters.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/parameters.utils.ts diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/path.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/path.utils.ts similarity index 93% rename from packages/twenty-server/src/engine/modules/open-api/utils/path.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/path.utils.ts index 269219badd05..497e95e778e6 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/path.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/path.utils.ts @@ -1,14 +1,14 @@ import { OpenAPIV3_1 } from 'openapi-types'; import { capitalize } from 'src/utils/capitalize'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { getDeleteResponse200, getJsonResponse, getManyResultResponse200, getSingleResultSuccessResponse, -} from 'src/engine/modules/open-api/utils/responses.utils'; -import { getRequestBody } from 'src/engine/modules/open-api/utils/request-body.utils'; +} from 'src/engine/core-modules/open-api/utils/responses.utils'; +import { getRequestBody } from 'src/engine/core-modules/open-api/utils/request-body.utils'; export const computeManyResultPath = ( item: ObjectMetadataEntity, diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/request-body.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/request-body.utils.ts similarity index 77% rename from packages/twenty-server/src/engine/modules/open-api/utils/request-body.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/request-body.utils.ts index 250913534bb3..6ba3b3023f61 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/request-body.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/request-body.utils.ts @@ -1,4 +1,4 @@ -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; export const getRequestBody = ( diff --git a/packages/twenty-server/src/engine/modules/open-api/utils/responses.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/responses.utils.ts similarity index 97% rename from packages/twenty-server/src/engine/modules/open-api/utils/responses.utils.ts rename to packages/twenty-server/src/engine/core-modules/open-api/utils/responses.utils.ts index e47d7cc57ebe..c3905e2d2841 100644 --- a/packages/twenty-server/src/engine/modules/open-api/utils/responses.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/responses.utils.ts @@ -1,4 +1,4 @@ -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; export const getManyResultResponse200 = ( diff --git a/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts b/packages/twenty-server/src/engine/core-modules/quick-actions/intelligence.service.ts similarity index 93% rename from packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts rename to packages/twenty-server/src/engine/core-modules/quick-actions/intelligence.service.ts index e56c2e2f069d..860b81f85715 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/intelligence.service.ts +++ b/packages/twenty-server/src/engine/core-modules/quick-actions/intelligence.service.ts @@ -1,7 +1,7 @@ import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; -import { CompanyInteface } from 'src/engine/modules/quick-actions/interfaces/company.interface'; +import { CompanyInteface } from 'src/engine/core-modules/quick-actions/interfaces/company.interface'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; diff --git a/packages/twenty-server/src/engine/modules/quick-actions/interfaces/company.interface.ts b/packages/twenty-server/src/engine/core-modules/quick-actions/interfaces/company.interface.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/quick-actions/interfaces/company.interface.ts rename to packages/twenty-server/src/engine/core-modules/quick-actions/interfaces/company.interface.ts diff --git a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts b/packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.module.ts similarity index 69% rename from packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts rename to packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.module.ts index 14e4bc82a1c3..95fa48dbcd19 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.module.ts +++ b/packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { HttpModule } from '@nestjs/axios'; -import { IntelligenceService } from 'src/engine/modules/quick-actions/intelligence.service'; -import { QuickActionsService } from 'src/engine/modules/quick-actions/quick-actions.service'; +import { IntelligenceService } from 'src/engine/core-modules/quick-actions/intelligence.service'; +import { QuickActionsService } from 'src/engine/core-modules/quick-actions/quick-actions.service'; import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module'; @Module({ diff --git a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts b/packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.service.ts similarity index 95% rename from packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts rename to packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.service.ts index 6ec86bb1cd62..ed16e678a718 100644 --- a/packages/twenty-server/src/engine/modules/quick-actions/quick-actions.service.ts +++ b/packages/twenty-server/src/engine/core-modules/quick-actions/quick-actions.service.ts @@ -3,12 +3,12 @@ import { Injectable } from '@nestjs/common'; import { v4 as uuidv4 } from 'uuid'; import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { isWorkEmail } from 'src/utils/is-work-email'; import { stringifyWithoutKeyQuote } from 'src/engine/api/graphql/workspace-query-builder/utils/stringify-without-key-quote.util'; import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service'; -import { IntelligenceService } from 'src/engine/modules/quick-actions/intelligence.service'; +import { IntelligenceService } from 'src/engine/core-modules/quick-actions/intelligence.service'; import { capitalize } from 'src/utils/capitalize'; @Injectable() diff --git a/packages/twenty-server/src/engine/modules/refresh-token/dtos/create-refresh-token.input.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/dtos/create-refresh-token.input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/refresh-token/dtos/create-refresh-token.input.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/dtos/create-refresh-token.input.ts diff --git a/packages/twenty-server/src/engine/modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts index 509ce1d79c01..f9e0f219c3db 100644 --- a/packages/twenty-server/src/engine/modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts +++ b/packages/twenty-server/src/engine/core-modules/refresh-token/hooks/before-create-one-refresh-token.hook.ts @@ -4,7 +4,7 @@ import { } from '@ptc-org/nestjs-query-graphql'; import { v4 as uuidv4 } from 'uuid'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; export class BeforeCreateOneRefreshToken implements BeforeCreateOneHook diff --git a/packages/twenty-server/src/engine/modules/refresh-token/refresh-token.auto-resolver-opts.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.auto-resolver-opts.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/refresh-token/refresh-token.auto-resolver-opts.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.auto-resolver-opts.ts diff --git a/packages/twenty-server/src/engine/modules/refresh-token/refresh-token.entity.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.entity.ts similarity index 94% rename from packages/twenty-server/src/engine/modules/refresh-token/refresh-token.entity.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.entity.ts index f1174ec60e49..d133aa8f9a24 100644 --- a/packages/twenty-server/src/engine/modules/refresh-token/refresh-token.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.entity.ts @@ -11,7 +11,7 @@ import { } from 'typeorm'; import { BeforeCreateOne, IDField } from '@ptc-org/nestjs-query-graphql'; -import { User } from 'src/engine/modules/user/user.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { BeforeCreateOneRefreshToken } from './hooks/before-create-one-refresh-token.hook'; diff --git a/packages/twenty-server/src/engine/modules/refresh-token/refresh-token.module.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.module.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/refresh-token/refresh-token.module.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/refresh-token.module.ts diff --git a/packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.spec.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.spec.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.spec.ts index 926309df97e8..cbf7110f6048 100644 --- a/packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; import { RefreshTokenService } from './refresh-token.service'; diff --git a/packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.ts b/packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.ts similarity index 62% rename from packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.ts rename to packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.ts index 704087f235bf..825a33ab50b9 100644 --- a/packages/twenty-server/src/engine/modules/refresh-token/services/refresh-token.service.ts +++ b/packages/twenty-server/src/engine/core-modules/refresh-token/services/refresh-token.service.ts @@ -1,5 +1,5 @@ import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; export class RefreshTokenService extends TypeOrmQueryService {} diff --git a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.entity.ts b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts similarity index 89% rename from packages/twenty-server/src/engine/modules/user-workspace/user-workspace.entity.ts rename to packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts index b167f82e84f2..45a83da72f95 100644 --- a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts @@ -12,8 +12,8 @@ import { UpdateDateColumn, } from 'typeorm'; -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; @Entity({ name: 'userWorkspace', schema: 'core' }) @ObjectType('UserWorkspace') diff --git a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.module.ts b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.module.ts similarity index 72% rename from packages/twenty-server/src/engine/modules/user-workspace/user-workspace.module.ts rename to packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.module.ts index ae4445aa96fa..bc827d9d32d3 100644 --- a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.module.ts +++ b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.module.ts @@ -4,9 +4,9 @@ import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; @Module({ diff --git a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.service.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts rename to packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.service.ts index b43afb61f17d..30703d0d3568 100644 --- a/packages/twenty-server/src/engine/modules/user-workspace/user-workspace.service.ts +++ b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.service.ts @@ -4,10 +4,10 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { Repository } from 'typeorm'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { User } from 'src/engine/modules/user/user.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event'; import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; diff --git a/packages/twenty-server/src/engine/modules/user/dtos/workspace-member.dto.ts b/packages/twenty-server/src/engine/core-modules/user/dtos/workspace-member.dto.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/user/dtos/workspace-member.dto.ts rename to packages/twenty-server/src/engine/core-modules/user/dtos/workspace-member.dto.ts diff --git a/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts b/packages/twenty-server/src/engine/core-modules/user/services/user.service.spec.ts similarity index 78% rename from packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/user/services/user.service.spec.ts index 9ad7b8ef41ec..64228c0eaf20 100644 --- a/packages/twenty-server/src/engine/modules/user/services/user.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/user/services/user.service.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { User } from 'src/engine/modules/user/user.entity'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { UserService } from './user.service'; diff --git a/packages/twenty-server/src/engine/modules/user/services/user.service.ts b/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts similarity index 88% rename from packages/twenty-server/src/engine/modules/user/services/user.service.ts rename to packages/twenty-server/src/engine/core-modules/user/services/user.service.ts index 59f139875396..505cb32c9312 100644 --- a/packages/twenty-server/src/engine/modules/user/services/user.service.ts +++ b/packages/twenty-server/src/engine/core-modules/user/services/user.service.ts @@ -4,12 +4,12 @@ import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { Repository } from 'typeorm'; import { assert } from 'src/utils/assert'; -import { User } from 'src/engine/modules/user/user.entity'; -import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; export class UserService extends TypeOrmQueryService { constructor( diff --git a/packages/twenty-server/src/engine/modules/user/user.auto-resolver-opts.ts b/packages/twenty-server/src/engine/core-modules/user/user.auto-resolver-opts.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/user/user.auto-resolver-opts.ts rename to packages/twenty-server/src/engine/core-modules/user/user.auto-resolver-opts.ts index 6b46942179b5..eeb6b95bbb25 100644 --- a/packages/twenty-server/src/engine/modules/user/user.auto-resolver-opts.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.auto-resolver-opts.ts @@ -4,7 +4,7 @@ import { PagingStrategies, } from '@ptc-org/nestjs-query-graphql'; -import { User } from 'src/engine/modules/user/user.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; export const userAutoResolverOpts: AutoResolverOpts< diff --git a/packages/twenty-server/src/engine/modules/user/user.entity.ts b/packages/twenty-server/src/engine/core-modules/user/user.entity.ts similarity index 84% rename from packages/twenty-server/src/engine/modules/user/user.entity.ts rename to packages/twenty-server/src/engine/core-modules/user/user.entity.ts index 6f8f6816430f..043c8a191b45 100644 --- a/packages/twenty-server/src/engine/modules/user/user.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.entity.ts @@ -11,10 +11,10 @@ import { } from 'typeorm'; import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { RefreshToken } from 'src/engine/modules/refresh-token/refresh-token.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { RefreshToken } from 'src/engine/core-modules/refresh-token/refresh-token.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; @Entity({ name: 'user', schema: 'core' }) @ObjectType('User') diff --git a/packages/twenty-server/src/engine/modules/user/user.module.ts b/packages/twenty-server/src/engine/core-modules/user/user.module.ts similarity index 63% rename from packages/twenty-server/src/engine/modules/user/user.module.ts rename to packages/twenty-server/src/engine/core-modules/user/user.module.ts index 3265e620da6a..81b3a708347c 100644 --- a/packages/twenty-server/src/engine/modules/user/user.module.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.module.ts @@ -4,14 +4,14 @@ import { Module } from '@nestjs/common'; import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; -import { User } from 'src/engine/modules/user/user.entity'; -import { UserResolver } from 'src/engine/modules/user/user.resolver'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { UserResolver } from 'src/engine/core-modules/user/user.resolver'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; +import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module'; import { userAutoResolverOpts } from './user.auto-resolver-opts'; diff --git a/packages/twenty-server/src/engine/modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts similarity index 87% rename from packages/twenty-server/src/engine/modules/user/user.resolver.ts rename to packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index 9485875d4001..fc505ae2bd7b 100644 --- a/packages/twenty-server/src/engine/modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -15,18 +15,18 @@ import { FileUpload, GraphQLUpload } from 'graphql-upload'; import { Repository } from 'typeorm'; import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; import { assert } from 'src/utils/assert'; import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { User } from 'src/engine/modules/user/user.entity'; -import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; import { UserService } from './services/user.service'; diff --git a/packages/twenty-server/src/engine/modules/workspace/dtos/activate-workspace-input.ts b/packages/twenty-server/src/engine/core-modules/workspace/dtos/activate-workspace-input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/workspace/dtos/activate-workspace-input.ts rename to packages/twenty-server/src/engine/core-modules/workspace/dtos/activate-workspace-input.ts diff --git a/packages/twenty-server/src/engine/modules/workspace/dtos/update-workspace-input.ts b/packages/twenty-server/src/engine/core-modules/workspace/dtos/update-workspace-input.ts similarity index 100% rename from packages/twenty-server/src/engine/modules/workspace/dtos/update-workspace-input.ts rename to packages/twenty-server/src/engine/core-modules/workspace/dtos/update-workspace-input.ts diff --git a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.spec.ts similarity index 74% rename from packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts rename to packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.spec.ts index af996f78e2cd..cce4de1f4208 100644 --- a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.spec.ts @@ -1,12 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { BillingService } from 'src/engine/core-modules/billing/billing.service'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; import { WorkspaceService } from './workspace.service'; diff --git a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts similarity index 92% rename from packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts rename to packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts index a87bdf26a732..7ff8309d235e 100644 --- a/packages/twenty-server/src/engine/modules/workspace/services/workspace.service.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts @@ -6,13 +6,13 @@ import assert from 'assert'; import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { Repository } from 'typeorm'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { User } from 'src/engine/modules/user/user.entity'; import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service'; -import { UserWorkspaceService } from 'src/engine/modules/user-workspace/user-workspace.service'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; -import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { ActivateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/activate-workspace-input'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; +import { BillingService } from 'src/engine/core-modules/billing/billing.service'; export class WorkspaceService extends TypeOrmQueryService { constructor( diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.auto-resolver-opts.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.auto-resolver-opts.ts similarity index 89% rename from packages/twenty-server/src/engine/modules/workspace/workspace.auto-resolver-opts.ts rename to packages/twenty-server/src/engine/core-modules/workspace/workspace.auto-resolver-opts.ts index 31493337e4ca..50f7a0a5aa13 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.auto-resolver-opts.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.auto-resolver-opts.ts @@ -5,7 +5,7 @@ import { } from '@ptc-org/nestjs-query-graphql'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { UpdateWorkspaceInput } from 'src/engine/modules/workspace/dtos/update-workspace-input'; +import { UpdateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/update-workspace-input'; import { Workspace } from './workspace.entity'; diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.entity.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.entity.ts similarity index 84% rename from packages/twenty-server/src/engine/modules/workspace/workspace.entity.ts rename to packages/twenty-server/src/engine/core-modules/workspace/workspace.entity.ts index 514213723992..e560fcf41b62 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.entity.ts @@ -11,10 +11,10 @@ import { } from 'typeorm'; import Stripe from 'stripe'; -import { User } from 'src/engine/modules/user/user.entity'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; @Entity({ name: 'workspace', schema: 'core' }) @ObjectType('Workspace') diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.module.ts similarity index 62% rename from packages/twenty-server/src/engine/modules/workspace/workspace.module.ts rename to packages/twenty-server/src/engine/core-modules/workspace/workspace.module.ts index e636e051cce3..60497404a6ca 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.module.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.module.ts @@ -4,15 +4,15 @@ import { NestjsQueryGraphQLModule } from '@ptc-org/nestjs-query-graphql'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; -import { WorkspaceResolver } from 'src/engine/modules/workspace/workspace.resolver'; +import { WorkspaceResolver } from 'src/engine/core-modules/workspace/workspace.resolver'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { BillingModule } from 'src/engine/modules/billing/billing.module'; -import { UserWorkspace } from 'src/engine/modules/user-workspace/user-workspace.entity'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; -import { User } from 'src/engine/modules/user/user.entity'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { FileUploadModule } from 'src/engine/modules/file/file-upload/file-upload.module'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; +import { User } from 'src/engine/core-modules/user/user.entity'; +import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; +import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; +import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { workspaceAutoResolverOpts } from './workspace.auto-resolver-opts'; import { Workspace } from './workspace.entity'; diff --git a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts similarity index 82% rename from packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts rename to packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts index db02e138425e..5cc961469ab3 100644 --- a/packages/twenty-server/src/engine/modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts @@ -10,19 +10,19 @@ import { UseGuards } from '@nestjs/common'; import { FileUpload, GraphQLUpload } from 'graphql-upload'; -import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.interface'; +import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; -import { FileUploadService } from 'src/engine/modules/file/file-upload/services/file-upload.service'; +import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { assert } from 'src/utils/assert'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { UpdateWorkspaceInput } from 'src/engine/modules/workspace/dtos/update-workspace-input'; -import { User } from 'src/engine/modules/user/user.entity'; +import { UpdateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/update-workspace-input'; +import { User } from 'src/engine/core-modules/user/user.entity'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; -import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; +import { ActivateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/activate-workspace-input'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { BillingService } from 'src/engine/core-modules/billing/billing.service'; import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { Workspace } from './workspace.entity'; diff --git a/packages/twenty-server/src/engine-metadata/decorators/is-valid-name.decorator.ts b/packages/twenty-server/src/engine/decorators/metadata/is-valid-metadata-name.decorator.ts similarity index 89% rename from packages/twenty-server/src/engine-metadata/decorators/is-valid-name.decorator.ts rename to packages/twenty-server/src/engine/decorators/metadata/is-valid-metadata-name.decorator.ts index afbc9314d8ec..d58663db3d40 100644 --- a/packages/twenty-server/src/engine-metadata/decorators/is-valid-name.decorator.ts +++ b/packages/twenty-server/src/engine/decorators/metadata/is-valid-metadata-name.decorator.ts @@ -4,7 +4,7 @@ import { ValidationArguments, } from 'class-validator'; -export function IsValidName(validationOptions?: ValidationOptions) { +export function IsValidMetadataName(validationOptions?: ValidationOptions) { return function (object: object, propertyName: string) { registerDecorator({ name: 'IsValidName', diff --git a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts index 1afb6e784e3b..452c643352b9 100644 --- a/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts +++ b/packages/twenty-server/src/engine/integrations/environment/environment-variables.ts @@ -11,6 +11,8 @@ import { IsBoolean, IsNumber, IsDefined, + Min, + Max, } from 'class-validator'; import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; @@ -38,6 +40,13 @@ export class EnvironmentVariables { @IsBoolean() DEBUG_MODE: boolean = false; + @CastToPositiveNumber() + @IsOptional() + @IsNumber() + @Min(0) + @Max(65535) + DEBUG_PORT: number = 9000; + @CastToBoolean() @IsOptional() @IsBoolean() @@ -130,11 +139,12 @@ export class EnvironmentVariables { LOGIN_TOKEN_EXPIRES_IN: string = '15m'; @IsString() - FILE_TOKEN_SECRET: string; + @IsOptional() + FILE_TOKEN_SECRET: string = 'random_string'; @IsDuration() @IsOptional() - FILE_TOKEN_EXPIRES_IN: string; + FILE_TOKEN_EXPIRES_IN: string = '1d'; // Auth @IsUrl({ require_tld: false }) @@ -197,6 +207,11 @@ export class EnvironmentVariables { @IsOptional() LOGGER_DRIVER: LoggerDriverType = LoggerDriverType.Console; + @CastToBoolean() + @IsBoolean() + @IsOptional() + LOGGER_IS_BUFFER_ENABLED: boolean = true; + @IsEnum(ExceptionHandlerDriver) @IsOptional() EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver = @@ -288,8 +303,6 @@ export class EnvironmentVariables { CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean = false; AUTH_GOOGLE_APIS_CALLBACK_URL: string; - - LOGGER_IS_BUFFER_ENABLED: boolean = true; } export const validate = (config: Record) => { diff --git a/packages/twenty-server/src/engine/integrations/environment/environment.default.ts b/packages/twenty-server/src/engine/integrations/environment/environment.default.ts deleted file mode 100644 index 3b3632d4fbb1..000000000000 --- a/packages/twenty-server/src/engine/integrations/environment/environment.default.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; -import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; - -import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; -import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; -import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; -import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; -import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; - -const EnvironmentDefault = new EnvironmentVariables(); - -EnvironmentDefault.DEBUG_MODE = false; -EnvironmentDefault.SIGN_IN_PREFILLED = false; -EnvironmentDefault.IS_BILLING_ENABLED = false; -EnvironmentDefault.BILLING_PLAN_REQUIRED_LINK = ''; -EnvironmentDefault.BILLING_STRIPE_BASE_PLAN_PRODUCT_ID = ''; -EnvironmentDefault.BILLING_FREE_TRIAL_DURATION_IN_DAYS = 7; -EnvironmentDefault.BILLING_STRIPE_API_KEY = ''; -EnvironmentDefault.BILLING_STRIPE_WEBHOOK_SECRET = ''; -EnvironmentDefault.TELEMETRY_ENABLED = true; -EnvironmentDefault.TELEMETRY_ANONYMIZATION_ENABLED = true; -EnvironmentDefault.PORT = 3000; -EnvironmentDefault.REDIS_HOST = '127.0.0.1'; -EnvironmentDefault.REDIS_PORT = 6379; -EnvironmentDefault.PG_DATABASE_URL = ''; -EnvironmentDefault.FRONT_BASE_URL = ''; -EnvironmentDefault.SERVER_URL = ''; -EnvironmentDefault.ACCESS_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.ACCESS_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.REFRESH_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.REFRESH_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.REFRESH_TOKEN_COOL_DOWN = '1m'; -EnvironmentDefault.LOGIN_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.LOGIN_TOKEN_EXPIRES_IN = '30m'; -EnvironmentDefault.FILE_TOKEN_SECRET = 'random_string'; -EnvironmentDefault.FILE_TOKEN_EXPIRES_IN = '1d'; -EnvironmentDefault.API_TOKEN_EXPIRES_IN = '100y'; -EnvironmentDefault.SHORT_TERM_TOKEN_EXPIRES_IN = '5m'; -EnvironmentDefault.FRONT_AUTH_CALLBACK_URL = ''; -EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_ENABLED = false; -EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_CALLBACK_URL = ''; -EnvironmentDefault.AUTH_GOOGLE_ENABLED = false; -EnvironmentDefault.AUTH_GOOGLE_CLIENT_ID = ''; -EnvironmentDefault.AUTH_GOOGLE_CLIENT_SECRET = ''; -EnvironmentDefault.AUTH_GOOGLE_CALLBACK_URL = ''; -EnvironmentDefault.STORAGE_TYPE = StorageDriverType.Local; -EnvironmentDefault.STORAGE_S3_REGION = 'aws-east-1'; -EnvironmentDefault.STORAGE_S3_NAME = ''; -EnvironmentDefault.STORAGE_S3_ENDPOINT = ''; -EnvironmentDefault.STORAGE_LOCAL_PATH = '.local-storage'; -EnvironmentDefault.MESSAGE_QUEUE_TYPE = MessageQueueDriverType.Sync; -EnvironmentDefault.EMAIL_FROM_ADDRESS = 'noreply@yourdomain.com'; -EnvironmentDefault.EMAIL_SYSTEM_ADDRESS = 'system@yourdomain.com'; -EnvironmentDefault.EMAIL_FROM_NAME = 'John from Twenty'; -EnvironmentDefault.EMAIL_DRIVER = EmailDriver.Logger; -EnvironmentDefault.EMAIL_SMTP_HOST = ''; -EnvironmentDefault.EMAIL_SMTP_PORT = 587; -EnvironmentDefault.EMAIL_SMTP_USER = ''; -EnvironmentDefault.EMAIL_SMTP_PASSWORD = ''; -EnvironmentDefault.SUPPORT_DRIVER = SupportDriver.None; -EnvironmentDefault.SUPPORT_FRONT_CHAT_ID = ''; -EnvironmentDefault.SUPPORT_FRONT_HMAC_KEY = ''; -EnvironmentDefault.LOGGER_DRIVER = LoggerDriverType.Console; -EnvironmentDefault.EXCEPTION_HANDLER_DRIVER = ExceptionHandlerDriver.Console; -EnvironmentDefault.LOG_LEVELS = ['log', 'error', 'warn']; -EnvironmentDefault.SENTRY_DSN = ''; -EnvironmentDefault.DEMO_WORKSPACE_IDS = []; -EnvironmentDefault.OPENROUTER_API_KEY = ''; -EnvironmentDefault.PASSWORD_RESET_TOKEN_EXPIRES_IN = '5m'; -EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION = 30; -EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION = 60; -EnvironmentDefault.IS_SIGN_UP_DISABLED = false; -EnvironmentDefault.API_RATE_LIMITING_TTL = 100; -EnvironmentDefault.API_RATE_LIMITING_LIMIT = 500; -EnvironmentDefault.MUTATION_MAXIMUM_RECORD_AFFECTED = 100; -EnvironmentDefault.CACHE_STORAGE_TYPE = 'memory'; -EnvironmentDefault.CACHE_STORAGE_TTL = 3600 * 24 * 7; - -export { EnvironmentDefault }; diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts index d926f9efa8b7..24b59342749f 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts @@ -1,4 +1,4 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; export class ObjectRecordBaseEvent { workspaceId: string; diff --git a/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts index 76212bacacdf..7d8892d1391b 100644 --- a/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-exception-handler.hook.ts @@ -6,13 +6,13 @@ import { Plugin, } from '@envelop/core'; -import { GraphQLContext } from 'src/engine-graphql-config/interfaces/graphql-context.interface'; +import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { convertExceptionToGraphQLError, filterException, -} from 'src/engine/filters/utils/global-exception-handler.util'; +} from 'src/engine/utils/global-exception-handler.util'; export type ExceptionHandlerPluginOptions = { /** diff --git a/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts index a40d5547b139..3db35cca3abf 100644 --- a/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts +++ b/packages/twenty-server/src/engine/integrations/exception-handler/hooks/use-sentry-tracing.ts @@ -6,7 +6,7 @@ import { } from '@envelop/core'; import { OperationDefinitionNode, Kind, print } from 'graphql'; -import { GraphQLContext } from 'src/engine-graphql-config/graphql-config.service'; +import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/graphql-config.service'; export const useSentryTracing = < PluginContext extends GraphQLContext, diff --git a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts index d2f056b721c2..5e54e6dc3ae0 100644 --- a/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/jobs.module.ts @@ -7,13 +7,13 @@ import { GmailFullSyncJob } from 'src/modules/messaging/jobs/gmail-full-sync.job import { CallWebhookJobsJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook-jobs.job'; import { CallWebhookJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { CleanInactiveWorkspaceJob } from 'src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { GmailPartialSyncJob } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; import { EmailSenderJob } from 'src/engine/integrations/email/email-sender.job'; -import { UserModule } from 'src/engine/modules/user/user.module'; +import { UserModule } from 'src/engine/core-modules/user/user.module'; import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module'; import { FetchAllWorkspacesMessagesJob } from 'src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job'; import { MatchMessageParticipantJob } from 'src/modules/messaging/jobs/match-message-participant.job'; @@ -23,13 +23,13 @@ import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-dem import { DataSeedDemoWorkspaceJob } from 'src/database/commands/data-seed-demo-workspace/jobs/data-seed-demo-workspace.job'; import { DeleteConnectedAccountAssociatedMessagingDataJob } from 'src/modules/messaging/jobs/delete-connected-account-associated-messaging-data.job'; import { ThreadCleanerModule } from 'src/modules/messaging/services/thread-cleaner/thread-cleaner.module'; -import { UpdateSubscriptionJob } from 'src/engine/modules/billing/jobs/update-subscription.job'; -import { BillingModule } from 'src/engine/modules/billing/billing.module'; -import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; -import { StripeModule } from 'src/engine/modules/billing/stripe/stripe.module'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { UpdateSubscriptionJob } from 'src/engine/core-modules/billing/jobs/update-subscription.job'; +import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; +import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; +import { StripeModule } from 'src/engine/core-modules/billing/stripe/stripe.module'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { GoogleCalendarFullSyncJob } from 'src/modules/calendar/jobs/google-calendar-full-sync.job'; import { CalendarEventCleanerModule } from 'src/modules/calendar/services/calendar-event-cleaner/calendar-event-cleaner.module'; import { RecordPositionBackfillJob } from 'src/engine/api/graphql/workspace-query-runner/jobs/record-position-backfill.job'; diff --git a/packages/twenty-server/src/engine-metadata/data-source/data-source.entity.ts b/packages/twenty-server/src/engine/metadata-modules/data-source/data-source.entity.ts similarity index 89% rename from packages/twenty-server/src/engine-metadata/data-source/data-source.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/data-source/data-source.entity.ts index af1904194eb0..7224b7542f9f 100644 --- a/packages/twenty-server/src/engine-metadata/data-source/data-source.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/data-source/data-source.entity.ts @@ -8,7 +8,7 @@ import { OneToMany, } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export type DataSourceType = DataSourceOptions['type']; diff --git a/packages/twenty-server/src/engine-metadata/data-source/data-source.module.ts b/packages/twenty-server/src/engine/metadata-modules/data-source/data-source.module.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/data-source/data-source.module.ts rename to packages/twenty-server/src/engine/metadata-modules/data-source/data-source.module.ts diff --git a/packages/twenty-server/src/engine-metadata/data-source/data-source.service.ts b/packages/twenty-server/src/engine/metadata-modules/data-source/data-source.service.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/data-source/data-source.service.ts rename to packages/twenty-server/src/engine/metadata-modules/data-source/data-source.service.ts diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/currency.composite-type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type.ts similarity index 81% rename from packages/twenty-server/src/engine-metadata/field-metadata/composite-types/currency.composite-type.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type.ts index 84b2714f152f..3e0194c858b5 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/currency.composite-type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type.ts @@ -1,8 +1,8 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; export const currencyFields = ( fieldMetadata?: FieldMetadataInterface, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/full-name.composite-type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type.ts similarity index 81% rename from packages/twenty-server/src/engine-metadata/field-metadata/composite-types/full-name.composite-type.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type.ts index bb39128fef0c..e05939c52e0d 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/full-name.composite-type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type.ts @@ -1,8 +1,8 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; export const fullNameFields = ( fieldMetadata?: FieldMetadataInterface, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts new file mode 100644 index 000000000000..c88c50aebcc4 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts @@ -0,0 +1,19 @@ +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; + +import { currencyFields } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type'; +import { fullNameFields } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; +import { linkFields } from 'src/engine/metadata-modules/field-metadata/composite-types/link.composite-type'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; + +export type CompositeFieldsDefinitionFunction = ( + fieldMetadata?: FieldMetadataInterface, +) => FieldMetadataInterface[]; + +export const compositeDefinitions = new Map< + string, + CompositeFieldsDefinitionFunction +>([ + [FieldMetadataType.LINK, linkFields], + [FieldMetadataType.CURRENCY, currencyFields], + [FieldMetadataType.FULL_NAME, fullNameFields], +]); diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/link.composite-type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts similarity index 80% rename from packages/twenty-server/src/engine-metadata/field-metadata/composite-types/link.composite-type.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts index d46511482c83..7776a1f8db4b 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/composite-types/link.composite-type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts @@ -1,8 +1,8 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; export const linkFields = ( fieldMetadata?: FieldMetadataInterface, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/create-field.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/create-field.input.ts similarity index 84% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/create-field.input.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/create-field.input.ts index d105dfe85e6c..40ccd7467a89 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/create-field.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/create-field.input.ts @@ -3,7 +3,7 @@ import { Field, InputType, OmitType } from '@nestjs/graphql'; import { IsUUID, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; @InputType() export class CreateFieldInput extends OmitType( diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/default-value.input.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/field-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts similarity index 69% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/field-metadata.dto.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts index 37dea5a5c17c..b901fca7ae63 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/field-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts @@ -26,15 +26,15 @@ import { Validate, } from 'class-validator'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { RelationMetadataDTO } from 'src/engine-metadata/relation-metadata/dtos/relation-metadata.dto'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { BeforeDeleteOneField } from 'src/engine-metadata/field-metadata/hooks/before-delete-one-field.hook'; -import { IsFieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/validators/is-field-metadata-default-value.validator'; -import { IsFieldMetadataOptions } from 'src/engine-metadata/field-metadata/validators/is-field-metadata-options.validator'; -import { IsValidName } from 'src/engine-metadata/decorators/is-valid-name.decorator'; +import { RelationMetadataDTO } from 'src/engine/metadata-modules/relation-metadata/dtos/relation-metadata.dto'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { BeforeDeleteOneField } from 'src/engine/metadata-modules/field-metadata/hooks/before-delete-one-field.hook'; +import { IsFieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator'; +import { IsFieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator'; +import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator'; registerEnumType(FieldMetadataType, { name: 'FieldMetadataType', @@ -75,7 +75,7 @@ export class FieldMetadataDTO< @IsString() @IsNotEmpty() @Field() - @IsValidName() + @IsValidMetadataName() name: string; @IsString() diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/options.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/options.input.ts similarity index 76% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/options.input.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/options.input.ts index c40baa7f56e0..19ab79a7fb03 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/options.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/options.input.ts @@ -1,6 +1,6 @@ import { IsString, IsNumber, IsOptional, IsNotEmpty } from 'class-validator'; -import { IsValidGraphQLEnumName } from 'src/engine-metadata/field-metadata/validators/is-valid-graphql-enum-name.validator'; +import { IsValidGraphQLEnumName } from 'src/engine/metadata-modules/field-metadata/validators/is-valid-graphql-enum-name.validator'; export class FieldMetadataDefaultOption { @IsOptional() diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/relation-definition.dto.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto.ts similarity index 76% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/relation-definition.dto.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto.ts index 96514fedecfb..3f97279947e9 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/relation-definition.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto.ts @@ -2,9 +2,9 @@ import { Field, ObjectType, registerEnumType } from '@nestjs/graphql'; import { IsEnum, IsNotEmpty } from 'class-validator'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; -import { ObjectMetadataDTO } from 'src/engine-metadata/object-metadata/dtos/object-metadata.dto'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; +import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export enum RelationDefinitionType { ONE_TO_ONE = RelationMetadataType.ONE_TO_ONE, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/update-field.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/update-field.input.ts similarity index 88% rename from packages/twenty-server/src/engine-metadata/field-metadata/dtos/update-field.input.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/update-field.input.ts index ab44d88dccfe..ffa8049a672e 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/dtos/update-field.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/update-field.input.ts @@ -10,7 +10,7 @@ import { import { Type } from 'class-transformer'; import { IsNotEmpty, IsUUID, ValidateNested } from 'class-validator'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; @InputType() export class UpdateFieldInput extends OmitType( diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts similarity index 76% rename from packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts index 2ac194c4dabd..11bf1de227f8 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts @@ -10,13 +10,13 @@ import { UpdateDateColumn, } from 'typeorm'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataTargetColumnMap } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export enum FieldMetadataType { UUID = 'UUID', diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts similarity index 71% rename from packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.module.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts index 89662c32a05a..0104a59b64dc 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.module.ts @@ -8,16 +8,16 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { SortDirection } from '@ptc-org/nestjs-query-core'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { IsFieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/validators/is-field-metadata-default-value.validator'; -import { FieldMetadataResolver } from 'src/engine-metadata/field-metadata/field-metadata.resolver'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; -import { IsFieldMetadataOptions } from 'src/engine-metadata/field-metadata/validators/is-field-metadata-options.validator'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { IsFieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator'; +import { FieldMetadataResolver } from 'src/engine/metadata-modules/field-metadata/field-metadata.resolver'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; +import { IsFieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { FieldMetadataService } from './field-metadata.service'; import { FieldMetadataEntity } from './field-metadata.entity'; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts similarity index 67% rename from packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.resolver.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts index 6f465de5f6f8..99d145a3df62 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts @@ -7,14 +7,14 @@ import { Resolver, } from '@nestjs/graphql'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { CreateOneFieldMetadataInput } from 'src/engine-metadata/field-metadata/dtos/create-field.input'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; -import { RelationDefinitionDTO } from 'src/engine-metadata/field-metadata/dtos/relation-definition.dto'; -import { UpdateOneFieldMetadataInput } from 'src/engine-metadata/field-metadata/dtos/update-field.input'; -import { FieldMetadataService } from 'src/engine-metadata/field-metadata/field-metadata.service'; +import { CreateOneFieldMetadataInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; +import { RelationDefinitionDTO } from 'src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto'; +import { UpdateOneFieldMetadataInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input'; +import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; @UseGuards(JwtAuthGuard) @Resolver(() => FieldMetadataDTO) diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts similarity index 90% rename from packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts index 038b0a83c5d5..de36dd302889 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts @@ -11,30 +11,30 @@ import { FindOneOptions, Repository } from 'typeorm'; import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; -import { WorkspaceMigrationService } from 'src/engine-metadata/workspace-migration/workspace-migration.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { CreateFieldInput } from 'src/engine-metadata/field-metadata/dtos/create-field.input'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationTableAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { UpdateFieldInput } from 'src/engine-metadata/field-metadata/dtos/update-field.input'; -import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input'; +import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; -import { generateNullable } from 'src/engine-metadata/field-metadata/utils/generate-nullable'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; +import { generateNullable } from 'src/engine/metadata-modules/field-metadata/utils/generate-nullable'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; import { RelationDefinitionDTO, RelationDefinitionType, -} from 'src/engine-metadata/field-metadata/dtos/relation-definition.dto'; +} from 'src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto'; import { RelationMetadataEntity, RelationMetadataType, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { FieldMetadataEntity, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/hooks/before-delete-one-field.hook.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/hooks/before-delete-one-field.hook.ts similarity index 86% rename from packages/twenty-server/src/engine-metadata/field-metadata/hooks/before-delete-one-field.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/hooks/before-delete-one-field.hook.ts index fa85f76e2691..a9f65528b616 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/hooks/before-delete-one-field.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/hooks/before-delete-one-field.hook.ts @@ -9,8 +9,8 @@ import { DeleteOneInputType, } from '@ptc-org/nestjs-query-graphql'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { FieldMetadataService } from 'src/engine-metadata/field-metadata/field-metadata.service'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; @Injectable() export class BeforeDeleteOneField implements BeforeDeleteOneHook { diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts similarity index 94% rename from packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts index d08a8be1cf28..191f077bc2f0 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts @@ -10,8 +10,8 @@ import { FieldMetadataDefaultValueStringArray, FieldMetadataDynamicDefaultValueNow, FieldMetadataDynamicDefaultValueUuid, -} from 'src/engine-metadata/field-metadata/dtos/default-value.input'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; type FieldMetadataScalarDefaultValue = | FieldMetadataDefaultValueString diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface.ts similarity index 79% rename from packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface.ts index 5a7c966591e3..c6139048b511 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface.ts @@ -1,8 +1,8 @@ import { FieldMetadataComplexOption, FieldMetadataDefaultOption, -} from 'src/engine-metadata/field-metadata/dtos/options.input'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; type FieldMetadataOptionsMapping = { [FieldMetadataType.RATING]: FieldMetadataDefaultOption[]; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface.ts similarity index 91% rename from packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface.ts index 39e573e1834f..946b0acf4dc5 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export interface FieldMetadataTargetColumnMapValue { value: string; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface.ts new file mode 100644 index 000000000000..2f276ae21679 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface.ts @@ -0,0 +1,25 @@ +import { FieldMetadataTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; + +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; + +export interface FieldMetadataInterface< + T extends FieldMetadataType | 'default' = 'default', +> { + id: string; + type: FieldMetadataType; + name: string; + label: string; + targetColumnMap: FieldMetadataTargetColumnMap; + defaultValue?: FieldMetadataDefaultValue; + options?: FieldMetadataOptions; + objectMetadataId: string; + workspaceId?: string; + description?: string; + isNullable?: boolean; + fromRelationMetadata?: RelationMetadataEntity; + toRelationMetadata?: RelationMetadataEntity; + isCustom?: boolean; +} diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/object-metadata.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/field-metadata/interfaces/object-metadata.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface.ts diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/relation-metadata.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface.ts similarity index 83% rename from packages/twenty-server/src/engine-metadata/field-metadata/interfaces/relation-metadata.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface.ts index cbb094a31811..b1342b4b8396 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/interfaces/relation-metadata.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface.ts @@ -1,4 +1,4 @@ -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { ObjectMetadataInterface } from './object-metadata.interface'; import { FieldMetadataInterface } from './field-metadata.interface'; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-nullable.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-nullable.spec.ts similarity index 85% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-nullable.spec.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-nullable.spec.ts index f1393dc1c162..6d4ab103196d 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-nullable.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-nullable.spec.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateNullable } from 'src/engine-metadata/field-metadata/utils/generate-nullable'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateNullable } from 'src/engine/metadata-modules/field-metadata/utils/generate-nullable'; describe('generateNullable', () => { it('should generate a nullable value false for TEXT, EMAIL, PHONE no matter what the input is', () => { diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-target-column-map.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-target-column-map.spec.ts similarity index 81% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-target-column-map.spec.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-target-column-map.spec.ts index c7e53f0fe2a1..578e19191129 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/generate-target-column-map.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/generate-target-column-map.spec.ts @@ -1,7 +1,7 @@ import { BadRequestException } from '@nestjs/common'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; describe('generateTargetColumnMap', () => { it('should generate a target column map for a given type', () => { diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/serialize-default-value.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/serialize-default-value.spec.ts similarity index 92% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/serialize-default-value.spec.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/serialize-default-value.spec.ts index 4e0489b9021f..160c77579c33 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/serialize-default-value.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/serialize-default-value.spec.ts @@ -1,6 +1,6 @@ import { BadRequestException } from '@nestjs/common'; -import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; describe('serializeDefaultValue', () => { it('should return null for undefined defaultValue', () => { diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts similarity index 95% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts index 83752ae8bbe7..bc8146b3fc8d 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { validateDefaultValueForType } from 'src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { validateDefaultValueForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util'; describe('validateDefaultValueForType', () => { it('should return true for null defaultValue', () => { diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-default-value.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts similarity index 71% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-default-value.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts index 02e8cff1e280..426a0c510d67 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-default-value.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts @@ -1,6 +1,6 @@ -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export function generateDefaultValue( type: FieldMetadataType, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-nullable.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts similarity index 75% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-nullable.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts index 16f7eb352789..650a01f40665 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-nullable.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export function generateNullable( type: FieldMetadataType, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-rating-optionts.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-rating-optionts.util.ts similarity index 79% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-rating-optionts.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-rating-optionts.util.ts index 665563b12af0..06f4f5a9e272 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-rating-optionts.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-rating-optionts.util.ts @@ -1,6 +1,6 @@ import { v4 as uuidV4 } from 'uuid'; -import { FieldMetadataDefaultOption } from 'src/engine-metadata/field-metadata/dtos/options.input'; +import { FieldMetadataDefaultOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; const range = { start: 1, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts similarity index 83% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts index 54161679cae3..e1d469439993 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/generate-target-column-map.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts @@ -1,9 +1,9 @@ import { BadRequestException } from '@nestjs/common'; -import { FieldMetadataTargetColumnMap } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface'; +import { FieldMetadataTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { createCustomColumnName } from 'src/engine-metadata/utils/create-custom-column-name.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { createCustomColumnName } from 'src/engine/utils/create-custom-column-name.util'; /** * Generate a target column map for a given type, this is used to map the field to the correct column(s) in the database. diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts similarity index 75% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts index 032617d389b9..c62caada5c4a 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export const isCompositeFieldMetadataType = ( type: FieldMetadataType, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util.ts similarity index 79% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util.ts index 1262c8b5bf8b..2e179b45f277 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export type EnumFieldMetadataUnionType = | FieldMetadataType.RATING diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-default-value.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-default-value.ts similarity index 85% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-default-value.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-default-value.ts index 0cb3f0e1dee6..6ce2b5153502 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-default-value.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-default-value.ts @@ -1,8 +1,8 @@ import { BadRequestException } from '@nestjs/common'; -import { FieldMetadataDefaultSerializableValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultSerializableValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { serializeTypeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-type-default-value.util'; +import { serializeTypeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-type-default-value.util'; export const serializeDefaultValue = ( defaultValue?: FieldMetadataDefaultSerializableValue, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-type-default-value.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-type-default-value.util.ts similarity index 68% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-type-default-value.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-type-default-value.util.ts index f31a92d9a963..02831c631ecf 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/serialize-type-default-value.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/serialize-type-default-value.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataDynamicDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDynamicDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; export const serializeTypeDefaultValue = ( defaultValue?: FieldMetadataDynamicDefaultValue, diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts similarity index 88% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts index 9e9377e24020..4c436bff8a8c 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts @@ -1,9 +1,9 @@ import { plainToInstance } from 'class-transformer'; import { validateSync } from 'class-validator'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataDefaultValueBoolean, FieldMetadataDefaultValueCurrency, @@ -16,7 +16,7 @@ import { FieldMetadataDefaultValueStringArray, FieldMetadataDynamicDefaultValueNow, FieldMetadataDynamicDefaultValueUuid, -} from 'src/engine-metadata/field-metadata/dtos/default-value.input'; +} from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; export const defaultValueValidatorsMap = { [FieldMetadataType.UUID]: [ diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-options-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util.ts similarity index 82% rename from packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-options-for-type.util.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util.ts index e68b328b0021..f671d0ea0aa1 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/utils/validate-options-for-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util.ts @@ -1,13 +1,13 @@ import { plainToInstance } from 'class-transformer'; import { validateSync } from 'class-validator'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataComplexOption, FieldMetadataDefaultOption, -} from 'src/engine-metadata/field-metadata/dtos/options.input'; +} from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; import { isEnumFieldMetadataType } from './is-enum-field-metadata-type.util'; diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-default-value.validator.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator.ts similarity index 73% rename from packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-default-value.validator.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator.ts index a9eaf4f69925..1064f999afd5 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-default-value.validator.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator.ts @@ -6,14 +6,14 @@ import { ValidatorConstraintInterface, } from 'class-validator'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataService } from 'src/engine-metadata/field-metadata/field-metadata.service'; +import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { validateDefaultValueForType } from 'src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { validateDefaultValueForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util'; @Injectable() @ValidatorConstraint({ name: 'isFieldMetadataDefaultValue', async: true }) diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-options.validator.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator.ts similarity index 72% rename from packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-options.validator.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator.ts index 783bafdfb97f..ecbb09153917 100644 --- a/packages/twenty-server/src/engine-metadata/field-metadata/validators/is-field-metadata-options.validator.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator.ts @@ -2,14 +2,14 @@ import { Injectable } from '@nestjs/common'; import { ValidationArguments, ValidatorConstraint } from 'class-validator'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; -import { FieldMetadataService } from 'src/engine-metadata/field-metadata/field-metadata.service'; +import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { validateOptionsForType } from 'src/engine-metadata/field-metadata/utils/validate-options-for-type.util'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { validateOptionsForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util'; @Injectable() @ValidatorConstraint({ name: 'isFieldMetadataOptions', async: true }) diff --git a/packages/twenty-server/src/engine-metadata/field-metadata/validators/is-valid-graphql-enum-name.validator.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-valid-graphql-enum-name.validator.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/field-metadata/validators/is-valid-graphql-enum-name.validator.ts rename to packages/twenty-server/src/engine/metadata-modules/field-metadata/validators/is-valid-graphql-enum-name.validator.ts diff --git a/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts b/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts new file mode 100644 index 000000000000..9eb3ea468253 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts @@ -0,0 +1,27 @@ +import { Module } from '@nestjs/common'; + +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { RelationMetadataModule } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; + +@Module({ + imports: [ + DataSourceModule, + FieldMetadataModule, + ObjectMetadataModule, + RelationMetadataModule, + WorkspaceCacheVersionModule, + WorkspaceMigrationModule, + ], + providers: [], + exports: [ + DataSourceModule, + FieldMetadataModule, + ObjectMetadataModule, + RelationMetadataModule, + ], +}) +export class MetadataEngineModule {} diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/create-object.input.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/create-object.input.ts similarity index 78% rename from packages/twenty-server/src/engine-metadata/object-metadata/dtos/create-object.input.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/create-object.input.ts index c6e031944ba3..7719af1d0904 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/create-object.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/create-object.input.ts @@ -3,8 +3,8 @@ import { Field, HideField, InputType } from '@nestjs/graphql'; import { BeforeCreateOne } from '@ptc-org/nestjs-query-graphql'; import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; -import { IsValidName } from 'src/engine-metadata/decorators/is-valid-name.decorator'; -import { BeforeCreateOneObject } from 'src/engine-metadata/object-metadata/hooks/before-create-one-object.hook'; +import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator'; +import { BeforeCreateOneObject } from 'src/engine/metadata-modules/object-metadata/hooks/before-create-one-object.hook'; @InputType() @BeforeCreateOne(BeforeCreateOneObject) @@ -12,13 +12,13 @@ export class CreateObjectInput { @IsString() @IsNotEmpty() @Field() - @IsValidName() + @IsValidMetadataName() nameSingular: string; @IsString() @IsNotEmpty() @Field() - @IsValidName() + @IsValidMetadataName() namePlural: string; @IsString() diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/delete-object.input.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/delete-object.input.ts similarity index 71% rename from packages/twenty-server/src/engine-metadata/object-metadata/dtos/delete-object.input.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/delete-object.input.ts index ab5a4331812a..578f63b320f9 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/delete-object.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/delete-object.input.ts @@ -2,7 +2,7 @@ import { ID, InputType } from '@nestjs/graphql'; import { BeforeDeleteOne, IDField } from '@ptc-org/nestjs-query-graphql'; -import { BeforeDeleteOneObject } from 'src/engine-metadata/object-metadata/hooks/before-delete-one-object.hook'; +import { BeforeDeleteOneObject } from 'src/engine/metadata-modules/object-metadata/hooks/before-delete-one-object.hook'; @InputType() @BeforeDeleteOne(BeforeDeleteOneObject) diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/object-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts similarity index 84% rename from packages/twenty-server/src/engine-metadata/object-metadata/dtos/object-metadata.dto.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts index 48a9ef32863c..0ca4d75ae256 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/object-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto.ts @@ -9,8 +9,8 @@ import { QueryOptions, } from '@ptc-org/nestjs-query-graphql'; -import { FieldMetadataDTO } from 'src/engine-metadata/field-metadata/dtos/field-metadata.dto'; -import { BeforeDeleteOneObject } from 'src/engine-metadata/object-metadata/hooks/before-delete-one-object.hook'; +import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; +import { BeforeDeleteOneObject } from 'src/engine/metadata-modules/object-metadata/hooks/before-delete-one-object.hook'; @ObjectType('object') @Authorize({ diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/update-object.input.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/update-object.input.ts similarity index 79% rename from packages/twenty-server/src/engine-metadata/object-metadata/dtos/update-object.input.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/update-object.input.ts index 28f5b957d247..cb74a3a30004 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/dtos/update-object.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/dtos/update-object.input.ts @@ -3,8 +3,8 @@ import { Field, InputType } from '@nestjs/graphql'; import { BeforeUpdateOne } from '@ptc-org/nestjs-query-graphql'; import { IsBoolean, IsOptional, IsString, IsUUID } from 'class-validator'; -import { IsValidName } from 'src/engine-metadata/decorators/is-valid-name.decorator'; -import { BeforeUpdateOneObject } from 'src/engine-metadata/object-metadata/hooks/before-update-one-object.hook'; +import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator'; +import { BeforeUpdateOneObject } from 'src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook'; @InputType() @BeforeUpdateOne(BeforeUpdateOneObject) @@ -22,13 +22,13 @@ export class UpdateObjectInput { @IsString() @IsOptional() @Field({ nullable: true }) - @IsValidName() + @IsValidMetadataName() nameSingular?: string; @IsString() @IsOptional() @Field({ nullable: true }) - @IsValidName() + @IsValidMetadataName() namePlural?: string; @IsString() diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-create-one-object.hook.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-create-one-object.hook.ts similarity index 90% rename from packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-create-one-object.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-create-one-object.hook.ts index b876313c774b..5d9960f27060 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-create-one-object.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-create-one-object.hook.ts @@ -9,7 +9,7 @@ import { CreateOneInputType, } from '@ptc-org/nestjs-query-graphql'; -import { CreateObjectInput } from 'src/engine-metadata/object-metadata/dtos/create-object.input'; +import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input'; const coreObjectNames = [ 'featureFlag', diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-delete-one-object.hook.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-delete-one-object.hook.ts similarity index 91% rename from packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-delete-one-object.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-delete-one-object.hook.ts index 9d9a4404402a..6c3db542dd05 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-delete-one-object.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-delete-one-object.hook.ts @@ -9,7 +9,7 @@ import { DeleteOneInputType, } from '@ptc-org/nestjs-query-graphql'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; @Injectable() export class BeforeDeleteOneObject implements BeforeDeleteOneHook { diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-update-one-object.hook.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts similarity index 90% rename from packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-update-one-object.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts index 5e43f76b9bfa..53018786215e 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/hooks/before-update-one-object.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/hooks/before-update-one-object.hook.ts @@ -11,10 +11,10 @@ import { } from '@ptc-org/nestjs-query-graphql'; import { Equal, In, Repository } from 'typeorm'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { UpdateObjectInput } from 'src/engine-metadata/object-metadata/dtos/update-object.input'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { UpdateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; @Injectable() export class BeforeUpdateOneObject diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts similarity index 83% rename from packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts index 83c03536e467..d6e68baf8e93 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.entity.ts @@ -9,11 +9,11 @@ import { ManyToOne, } from 'typeorm'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; @Entity('objectMetadata') @Unique('IndexOnNameSingularAndWorkspaceIdUnique', [ diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts similarity index 79% rename from packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.module.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts index 54686f3f094e..722835a02ad0 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.module.ts @@ -7,14 +7,14 @@ import { import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { SortDirection } from '@ptc-org/nestjs-query-core'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { ObjectMetadataResolver } from 'src/engine-metadata/object-metadata/object-metadata.resolver'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { ObjectMetadataResolver } from 'src/engine/metadata-modules/object-metadata/object-metadata.resolver'; import { ObjectMetadataService } from './object-metadata.service'; import { ObjectMetadataEntity } from './object-metadata.entity'; diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts similarity index 62% rename from packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.resolver.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts index 37c3a4634997..002ab0a2b05c 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts @@ -1,12 +1,12 @@ import { UseGuards } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { ObjectMetadataDTO } from 'src/engine-metadata/object-metadata/dtos/object-metadata.dto'; -import { DeleteOneObjectInput } from 'src/engine-metadata/object-metadata/dtos/delete-object.input'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; +import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; @UseGuards(JwtAuthGuard) @Resolver(() => ObjectMetadataDTO) diff --git a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts similarity index 97% rename from packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts rename to packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 6fde2aca992f..87817d3c3639 100644 --- a/packages/twenty-server/src/engine-metadata/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -11,30 +11,30 @@ import { FindManyOptions, FindOneOptions, Repository } from 'typeorm'; import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { Query, QueryOptions } from '@ptc-org/nestjs-query-core'; -import { WorkspaceMigrationService } from 'src/engine-metadata/workspace-migration/workspace-migration.service'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnCreate, WorkspaceMigrationColumnDrop, WorkspaceMigrationTableAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { RelationMetadataEntity, RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { computeCustomName } from 'src/engine/utils/compute-custom-name.util'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { DeleteOneObjectInput } from 'src/engine-metadata/object-metadata/dtos/delete-object.input'; -import { RelationToDelete } from 'src/engine-metadata/relation-metadata/types/relation-to-delete'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; +import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input'; +import { RelationToDelete } from 'src/engine/metadata-modules/relation-metadata/types/relation-to-delete'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { activityTargetStandardFieldIds, attachmentStandardFieldIds, diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/dtos/create-relation.input.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/create-relation.input.ts similarity index 84% rename from packages/twenty-server/src/engine-metadata/relation-metadata/dtos/create-relation.input.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/create-relation.input.ts index a37f022cbb05..d420b16ce96d 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/dtos/create-relation.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/create-relation.input.ts @@ -9,8 +9,8 @@ import { IsUUID, } from 'class-validator'; -import { BeforeCreateOneRelation } from 'src/engine-metadata/relation-metadata/hooks/before-create-one-relation.hook'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { BeforeCreateOneRelation } from 'src/engine/metadata-modules/relation-metadata/hooks/before-create-one-relation.hook'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; @InputType() @BeforeCreateOne(BeforeCreateOneRelation) diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/dtos/relation-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/relation-metadata.dto.ts similarity index 78% rename from packages/twenty-server/src/engine-metadata/relation-metadata/dtos/relation-metadata.dto.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/relation-metadata.dto.ts index 37928b4b7d3f..bdb669a2241b 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/dtos/relation-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/dtos/relation-metadata.dto.ts @@ -15,9 +15,9 @@ import { Relation, } from '@ptc-org/nestjs-query-graphql'; -import { ObjectMetadataDTO } from 'src/engine-metadata/object-metadata/dtos/object-metadata.dto'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { BeforeDeleteOneRelation } from 'src/engine-metadata/relation-metadata/hooks/before-delete-one-field.hook'; +import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { BeforeDeleteOneRelation } from 'src/engine/metadata-modules/relation-metadata/hooks/before-delete-one-field.hook'; registerEnumType(RelationMetadataType, { name: 'RelationMetadataType', diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-create-one-relation.hook.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-create-one-relation.hook.ts similarity index 84% rename from packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-create-one-relation.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-create-one-relation.hook.ts index f1dadd4dd25a..d91d9c923d3f 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-create-one-relation.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-create-one-relation.hook.ts @@ -5,7 +5,7 @@ import { CreateOneInputType, } from '@ptc-org/nestjs-query-graphql'; -import { CreateRelationInput } from 'src/engine-metadata/relation-metadata/dtos/create-relation.input'; +import { CreateRelationInput } from 'src/engine/metadata-modules/relation-metadata/dtos/create-relation.input'; @Injectable() export class BeforeCreateOneRelation diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-delete-one-field.hook.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-delete-one-field.hook.ts similarity index 91% rename from packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-delete-one-field.hook.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-delete-one-field.hook.ts index 91fe67a1c1fc..7976185590ac 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/hooks/before-delete-one-field.hook.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/hooks/before-delete-one-field.hook.ts @@ -9,7 +9,7 @@ import { DeleteOneInputType, } from '@ptc-org/nestjs-query-graphql'; -import { RelationMetadataService } from 'src/engine-metadata/relation-metadata/relation-metadata.service'; +import { RelationMetadataService } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.service'; @Injectable() export class BeforeDeleteOneRelation implements BeforeDeleteOneHook { diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.entity.ts similarity index 85% rename from packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.entity.ts index 8fe38dbc87df..6c2f55ad330f 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.entity.ts @@ -9,10 +9,10 @@ import { UpdateDateColumn, } from 'typeorm'; -import { RelationMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/relation-metadata.interface'; +import { RelationMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export enum RelationMetadataType { ONE_TO_ONE = 'ONE_TO_ONE', diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts similarity index 83% rename from packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.module.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts index e00f40e4f8bc..f0be7bc7df98 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.module.ts @@ -7,9 +7,9 @@ import { import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; -import { FieldMetadataModule } from 'src/engine-metadata/field-metadata/field-metadata.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; +import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; import { RelationMetadataService } from './relation-metadata.service'; diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts similarity index 89% rename from packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts index 3620989390e7..b502772be1c7 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/relation-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts @@ -11,18 +11,18 @@ import { FindOneOptions, In, Repository } from 'typeorm'; import camelCase from 'lodash.camelcase'; import { v4 as uuidV4 } from 'uuid'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { FieldMetadataService } from 'src/engine-metadata/field-metadata/field-metadata.service'; -import { CreateRelationInput } from 'src/engine-metadata/relation-metadata/dtos/create-relation.input'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; +import { CreateRelationInput } from 'src/engine/metadata-modules/relation-metadata/dtos/create-relation.input'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; -import { WorkspaceMigrationService } from 'src/engine-metadata/workspace-migration/workspace-migration.service'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { WorkspaceMigrationColumnActionType } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { createCustomColumnName } from 'src/engine-metadata/utils/create-custom-column-name.util'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { WorkspaceMigrationColumnActionType } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { createCustomColumnName } from 'src/engine/utils/create-custom-column-name.util'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { createRelationForeignKeyColumnName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; +import { createRelationForeignKeyColumnName } from 'src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-column-name.util'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { RelationMetadataEntity, diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/types/relation-to-delete.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/types/relation-to-delete.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/relation-metadata/types/relation-to-delete.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/types/relation-to-delete.ts diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts similarity index 77% rename from packages/twenty-server/src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts index 40d2b0f2aae0..727fcf763712 100644 --- a/packages/twenty-server/src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-column-name.util.ts @@ -1,4 +1,4 @@ -import { createCustomColumnName } from 'src/engine-metadata/utils/create-custom-column-name.util'; +import { createCustomColumnName } from 'src/engine/utils/create-custom-column-name.util'; import { camelCase } from 'src/utils/camel-case'; export const createRelationForeignKeyColumnName = ( diff --git a/packages/twenty-server/src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util.ts rename to packages/twenty-server/src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util.ts diff --git a/packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.entity.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.entity.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.entity.ts diff --git a/packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.module.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module.ts similarity index 55% rename from packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.module.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module.ts index 621892ff5893..a0df038e4ee6 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { WorkspaceCacheVersionEntity } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.entity'; -import { WorkspaceCacheVersionService } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.service'; +import { WorkspaceCacheVersionEntity } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.entity'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; @Module({ imports: [ diff --git a/packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.service.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service.ts similarity index 88% rename from packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.service.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service.ts index 7730d11e5bf7..347dc81a0927 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-cache-version/workspace-cache-version.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service.ts @@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { WorkspaceCacheVersionEntity } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.entity'; +import { WorkspaceCacheVersionEntity } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.entity'; @Injectable() export class WorkspaceCacheVersionService { diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/basic-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts similarity index 77% rename from packages/twenty-server/src/engine-metadata/workspace-migration/factories/basic-column-action.factory.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts index 35b772d13de8..795b22861d2c 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/basic-column-action.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts @@ -1,18 +1,18 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceColumnActionOptions } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnCreate, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; -import { fieldMetadataTypeToColumnType } from 'src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util'; -import { ColumnActionAbstractFactory } from 'src/engine-metadata/workspace-migration/factories/column-action-abstract.factory'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; +import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; +import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory'; export type BasicFieldMetadataType = | FieldMetadataType.UUID diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/column-action-abstract.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory.ts similarity index 76% rename from packages/twenty-server/src/engine-metadata/workspace-migration/factories/column-action-abstract.factory.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory.ts index 40a5eec2448f..12941e92a99a 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/column-action-abstract.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory.ts @@ -1,17 +1,17 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Logger } from '@nestjs/common'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { WorkspaceColumnActionOptions } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface'; -import { WorkspaceColumnActionFactory } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-factory.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; +import { WorkspaceColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnAction, WorkspaceMigrationColumnCreate, WorkspaceMigrationColumnAlter, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export class ColumnActionAbstractFactory< T extends FieldMetadataType | 'default', diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/enum-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory.ts similarity index 82% rename from packages/twenty-server/src/engine-metadata/workspace-migration/factories/enum-column-action.factory.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory.ts index 4f39f4959abd..6829ad6aecba 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/factories/enum-column-action.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory.ts @@ -1,17 +1,17 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceColumnActionOptions } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnCreate, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; -import { fieldMetadataTypeToColumnType } from 'src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util'; -import { ColumnActionAbstractFactory } from 'src/engine-metadata/workspace-migration/factories/column-action-abstract.factory'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; +import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; +import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory'; export type EnumFieldMetadataType = | FieldMetadataType.RATING diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/factories.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/factories.ts new file mode 100644 index 000000000000..919ead74cbbb --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/factories.ts @@ -0,0 +1,7 @@ +import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory'; +import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory'; + +export const workspaceColumnActionFactories = [ + BasicColumnActionFactory, + EnumColumnActionFactory, +]; diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/interfaces/workspace-column-action-factory.interface.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface.ts similarity index 52% rename from packages/twenty-server/src/engine-metadata/workspace-migration/interfaces/workspace-column-action-factory.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface.ts index 9b02f358b14a..05ef6f31354b 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/interfaces/workspace-column-action-factory.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface.ts @@ -1,11 +1,11 @@ -import { WorkspaceColumnActionOptions } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; export interface WorkspaceColumnActionFactory< T extends FieldMetadataType | 'default', diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface.ts diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts similarity index 91% rename from packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts index 36bf8c30ac28..cb309c3a4b08 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export const fieldMetadataTypeToColumnType = ( fieldMetadataType: Type, diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/utils/generate-migration-name.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/workspace-migration/utils/generate-migration-name.util.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util.ts diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.entity.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.entity.ts similarity index 95% rename from packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.entity.ts index 856f296fe2e0..edb9746fd3bf 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.entity.ts @@ -5,7 +5,7 @@ import { PrimaryGeneratedColumn, } from 'typeorm'; -import { RelationOnDeleteAction } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export enum WorkspaceMigrationColumnActionType { CREATE = 'CREATE', diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts similarity index 83% rename from packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts index 55819d2d6f60..8a4faf5a6bbb 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts @@ -1,18 +1,18 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceColumnActionFactory } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-factory.interface'; -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { WorkspaceColumnActionOptions } from 'src/engine-metadata/workspace-migration/interfaces/workspace-column-action-options.interface'; +import { WorkspaceColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { BasicColumnActionFactory } from 'src/engine-metadata/workspace-migration/factories/basic-column-action.factory'; -import { EnumColumnActionFactory } from 'src/engine-metadata/workspace-migration/factories/enum-column-action.factory'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory'; +import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory'; import { WorkspaceMigrationColumnAction, WorkspaceMigrationColumnActionType, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; -import { compositeDefinitions } from 'src/engine-metadata/field-metadata/composite-types'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; +import { compositeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; @Injectable() export class WorkspaceMigrationFactory { diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.module.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.module.ts similarity index 70% rename from packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.module.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.module.ts index 00592c97c8e8..9e0d4072c476 100644 --- a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { workspaceColumnActionFactories } from 'src/engine-metadata/workspace-migration/factories/factories'; -import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; +import { workspaceColumnActionFactories } from 'src/engine/metadata-modules/workspace-migration/factories/factories'; +import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory'; import { WorkspaceMigrationService } from './workspace-migration.service'; import { WorkspaceMigrationEntity } from './workspace-migration.entity'; diff --git a/packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.service.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/workspace-migration/workspace-migration.service.ts rename to packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts diff --git a/packages/twenty-server/src/engine/modules/auth/types/jwt-data.type.ts b/packages/twenty-server/src/engine/modules/auth/types/jwt-data.type.ts deleted file mode 100644 index 6117bdd02c21..000000000000 --- a/packages/twenty-server/src/engine/modules/auth/types/jwt-data.type.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { User } from 'src/engine/modules/user/user.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; - -export type JwtData = { - user?: User | undefined; - workspace: Workspace; -}; diff --git a/packages/twenty-server/src/engine/modules/billing/billing.module.ts b/packages/twenty-server/src/engine/modules/billing/billing.module.ts deleted file mode 100644 index bcdb7a6d4d28..000000000000 --- a/packages/twenty-server/src/engine/modules/billing/billing.module.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -import { BillingController } from 'src/engine/modules/billing/billing.controller'; -import { BillingService } from 'src/engine/modules/billing/billing.service'; -import { StripeModule } from 'src/engine/modules/billing/stripe/stripe.module'; -import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity'; -import { BillingSubscriptionItem } from 'src/engine/modules/billing/entities/billing-subscription-item.entity'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; -import { BillingResolver } from 'src/engine/modules/billing/billing.resolver'; -import { BillingWorkspaceMemberListener } from 'src/engine/modules/billing/listeners/billing-workspace-member.listener'; -import { UserWorkspaceModule } from 'src/engine/modules/user-workspace/user-workspace.module'; - -@Module({ - imports: [ - StripeModule, - UserWorkspaceModule, - TypeOrmModule.forFeature( - [BillingSubscription, BillingSubscriptionItem, Workspace], - 'core', - ), - ], - controllers: [BillingController], - providers: [BillingService, BillingResolver, BillingWorkspaceMemberListener], - exports: [BillingService], -}) -export class BillingModule {} diff --git a/packages/twenty-server/src/engine/modules/engine-modules.module.ts b/packages/twenty-server/src/engine/modules/engine-modules.module.ts deleted file mode 100644 index d0dd3097398b..000000000000 --- a/packages/twenty-server/src/engine/modules/engine-modules.module.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { WorkspaceModule } from 'src/engine/modules/workspace/workspace.module'; -import { UserModule } from 'src/engine/modules/user/user.module'; -import { RefreshTokenModule } from 'src/engine/modules/refresh-token/refresh-token.module'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; -import { FeatureFlagModule } from 'src/engine/modules/feature-flag/feature-flag.module'; -import { OpenApiModule } from 'src/engine/modules/open-api/open-api.module'; -import { TimelineMessagingModule } from 'src/engine/modules/messaging/timeline-messaging.module'; -import { BillingModule } from 'src/engine/modules/billing/billing.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 { FileModule } from './file/file.module'; -import { ClientConfigModule } from './client-config/client-config.module'; - -@Module({ - imports: [ - HealthModule, - AnalyticsModule, - AuthModule, - BillingModule, - ClientConfigModule, - FeatureFlagModule, - FileModule, - OpenApiModule, - RefreshTokenModule, - TimelineMessagingModule, - TimelineCalendarEventModule, - UserModule, - WorkspaceModule, - ], - exports: [ - AnalyticsModule, - AuthModule, - FeatureFlagModule, - TimelineMessagingModule, - TimelineCalendarEventModule, - UserModule, - WorkspaceModule, - ], -}) -export class EngineModulesModule {} diff --git a/packages/twenty-server/src/engine/modules/feature-flag/interfaces/feature-flag-map.interface.ts b/packages/twenty-server/src/engine/modules/feature-flag/interfaces/feature-flag-map.interface.ts deleted file mode 100644 index 29fd78252097..000000000000 --- a/packages/twenty-server/src/engine/modules/feature-flag/interfaces/feature-flag-map.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; - -export type FeatureFlagMap = Record<`${FeatureFlagKeys}`, boolean>; diff --git a/packages/twenty-server/src/engine/modules/open-api/open-api.module.ts b/packages/twenty-server/src/engine/modules/open-api/open-api.module.ts deleted file mode 100644 index 0b8c25a64f3f..000000000000 --- a/packages/twenty-server/src/engine/modules/open-api/open-api.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { OpenApiController } from 'src/engine/modules/open-api/open-api.controller'; -import { OpenApiService } from 'src/engine/modules/open-api/open-api.service'; -import { AuthModule } from 'src/engine/modules/auth/auth.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; - -@Module({ - imports: [ObjectMetadataModule, AuthModule], - controllers: [OpenApiController], - providers: [OpenApiService], -}) -export class OpenApiModule {} diff --git a/packages/twenty-server/src/engine/strategies/aggregate-by-workspace-context-id.strategy.ts b/packages/twenty-server/src/engine/strategies/aggregate-by-workspace-context-id.strategy.ts new file mode 100644 index 000000000000..0a61e7354e9f --- /dev/null +++ b/packages/twenty-server/src/engine/strategies/aggregate-by-workspace-context-id.strategy.ts @@ -0,0 +1,38 @@ +import { + HostComponentInfo, + ContextId, + ContextIdFactory, + ContextIdStrategy, +} from '@nestjs/core'; + +import { jwtDecode } from 'jwt-decode'; +import { Request } from 'express'; + +import { JwtPayload } from 'src/engine/core-modules/auth/strategies/jwt.auth.strategy'; + +const workspaces = new Map(); + +export class AggregateByWorkspaceContextIdStrategy + implements ContextIdStrategy +{ + attach(contextId: ContextId, request: Request) { + const token = request.header('Authorization')?.replace('Bearer ', ''); + const jwtPayload = token ? jwtDecode(token) : null; + let workspaceSubTreeId: ContextId; + + if (!jwtPayload) { + return () => contextId; + } + + if (workspaces.has(jwtPayload.workspaceId)) { + workspaceSubTreeId = workspaces.get(jwtPayload.workspaceId)!; + } else { + workspaceSubTreeId = ContextIdFactory.create(); + workspaces.set(jwtPayload.workspaceId, workspaceSubTreeId); + } + + // If tree is not durable, return the original "contextId" object + return (info: HostComponentInfo) => + info.isTreeDurable ? workspaceSubTreeId : contextId; + } +} diff --git a/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts b/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts index fb8261818e5b..19630b0ec358 100644 --- a/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts +++ b/packages/twenty-server/src/engine/utils/__tests__/deduce-relation-direction.spec.ts @@ -1,8 +1,8 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { RelationMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/relation-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { RelationMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { deduceRelationDirection, RelationDirection, diff --git a/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts b/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts index 5f7ee9174917..05e22fb171fa 100644 --- a/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts +++ b/packages/twenty-server/src/engine/utils/compute-object-target-table.util.ts @@ -1,4 +1,4 @@ -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { computeCustomName } from './compute-custom-name.util'; diff --git a/packages/twenty-server/src/engine-metadata/utils/create-custom-column-name.util.ts b/packages/twenty-server/src/engine/utils/create-custom-column-name.util.ts similarity index 100% rename from packages/twenty-server/src/engine-metadata/utils/create-custom-column-name.util.ts rename to packages/twenty-server/src/engine/utils/create-custom-column-name.util.ts diff --git a/packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts b/packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts index 0122752b29c0..1d78d049bb15 100644 --- a/packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts +++ b/packages/twenty-server/src/engine/utils/deduce-relation-direction.util.ts @@ -1,5 +1,5 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; -import { RelationMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/relation-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { RelationMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-metadata.interface'; export enum RelationDirection { FROM = 'from', diff --git a/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts index 25ac725369b8..1f4d0ebc7b31 100644 --- a/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts +++ b/packages/twenty-server/src/engine/utils/get-resolver-name.util.ts @@ -1,5 +1,5 @@ import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { camelCase } from 'src/utils/camel-case'; import { pascalCase } from 'src/utils/pascal-case'; diff --git a/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts b/packages/twenty-server/src/engine/utils/global-exception-handler.util.ts similarity index 97% rename from packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts rename to packages/twenty-server/src/engine/utils/global-exception-handler.util.ts index cae610a89c34..12f32656f86c 100644 --- a/packages/twenty-server/src/engine/filters/utils/global-exception-handler.util.ts +++ b/packages/twenty-server/src/engine/utils/global-exception-handler.util.ts @@ -9,7 +9,7 @@ import { ValidationError, NotFoundError, ConflictError, -} from 'src/engine/filters/utils/graphql-errors.util'; +} from 'src/engine/utils/graphql-errors.util'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; const graphQLPredefinedExceptions = { diff --git a/packages/twenty-server/src/engine/filters/utils/graphql-errors.util.ts b/packages/twenty-server/src/engine/utils/graphql-errors.util.ts similarity index 100% rename from packages/twenty-server/src/engine/filters/utils/graphql-errors.util.ts rename to packages/twenty-server/src/engine/utils/graphql-errors.util.ts diff --git a/packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts b/packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts index 12c119d9f36f..a5ed9d644eba 100644 --- a/packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts +++ b/packages/twenty-server/src/engine/utils/is-relation-field-metadata-type.util.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export const isRelationFieldMetadataType = ( type: FieldMetadataType, diff --git a/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.module.ts b/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.module.ts index 81ba4b09c7fd..17d0a5cf3dda 100644 --- a/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.module.ts +++ b/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceDataSourceService } from './workspace-datasource.service'; diff --git a/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.service.ts b/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.service.ts index a0f0583e4493..d4400a85e985 100644 --- a/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.service.ts +++ b/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.service.ts @@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common'; import { DataSource, EntityManager } from 'typeorm'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; @Injectable() export class WorkspaceDataSourceService { diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts index 99fb806c4665..6ff99007198b 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts @@ -1,6 +1,6 @@ import { DataSource, EntityManager } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { viewPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/view'; import { companyPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/company'; import { personPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/person'; diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts index f5031799182b..e51867aa6ff8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts @@ -1,6 +1,6 @@ import { EntityManager } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export const viewPrefillData = async ( entityManager: EntityManager, diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts index a33bdc9d1fa2..5b63225badf3 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts @@ -1,6 +1,6 @@ import { DataSource, EntityManager } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; import { companyPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/company'; import { personPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/person'; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts index f5031799182b..e51867aa6ff8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts @@ -1,6 +1,6 @@ import { EntityManager } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export const viewPrefillData = async ( entityManager: EntityManager, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/delete-incomplete-workspaces.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/delete-incomplete-workspaces.command.ts index 71c8c2b98815..27f02bcc48eb 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/delete-incomplete-workspaces.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/commands/delete-incomplete-workspaces.command.ts @@ -4,10 +4,10 @@ import { Logger } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; import { FindOptionsWhere, In, Repository } from 'typeorm'; -import { WorkspaceService } from 'src/engine/modules/workspace/services/workspace.service'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { getDryRunLogHeader } from 'src/utils/get-dry-run-log-header'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; type DeleteIncompleteWorkspacesCommandOptions = { dryRun?: boolean; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts index af75e69bb239..952c606f6903 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/crons/clean-inactive-workspace.job.ts @@ -9,14 +9,14 @@ import { import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { UserService } from 'src/engine/modules/user/services/user.service'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; +import { UserService } from 'src/engine/core-modules/user/services/user.service'; import { EmailService } from 'src/engine/integrations/email/email.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { CleanInactiveWorkspacesCommandOptions } from 'src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command'; import { getDryRunLogHeader } from 'src/utils/get-dry-run-log-header'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/workspace-cleaner.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/workspace-cleaner.module.ts index 300d3e6dcca0..6bf7eb0136ad 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/workspace-cleaner.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-cleaner/workspace-cleaner.module.ts @@ -1,13 +1,13 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { WorkspaceModule } from 'src/engine/modules/workspace/workspace.module'; +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; import { DeleteIncompleteWorkspacesCommand } from 'src/engine/workspace-manager/workspace-cleaner/commands/delete-incomplete-workspaces.command'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { CleanInactiveWorkspacesCommand } from 'src/engine/workspace-manager/workspace-cleaner/commands/clean-inactive-workspaces.command'; import { StartCleanInactiveWorkspacesCronCommand } from 'src/engine/workspace-manager/workspace-cleaner/commands/start-clean-inactive-workspaces.cron.command'; import { StopCleanInactiveWorkspacesCronCommand } from 'src/engine/workspace-manager/workspace-cleaner/commands/stop-clean-inactive-workspaces.cron.command'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; @Module({ imports: [ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/abstract-workspace.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/abstract-workspace.fixer.ts index 275762880680..73af458d766c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/abstract-workspace.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/abstract-workspace.fixer.ts @@ -6,8 +6,8 @@ import { WorkspaceIssueTypeToInterface, } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; export class CompareEntity { current: T | null; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-default-value.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-default-value.fixer.ts index c1bce7bc47ef..eeaf4d708ffb 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-default-value.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-default-value.fixer.ts @@ -7,10 +7,10 @@ import { WorkspaceHealthIssueType, } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; import { AbstractWorkspaceFixer } from './abstract-workspace.fixer'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-nullable.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-nullable.fixer.ts index da9f687b1b0b..639acba87fae 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-nullable.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-nullable.fixer.ts @@ -8,8 +8,8 @@ import { } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; import { AbstractWorkspaceFixer } from './abstract-workspace.fixer'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts index 57286171af19..5b759c2bdb71 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-target-column-map.fixer.ts @@ -9,15 +9,15 @@ import { } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { AbstractWorkspaceFixer, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-type.fixer.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-type.fixer.ts index 827cde3719c2..280cb66133b4 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-type.fixer.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/fixer/workspace-type.fixer.ts @@ -8,8 +8,8 @@ import { } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { FieldMetadataUpdate, WorkspaceMigrationFieldFactory, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface.ts index 62b653b72da3..6c7afab3f5d1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface.ts @@ -1,8 +1,8 @@ import { WorkspaceTableStructure } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export enum WorkspaceHealthIssueType { MISSING_TABLE = 'MISSING_TABLE', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts index 65a2971c7a1e..9ace9434acfc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts @@ -7,16 +7,16 @@ import { WorkspaceTableStructure, WorkspaceTableStructureResult, } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { fieldMetadataTypeToColumnType } from 'src/engine-metadata/workspace-migration/utils/field-metadata-type-to-column-type.util'; -import { serializeTypeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-type-default-value.util'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; +import { serializeTypeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-type-default-value.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; @Injectable() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts index 098aac67a466..a8dc1595f8c5 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts @@ -8,25 +8,25 @@ import { } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceTableStructure } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; import { WorkspaceHealthOptions } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-options.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { isCompositeFieldMetadataType } from 'src/engine-metadata/field-metadata/utils/is-composite-field-metadata-type.util'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; import { validName } from 'src/engine/workspace-manager/workspace-health/utils/valid-name.util'; -import { compositeDefinitions } from 'src/engine-metadata/field-metadata/composite-types'; -import { validateDefaultValueForType } from 'src/engine-metadata/field-metadata/utils/validate-default-value-for-type.util'; +import { compositeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { validateDefaultValueForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util'; import { EnumFieldMetadataUnionType, isEnumFieldMetadataType, -} from 'src/engine-metadata/field-metadata/utils/is-enum-field-metadata-type.util'; -import { validateOptionsForType } from 'src/engine-metadata/field-metadata/utils/validate-options-for-type.util'; -import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; +} from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util'; +import { validateOptionsForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; import { computeCompositeFieldMetadata } from 'src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; import { customNamePrefix } from 'src/engine/utils/compute-custom-name.util'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts index 2d730b1ab4f8..aa73f2e89dcc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/object-metadata-health.service.ts @@ -6,7 +6,7 @@ import { } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; import { WorkspaceHealthOptions } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-options.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { validName } from 'src/engine/workspace-manager/workspace-health/utils/valid-name.util'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts index 8433cc2e5417..61a45e88b125 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service.ts @@ -10,18 +10,18 @@ import { WorkspaceHealthOptions, } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-options.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataEntity, RelationMetadataType, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { RelationDirection, deduceRelationDirection, } from 'src/engine/utils/deduce-relation-direction.util'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { createRelationForeignKeyColumnName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util'; -import { createRelationForeignKeyFieldMetadataName } from 'src/engine-metadata/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { createRelationForeignKeyColumnName } from 'src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-column-name.util'; +import { createRelationForeignKeyFieldMetadataName } from 'src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/workspace-fix.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/workspace-fix.service.ts index 1e767530de7d..523ba4563068 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/workspace-fix.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/workspace-fix.service.ts @@ -5,8 +5,8 @@ import { EntityManager } from 'typeorm'; import { WorkspaceHealthFixKind } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-fix-kind.interface'; import { WorkspaceHealthIssue } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceNullableFixer } from 'src/engine/workspace-manager/workspace-health/fixer/workspace-nullable.fixer'; import { WorkspaceDefaultValueFixer } from 'src/engine/workspace-manager/workspace-health/fixer/workspace-default-value.fixer'; import { WorkspaceTypeFixer } from 'src/engine/workspace-manager/workspace-health/fixer/workspace-type.fixer'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util.ts index f7c8f2df009c..02051e1283e2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/compute-composite-field-metadata.util.ts @@ -1,6 +1,6 @@ -import { FieldMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/field-metadata.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { camelCase } from 'src/utils/camel-case'; // Compute composite field metadata by combining the composite field metadata with the field metadata diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts index c219eeca6ab6..c8999c7185cb 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts @@ -1,6 +1,6 @@ import { ConflictException } from '@nestjs/common'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export const mapFieldMetadataTypeToDataType = ( fieldMetadataType: FieldMetadataType, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.module.ts index 575d0992e5ea..90e87ba941f1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; import { FieldMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/field-metadata-health.service'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts index 70c3cd316a16..e62b56ef9b6a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/workspace-health.service.ts @@ -11,15 +11,15 @@ import { import { WorkspaceHealthFixKind } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-fix-kind.interface'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { ObjectMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/object-metadata-health.service'; import { FieldMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/field-metadata-health.service'; import { RelationMetadataHealthService } from 'src/engine/workspace-manager/workspace-health/services/relation-metadata.health.service'; import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service'; import { WorkspaceFixService } from 'src/engine/workspace-manager/workspace-health/services/workspace-fix.service'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts index 0a482c3838fd..a3afeb00cc42 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; -import { ObjectMetadataModule } from 'src/engine-metadata/object-metadata/object-metadata.module'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts index 3210df529793..3a17901ee2d6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@nestjs/common'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; -import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service'; -import { WorkspaceMigrationService } from 'src/engine-metadata/workspace-migration/workspace-migration.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; import { standardObjectsPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data'; import { demoObjectsPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts index 7608cbb862b1..ceecfef00690 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts @@ -5,16 +5,16 @@ import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/wo import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationEntity, WorkspaceMigrationTableAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; +import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; export interface FieldMetadataUpdate { current: FieldMetadataEntity; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts index e4118ddac006..e5839b232e76 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory.ts @@ -2,16 +2,16 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationEntity, WorkspaceMigrationTableAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; -import { WorkspaceMigrationFactory } from 'src/engine-metadata/workspace-migration/workspace-migration.factory'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; +import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; @Injectable() export class WorkspaceMigrationObjectFactory { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts index 980d9172346e..b195479d8ab1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory.ts @@ -2,19 +2,19 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationEntity, WorkspaceMigrationTableAction, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { RelationMetadataEntity, RelationMetadataType, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { camelCase } from 'src/utils/camel-case'; -import { generateMigrationName } from 'src/engine-metadata/workspace-migration/utils/generate-migration-name.util'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; @Injectable() export class WorkspaceMigrationRelationFactory { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/workspace-migration-builder.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/workspace-migration-builder.module.ts index e8fdacbf8e55..cdf08d16d741 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/workspace-migration-builder.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/workspace-migration-builder.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { workspaceMigrationBuilderFactories } from './factories'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service.ts index f7231035170a..5d8692c13466 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service.ts @@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common'; import { QueryRunner } from 'typeorm'; -import { WorkspaceMigrationColumnAlter } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { serializeDefaultValue } from 'src/engine-metadata/field-metadata/utils/serialize-default-value'; +import { WorkspaceMigrationColumnAlter } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; @Injectable() export class WorkspaceMigrationEnumService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service.ts index d3eb7eedf7a2..08c6ecbdf081 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { QueryRunner } from 'typeorm'; -import { WorkspaceMigrationColumnAlter } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationColumnAlter } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; @Injectable() export class WorkspaceMigrationTypeService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util.ts index 8b391f28f333..5bdb4e08f2bc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util.ts @@ -1,4 +1,4 @@ -import { RelationOnDeleteAction } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export const convertOnDeleteActionToOnDelete = ( onDeleteAction: RelationOnDeleteAction | undefined, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module.ts index c0642d6dee3d..59f0bec2e661 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; -import { WorkspaceMigrationModule } from 'src/engine-metadata/workspace-migration/workspace-migration.module'; +import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { WorkspaceCacheVersionModule } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service'; import { WorkspaceMigrationRunnerService } from './workspace-migration-runner.service'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts index 63e518724520..32fa10802695 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts @@ -8,7 +8,7 @@ import { TableUnique, } from 'typeorm'; -import { WorkspaceMigrationService } from 'src/engine-metadata/workspace-migration/workspace-migration.service'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { WorkspaceMigrationTableAction, @@ -18,8 +18,8 @@ import { WorkspaceMigrationColumnCreateRelation, WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnDropRelation, -} from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; -import { WorkspaceCacheVersionService } from 'src/engine-metadata/workspace-cache-version/workspace-cache-version.service'; +} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service'; import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts index 8c70d3ecf8dd..5e7cb3151e19 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command.ts @@ -4,8 +4,8 @@ import { InjectDataSource } from '@nestjs/typeorm'; import { Command, CommandRunner } from 'nest-commander'; import { DataSource } from 'typeorm'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects'; import { StandardObjectFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory'; import { computeStandardObject } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts index 397834ff623a..25f92347d96f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { CommandLogger } from 'src/command/command-logger'; @Injectable() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command.ts index a338a3aa7934..c43d6f9a4bbc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command.ts @@ -2,10 +2,10 @@ import { Logger } from '@nestjs/common'; import { Command, CommandRunner, Option } from 'nest-commander'; -import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; import { WorkspaceHealthService } from 'src/engine/workspace-manager/workspace-health/workspace-health.service'; -import { WorkspaceService } from 'src/engine/modules/workspace/services/workspace.service'; +import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service'; import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts index 742b944003be..c9fc90423322 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts @@ -1,9 +1,9 @@ import { Module } from '@nestjs/common'; -import { DataSourceModule } from 'src/engine-metadata/data-source/data-source.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module'; -import { WorkspaceModule } from 'src/engine/modules/workspace/workspace.module'; +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; import { AddStandardIdCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/add-standard-id.command'; import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator.ts index 4556b95a1fb2..6de6fd2332e4 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator.ts @@ -9,12 +9,12 @@ import { import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; import { ComputedPartialObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; const commonFieldPropertiesToIgnore = [ 'id', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator.ts index 7e2ae26d9f07..40f1ad2d8510 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator.ts @@ -10,7 +10,7 @@ import { import { ComputedPartialObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; const objectPropertiesToIgnore = [ 'id', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-relation.comparator.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-relation.comparator.ts index 2c170e0fc073..a0baf8e53437 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-relation.comparator.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-relation.comparator.ts @@ -7,7 +7,7 @@ import { RelationComparatorResult, } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; const relationPropertiesToIgnore = ['createdAt', 'updatedAt']; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts index d1baad13c787..523d79b0df2a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata.ts @@ -1,13 +1,13 @@ import { BaseCustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/base-custom-object-metadata.decorator'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { ActivityTargetObjectMetadata } from 'src/modules/activity/standard-objects/activity-target.object-metadata'; import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface.ts index 1876482b23b2..3d0b49ec3759 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface.ts @@ -1,7 +1,7 @@ import { DynamicRelationFieldMetadataDecoratorParams } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface'; import { TypedReflect } from 'src/utils/typed-reflect'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export function DynamicRelationFieldMetadata( params: DynamicRelationFieldMetadataDecoratorParams, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator.ts index 7ff971e8b868..641c9a6616fa 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator.ts @@ -3,11 +3,11 @@ import { ReflectFieldMetadata, } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-field-metadata.interface'; import { GateDecoratorParams } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/gate-decorator.interface'; -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; -import { generateDefaultValue } from 'src/engine-metadata/field-metadata/utils/generate-default-value'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; +import { generateDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/generate-default-value'; import { TypedReflect } from 'src/utils/typed-reflect'; import { createDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator.ts index ceb6ca32a7ed..3307f6093ba9 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator.ts @@ -6,7 +6,7 @@ import { } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-relation-metadata.interface'; import { TypedReflect } from 'src/utils/typed-reflect'; -import { RelationOnDeleteAction } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export function RelationMetadata( params: RelationMetadataDecoratorParams, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/feature-flags.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/feature-flags.factory.ts index c8c3fa29ff94..763f1b43701e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/feature-flags.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/feature-flags.factory.ts @@ -4,9 +4,9 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @Injectable() export class FeatureFlagFactory { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory.ts index 56608eb87c45..d665fa556273 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { PartialComputedFieldMetadata, PartialFieldMetadata, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory.ts index 3d4561838177..b68fd2393aa2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { PartialObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; import { TypedReflect } from 'src/utils/typed-reflect'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-relation.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-relation.factory.ts index dbb4d2be0026..01b1e561aeae 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-relation.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/factories/standard-relation.factory.ts @@ -1,14 +1,14 @@ import { Injectable } from '@nestjs/common'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; import { TypedReflect } from 'src/utils/typed-reflect'; import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util'; import { assert } from 'src/utils/assert'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util'; interface CustomRelationFactory { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface.ts index e01fa7559c27..bb83fc881dec 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface.ts @@ -1,5 +1,5 @@ -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { ComputedPartialFieldMetadata } from './partial-field-metadata.interface'; import { ComputedPartialObjectMetadata } from './partial-object-metadata.interface'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/mapped-metadata.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/mapped-metadata.interface.ts index c9be4f066dda..fc4f329fa712 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/mapped-metadata.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/mapped-metadata.interface.ts @@ -1,8 +1,8 @@ import { PartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; import { PartialObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export type MappedFieldMetadata = Record; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts index 4be992e1eddf..01b2fd3c01b6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts @@ -1,7 +1,7 @@ import { GateDecoratorParams } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/gate-decorator.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export type DynamicRelationFieldMetadataDecoratorParams = ( oppositeObjectMetadata: ObjectMetadataEntity, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts index 1c9d837a97ac..74cde9084777 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts @@ -1,10 +1,10 @@ -import { FieldMetadataDefaultValue } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-default-value.interface'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; import { GateDecoratorParams } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/gate-decorator.interface'; -import { FieldMetadataOptions } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-options.interface'; -import { FieldMetadataTargetColumnMap } from 'src/engine-metadata/field-metadata/interfaces/field-metadata-target-column-map.interface'; +import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; +import { FieldMetadataTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-target-column-map.interface'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; export interface FieldMetadataDecoratorParams< T extends FieldMetadataType | 'default', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-relation-metadata.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-relation-metadata.interface.ts index abbb593c65cd..32282798f424 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-relation-metadata.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/interfaces/reflect-relation-metadata.interface.ts @@ -5,7 +5,7 @@ import { GateDecoratorParams } from 'src/engine/workspace-manager/workspace-sync import { RelationOnDeleteAction, RelationMetadataType, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export interface RelationMetadataDecoratorParams { type: RelationMetadataType; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service.ts index c75309aaab70..85b09148fd17 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service.ts @@ -6,13 +6,13 @@ import omit from 'lodash.omit'; import { PartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { FieldMetadataEntity, FieldMetadataType, -} from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { FieldMetadataComplexOption } from 'src/engine-metadata/field-metadata/dtos/options.input'; +} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; @Injectable() diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts index 7461a4d52ec1..049e8c689385 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts @@ -4,11 +4,11 @@ import { EntityManager } from 'typeorm'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { ComparatorAction } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceFieldComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator'; import { WorkspaceMetadataUpdaterService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts index 1c271e293029..4707c7c45e04 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts @@ -4,12 +4,12 @@ import { EntityManager } from 'typeorm'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { ComparatorAction } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { mapObjectMetadataByUniqueIdentifier } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { StandardObjectFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory'; import { WorkspaceObjectComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator'; import { WorkspaceFieldComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts index 5e830fea966d..9f89d19498aa 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts @@ -3,17 +3,17 @@ import { Injectable, Logger } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; -import { FeatureFlagMap } from 'src/engine/modules/feature-flag/interfaces/feature-flag-map.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { ComparatorAction } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { mapObjectMetadataByUniqueIdentifier } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util'; import { StandardRelationFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-relation.factory'; import { WorkspaceRelationComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-relation.comparator'; import { WorkspaceMetadataUpdaterService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; import { WorkspaceMigrationRelationFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-relation.factory'; import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata.ts index 0594befd154a..5277c7c8cb77 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { baseObjectStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage.ts index 4589d7e4e6cf..9c3904054643 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage.ts @@ -2,9 +2,9 @@ import { ComputedPartialObjectMetadata } from 'src/engine/workspace-manager/work import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; import { PartialRelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-relation-metadata.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; export class WorkspaceSyncStorage { // Object metadata diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util.ts index 833a63d6f7ee..3356023f26df 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-object.util.ts @@ -4,9 +4,9 @@ import { } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { generateTargetColumnMap } from 'src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { createDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util'; export const computeStandardObject = ( diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util.spec.ts index 9a5e171809cf..3ab01cd8e3da 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util.spec.ts @@ -1,5 +1,5 @@ -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { mapObjectMetadataByUniqueIdentifier } from './sync-metadata.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module.ts index 2441f589d2d2..fe2634b78e88 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module.ts @@ -1,11 +1,11 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FieldMetadataEntity } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity'; -import { RelationMetadataEntity } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service'; import { workspaceSyncMetadataFactories } from 'src/engine/workspace-manager/workspace-sync-metadata/factories'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts index f1fc5e8cdb41..8f908b637546 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts @@ -11,7 +11,7 @@ import { WorkspaceSyncObjectMetadataService } from 'src/engine/workspace-manager import { WorkspaceSyncRelationMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-relation-metadata.service'; import { WorkspaceSyncFieldMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service'; import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; -import { WorkspaceMigrationEntity } from 'src/engine-metadata/workspace-migration/workspace-migration.entity'; +import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; interface SynchronizeOptions { applyChanges?: boolean; diff --git a/packages/twenty-server/src/main.ts b/packages/twenty-server/src/main.ts index 5e7913012264..8546fabe1d3f 100644 --- a/packages/twenty-server/src/main.ts +++ b/packages/twenty-server/src/main.ts @@ -17,14 +17,18 @@ import { EnvironmentService } from './engine/integrations/environment/environmen const bootstrap = async () => { const environmentService = new EnvironmentService(new ConfigService()); - const app = await NestFactory.create(AppModule, { cors: true, bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), rawBody: true, + snapshot: environmentService.get('DEBUG_MODE'), }); const logger = app.get(LoggerService); + // TODO: Double check this as it's not working for now, it's going to be heplful for durable trees in twenty "orm" + // // Apply context id strategy for durable trees + // ContextIdFactory.apply(new AggregateByWorkspaceContextIdStrategy()); + // Apply class-validator container so that we can use injection in validators useContainer(app.select(AppModule), { fallbackOnErrors: true }); diff --git a/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts index 1a39445b047a..69986a503188 100644 --- a/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/activity-target.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { activityTargetStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata'; diff --git a/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts index d22cc6d267d5..f9e6bfa1623e 100644 --- a/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/activity.object-metadata.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { activityStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts b/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts index 7fdb4595da78..374751a21813 100644 --- a/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts +++ b/packages/twenty-server/src/modules/activity/standard-objects/comment.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { commentStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts b/packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts index 0f2757328c06..cc62e90a6c7d 100644 --- a/packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts +++ b/packages/twenty-server/src/modules/api-key/standard-objects/api-key.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { apiKeyStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts index 470abe7a5c78..26f410665e6d 100644 --- a/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts +++ b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { attachmentStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata'; diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts index e744f62b8b6a..c8e5ce07676e 100644 --- a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts index d7a7a3abfd51..fb4a0f9d48b7 100644 --- a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts @@ -8,7 +8,7 @@ import { BlocklistRepository } from 'src/modules/connected-account/repositories/ import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { GoogleCalendarClientProvider } from 'src/modules/calendar/services/providers/google-calendar/google-calendar.provider'; import { googleCalendarSearchFilterExcludeEmails } from 'src/modules/calendar/utils/google-calendar-search-filter.util'; import { CalendarChannelEventAssociationRepository } from 'src/modules/calendar/repositories/calendar-channel-event-association.repository'; diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts index 01557560ebac..ca5d82590355 100644 --- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata.ts @@ -1,5 +1,5 @@ -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { calendarChannelEventAssociationStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts index dfeb0a2b5229..8acb2b869113 100644 --- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-channel.object-metadata.ts @@ -1,9 +1,9 @@ import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { calendarChannelStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts index 2ba5c28789aa..f346d8eb06db 100644 --- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { calendarEventAttendeeStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts index 968c83c3cb5e..fcba4feb0580 100644 --- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event.object-metadata.ts @@ -1,10 +1,10 @@ import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator'; import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; diff --git a/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts index 214e80439b41..9dff6ead3436 100644 --- a/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts +++ b/packages/twenty-server/src/modules/company/standard-objects/company.object-metadata.ts @@ -1,10 +1,10 @@ -import { CurrencyMetadata } from 'src/engine-metadata/field-metadata/composite-types/currency.composite-type'; -import { LinkMetadata } from 'src/engine-metadata/field-metadata/composite-types/link.composite-type'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { CurrencyMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type'; +import { LinkMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/link.composite-type'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { companyStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts b/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts index fb47bddfa8e4..089da894effe 100644 --- a/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts +++ b/packages/twenty-server/src/modules/connected-account/standard-objects/blocklist.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { blocklistStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts b/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts index 1044708e4ea5..7c922b61244d 100644 --- a/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts +++ b/packages/twenty-server/src/modules/connected-account/standard-objects/connected-account.object-metadata.ts @@ -1,9 +1,9 @@ -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { connectedAccountStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts index 545370acfb56..78cc91bbf599 100644 --- a/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts +++ b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { FeatureFlagKeys } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { eventStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata'; diff --git a/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts index 3081099b96a3..c3925754217b 100644 --- a/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts +++ b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { favoriteStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts index d6756626ee45..804573470e5e 100644 --- a/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts +++ b/packages/twenty-server/src/modules/messaging/commands/crons/fetch-all-workspaces-messages.job.ts @@ -8,12 +8,12 @@ import { MessageQueueJob } from 'src/engine/integrations/message-queue/interface import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; -import { Workspace } from 'src/engine/modules/workspace/workspace.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { GmailPartialSyncJobData, GmailPartialSyncJob, } from 'src/modules/messaging/jobs/gmail-partial-sync.job'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts index d22bf5f36708..1e363af19a6c 100644 --- a/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts +++ b/packages/twenty-server/src/modules/messaging/listeners/messaging-connected-account.listener.ts @@ -19,7 +19,7 @@ import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/st import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @Injectable() export class MessagingConnectedAccountListener { diff --git a/packages/twenty-server/src/modules/messaging/messaging.module.ts b/packages/twenty-server/src/modules/messaging/messaging.module.ts index 9dd275e9f3d9..701262b2f277 100644 --- a/packages/twenty-server/src/modules/messaging/messaging.module.ts +++ b/packages/twenty-server/src/modules/messaging/messaging.module.ts @@ -5,7 +5,8 @@ import { MessagingPersonListener } from 'src/modules/messaging/listeners/messagi import { MessagingWorkspaceMemberListener } from 'src/modules/messaging/listeners/messaging-workspace-member.listener'; import { MessagingMessageChannelListener } from 'src/modules/messaging/listeners/messaging-message-channel.listener'; import { MessagingConnectedAccountListener } from 'src/modules/messaging/listeners/messaging-connected-account.listener'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; + @Module({ imports: [TypeOrmModule.forFeature([FeatureFlagEntity], 'core')], providers: [ diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts index b9a12f9c2947..eeb376b06074 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts index 61cd34f11a9f..f7dea7c24556 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service.ts @@ -21,7 +21,7 @@ import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/serv import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts index 744e70295bf4..09358d236043 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { FeatureFlagEntity } from 'src/engine/modules/feature-flag/feature-flag.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts index e202fb820d4e..197f383b2a06 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service.ts @@ -22,7 +22,7 @@ import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/serv import { FeatureFlagEntity, FeatureFlagKeys, -} from 'src/engine/modules/feature-flag/feature-flag.entity'; +} from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; diff --git a/packages/twenty-server/src/modules/messaging/services/message/message.service.ts b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts index 7832ecefe17e..9a73b7b7c36d 100644 --- a/packages/twenty-server/src/modules/messaging/services/message/message.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts @@ -3,21 +3,21 @@ import { Injectable, Logger } from '@nestjs/common'; import { DataSource, EntityManager } from 'typeorm'; import { v4 } from 'uuid'; -import { DataSourceEntity } from 'src/engine-metadata/data-source/data-source.entity'; -import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; +import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; +import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; -import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; -import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; import { MessageThreadService } from 'src/modules/messaging/services/message-thread/message-thread.service'; import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; @Injectable() export class MessageService { diff --git a/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts index 47e6169020ef..19e946bbc047 100644 --- a/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel-message-association.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { messageChannelMessageAssociationStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts index 39ee80fa6056..b5167c86625d 100644 --- a/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-channel.object-metadata.ts @@ -1,8 +1,8 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { messageChannelStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts index 49fdaf291b5f..c3de6e6973e0 100644 --- a/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-participant.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { messageParticipantStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts index d35b3aff8626..a6c934c917ad 100644 --- a/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message-thread.object-metadata.ts @@ -1,8 +1,8 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { messageThreadStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts b/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts index 1c2aa129abe5..4b81f30ef0e8 100644 --- a/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts +++ b/packages/twenty-server/src/modules/messaging/standard-objects/message.object-metadata.ts @@ -1,8 +1,8 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { messageStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts index 73af78b73520..63458e22456e 100644 --- a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts +++ b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts @@ -1,9 +1,9 @@ -import { CurrencyMetadata } from 'src/engine-metadata/field-metadata/composite-types/currency.composite-type'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { CurrencyMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { opportunityStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts index 1461c49af6b1..67b0decbe5b6 100644 --- a/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts +++ b/packages/twenty-server/src/modules/person/standard-objects/person.object-metadata.ts @@ -1,10 +1,10 @@ -import { FullNameMetadata } from 'src/engine-metadata/field-metadata/composite-types/full-name.composite-type'; -import { LinkMetadata } from 'src/engine-metadata/field-metadata/composite-types/link.composite-type'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FullNameMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; +import { LinkMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/link.composite-type'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { personStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts b/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts index b1a6ea25330f..2c99585c3824 100644 --- a/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts +++ b/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { pipelineStepStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts index e2771474c031..06b3c44c604e 100644 --- a/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-field.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { viewFieldStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts index 8f8479893b6e..7e2588c85ccd 100644 --- a/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-filter.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { viewFilterStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts index 8380ff7ac377..d41ff278aa50 100644 --- a/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view-sort.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { viewSortStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts index b1055cda4192..1660025a524d 100644 --- a/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts @@ -1,5 +1,5 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { viewStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts b/packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts index 9e90c63aef4c..5d3bdc5a262f 100644 --- a/packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts +++ b/packages/twenty-server/src/modules/webhook/standard-objects/webhook.object-metadata.ts @@ -1,4 +1,4 @@ -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { webhookStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts index 6c42fd51594e..512185fbaa4c 100644 --- a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts +++ b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.object-metadata.ts @@ -1,9 +1,9 @@ -import { FullNameMetadata } from 'src/engine-metadata/field-metadata/composite-types/full-name.composite-type'; -import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity'; +import { FullNameMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, -} from 'src/engine-metadata/relation-metadata/relation-metadata.entity'; +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { workspaceMemberStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; diff --git a/packages/twenty-server/src/queue-worker/queue-worker.ts b/packages/twenty-server/src/queue-worker/queue-worker.ts index eae85670f7eb..be9e6da912fe 100644 --- a/packages/twenty-server/src/queue-worker/queue-worker.ts +++ b/packages/twenty-server/src/queue-worker/queue-worker.ts @@ -6,7 +6,7 @@ import { MessageQueueJobData, } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; +import { filterException } from 'src/engine/utils/global-exception-handler.util'; import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; import { LoggerService } from 'src/engine/integrations/logger/logger.service'; import { JobsModule } from 'src/engine/integrations/message-queue/jobs.module'; diff --git a/yarn.lock b/yarn.lock index 9bc8d86202da..400416175a46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6343,15 +6343,15 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/merge@npm:9.0.0": - version: 9.0.0 - resolution: "@graphql-tools/merge@npm:9.0.0" +"@graphql-tools/merge@npm:9.0.1, @graphql-tools/merge@npm:^9.0.1": + version: 9.0.1 + resolution: "@graphql-tools/merge@npm:9.0.1" dependencies: - "@graphql-tools/utils": "npm:^10.0.0" + "@graphql-tools/utils": "npm:^10.0.10" tslib: "npm:^2.4.0" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 10376dbf1b64a3659dfa01d63bdafbb8addac829c0e772fc4596df4b46f249bee179692cc3f06b1157bdc3dccfe3a46caf5499786cce203eb0f7e124c88a5648 + checksum: cbfcb2c10490a11417991e8b61b8df2eba73a2c576e57cbf2d928902030d4391122536b9442bf042609ec24376b79b8bc6d9117e137dd8db2255ed90613acbc7 languageName: node linkType: hard @@ -6367,18 +6367,6 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/merge@npm:^9.0.0, @graphql-tools/merge@npm:^9.0.1": - version: 9.0.1 - resolution: "@graphql-tools/merge@npm:9.0.1" - dependencies: - "@graphql-tools/utils": "npm:^10.0.10" - tslib: "npm:^2.4.0" - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: cbfcb2c10490a11417991e8b61b8df2eba73a2c576e57cbf2d928902030d4391122536b9442bf042609ec24376b79b8bc6d9117e137dd8db2255ed90613acbc7 - languageName: node - linkType: hard - "@graphql-tools/mock@npm:^8.1.2": version: 8.7.20 resolution: "@graphql-tools/mock@npm:8.7.20" @@ -6469,17 +6457,17 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/schema@npm:10.0.0": - version: 10.0.0 - resolution: "@graphql-tools/schema@npm:10.0.0" +"@graphql-tools/schema@npm:10.0.2, @graphql-tools/schema@npm:^10.0.0": + version: 10.0.2 + resolution: "@graphql-tools/schema@npm:10.0.2" dependencies: - "@graphql-tools/merge": "npm:^9.0.0" - "@graphql-tools/utils": "npm:^10.0.0" + "@graphql-tools/merge": "npm:^9.0.1" + "@graphql-tools/utils": "npm:^10.0.10" tslib: "npm:^2.4.0" value-or-promise: "npm:^1.0.12" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: b746c69cefb3b89fad13d56f0abb9e764efe1569836ea9ae5e5c510a6f0bce6e08f324b28aebcb5b2c11ba2ea1c308f18c204e322a188e254e2c7e426d3ccecb + checksum: 3d71117c8d8ed491aa5b988bcdfcc1a7ca8cea8638b37083af2665a0dbb95e1255961a8a43658538ad33b83d621812886a4626ad7a5333d7d9e6c62304b52cb2 languageName: node linkType: hard @@ -6497,20 +6485,6 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/schema@npm:^10.0.0": - version: 10.0.2 - resolution: "@graphql-tools/schema@npm:10.0.2" - dependencies: - "@graphql-tools/merge": "npm:^9.0.1" - "@graphql-tools/utils": "npm:^10.0.10" - tslib: "npm:^2.4.0" - value-or-promise: "npm:^1.0.12" - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 3d71117c8d8ed491aa5b988bcdfcc1a7ca8cea8638b37083af2665a0dbb95e1255961a8a43658538ad33b83d621812886a4626ad7a5333d7d9e6c62304b52cb2 - languageName: node - linkType: hard - "@graphql-tools/schema@npm:^9.0.0, @graphql-tools/schema@npm:^9.0.18, @graphql-tools/schema@npm:^9.0.19": version: 9.0.19 resolution: "@graphql-tools/schema@npm:9.0.19" @@ -6548,15 +6522,17 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:10.0.1": - version: 10.0.1 - resolution: "@graphql-tools/utils@npm:10.0.1" +"@graphql-tools/utils@npm:10.0.13": + version: 10.0.13 + resolution: "@graphql-tools/utils@npm:10.0.13" dependencies: "@graphql-typed-document-node/core": "npm:^3.1.1" + cross-inspect: "npm:1.0.0" + dset: "npm:^3.1.2" tslib: "npm:^2.4.0" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: c3562240f99543428fa960c1c9836225b33492e16a1ce0622ca71a3abbc3ef4e4f8e453cdb5cc32227e1866f1cdd9e20e09518f8354fa50c87164b2f793f03ae + checksum: 6505c494716bb7aa36eba3d731f5a3e28c0bbd2efc818f1fdc7367a408ced8878bfff40f4dafbcef70d912219df81484e32e28130366e8355c126fcbc8ac9dd5 languageName: node linkType: hard @@ -7981,24 +7957,24 @@ __metadata: languageName: node linkType: hard -"@nestjs/graphql@npm:12.0.8": - version: 12.0.8 - resolution: "@nestjs/graphql@npm:12.0.8" +"@nestjs/graphql@npm:12.1.1": + version: 12.1.1 + resolution: "@nestjs/graphql@npm:12.1.1" dependencies: - "@graphql-tools/merge": "npm:9.0.0" - "@graphql-tools/schema": "npm:10.0.0" - "@graphql-tools/utils": "npm:10.0.1" - "@nestjs/mapped-types": "npm:2.0.2" - chokidar: "npm:3.5.3" - fast-glob: "npm:3.2.12" + "@graphql-tools/merge": "npm:9.0.1" + "@graphql-tools/schema": "npm:10.0.2" + "@graphql-tools/utils": "npm:10.0.13" + "@nestjs/mapped-types": "npm:2.0.5" + chokidar: "npm:3.6.0" + fast-glob: "npm:3.3.2" graphql-tag: "npm:2.12.6" - graphql-ws: "npm:5.14.0" + graphql-ws: "npm:5.14.3" lodash: "npm:4.17.21" normalize-path: "npm:3.0.0" subscriptions-transport-ws: "npm:0.11.0" - tslib: "npm:2.6.0" - uuid: "npm:9.0.0" - ws: "npm:8.13.0" + tslib: "npm:2.6.2" + uuid: "npm:9.0.1" + ws: "npm:8.16.0" peerDependencies: "@apollo/subgraph": ^2.0.0 "@nestjs/common": ^9.3.8 || ^10.0.0 @@ -8006,8 +7982,8 @@ __metadata: class-transformer: "*" class-validator: "*" graphql: ^16.6.0 - reflect-metadata: ^0.1.13 - ts-morph: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + ts-morph: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 peerDependenciesMeta: "@apollo/subgraph": optional: true @@ -8017,28 +7993,28 @@ __metadata: optional: true ts-morph: optional: true - checksum: 85bfb0e198dc13e8e549cd4c1e9c33f08171f19fc01dccdd0822f72bfd5dcacb55967c87d690f13384252fadf6a4d254a7d0571a547a40c1f259e3b4d2d15143 + checksum: b2c371d443007b583b75cbffd86714fc87551e2f6c56a89b70f95eae2ee3fc9a5ae0673b44d1c9d59f42b38e6f54fe20f92396a8be02c5bf87d8e83d5da764a6 languageName: node linkType: hard -"@nestjs/graphql@patch:@nestjs/graphql@12.0.8#./patches/@nestjs+graphql+12.0.8.patch::locator=twenty-server%40workspace%3Apackages%2Ftwenty-server": - version: 12.0.8 - resolution: "@nestjs/graphql@patch:@nestjs/graphql@npm%3A12.0.8#./patches/@nestjs+graphql+12.0.8.patch::version=12.0.8&hash=daa690&locator=twenty-server%40workspace%3Apackages%2Ftwenty-server" +"@nestjs/graphql@patch:@nestjs/graphql@12.1.1#./patches/@nestjs+graphql+12.1.1.patch::locator=twenty-server%40workspace%3Apackages%2Ftwenty-server": + version: 12.1.1 + resolution: "@nestjs/graphql@patch:@nestjs/graphql@npm%3A12.1.1#./patches/@nestjs+graphql+12.1.1.patch::version=12.1.1&hash=214dda&locator=twenty-server%40workspace%3Apackages%2Ftwenty-server" dependencies: - "@graphql-tools/merge": "npm:9.0.0" - "@graphql-tools/schema": "npm:10.0.0" - "@graphql-tools/utils": "npm:10.0.1" - "@nestjs/mapped-types": "npm:2.0.2" - chokidar: "npm:3.5.3" - fast-glob: "npm:3.2.12" + "@graphql-tools/merge": "npm:9.0.1" + "@graphql-tools/schema": "npm:10.0.2" + "@graphql-tools/utils": "npm:10.0.13" + "@nestjs/mapped-types": "npm:2.0.5" + chokidar: "npm:3.6.0" + fast-glob: "npm:3.3.2" graphql-tag: "npm:2.12.6" - graphql-ws: "npm:5.14.0" + graphql-ws: "npm:5.14.3" lodash: "npm:4.17.21" normalize-path: "npm:3.0.0" subscriptions-transport-ws: "npm:0.11.0" - tslib: "npm:2.6.0" - uuid: "npm:9.0.0" - ws: "npm:8.13.0" + tslib: "npm:2.6.2" + uuid: "npm:9.0.1" + ws: "npm:8.16.0" peerDependencies: "@apollo/subgraph": ^2.0.0 "@nestjs/common": ^9.3.8 || ^10.0.0 @@ -8046,8 +8022,8 @@ __metadata: class-transformer: "*" class-validator: "*" graphql: ^16.6.0 - reflect-metadata: ^0.1.13 - ts-morph: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + ts-morph: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 peerDependenciesMeta: "@apollo/subgraph": optional: true @@ -8057,7 +8033,7 @@ __metadata: optional: true ts-morph: optional: true - checksum: e53b804e87e65c78e0e231a7033e135a8346d44ee110a8e2f270b026bd47fda41525b598a301b5ca84537b3c8e37fa92462be353e611751a5b433aadb1f6f290 + checksum: eabde73e30747ea5d6ee33912516def4c87bc14adfb51ec7e9a037faa1d5c5446211774f6765686da778b17e37d72485d561c51f6e70a86562415b0f590f20d1 languageName: node linkType: hard @@ -8073,20 +8049,20 @@ __metadata: languageName: node linkType: hard -"@nestjs/mapped-types@npm:2.0.2": - version: 2.0.2 - resolution: "@nestjs/mapped-types@npm:2.0.2" +"@nestjs/mapped-types@npm:2.0.5": + version: 2.0.5 + resolution: "@nestjs/mapped-types@npm:2.0.5" peerDependencies: "@nestjs/common": ^8.0.0 || ^9.0.0 || ^10.0.0 class-transformer: ^0.4.0 || ^0.5.0 class-validator: ^0.13.0 || ^0.14.0 - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 peerDependenciesMeta: class-transformer: optional: true class-validator: optional: true - checksum: 9a6d4c32242926aebc267d5a4a0b50f8aa8eeea8797e25aa9fb762637a45879c1ec103a9a0a30d24e8a6e3f75d0f4640208aaf4f9003e350b52f7e4acb07bab9 + checksum: f92743cb4c0fe3b1eecdf0c7c6a40f0e7478574a9e1a25ebdbd29db29a7319c2ae608c08d07f7b9525bea01a5e20dbd73222100204d3a13500db4f56676446a1 languageName: node linkType: hard @@ -21863,6 +21839,25 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:3.6.0": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: "npm:~3.1.2" + braces: "npm:~3.0.2" + fsevents: "npm:~2.3.2" + glob-parent: "npm:~5.1.2" + is-binary-path: "npm:~2.1.0" + is-glob: "npm:~4.0.1" + normalize-path: "npm:~3.0.0" + readdirp: "npm:~3.6.0" + dependenciesMeta: + fsevents: + optional: true + checksum: 8361dcd013f2ddbe260eacb1f3cb2f2c6f2b0ad118708a343a5ed8158941a39cb8fb1d272e0f389712e74ee90ce8ba864eece9e0e62b9705cb468a2f6d917462 + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -26695,19 +26690,6 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.2.12": - version: 3.2.12 - resolution: "fast-glob@npm:3.2.12" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 08604fb8ef6442ce74068bef3c3104382bb1f5ab28cf75e4ee904662778b60ad620e1405e692b7edea598ef445f5d387827a965ba034e1892bf54b1dfde97f26 - languageName: node - linkType: hard - "fast-glob@npm:3.2.7": version: 3.2.7 resolution: "fast-glob@npm:3.2.7" @@ -26721,7 +26703,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1": +"fast-glob@npm:3.3.2, fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -28598,12 +28580,12 @@ __metadata: languageName: node linkType: hard -"graphql-ws@npm:5.14.0": - version: 5.14.0 - resolution: "graphql-ws@npm:5.14.0" +"graphql-ws@npm:5.14.3": + version: 5.14.3 + resolution: "graphql-ws@npm:5.14.3" peerDependencies: graphql: ">=0.11 <=16" - checksum: 505c1b1332b1a45a4a410ada0f335cc21b1a9511deb034bf0631d786d5fe328af2b4887dadc99a9eb3b7f9be0e1d0643e5cada6e3485d05b20851eabb5e7b92d + checksum: 0715feb7b6bf760e2460c31848983bd3bd5958c95d8120c2acc7416f24137585dab2eb731d6bb6f8de992afbc2ad0cf258a00c6a08aa21479fb3e9bd1d3e120a languageName: node linkType: hard @@ -32858,6 +32840,13 @@ __metadata: languageName: node linkType: hard +"jwt-decode@npm:^4.0.0": + version: 4.0.0 + resolution: "jwt-decode@npm:4.0.0" + checksum: de75bbf89220746c388cf6a7b71e56080437b77d2edb29bae1c2155048b02c6b8c59a3e5e8d6ccdfd54f0b8bda25226e491a4f1b55ac5f8da04cfbadec4e546c + languageName: node + linkType: hard + "keyv@npm:^3.0.0": version: 3.1.0 resolution: "keyv@npm:3.1.0" @@ -45589,10 +45578,10 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.0": - version: 2.6.0 - resolution: "tslib@npm:2.6.0" - checksum: 8d18020a8b9e70ecc529a744c883c095f177805efdbc9786bd50bd82a46c17547923133c5444fbcaf1f7f1c44e0e29c89f73ecf6d8fd1039668024a073a81dc6 +"tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.5.2, tslib@npm:^2.6.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb languageName: node linkType: hard @@ -45603,13 +45592,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.5.2, tslib@npm:^2.6.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb - languageName: node - linkType: hard - "tslib@npm:~2.0.1": version: 2.0.3 resolution: "tslib@npm:2.0.3" @@ -45763,7 +45745,7 @@ __metadata: "@nestjs/cache-manager": "npm:^2.2.1" "@nestjs/cli": "npm:10.3.0" "@nestjs/devtools-integration": "npm:^0.1.6" - "@nestjs/graphql": "patch:@nestjs/graphql@12.0.8#./patches/@nestjs+graphql+12.0.8.patch" + "@nestjs/graphql": "patch:@nestjs/graphql@12.1.1#./patches/@nestjs+graphql+12.1.1.patch" "@nx/js": "npm:17.2.8" "@ptc-org/nestjs-query-graphql": "patch:@ptc-org/nestjs-query-graphql@4.2.0#./patches/@ptc-org+nestjs-query-graphql+4.2.0.patch" "@types/lodash.isempty": "npm:^4.4.7" @@ -45777,6 +45759,7 @@ __metadata: cache-manager-redis-yet: "npm:^4.1.2" class-validator: "patch:class-validator@0.14.0#./patches/class-validator+0.14.0.patch" graphql-middleware: "npm:^6.1.35" + jwt-decode: "npm:^4.0.0" passport: "npm:^0.7.0" psl: "npm:^1.9.0" rimraf: "npm:^5.0.5" @@ -48694,6 +48677,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.16.0, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.2.3": + version: 8.16.0 + resolution: "ws@npm:8.16.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: a7783bb421c648b1e622b423409cb2a58ac5839521d2f689e84bc9dc41d59379c692dd405b15a997ea1d4c0c2e5314ad707332d0c558f15232d2bc07c0b4618a + languageName: node + linkType: hard + "ws@npm:^5.2.0 || ^6.0.0 || ^7.0.0, ws@npm:^7.3.1": version: 7.5.9 resolution: "ws@npm:7.5.9" @@ -48718,21 +48716,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.2.3": - version: 8.16.0 - resolution: "ws@npm:8.16.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: a7783bb421c648b1e622b423409cb2a58ac5839521d2f689e84bc9dc41d59379c692dd405b15a997ea1d4c0c2e5314ad707332d0c558f15232d2bc07c0b4618a - languageName: node - linkType: hard - "ws@npm:^8.13.0": version: 8.15.0 resolution: "ws@npm:8.15.0" From b089b93e67e3e63ca3b8a41726ac7bf585c9c7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eldar=20Dautovi=C4=87?= <49655828+eldardautovic@users.noreply.github.com> Date: Thu, 21 Mar 2024 09:50:11 +0100 Subject: [PATCH 34/44] feat: modified DoubleTextInput to split First and Last name accordingly (#4598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: modified DoubleTextInput to split First and Last name accordingly * Fix Linter --------- Co-authored-by: Félix Malfait --- .../input/components/FullNameFieldInput.tsx | 5 ++++ .../input/components/DoubleTextInput.tsx | 27 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/FullNameFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/FullNameFieldInput.tsx index 77fa108e15ed..7756c1ef678b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/FullNameFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/FullNameFieldInput.tsx @@ -66,6 +66,10 @@ export const FullNameFieldInput = ({ setDraftValue(convertToFullName(newDoubleText)); }; + const handlePaste = (newDoubleText: FieldDoubleText) => { + setDraftValue(convertToFullName(newDoubleText)); + }; + return ( diff --git a/packages/twenty-front/src/modules/ui/field/input/components/DoubleTextInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/DoubleTextInput.tsx index 3a5b387aa0d8..1ca95288f903 100644 --- a/packages/twenty-front/src/modules/ui/field/input/components/DoubleTextInput.tsx +++ b/packages/twenty-front/src/modules/ui/field/input/components/DoubleTextInput.tsx @@ -1,4 +1,10 @@ -import { ChangeEvent, useEffect, useRef, useState } from 'react'; +import { + ChangeEvent, + ClipboardEvent, + useEffect, + useRef, + useState, +} from 'react'; import styled from '@emotion/styled'; import { Key } from 'ts-key-enum'; @@ -39,6 +45,7 @@ type DoubleTextInputProps = { newDoubleTextValue: FieldDoubleText, ) => void; onChange?: (newDoubleTextValue: FieldDoubleText) => void; + onPaste?: (newDoubleTextValue: FieldDoubleText) => void; }; export const DoubleTextInput = ({ @@ -53,6 +60,7 @@ export const DoubleTextInput = ({ onShiftTab, onTab, onChange, + onPaste, }: DoubleTextInputProps) => { const [firstInternalValue, setFirstInternalValue] = useState(firstValue); const [secondInternalValue, setSecondInternalValue] = useState(secondValue); @@ -150,6 +158,20 @@ export const DoubleTextInput = ({ enabled: isDefined(onClickOutside), }); + const handleOnPaste = (event: ClipboardEvent) => { + if (firstInternalValue.length > 0 || secondInternalValue.length > 0) { + return; + } + + event.preventDefault(); + + const name = event.clipboardData.getData('Text'); + + const splittedName = name.split(' '); + + onPaste?.({ firstValue: splittedName[0], secondValue: splittedName[1] }); + }; + return ( ) => { handleChange(event.target.value, secondInternalValue); }} + onPaste={(event: ClipboardEvent) => + handleOnPaste(event) + } /> Date: Thu, 21 Mar 2024 02:17:06 -0700 Subject: [PATCH 35/44] update example docker-compose to bitnami postgres path (#4491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update example docker-compose to bitnami postgres path * leave a note that Postgres needs configuration * Revert example docker-compose * Edit text --------- Co-authored-by: Félix Malfait --- packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx index 0204e30fb281..9aee44c73728 100644 --- a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx @@ -35,7 +35,7 @@ Complete step three and four with : ## Production docker containers -Prebuilt images for both Postgres, frontend, and back-end can be found on [docker hub](https://hub.docker.com/r/twentycrm/). +Prebuilt images for both Postgres, frontend, and back-end can be found on [docker hub](https://hub.docker.com/r/twentycrm/). Note that the Postgres container will not persist data if your server is not configured to be stateful (e.g. Heroku). You probably want to configure a special stateful resource for the database. ## Environment Variables From 8e4123e772abbceb23f9739c9c2b971050aa4101 Mon Sep 17 00:00:00 2001 From: martmull Date: Thu, 21 Mar 2024 10:47:25 +0100 Subject: [PATCH 36/44] 48 add yearly monthly sub switch (#4577) --- .../effect-components/PageChangeEffect.tsx | 9 +- .../twenty-front/src/generated/graphql.tsx | 48 +++++- .../graphql/updateBillingSubscription.ts | 9 ++ .../src/modules/ui/display/icon/index.ts | 1 + .../modal/components/ConfirmationModal.tsx | 6 +- .../users/graphql/queries/getCurrentUser.ts | 1 + .../src/pages/settings/SettingsBilling.tsx | 151 +++++++++++++++--- ...613773-addIntervalToBillingSubscription.ts | 19 +++ .../core-modules/billing/billing.resolver.ts | 9 ++ .../core-modules/billing/billing.service.ts | 27 ++++ .../billing/dto/update-billing.entity.ts | 9 ++ .../entities/billing-subscription.entity.ts | 4 + .../billing/stripe/stripe.service.ts | 14 ++ .../engine/core-modules/user/user.resolver.ts | 2 - 14 files changed, 284 insertions(+), 25 deletions(-) create mode 100644 packages/twenty-front/src/modules/billing/graphql/updateBillingSubscription.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/1710926613773-addIntervalToBillingSubscription.ts create mode 100644 packages/twenty-server/src/engine/core-modules/billing/dto/update-billing.entity.ts diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 2cf692c3e3b5..820ce959cd60 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -113,11 +113,16 @@ export const PageChangeEffect = () => { ) { navigate(AppPath.CreateProfile); } else if ( - (onboardingStatus === OnboardingStatus.Completed || - onboardingStatus === OnboardingStatus.CompletedWithoutSubscription) && + onboardingStatus === OnboardingStatus.Completed && isMatchingOnboardingRoute ) { navigate(AppPath.Index); + } else if ( + onboardingStatus === OnboardingStatus.CompletedWithoutSubscription && + isMatchingOnboardingRoute && + !isMatchingLocation(AppPath.PlanRequired) + ) { + navigate(AppPath.Index); } else if (isMatchingLocation(AppPath.Invite)) { const inviteHash = matchPath({ path: '/invite/:workspaceInviteHash' }, location.pathname) diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 1c89af101e9b..73da02df1083 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -68,6 +68,7 @@ export type Billing = { export type BillingSubscription = { __typename?: 'BillingSubscription'; id: Scalars['ID']; + interval?: Maybe; status: Scalars['String']; }; @@ -258,6 +259,7 @@ export type Mutation = { renewToken: AuthTokens; signUp: LoginToken; track: Analytics; + updateBillingSubscription: UpdateBillingEntity; updateOneObject: Object; updatePasswordViaResetToken: InvalidatePassword; updateWorkspace: Workspace; @@ -660,6 +662,12 @@ export type TransientToken = { transientToken: AuthToken; }; +export type UpdateBillingEntity = { + __typename?: 'UpdateBillingEntity'; + /** Boolean that confirms query was successful */ + success: Scalars['Boolean']; +}; + export type UpdateWorkspaceInput = { allowImpersonation?: InputMaybe; displayName?: InputMaybe; @@ -1045,6 +1053,11 @@ export type GetProductPricesQueryVariables = Exact<{ export type GetProductPricesQuery = { __typename?: 'Query', getProductPrices: { __typename?: 'ProductPricesEntity', productPrices: Array<{ __typename?: 'ProductPriceEntity', created: number, recurringInterval: string, stripePriceId: string, unitAmount: number }> } }; +export type UpdateBillingSubscriptionMutationVariables = Exact<{ [key: string]: never; }>; + + +export type UpdateBillingSubscriptionMutation = { __typename?: 'Mutation', updateBillingSubscription: { __typename?: 'UpdateBillingEntity', success: boolean } }; + export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>; @@ -1083,7 +1096,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; -export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', status: string } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null } | null }> } }; +export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', status: string, interval?: string | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null } | null }> } }; export type RemoveWorkspaceMemberMutationVariables = Exact<{ memberId: Scalars['String']; @@ -2006,6 +2019,38 @@ export function useGetProductPricesLazyQuery(baseOptions?: Apollo.LazyQueryHookO export type GetProductPricesQueryHookResult = ReturnType; export type GetProductPricesLazyQueryHookResult = ReturnType; export type GetProductPricesQueryResult = Apollo.QueryResult; +export const UpdateBillingSubscriptionDocument = gql` + mutation UpdateBillingSubscription { + updateBillingSubscription { + success + } +} + `; +export type UpdateBillingSubscriptionMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateBillingSubscriptionMutation__ + * + * To run a mutation, you first call `useUpdateBillingSubscriptionMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateBillingSubscriptionMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateBillingSubscriptionMutation, { data, loading, error }] = useUpdateBillingSubscriptionMutation({ + * variables: { + * }, + * }); + */ +export function useUpdateBillingSubscriptionMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateBillingSubscriptionDocument, options); + } +export type UpdateBillingSubscriptionMutationHookResult = ReturnType; +export type UpdateBillingSubscriptionMutationResult = Apollo.MutationResult; +export type UpdateBillingSubscriptionMutationOptions = Apollo.BaseMutationOptions; export const GetClientConfigDocument = gql` query GetClientConfig { clientConfig { @@ -2225,6 +2270,7 @@ export const GetCurrentUserDocument = gql` } currentBillingSubscription { status + interval } } workspaces { diff --git a/packages/twenty-front/src/modules/billing/graphql/updateBillingSubscription.ts b/packages/twenty-front/src/modules/billing/graphql/updateBillingSubscription.ts new file mode 100644 index 000000000000..2f75c7610b37 --- /dev/null +++ b/packages/twenty-front/src/modules/billing/graphql/updateBillingSubscription.ts @@ -0,0 +1,9 @@ +import { gql } from '@apollo/client'; + +export const UPDATE_BILLING_SUBSCRIPTION = gql` + mutation UpdateBillingSubscription { + updateBillingSubscription { + success + } + } +`; diff --git a/packages/twenty-front/src/modules/ui/display/icon/index.ts b/packages/twenty-front/src/modules/ui/display/icon/index.ts index 74f81ccb9b9e..7bfc09d63b04 100644 --- a/packages/twenty-front/src/modules/ui/display/icon/index.ts +++ b/packages/twenty-front/src/modules/ui/display/icon/index.ts @@ -37,6 +37,7 @@ export { IconChevronUp, IconCircleDot, IconCircleOff, + IconCircleX, IconClick, IconCode, IconCoins, diff --git a/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx b/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx index e71955d62bad..515a27bfe0b1 100644 --- a/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx +++ b/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx @@ -7,7 +7,7 @@ import { H1Title, H1TitleFontColor, } from '@/ui/display/typography/components/H1Title'; -import { Button } from '@/ui/input/button/components/Button'; +import { Button, ButtonAccent } from '@/ui/input/button/components/Button'; import { TextInput } from '@/ui/input/components/TextInput'; import { Modal } from '@/ui/layout/modal/components/Modal'; import { @@ -25,6 +25,7 @@ export type ConfirmationModalProps = { deleteButtonText?: string; confirmationPlaceholder?: string; confirmationValue?: string; + confirmButtonAccent?: ButtonAccent; }; const StyledConfirmationModal = styled(Modal)` @@ -66,6 +67,7 @@ export const ConfirmationModal = ({ deleteButtonText = 'Delete', confirmationValue, confirmationPlaceholder, + confirmButtonAccent = 'danger', }: ConfirmationModalProps) => { const [inputConfirmationValue, setInputConfirmationValue] = useState(''); @@ -127,7 +129,7 @@ export const ConfirmationModal = ({ setIsOpen(false); }} variant="secondary" - accent="danger" + accent={confirmButtonAccent} title={deleteButtonText} disabled={!isValidValue} fullWidth diff --git a/packages/twenty-front/src/modules/users/graphql/queries/getCurrentUser.ts b/packages/twenty-front/src/modules/users/graphql/queries/getCurrentUser.ts index 5568ae49c464..03a6a06a4e61 100644 --- a/packages/twenty-front/src/modules/users/graphql/queries/getCurrentUser.ts +++ b/packages/twenty-front/src/modules/users/graphql/queries/getCurrentUser.ts @@ -37,6 +37,7 @@ export const GET_CURRENT_USER = gql` } currentBillingSubscription { status + interval } } workspaces { diff --git a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx index 13de2e854778..e0f9f92eef3d 100644 --- a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx @@ -1,21 +1,29 @@ -import React from 'react'; +import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styled from '@emotion/styled'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus.ts'; +import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState.ts'; import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus.ts'; import { SettingsBillingCoverImage } from '@/billing/components/SettingsBillingCoverImage.tsx'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SupportChat } from '@/support/components/SupportChat.tsx'; import { AppPath } from '@/types/AppPath.ts'; +import { IconCalendarEvent, IconCircleX } from '@/ui/display/icon'; import { IconCreditCard, IconCurrencyDollar } from '@/ui/display/icon'; import { Info } from '@/ui/display/info/components/Info.tsx'; import { H1Title } from '@/ui/display/typography/components/H1Title.tsx'; import { H2Title } from '@/ui/display/typography/components/H2Title.tsx'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx'; import { Button } from '@/ui/input/button/components/Button.tsx'; +import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal.tsx'; import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; import { Section } from '@/ui/layout/section/components/Section.tsx'; -import { useBillingPortalSessionQuery } from '~/generated/graphql.tsx'; +import { + useBillingPortalSessionQuery, + useUpdateBillingSubscriptionMutation, +} from '~/generated/graphql.tsx'; import { isDefined } from '~/utils/isDefined'; const StyledH1Title = styled(H1Title)` @@ -26,9 +34,45 @@ const StyledInvisibleChat = styled.div` display: none; `; +type SwitchInfo = { + newInterval: string; + to: string; + from: string; + impact: string; +}; + +const MONTHLY_SWITCH_INFO: SwitchInfo = { + newInterval: 'year', + to: 'to yearly', + from: 'from monthly to yearly', + impact: 'You will be charged immediately for the full year.', +}; + +const YEARLY_SWITCH_INFO: SwitchInfo = { + newInterval: 'month', + to: 'to monthly', + from: 'from yearly to monthly', + impact: 'Your credit balance will be used to pay the monthly bills.', +}; + +const SWITCH_INFOS = { + year: YEARLY_SWITCH_INFO, + month: MONTHLY_SWITCH_INFO, +}; + export const SettingsBilling = () => { const navigate = useNavigate(); + const { enqueueSnackBar } = useSnackBar(); const onboardingStatus = useOnboardingStatus(); + const currentWorkspace = useRecoilValue(currentWorkspaceState); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); + const switchingInfo = + currentWorkspace?.currentBillingSubscription?.interval === 'year' + ? SWITCH_INFOS.year + : SWITCH_INFOS.month; + const [isSwitchingIntervalModalOpen, setIsSwitchingIntervalModalOpen] = + useState(false); + const [updateBillingSubscription] = useUpdateBillingSubscriptionMutation(); const { data, loading } = useBillingPortalSessionQuery({ variables: { returnUrlPath: '/settings/billing', @@ -54,6 +98,36 @@ export const SettingsBilling = () => { } }; + const openSwitchingIntervalModal = () => { + setIsSwitchingIntervalModalOpen(true); + }; + + const switchInterval = async () => { + try { + await updateBillingSubscription(); + if (isDefined(currentWorkspace?.currentBillingSubscription)) { + const newCurrentWorkspace = { + ...currentWorkspace, + currentBillingSubscription: { + ...currentWorkspace?.currentBillingSubscription, + interval: switchingInfo.newInterval, + }, + }; + setCurrentWorkspace(newCurrentWorkspace); + } + enqueueSnackBar(`Subscription has been switched ${switchingInfo.to}`, { + variant: 'success', + }); + } catch (error: any) { + enqueueSnackBar( + `Error while switching subscription ${switchingInfo.to}.`, + { + variant: 'error', + }, + ); + } + }; + const redirectToSubscribePage = () => { navigate(AppPath.PlanRequired); }; @@ -79,33 +153,74 @@ export const SettingsBilling = () => { onClick={redirectToSubscribePage} /> )} - {displaySubscribeInfo && ( + {displaySubscribeInfo ? ( - )} - {!displaySubscribeInfo && ( -
      - -
      + ) : ( + <> +
      + +
      +
      + +
      +
      + +
      + )} + + {`Are you sure that you want to change your billing interval? + ${switchingInfo.impact}`} + + } + onConfirmClick={switchInterval} + deleteButtonText={`Change ${switchingInfo.to}`} + confirmButtonAccent={'blue'} + /> ); }; diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/1710926613773-addIntervalToBillingSubscription.ts b/packages/twenty-server/src/database/typeorm/core/migrations/1710926613773-addIntervalToBillingSubscription.ts new file mode 100644 index 000000000000..441cf54d0785 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/1710926613773-addIntervalToBillingSubscription.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddIntervalToBillingSubscription1710926613773 + implements MigrationInterface +{ + name = 'AddIntervalToBillingSubscription1710926613773'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."billingSubscription" ADD "interval" character varying`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."billingSubscription" DROP COLUMN "interval"`, + ); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts index 0050a6576695..8766c4adc37e 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts @@ -14,6 +14,7 @@ import { User } from 'src/engine/core-modules/user/user.entity'; import { CheckoutSessionInput } from 'src/engine/core-modules/billing/dto/checkout-session.input'; import { SessionEntity } from 'src/engine/core-modules/billing/dto/session.entity'; import { BillingSessionInput } from 'src/engine/core-modules/billing/dto/billing-session.input'; +import { UpdateBillingEntity } from 'src/engine/core-modules/billing/dto/update-billing.entity'; @Resolver() export class BillingResolver { @@ -88,4 +89,12 @@ export class BillingResolver { ), }; } + + @Mutation(() => UpdateBillingEntity) + @UseGuards(JwtAuthGuard) + async updateBillingSubscription(@AuthUser() user: User) { + await this.billingService.updateBillingSubscription(user); + + return { success: true }; + } } diff --git a/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts index f95580085cab..722c9f8c2303 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.service.ts @@ -154,6 +154,32 @@ export class BillingService { return session.url; } + async updateBillingSubscription(user: User) { + const billingSubscription = await this.getCurrentBillingSubscription({ + workspaceId: user.defaultWorkspaceId, + }); + const newInterval = + billingSubscription?.interval === 'year' ? 'month' : 'year'; + const billingSubscriptionItem = await this.getBillingSubscriptionItem( + user.defaultWorkspaceId, + ); + const stripeProductId = this.getProductStripeId(AvailableProduct.BasePlan); + + if (!stripeProductId) { + throw new Error('Stripe product id not found for basePlan'); + } + const productPrices = await this.getProductPrices(stripeProductId); + + const stripePriceId = productPrices.filter( + (price) => price.recurringInterval === newInterval, + )?.[0]?.stripePriceId; + + await this.stripeService.updateBillingSubscriptionItem( + billingSubscriptionItem, + stripePriceId, + ); + } + async computeCheckoutSessionURL( user: User, priceId: string, @@ -230,6 +256,7 @@ export class BillingService { stripeCustomerId: data.object.customer as string, stripeSubscriptionId: data.object.id, status: data.object.status, + interval: data.object.items.data[0].plan.interval, }, { conflictPaths: ['stripeSubscriptionId'], diff --git a/packages/twenty-server/src/engine/core-modules/billing/dto/update-billing.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/dto/update-billing.entity.ts new file mode 100644 index 000000000000..ae8f8660d0f0 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/billing/dto/update-billing.entity.ts @@ -0,0 +1,9 @@ +import { Field, ObjectType } from '@nestjs/graphql'; + +@ObjectType() +export class UpdateBillingEntity { + @Field(() => Boolean, { + description: 'Boolean that confirms query was successful', + }) + success: boolean; +} diff --git a/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts index 4a6a7c046d20..9198e9a8c5d1 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/entities/billing-subscription.entity.ts @@ -51,6 +51,10 @@ export class BillingSubscription { @Column({ nullable: false }) status: Stripe.Subscription.Status; + @Field({ nullable: true }) + @Column({ nullable: true }) + interval: Stripe.Price.Recurring.Interval; + @OneToMany( () => BillingSubscriptionItem, (billingSubscriptionItem) => billingSubscriptionItem.billingSubscription, diff --git a/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts index be72dda1a4d3..1a4e728fe24c 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/stripe/stripe.service.ts @@ -4,6 +4,7 @@ import Stripe from 'stripe'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; import { User } from 'src/engine/core-modules/user/user.entity'; +import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity'; @Injectable() export class StripeService { @@ -105,4 +106,17 @@ export class StripeService { } await this.stripe.invoices.pay(latestInvoice.id); } + + async updateBillingSubscriptionItem( + stripeSubscriptionItem: BillingSubscriptionItem, + stripePriceId: string, + ) { + await this.stripe.subscriptionItems.update( + stripeSubscriptionItem.stripeSubscriptionItemId, + { + price: stripePriceId, + quantity: stripeSubscriptionItem.quantity, + }, + ); + } } diff --git a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index fc505ae2bd7b..2ec203b1014a 100644 --- a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -26,7 +26,6 @@ import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard'; import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; import { User } from 'src/engine/core-modules/user/user.entity'; import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto'; -import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service'; import { UserService } from './services/user.service'; @@ -45,7 +44,6 @@ export class UserResolver { @InjectRepository(User, 'core') private readonly userRepository: Repository, private readonly userService: UserService, - private readonly userWorkspaceService: UserWorkspaceService, private readonly environmentService: EnvironmentService, private readonly fileUploadService: FileUploadService, ) {} From cc0e3c8a9a7cc762f201b30d5ef57d4825cf8814 Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Thu, 21 Mar 2024 12:10:09 +0100 Subject: [PATCH 37/44] Fixed TS error with blocknote/react package (#4601) --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f7e14be3a000..312f4a45e691 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@aws-sdk/client-s3": "^3.363.0", "@aws-sdk/credential-providers": "^3.363.0", "@blocknote/core": "^0.12.1", - "@blocknote/react": "^0.12.1", + "@blocknote/react": "^0.12.2", "@chakra-ui/accordion": "^2.3.0", "@chakra-ui/system": "^2.6.0", "@codesandbox/sandpack-react": "^2.13.5", diff --git a/yarn.lock b/yarn.lock index 400416175a46..0310f5992701 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3602,7 +3602,7 @@ __metadata: languageName: node linkType: hard -"@blocknote/react@npm:^0.12.1": +"@blocknote/react@npm:^0.12.2": version: 0.12.2 resolution: "@blocknote/react@npm:0.12.2" dependencies: @@ -45810,7 +45810,7 @@ __metadata: "@babel/core": "npm:^7.14.5" "@babel/preset-react": "npm:^7.14.5" "@blocknote/core": "npm:^0.12.1" - "@blocknote/react": "npm:^0.12.1" + "@blocknote/react": "npm:^0.12.2" "@chakra-ui/accordion": "npm:^2.3.0" "@chakra-ui/system": "npm:^2.6.0" "@codesandbox/sandpack-react": "npm:^2.13.5" From 3fa8c4bace02fd4e5c0ca170e445c0bc48359577 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Thu, 21 Mar 2024 18:08:27 +0100 Subject: [PATCH 38/44] Add KanbanFieldMetadataId on View standard object (#4604) * Add KanbanFieldMetadataId on View standard object * Deprecate Pipeline step * Fix * Use Constants instead of raw ids * Fix * Fix query runner * Fix according to review * Fix tests * Fix tests * Fix tests --- .../start/self-hosting/docker-compose.mdx | 2 +- packages/twenty-front/nyc.config.cjs | 2 +- .../types/CoreObjectNameSingular.ts | 1 - .../mapFieldMetadataToGraphQLQuery.test.tsx | 1 - .../mapObjectMetadataToGraphQLQuery.test.tsx | 2 - .../utils/getObjectMetadataItemsMock.ts | 247 ++++------------ .../hooks/__mocks__/useFindManyRecords.ts | 4 +- .../utils/filterAvailableTableColumns.ts | 7 - .../__mocks__/useFilteredSearchEntityQuery.ts | 4 +- .../SignInBackgroundMockCompanies.ts | 8 +- .../src/testing/mock-data/metadata.ts | 272 ------------------ .../data-seed-dev-workspace.command.ts | 45 ++- .../workspace/calendar-events.ts | 6 +- .../typeorm-seeds/workspace/companies.ts | 6 +- .../typeorm-seeds/workspace/opportunity.ts | 11 +- .../typeorm-seeds/workspace/people.ts | 6 +- .../typeorm-seeds/workspace/pipeline-step.ts | 47 --- .../database/typeorm-seeds/workspace/views.ts | 263 ----------------- .../workspace/workspaceMember.ts | 6 +- .../demo-objects-prefill-data/company.ts | 2 +- .../demo-objects-prefill-data.ts | 34 +-- .../demo-objects-prefill-data/opportunity.ts | 24 +- .../demo-objects-prefill-data/person.ts | 2 +- .../pipeline-step.ts | 41 --- .../demo-objects-prefill-data/view.ts | 269 ----------------- .../standard-objects-prefill-data.ts | 14 +- .../view-company-fields.ts | 84 ++++++ .../view-opportunity-fields.ts | 61 ++++ .../view-person-fields.ts | 104 +++++++ .../standard-objects-prefill-data/view.ts | 238 +++------------ .../constants/standard-field-ids.ts | 9 +- .../constants/standard-object-ids.ts | 1 - .../standard-objects/index.ts | 2 - .../opportunity.object-metadata.ts | 13 - .../pipeline-step.object-metadata.ts | 66 ----- .../standard-objects/view.object-metadata.ts | 8 + 36 files changed, 425 insertions(+), 1487 deletions(-) delete mode 100644 packages/twenty-server/src/database/typeorm-seeds/workspace/pipeline-step.ts delete mode 100644 packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/pipeline-step.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts delete mode 100644 packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts diff --git a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx index 9aee44c73728..a5594f7edf5b 100644 --- a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx +++ b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx @@ -35,7 +35,7 @@ Complete step three and four with : ## Production docker containers -Prebuilt images for both Postgres, frontend, and back-end can be found on [docker hub](https://hub.docker.com/r/twentycrm/). Note that the Postgres container will not persist data if your server is not configured to be stateful (e.g. Heroku). You probably want to configure a special stateful resource for the database. +Prebuilt images for both Postgres, frontend, and back-end can be found on [docker hub](https://hub.docker.com/r/twentycrm/). Note that the Postgres container will not persist data if your server is not configured to be stateful (for example Heroku). You probably want to configure a special stateful resource for the database. ## Environment Variables diff --git a/packages/twenty-front/nyc.config.cjs b/packages/twenty-front/nyc.config.cjs index bf92d9cde36d..0ee161423bb3 100644 --- a/packages/twenty-front/nyc.config.cjs +++ b/packages/twenty-front/nyc.config.cjs @@ -6,7 +6,7 @@ const globalCoverage = { }; const modulesCoverage = { - statements: 75, + statements: 70, lines: 75, functions: 70, include: ['src/modules/**/*'], diff --git a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts index 13591a07d002..10602b7e3020 100644 --- a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts @@ -15,7 +15,6 @@ export enum CoreObjectNameSingular { MessageThread = 'messageThread', Opportunity = 'opportunity', Person = 'person', - PipelineStep = 'pipelineStep', View = 'view', ViewField = 'viewField', ViewFilter = 'viewFilter', diff --git a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx index 4ca474d31f13..c71702c94238 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx @@ -150,7 +150,6 @@ personId pointOfContactId updatedAt companyId -pipelineStepId probability closeDate amount diff --git a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx index 7473906175f9..a1d34e9b5b75 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx @@ -78,7 +78,6 @@ personId pointOfContactId updatedAt companyId -pipelineStepId probability closeDate amount @@ -106,7 +105,6 @@ personId pointOfContactId updatedAt companyId -pipelineStepId probability closeDate amount diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts index f14d5607e409..e9549cf70904 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts @@ -401,23 +401,6 @@ export const getObjectMetadataItemsMock = () => { fromRelationMetadata: null, toRelationMetadata: null, }, - { - __typename: 'field', - id: '20202020-0a2e-4676-8011-3fdb2c30d7f8', - type: 'UUID', - name: 'pipelineStepId', - label: 'Pipeline Step ID (foreign key)', - description: 'Foreign key for pipeline step', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, { __typename: 'field', id: '20202020-3b9c-4e58-a3d2-c617d3b596b1', @@ -436,32 +419,63 @@ export const getObjectMetadataItemsMock = () => { toRelationMetadata: null, }, { - __typename: 'field', - id: '20202020-0a2e-4676-8011-3fdb2c30c258', - type: 'RELATION', - name: 'pipelineStep', - label: 'Pipeline Step', - description: 'Opportunity pipeline step', - icon: 'IconKanban', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'dfb44970-3e09-49f2-9f1d-51c8c451b8f5', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-1029-4661-9e91-83bad932bdcd', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'pipelineStep', - namePlural: 'pipelineSteps', + __typename: 'fieldEdge', + node: { + __typename: 'field', + id: '20202020-46cc-42bb-90d5-c724921a012d', + type: 'SELECT', + name: 'stage', + label: 'Stage', + description: 'Opportunity stage', + icon: 'IconProgressCheck', + isCustom: false, + isActive: true, + isSystem: false, + isNullable: false, + createdAt: '2024-03-21T16:48:40.384Z', + updatedAt: '2024-03-21T16:48:40.384Z', + defaultValue: { + value: 'NEW', }, - fromFieldMetadataId: '20202020-22c4-443a-b114-43c97dda5867', + options: [ + { + id: '20202020-aa3b-4c0b-bd90-9d071e3b9bf2', + color: 'red', + label: 'New', + value: 'NEW', + position: 0, + }, + { + id: '20202020-8f9b-4bc3-b0a0-ce6a5085c1cf', + color: 'purple', + label: 'Screening', + value: 'SCREENING', + position: 1, + }, + { + id: '20202020-9797-448d-81e4-49b055a1d19b', + color: 'sky', + label: 'Meeting', + value: 'MEETING', + position: 2, + }, + { + id: '20202020-d542-479c-bc88-3c6d4ee78d09', + color: 'turquoise', + label: 'Proposal', + value: 'PROPOSAL', + position: 3, + }, + { + id: '20202020-b69a-4c9c-ac16-adcba0ec972d', + color: 'yellow', + label: 'Customer', + value: 'CUSTOMER', + position: 4, + }, + ], + fromRelationMetadata: null, + toRelationMetadata: null, }, }, { @@ -3537,155 +3551,6 @@ export const getObjectMetadataItemsMock = () => { }, ], }, - { - __typename: 'object', - id: '20202020-1029-4661-9e91-83bad932bdcd', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'pipelineStep', - namePlural: 'pipelineSteps', - labelSingular: 'Pipeline Step', - labelPlural: 'Pipeline Steps', - description: 'A pipeline step', - icon: 'IconLayoutKanban', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-f294-430e-b800-3a411fc05ad3', - type: 'TEXT', - name: 'name', - label: 'Name', - description: 'Pipeline Step name', - icon: 'IconCurrencyDollar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-039a-4fbd-b4c1-66dfa9e4bd3f', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-816f-4861-9b36-4a2f8ae2791c', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-22c4-443a-b114-43c97dda5867', - type: 'RELATION', - name: 'opportunities', - label: 'Opportunities', - description: 'Opportunities linked to the step.', - icon: 'IconTargetArrow', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'dfb44970-3e09-49f2-9f1d-51c8c451b8f5', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-cae9-4ff4-9579-f7d9fe44c937', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - }, - toFieldMetadataId: '20202020-0a2e-4676-8011-3fdb2c30c258', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-6296-4cab-aafb-121ef5822b13', - type: 'NUMBER', - name: 'position', - label: 'Position', - description: 'Pipeline Step position', - icon: 'IconHierarchy2', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5b93-4b28-8c45-7988ea68f91b', - type: 'TEXT', - name: 'color', - label: 'Color', - description: 'Pipeline Step color', - icon: 'IconColorSwatch', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2d73-4829-b774-522c2f5627d7', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.337Z', - updatedAt: '2023-11-30T11:13:15.337Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, ]; // Todo fix typing here (the backend is not in sync with the frontend) diff --git a/packages/twenty-front/src/modules/object-record/hooks/__mocks__/useFindManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/__mocks__/useFindManyRecords.ts index 84eb553d97e9..7a756cac76ef 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__mocks__/useFindManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/__mocks__/useFindManyRecords.ts @@ -26,7 +26,7 @@ export const query = gql` pointOfContactId updatedAt companyId - pipelineStepId + stage probability closeDate amount { @@ -52,7 +52,7 @@ export const query = gql` pointOfContactId updatedAt companyId - pipelineStepId + stage probability closeDate amount { diff --git a/packages/twenty-front/src/modules/object-record/utils/filterAvailableTableColumns.ts b/packages/twenty-front/src/modules/object-record/utils/filterAvailableTableColumns.ts index 176ccbad2867..bb7cc3578b3d 100644 --- a/packages/twenty-front/src/modules/object-record/utils/filterAvailableTableColumns.ts +++ b/packages/twenty-front/src/modules/object-record/utils/filterAvailableTableColumns.ts @@ -16,12 +16,5 @@ export const filterAvailableTableColumns = ( return false; } - if ( - isFieldRelation(columnDefinition) && - columnDefinition.metadata?.fieldName === 'pipelineStep' - ) { - return false; - } - return true; }; diff --git a/packages/twenty-front/src/modules/search/hooks/__mocks__/useFilteredSearchEntityQuery.ts b/packages/twenty-front/src/modules/search/hooks/__mocks__/useFilteredSearchEntityQuery.ts index 39201e66a8fc..cb1daf98147c 100644 --- a/packages/twenty-front/src/modules/search/hooks/__mocks__/useFilteredSearchEntityQuery.ts +++ b/packages/twenty-front/src/modules/search/hooks/__mocks__/useFilteredSearchEntityQuery.ts @@ -24,7 +24,7 @@ export const query = gql` pointOfContactId updatedAt companyId - pipelineStepId + stage probability closeDate amount { @@ -49,7 +49,7 @@ export const query = gql` pointOfContactId updatedAt companyId - pipelineStepId + stage probability closeDate amount { diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockCompanies.ts b/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockCompanies.ts index 1dac5f635214..7c0e709187f4 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockCompanies.ts +++ b/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockCompanies.ts @@ -401,8 +401,8 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [ __typename: 'Opportunity', id: '53f66647-0543-4cc2-9f96-95cc699960f2', probability: '0.5', - pipelineStepId: 'd8361722-03fb-4e65-bd4f-ec9e52e5ec0a', pointOfContactId: '93c72d2e-f517-42fd-80ae-14173b3b70ae', + stage: 'NEW', amount: { __typename: 'Currency', amountMicros: 2000000, @@ -609,7 +609,7 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [ __typename: 'Opportunity', id: '81ab695d-2f89-406f-90ea-180f433b2445', probability: '0.5', - pipelineStepId: '30b14887-d592-427d-bd97-6e670158db02', + stage: 'NEW', pointOfContactId: '9b324a88-6784-4449-afdf-dc62cb8702f2', amount: { __typename: 'Currency', @@ -629,7 +629,7 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [ __typename: 'Opportunity', id: '9b059852-35b1-4045-9cde-42f715148954', probability: '0.5', - pipelineStepId: '30b14887-d592-427d-bd97-6e670158db02', + stage: 'NEW', pointOfContactId: '98406e26-80f1-4dff-b570-a74942528de3', amount: { __typename: 'Currency', @@ -1157,7 +1157,7 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [ __typename: 'Opportunity', id: '7c887ee3-be10-412b-a663-16bd3c2228e1', probability: '0.5', - pipelineStepId: '6edf4ead-006a-46e1-9c6d-228f1d0143c9', + stage: 'NEW', pointOfContactId: '86083141-1c0e-494c-a1b6-85b1c6fefaa5', amount: { __typename: 'Currency', diff --git a/packages/twenty-front/src/testing/mock-data/metadata.ts b/packages/twenty-front/src/testing/mock-data/metadata.ts index 768608ccfcd3..d6c6464f4178 100644 --- a/packages/twenty-front/src/testing/mock-data/metadata.ts +++ b/packages/twenty-front/src/testing/mock-data/metadata.ts @@ -1184,220 +1184,6 @@ export const mockedCompaniesMetadata = { }, } as ObjectEdge; -export const mockedPipelineStepsMetadata = { - __typename: 'objectEdge', - node: { - __typename: 'object', - id: 'afa12866-0de4-4f97-97fa-cd8a7c953037', - dataSourceId: 'cabbcaa6-05d6-41f4-920f-9144172a4f08', - nameSingular: 'pipelineStep', - namePlural: 'pipelineSteps', - labelSingular: 'Pipeline Step', - labelPlural: 'Pipeline Steps', - description: 'A pipeline step', - icon: 'IconLayoutKanban', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - labelIdentifierFieldMetadataId: null, - imageIdentifierFieldMetadataId: null, - fields: { - __typename: 'ObjectFieldsConnection', - edges: [ - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '202efca6-9820-4e4a-9a27-f362dc5b46ed', - type: FieldMetadataType.Uuid, - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - type: FieldMetadataType.Uuid, - }, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: 'c9b9d516-10d2-4eca-94ce-a872547f429f', - type: FieldMetadataType.Text, - name: 'color', - label: 'Color', - description: 'Pipeline Step color', - icon: 'IconColorSwatch', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - value: '', - }, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '7928241f-6fe9-4ab2-84c6-7e84c5bea05f', - type: FieldMetadataType.DateTime, - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - type: 'now', - }, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: 'ad3e919f-4258-4e21-8caf-bf122f17ca5c', - type: FieldMetadataType.Relation, - name: 'opportunities', - label: 'Opportunities', - description: 'Opportunities linked to the step.', - icon: 'IconTargetArrow', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: { - __typename: 'relation', - id: '7b0474c4-d82d-4c1d-96de-c6728b53339a', - relationType: RelationMetadataType.OneToMany, - toObjectMetadata: { - __typename: 'object', - id: '941ad274-2d26-4e90-94d9-5e446aa5b91e', - dataSourceId: 'cabbcaa6-05d6-41f4-920f-9144172a4f08', - nameSingular: 'opportunity', - namePlural: 'opportunities', - isSystem: true, - }, - toFieldMetadataId: '4756a816-8a18-433a-9414-c756db4727e8', - }, - toRelationMetadata: null, - options: [], - defaultValue: null, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: 'c26ba58c-5629-4a6b-ae7f-5c06d3045a9b', - type: FieldMetadataType.DateTime, - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - type: 'now', - }, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '4f383c05-3f9b-433a-8617-20ed3861e490', - type: FieldMetadataType.Text, - name: 'name', - label: 'Name', - description: 'Pipeline Step name', - icon: 'IconCurrencyDollar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - value: '', - }, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '8c712fbc-306f-4534-86c1-caae09b840a2', - type: FieldMetadataType.Number, - name: 'position', - label: 'Position', - description: 'Pipeline Step position', - icon: 'IconHierarchy2', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: { - value: 0, - }, - }, - }, - ], - pageInfo: { - __typename: 'PageInfo', - hasNextPage: false, - hasPreviousPage: false, - startCursor: 'YXJyYXljb25uZWN0aW9uOjA=', - endCursor: 'YXJyYXljb25uZWN0aW9uOjY=', - }, - totalCount: 7, - }, - }, -}; - const mockedCalendarEventsMetadata = { __typename: 'objectEdge', node: { @@ -4837,63 +4623,6 @@ export const mockedOpportunitiesMetadata = { defaultValue: null, }, }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '480e430d-ec7b-4297-93fd-0c6463b9fad3', - type: FieldMetadataType.Uuid, - name: 'pipelineStepId', - label: 'Pipeline Step id (foreign key)', - description: 'Opportunity pipeline step id foreign key', - icon: 'IconKanban', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - toRelationMetadata: null, - options: [], - defaultValue: null, - }, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '4756a816-8a18-433a-9414-c756db4727e8', - type: FieldMetadataType.Relation, - name: 'pipelineStep', - label: 'Pipeline Step', - description: 'Opportunity pipeline step', - icon: 'IconKanban', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-12-15T15:29:39.070Z', - updatedAt: '2023-12-15T15:29:39.070Z', - fromRelationMetadata: null, - options: [], - toRelationMetadata: { - __typename: 'relation', - id: '7b0474c4-d82d-4c1d-96de-c6728b53339a', - relationType: RelationMetadataType.OneToMany, - fromObjectMetadata: { - __typename: 'object', - id: 'afa12866-0de4-4f97-97fa-cd8a7c953037', - dataSourceId: 'cabbcaa6-05d6-41f4-920f-9144172a4f08', - nameSingular: 'pipelineStep', - namePlural: 'pipelineSteps', - isSystem: true, - }, - fromFieldMetadataId: 'ad3e919f-4258-4e21-8caf-bf122f17ca5c', - }, - defaultValue: null, - }, - }, { __typename: 'fieldEdge', node: { @@ -7501,7 +7230,6 @@ export const mockedObjectMetadataItems = { mockedWebhooksMetadata, mockedPeopleMetadata, mockedCompaniesMetadata, - mockedPipelineStepsMetadata, mockedActivityTargetsMetadata, mockedActivitiesMetadata, mockedFavoritesMetadata, diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index 0a8ec622e022..8e9a7c7ca147 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -1,12 +1,10 @@ import { Command, CommandRunner } from 'nest-commander'; -import { DataSource } from 'typeorm'; +import { DataSource, EntityManager } from 'typeorm'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { seedCompanies } from 'src/database/typeorm-seeds/workspace/companies'; -import { seedViews } from 'src/database/typeorm-seeds/workspace/views'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { seedOpportunity } from 'src/database/typeorm-seeds/workspace/opportunity'; -import { seedPipelineStep } from 'src/database/typeorm-seeds/workspace/pipeline-step'; import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/workspaceMember'; import { seedPeople } from 'src/database/typeorm-seeds/workspace/people'; import { seedCoreSchema } from 'src/database/typeorm-seeds/core'; @@ -19,6 +17,7 @@ import { SeedAppleWorkspaceId, SeedTwentyWorkspaceId, } from 'src/database/typeorm-seeds/core/workspaces'; +import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; // TODO: implement dry-run @Command({ @@ -95,10 +94,10 @@ export class DataSeedWorkspaceCommand extends CommandRunner { const objectMetadata = await this.objectMetadataService.findManyWithinWorkspace(workspaceId); const objectMetadataMap = objectMetadata.reduce((acc, object) => { - acc[object.nameSingular] = { + acc[object.standardId ?? ''] = { id: object.id, fields: object.fields.reduce((acc, field) => { - acc[field.name] = field.id; + acc[field.standardId ?? ''] = field.id; return acc; }, {}), @@ -107,24 +106,24 @@ export class DataSeedWorkspaceCommand extends CommandRunner { return acc; }, {}); - await seedCompanies(workspaceDataSource, dataSourceMetadata.schema); - await seedPeople(workspaceDataSource, dataSourceMetadata.schema); - await seedPipelineStep(workspaceDataSource, dataSourceMetadata.schema); - await seedOpportunity(workspaceDataSource, dataSourceMetadata.schema); - await seedCalendarEvents( - workspaceDataSource, - dataSourceMetadata.schema, - ); - - await seedViews( - workspaceDataSource, - dataSourceMetadata.schema, - objectMetadataMap, - ); - await seedWorkspaceMember( - workspaceDataSource, - dataSourceMetadata.schema, - workspaceId, + await workspaceDataSource.transaction( + async (entityManager: EntityManager) => { + await seedCompanies(entityManager, dataSourceMetadata.schema); + await seedPeople(entityManager, dataSourceMetadata.schema); + await seedOpportunity(entityManager, dataSourceMetadata.schema); + await seedCalendarEvents(entityManager, dataSourceMetadata.schema); + await seedWorkspaceMember( + entityManager, + dataSourceMetadata.schema, + workspaceId, + ); + + await viewPrefillData( + entityManager, + dataSourceMetadata.schema, + objectMetadataMap, + ); + }, ); } catch (error) { console.error(error); diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts index 8f2f23db0fa9..cd643a6c8eb3 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts @@ -1,12 +1,12 @@ -import { DataSource } from 'typeorm'; +import { EntityManager } from 'typeorm'; const tableName = 'calendarEvent'; export const seedCalendarEvents = async ( - workspaceDataSource: DataSource, + entityManager: EntityManager, schemaName: string, ) => { - await workspaceDataSource + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.${tableName}`, [ diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/companies.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/companies.ts index f7f3e2011884..b9e83a2305cf 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/companies.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/companies.ts @@ -1,12 +1,12 @@ -import { DataSource } from 'typeorm'; +import { EntityManager } from 'typeorm'; const tableName = 'company'; export const seedCompanies = async ( - workspaceDataSource: DataSource, + entityManager: EntityManager, schemaName: string, ) => { - await workspaceDataSource + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.${tableName}`, [ diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/opportunity.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/opportunity.ts index 49f76de5ea30..a7e799a424c7 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/opportunity.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/opportunity.ts @@ -1,12 +1,12 @@ -import { DataSource } from 'typeorm'; +import { EntityManager } from 'typeorm'; const tableName = 'opportunity'; export const seedOpportunity = async ( - workspaceDataSource: DataSource, + entityManager: EntityManager, schemaName: string, ) => { - await workspaceDataSource + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.${tableName}`, [ @@ -18,7 +18,6 @@ export const seedOpportunity = async ( 'probability', 'stage', 'position', - 'pipelineStepId', 'pointOfContactId', 'companyId', ]) @@ -33,7 +32,6 @@ export const seedOpportunity = async ( probability: 0.5, stage: 'NEW', position: 1, - pipelineStepId: '6edf4ead-006a-46e1-9c6d-228f1d0143c9', pointOfContactId: '86083141-1c0e-494c-a1b6-85b1c6fefaa5', companyId: 'fe256b39-3ec3-4fe3-8997-b76aa0bfa408', }, @@ -46,7 +44,6 @@ export const seedOpportunity = async ( probability: 0.5, stage: 'MEETING', position: 2, - pipelineStepId: 'd8361722-03fb-4e65-bd4f-ec9e52e5ec0a', pointOfContactId: '93c72d2e-f517-42fd-80ae-14173b3b70ae', companyId: '118995f3-5d81-46d6-bf83-f7fd33ea6102', }, @@ -59,7 +56,6 @@ export const seedOpportunity = async ( probability: 0.5, stage: 'PROPOSAL', position: 3, - pipelineStepId: '30b14887-d592-427d-bd97-6e670158db02', pointOfContactId: '9b324a88-6784-4449-afdf-dc62cb8702f2', companyId: '460b6fb1-ed89-413a-b31a-962986e67bb4', }, @@ -72,7 +68,6 @@ export const seedOpportunity = async ( probability: 0.5, stage: 'PROPOSAL', position: 4, - pipelineStepId: '30b14887-d592-427d-bd97-6e670158db02', pointOfContactId: '98406e26-80f1-4dff-b570-a74942528de3', companyId: '460b6fb1-ed89-413a-b31a-962986e67bb4', }, diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/people.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/people.ts index 690ccd396fbe..74354119f0da 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/people.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/people.ts @@ -1,12 +1,12 @@ -import { DataSource } from 'typeorm'; +import { EntityManager } from 'typeorm'; const tableName = 'person'; export const seedPeople = async ( - workspaceDataSource: DataSource, + entityManager: EntityManager, schemaName: string, ) => { - await workspaceDataSource + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.${tableName}`, [ diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/pipeline-step.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/pipeline-step.ts deleted file mode 100644 index 4a9b25e4808d..000000000000 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/pipeline-step.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { DataSource } from 'typeorm'; - -const tableName = 'pipelineStep'; - -export const seedPipelineStep = async ( - workspaceDataSource: DataSource, - schemaName: string, -) => { - await workspaceDataSource - .createQueryBuilder() - .insert() - .into(`${schemaName}.${tableName}`, ['id', 'name', 'color', 'position']) - .orIgnore() - .values([ - { - id: '6edf4ead-006a-46e1-9c6d-228f1d0143c9', - name: 'NEW', - color: 'red', - position: 0, - }, - { - id: 'd8361722-03fb-4e65-bd4f-ec9e52e5ec0a', - name: 'SCREENING', - color: 'purple', - position: 1, - }, - { - id: '30b14887-d592-427d-bd97-6e670158db02', - name: 'MEETING', - color: 'sky', - position: 2, - }, - { - id: 'db5a6648-d80d-4020-af64-4817ab4a12e8', - name: 'PROPOSAL', - color: 'turquoise', - position: 3, - }, - { - id: 'bea8bb7b-5467-48a6-9a8a-a8fa500123fe', - name: 'CUSTOMER', - color: 'yellow', - position: 4, - }, - ]) - .execute(); -}; diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts deleted file mode 100644 index f3846bb2d500..000000000000 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/views.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { DataSource } from 'typeorm'; - -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; - -export const seedViews = async ( - workspaceDataSource: DataSource, - schemaName: string, - objectMetadataMap: Record, -) => { - const createdViews = await workspaceDataSource - .createQueryBuilder() - .insert() - .into(`${schemaName}.view`, [ - 'name', - 'objectMetadataId', - 'type', - 'key', - 'position', - 'icon', - ]) - .values([ - { - name: 'All Companies', - objectMetadataId: objectMetadataMap['company'].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconBuildingSkyscraper', - }, - { - name: 'All People', - objectMetadataId: objectMetadataMap['person'].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconUser', - }, - { - name: 'By Stage', - objectMetadataId: objectMetadataMap['opportunity'].id, - type: 'kanban', - key: null, - position: 0, - icon: 'IconLayoutKanban', - }, - { - name: 'All Opportunities', - objectMetadataId: objectMetadataMap['opportunity'].id, - type: 'table', - key: 'INDEX', - position: 1, - icon: 'IconTargetArrow', - }, - ]) - .returning('*') - .execute(); - - const viewIdMap = createdViews.raw.reduce((acc, view) => { - acc[`${view.name}`] = view.id; - - return acc; - }, {}); - - await workspaceDataSource - .createQueryBuilder() - .insert() - .into(`${schemaName}.viewField`, [ - 'fieldMetadataId', - 'viewId', - 'position', - 'isVisible', - 'size', - ]) - .values([ - { - fieldMetadataId: objectMetadataMap['company'].fields['name'], - viewId: viewIdMap['All Companies'], - position: 0, - isVisible: true, - size: 180, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['domainName'], - viewId: viewIdMap['All Companies'], - position: 1, - isVisible: true, - size: 100, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['accountOwner'], - viewId: viewIdMap['All Companies'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['createdAt'], - viewId: viewIdMap['All Companies'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['employees'], - viewId: viewIdMap['All Companies'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['linkedinLink'], - viewId: viewIdMap['All Companies'], - position: 5, - isVisible: true, - size: 170, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['address'], - viewId: viewIdMap['All Companies'], - position: 6, - isVisible: true, - size: 170, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['name'], - viewId: viewIdMap['All People'], - position: 0, - isVisible: true, - size: 210, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['email'], - viewId: viewIdMap['All People'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['company'], - viewId: viewIdMap['All People'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['phone'], - viewId: viewIdMap['All People'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['createdAt'], - viewId: viewIdMap['All People'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['city'], - viewId: viewIdMap['All People'], - position: 5, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['jobTitle'], - viewId: viewIdMap['All People'], - position: 6, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['linkedinLink'], - viewId: viewIdMap['All People'], - position: 7, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['xLink'], - viewId: viewIdMap['All People'], - position: 8, - isVisible: true, - size: 150, - }, - - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['All Opportunities'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['All Opportunities'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['All Opportunities'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['All Opportunities'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['All Opportunities'], - position: 4, - isVisible: true, - size: 150, - }, - - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['By Stage'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['By Stage'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['By Stage'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['By Stage'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['By Stage'], - position: 4, - isVisible: true, - size: 150, - }, - ]) - .execute(); -}; diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts index 7d686c130567..342bd56d3839 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/workspaceMember.ts @@ -1,4 +1,4 @@ -import { DataSource } from 'typeorm'; +import { EntityManager } from 'typeorm'; import { SeedUserIds } from 'src/database/typeorm-seeds/core/users'; import { @@ -26,7 +26,7 @@ type WorkspaceMembers = Pick< }; export const seedWorkspaceMember = async ( - workspaceDataSource: DataSource, + entityManager: EntityManager, schemaName: string, workspaceId: string, ) => { @@ -77,7 +77,7 @@ export const seedWorkspaceMember = async ( }, ]; } - await workspaceDataSource + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.${tableName}`, [ diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/company.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/company.ts index a7b724f612a9..f1df5a2ddc04 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/company.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/company.ts @@ -2,7 +2,7 @@ import { EntityManager } from 'typeorm'; import companiesDemo from './companies-demo.json'; -export const companyPrefillData = async ( +export const companyPrefillDemoData = async ( entityManager: EntityManager, schemaName: string, ) => { diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts index 6ff99007198b..1b4b4ec8b908 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/demo-objects-prefill-data.ts @@ -1,12 +1,11 @@ import { DataSource, EntityManager } from 'typeorm'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { viewPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/view'; -import { companyPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/company'; -import { personPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/person'; -import { pipelineStepPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/pipeline-step'; import { workspaceMemberPrefillData } from 'src/engine/workspace-manager/demo-objects-prefill-data/workspace-member'; -import { seedDemoOpportunity } from 'src/engine/workspace-manager/demo-objects-prefill-data/opportunity'; +import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; +import { companyPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/company'; +import { personPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/person'; +import { opportunityPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/opportunity'; export const demoObjectsPrefillData = async ( workspaceDataSource: DataSource, @@ -14,10 +13,10 @@ export const demoObjectsPrefillData = async ( objectMetadata: ObjectMetadataEntity[], ) => { const objectMetadataMap = objectMetadata.reduce((acc, object) => { - acc[object.nameSingular] = { + acc[object.standardId ?? ''] = { id: object.id, fields: object.fields.reduce((acc, field) => { - acc[field.name] = field.id; + acc[field.standardId ?? ''] = field.id; return acc; }, {}), @@ -26,18 +25,15 @@ export const demoObjectsPrefillData = async ( return acc; }, {}); - // TODO: udnerstand why only with this createQueryRunner transaction below works - const queryRunner = workspaceDataSource.createQueryRunner(); + await workspaceDataSource.transaction( + async (entityManager: EntityManager) => { + await companyPrefillDemoData(entityManager, schemaName); + await personPrefillDemoData(entityManager, schemaName); + await opportunityPrefillDemoData(entityManager, schemaName); - await queryRunner.connect(); + await viewPrefillData(entityManager, schemaName, objectMetadataMap); - workspaceDataSource.transaction(async (entityManager: EntityManager) => { - await companyPrefillData(entityManager, schemaName); - await personPrefillData(entityManager, schemaName); - await viewPrefillData(entityManager, schemaName, objectMetadataMap); - await pipelineStepPrefillData(entityManager, schemaName); - await seedDemoOpportunity(entityManager, schemaName); - - await workspaceMemberPrefillData(entityManager, schemaName); - }); + await workspaceMemberPrefillData(entityManager, schemaName); + }, + ); }; diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/opportunity.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/opportunity.ts index cd5f40e33d98..e2d53abfb311 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/opportunity.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/opportunity.ts @@ -9,9 +9,6 @@ const getRandomProbability = () => { return firstDigit / 10; }; -const getRandomPipelineStepId = (pipelineStepIds: { id: string }[]) => - pipelineStepIds[Math.floor(Math.random() * pipelineStepIds.length)].id; - const getRandomStage = () => { const stages = ['NEW', 'SCREENING', 'MEETING', 'PROPOSAL', 'CUSTOMER']; @@ -24,14 +21,7 @@ const generateRandomAmountMicros = () => { return firstDigit * 10000000000; }; -// Function to generate the array of opportunities -// companiesWithPeople - selecting from the db companies and 1 person related to the company.id to use companyId, pointOfContactId and personId -// pipelineStepIds - selecting from the db pipeline, getting random id from selected to use as pipelineStepId - -const generateOpportunities = ( - companies, - pipelineStepIds: { id: string }[], -) => { +const generateOpportunities = (companies) => { return companies.map((company) => ({ id: v4(), amountAmountMicros: generateRandomAmountMicros(), @@ -39,13 +29,12 @@ const generateOpportunities = ( closeDate: new Date(), stage: getRandomStage(), probability: getRandomProbability(), - pipelineStepId: getRandomPipelineStepId(pipelineStepIds), pointOfContactId: company.personId, companyId: company.id, })); }; -export const seedDemoOpportunity = async ( +export const opportunityPrefillDemoData = async ( entityManager: EntityManager, schemaName: string, ) => { @@ -55,14 +44,8 @@ export const seedDemoOpportunity = async ( LEFT JOIN ${schemaName}.person ON company.id = "person"."companyId" LIMIT 50`, ); - const pipelineStepIds = await entityManager?.query( - `SELECT id FROM ${schemaName}."pipelineStep"`, - ); - const opportunities = generateOpportunities( - companiesWithPeople, - pipelineStepIds, - ); + const opportunities = generateOpportunities(companiesWithPeople); await entityManager .createQueryBuilder() @@ -74,7 +57,6 @@ export const seedDemoOpportunity = async ( 'closeDate', 'stage', 'probability', - 'pipelineStepId', 'pointOfContactId', 'companyId', 'position', diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/person.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/person.ts index 9edd9639d290..48df7d4b8004 100644 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/person.ts +++ b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/person.ts @@ -2,7 +2,7 @@ import { EntityManager } from 'typeorm'; import peopleDemo from './people-demo.json'; -export const personPrefillData = async ( +export const personPrefillDemoData = async ( entityManager: EntityManager, schemaName: string, ) => { diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/pipeline-step.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/pipeline-step.ts deleted file mode 100644 index bbf86f127197..000000000000 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/pipeline-step.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { EntityManager } from 'typeorm'; - -export const pipelineStepPrefillData = async ( - entityManager: EntityManager, - schemaName: string, -) => { - await entityManager - .createQueryBuilder() - .insert() - .into(`${schemaName}.pipelineStep`, ['name', 'color', 'position']) - .orIgnore() - .values([ - { - name: 'NEW', - color: 'red', - position: 0, - }, - { - name: 'SCREENING', - color: 'purple', - position: 1, - }, - { - name: 'MEETING', - color: 'sky', - position: 2, - }, - { - name: 'PROPOSAL', - color: 'turquoise', - position: 3, - }, - { - name: 'CUSTOMER', - color: 'yellow', - position: 4, - }, - ]) - .returning('*') - .execute(); -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts b/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts deleted file mode 100644 index e51867aa6ff8..000000000000 --- a/packages/twenty-server/src/engine/workspace-manager/demo-objects-prefill-data/view.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { EntityManager } from 'typeorm'; - -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; - -export const viewPrefillData = async ( - entityManager: EntityManager, - schemaName: string, - objectMetadataMap: Record, -) => { - // Creating views - const createdViews = await entityManager - .createQueryBuilder() - .insert() - .into(`${schemaName}.view`, [ - 'name', - 'objectMetadataId', - 'type', - 'key', - 'position', - 'icon', - ]) - .orIgnore() - .values([ - { - name: 'All Companies', - objectMetadataId: objectMetadataMap['company'].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconBuildingSkyscraper', - }, - { - name: 'All People', - objectMetadataId: objectMetadataMap['person'].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconUser', - }, - { - name: 'By Stage', - objectMetadataId: objectMetadataMap['opportunity'].id, - type: 'kanban', - key: null, - position: 0, - icon: 'IconLayoutKanban', - }, - { - name: 'All Opportunities', - objectMetadataId: objectMetadataMap['opportunity'].id, - type: 'table', - key: 'INDEX', - position: 1, - icon: 'IconTargetArrow', - }, - ]) - .returning('*') - .execute(); - - const viewIdMap = createdViews.raw.reduce((acc, view) => { - acc[view.name] = view.id; - - return acc; - }, {}); - - // Creating viewFields - await entityManager - .createQueryBuilder() - .insert() - .into(`${schemaName}.viewField`, [ - 'fieldMetadataId', - 'viewId', - 'position', - 'isVisible', - 'size', - ]) - .orIgnore() - .values([ - // Company - { - fieldMetadataId: objectMetadataMap['company'].fields['name'], - viewId: viewIdMap['All Companies'], - position: 0, - isVisible: true, - size: 180, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['domainName'], - viewId: viewIdMap['All Companies'], - position: 1, - isVisible: true, - size: 100, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['accountOwner'], - viewId: viewIdMap['All Companies'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['createdAt'], - viewId: viewIdMap['All Companies'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['employees'], - viewId: viewIdMap['All Companies'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['linkedinLink'], - viewId: viewIdMap['All Companies'], - position: 5, - isVisible: true, - size: 170, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['address'], - viewId: viewIdMap['All Companies'], - position: 6, - isVisible: true, - size: 170, - }, - // Person - { - fieldMetadataId: objectMetadataMap['person'].fields['name'], - viewId: viewIdMap['All People'], - position: 0, - isVisible: true, - size: 210, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['email'], - viewId: viewIdMap['All People'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['company'], - viewId: viewIdMap['All People'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['phone'], - viewId: viewIdMap['All People'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['createdAt'], - viewId: viewIdMap['All People'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['city'], - viewId: viewIdMap['All People'], - position: 5, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['jobTitle'], - viewId: viewIdMap['All People'], - position: 6, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['linkedinLink'], - viewId: viewIdMap['All People'], - position: 7, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['xLink'], - viewId: viewIdMap['All People'], - position: 8, - isVisible: true, - size: 150, - }, - // Opportunity - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['All Opportunities'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['All Opportunities'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['All Opportunities'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['All Opportunities'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['All Opportunities'], - position: 4, - isVisible: true, - size: 150, - }, - - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['By Stage'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['By Stage'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['By Stage'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['By Stage'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['By Stage'], - position: 4, - isVisible: true, - size: 150, - }, - ]) - .execute(); -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts index 5b63225badf3..4e404878f9f4 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data.ts @@ -4,7 +4,6 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; import { companyPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/company'; import { personPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/person'; -import { pipelineStepPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/pipeline-step'; export const standardObjectsPrefillData = async ( workspaceDataSource: DataSource, @@ -12,10 +11,18 @@ export const standardObjectsPrefillData = async ( objectMetadata: ObjectMetadataEntity[], ) => { const objectMetadataMap = objectMetadata.reduce((acc, object) => { - acc[object.nameSingular] = { + if (!object.standardId) { + throw new Error('Standard Id is not set for object: ${object.name}'); + } + + acc[object.standardId] = { id: object.id, fields: object.fields.reduce((acc, field) => { - acc[field.name] = field.id; + if (!field.standardId) { + throw new Error('Standard Id is not set for field: ${field.name}'); + } + + acc[field.standardId] = field.id; return acc; }, {}), @@ -28,6 +35,5 @@ export const standardObjectsPrefillData = async ( await companyPrefillData(entityManager, schemaName); await personPrefillData(entityManager, schemaName); await viewPrefillData(entityManager, schemaName, objectMetadataMap); - await pipelineStepPrefillData(entityManager, schemaName); }); }; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts new file mode 100644 index 000000000000..20f5841ba4d3 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts @@ -0,0 +1,84 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + baseObjectStandardFieldIds, + companyStandardFieldIds, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const viewCompanyFields = ( + viewId: string, + objectMetadataMap: Record, +) => { + return [ + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.name + ], + viewId: viewId, + position: 0, + isVisible: true, + size: 180, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.domainName + ], + viewId: viewId, + position: 1, + isVisible: true, + size: 100, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.accountOwner + ], + viewId: viewId, + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + baseObjectStandardFieldIds.createdAt + ], + viewId: viewId, + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.employees + ], + viewId: viewId, + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.linkedinLink + ], + viewId: viewId, + position: 5, + isVisible: true, + size: 170, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.company].fields[ + companyStandardFieldIds.address + ], + viewId: viewId, + position: 6, + isVisible: true, + size: 170, + }, + ]; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts new file mode 100644 index 000000000000..d455e51bdfff --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts @@ -0,0 +1,61 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { opportunityStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const viewOpportunityFields = ( + viewId: string, + objectMetadataMap: Record, +) => { + return [ + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.name + ], + viewId: viewId, + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.amount + ], + viewId: viewId, + position: 1, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.closeDate + ], + viewId: viewId, + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.probability + ], + viewId: viewId, + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.pointOfContact + ], + viewId: viewId, + position: 4, + isVisible: true, + size: 150, + }, + ]; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts new file mode 100644 index 000000000000..19df85dbd9f5 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts @@ -0,0 +1,104 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + baseObjectStandardFieldIds, + personStandardFieldIds, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const viewPersonFields = ( + viewId: string, + objectMetadataMap: Record, +) => { + return [ + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.name + ], + viewId: viewId, + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.email + ], + viewId: viewId, + position: 1, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.company + ], + viewId: viewId, + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.phone + ], + viewId: viewId, + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + baseObjectStandardFieldIds.createdAt + ], + viewId: viewId, + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.city + ], + viewId: viewId, + position: 5, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.jobTitle + ], + viewId: viewId, + position: 6, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.linkedinLink + ], + viewId: viewId, + position: 7, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[standardObjectIds.person].fields[ + personStandardFieldIds.xLink + ], + viewId: viewId, + position: 8, + isVisible: true, + size: 150, + }, + ]; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts index e51867aa6ff8..12941d1fc8a1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts @@ -1,13 +1,17 @@ import { EntityManager } from 'typeorm'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { viewCompanyFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields'; +import { viewPersonFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields'; +import { viewOpportunityFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields'; +import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { opportunityStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; export const viewPrefillData = async ( entityManager: EntityManager, schemaName: string, objectMetadataMap: Record, ) => { - // Creating views const createdViews = await entityManager .createQueryBuilder() .insert() @@ -18,40 +22,47 @@ export const viewPrefillData = async ( 'key', 'position', 'icon', + 'kanbanFieldMetadataId', ]) - .orIgnore() .values([ { name: 'All Companies', - objectMetadataId: objectMetadataMap['company'].id, + objectMetadataId: objectMetadataMap[standardObjectIds.company].id, type: 'table', key: 'INDEX', position: 0, icon: 'IconBuildingSkyscraper', + kanbanFieldMetadataId: '', }, { name: 'All People', - objectMetadataId: objectMetadataMap['person'].id, + objectMetadataId: objectMetadataMap[standardObjectIds.person].id, type: 'table', key: 'INDEX', position: 0, icon: 'IconUser', - }, - { - name: 'By Stage', - objectMetadataId: objectMetadataMap['opportunity'].id, - type: 'kanban', - key: null, - position: 0, - icon: 'IconLayoutKanban', + kanbanFieldMetadataId: '', }, { name: 'All Opportunities', - objectMetadataId: objectMetadataMap['opportunity'].id, + objectMetadataId: objectMetadataMap[standardObjectIds.opportunity].id, type: 'table', key: 'INDEX', - position: 1, + position: 0, icon: 'IconTargetArrow', + kanbanFieldMetadataId: '', + }, + { + name: 'By Stage', + objectMetadataId: objectMetadataMap[standardObjectIds.opportunity].id, + type: 'kanban', + key: null, + position: 1, + icon: 'IconLayoutKanban', + kanbanFieldMetadataId: + objectMetadataMap[standardObjectIds.opportunity].fields[ + opportunityStandardFieldIds.stage + ], }, ]) .returning('*') @@ -63,7 +74,6 @@ export const viewPrefillData = async ( return acc; }, {}); - // Creating viewFields await entityManager .createQueryBuilder() .insert() @@ -74,196 +84,16 @@ export const viewPrefillData = async ( 'isVisible', 'size', ]) - .orIgnore() .values([ - // Company - { - fieldMetadataId: objectMetadataMap['company'].fields['name'], - viewId: viewIdMap['All Companies'], - position: 0, - isVisible: true, - size: 180, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['domainName'], - viewId: viewIdMap['All Companies'], - position: 1, - isVisible: true, - size: 100, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['accountOwner'], - viewId: viewIdMap['All Companies'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['createdAt'], - viewId: viewIdMap['All Companies'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['employees'], - viewId: viewIdMap['All Companies'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['linkedinLink'], - viewId: viewIdMap['All Companies'], - position: 5, - isVisible: true, - size: 170, - }, - { - fieldMetadataId: objectMetadataMap['company'].fields['address'], - viewId: viewIdMap['All Companies'], - position: 6, - isVisible: true, - size: 170, - }, - // Person - { - fieldMetadataId: objectMetadataMap['person'].fields['name'], - viewId: viewIdMap['All People'], - position: 0, - isVisible: true, - size: 210, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['email'], - viewId: viewIdMap['All People'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['company'], - viewId: viewIdMap['All People'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['phone'], - viewId: viewIdMap['All People'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['createdAt'], - viewId: viewIdMap['All People'], - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['city'], - viewId: viewIdMap['All People'], - position: 5, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['jobTitle'], - viewId: viewIdMap['All People'], - position: 6, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['linkedinLink'], - viewId: viewIdMap['All People'], - position: 7, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['person'].fields['xLink'], - viewId: viewIdMap['All People'], - position: 8, - isVisible: true, - size: 150, - }, - // Opportunity - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['All Opportunities'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['All Opportunities'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['All Opportunities'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['All Opportunities'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['All Opportunities'], - position: 4, - isVisible: true, - size: 150, - }, - - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['name'], - viewId: viewIdMap['By Stage'], - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['amount'], - viewId: viewIdMap['By Stage'], - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['closeDate'], - viewId: viewIdMap['By Stage'], - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: objectMetadataMap['opportunity'].fields['probability'], - viewId: viewIdMap['By Stage'], - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap['opportunity'].fields['pointOfContact'], - viewId: viewIdMap['By Stage'], - position: 4, - isVisible: true, - size: 150, - }, + ...viewCompanyFields(viewIdMap['Index Companies'], objectMetadataMap), + ...viewPersonFields(viewIdMap['Index People'], objectMetadataMap), + ...viewOpportunityFields( + viewIdMap['Index Opportunities'], + objectMetadataMap, + ), + ...viewCompanyFields(viewIdMap['All Companies'], objectMetadataMap), + ...viewPersonFields(viewIdMap['All People'], objectMetadataMap), + ...viewOpportunityFields(viewIdMap['By Stage'], objectMetadataMap), ]) .execute(); }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index f3cf6d23c04f..b8a8fbb21056 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -203,7 +203,6 @@ export const opportunityStandardFieldIds = { probability: '20202020-69d4-45f3-9703-690b09fafcf0', stage: '20202020-6f76-477d-8551-28cd65b2b4b9', position: '20202020-806d-493a-bbc6-6313e62958e2', - pipelineStep: '20202020-cc8c-4ae7-8d83-25c3addaec5a', pointOfContact: '20202020-8dfb-42fc-92b6-01afb759ed16', company: '20202020-cbac-457e-b565-adece5fc815f', favorites: '20202020-a1c2-4500-aaae-83ba8a0e827a', @@ -232,13 +231,6 @@ export const personStandardFieldIds = { events: '20202020-a43e-4873-9c23-e522de906ce5', }; -export const pipelineStepStandardFieldIds = { - name: '20202020-e10a-4119-9466-97873e86fa47', - color: '20202020-4a09-4088-90b8-ce1c72730f43', - position: '20202020-44e8-4520-af64-4a3cb37fa0c5', - opportunities: '20202020-0442-482a-867f-6d8fd4145ed1', -}; - export const viewFieldStandardFieldIds = { fieldMetadataId: '20202020-135f-4c5b-b361-15f24870473c', isVisible: '20202020-e966-473c-9c18-f00d3347e0ba', @@ -267,6 +259,7 @@ export const viewStandardFieldIds = { type: '20202020-dd11-4607-9ec7-c57217262a7f', key: '20202020-298e-49fa-9f4a-7b416b110443', icon: '20202020-1f08-4fd9-929b-cbc07f317166', + kanbanFieldMetadataId: '20202020-d09b-4f65-ac42-06a2f20ba0e8', position: '20202020-e9db-4303-b271-e8250c450172', isCompact: '20202020-674e-4314-994d-05754ea7b22b', viewFields: '20202020-542b-4bdc-b177-b63175d48edf', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts index e155df556982..4c9ba5844f1f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts @@ -27,7 +27,6 @@ export const standardObjectIds = { message: '20202020-3f6b-4425-80ab-e468899ab4b2', opportunity: '20202020-9549-49dd-b2b2-883999db8938', person: '20202020-e674-48e5-a542-72570eee7213', - pipelineStep: '20202020-f9a3-45f3-82e2-28952a8b19bf', viewField: '20202020-4d19-4655-95bf-b2a04cf206d4', viewFilter: '20202020-6fb6-4631-aded-b7d67e952ec8', viewSort: '20202020-e46a-47a8-939a-e5d911f83531', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts index dd53ab77b254..b9aaec347c0d 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts @@ -17,7 +17,6 @@ import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-obje import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; -import { PipelineStepObjectMetadata } from 'src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata'; import { ViewFieldObjectMetadata } from 'src/modules/view/standard-objects/view-field.object-metadata'; import { ViewFilterObjectMetadata } from 'src/modules/view/standard-objects/view-filter.object-metadata'; import { ViewSortObjectMetadata } from 'src/modules/view/standard-objects/view-sort.object-metadata'; @@ -40,7 +39,6 @@ export const standardObjectMetadataDefinitions = [ FavoriteObjectMetadata, OpportunityObjectMetadata, PersonObjectMetadata, - PipelineStepObjectMetadata, ViewFieldObjectMetadata, ViewFilterObjectMetadata, ViewSortObjectMetadata, diff --git a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts index 63458e22456e..c10ff0d351c2 100644 --- a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts +++ b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.object-metadata.ts @@ -17,7 +17,6 @@ import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync- import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/company.object-metadata'; import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; -import { PipelineStepObjectMetadata } from 'src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata'; import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator'; @@ -102,18 +101,6 @@ export class OpportunityObjectMetadata extends BaseObjectMetadata { @IsNullable() position: number; - // Relations - @FieldMetadata({ - standardId: opportunityStandardFieldIds.pipelineStep, - type: FieldMetadataType.RELATION, - label: 'Pipeline Step', - description: 'Opportunity pipeline step', - icon: 'IconKanban', - joinColumn: 'pipelineStepId', - }) - @IsNullable() - pipelineStep: PipelineStepObjectMetadata; - @FieldMetadata({ standardId: opportunityStandardFieldIds.pointOfContact, type: FieldMetadataType.RELATION, diff --git a/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts b/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts deleted file mode 100644 index 2c99585c3824..000000000000 --- a/packages/twenty-server/src/modules/pipeline-step/standard-objects/pipeline-step.object-metadata.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; -import { pipelineStepStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; -import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator'; -import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator'; -import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator'; -import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator'; -import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/relation-metadata.decorator'; -import { BaseObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects/base.object-metadata'; -import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-objects/opportunity.object-metadata'; - -@ObjectMetadata({ - standardId: standardObjectIds.pipelineStep, - namePlural: 'pipelineSteps', - labelSingular: 'Pipeline Step', - labelPlural: 'Pipeline Steps', - description: 'A pipeline step', - icon: 'IconLayoutKanban', -}) -@IsSystem() -export class PipelineStepObjectMetadata extends BaseObjectMetadata { - @FieldMetadata({ - standardId: pipelineStepStandardFieldIds.name, - type: FieldMetadataType.TEXT, - label: 'Name', - description: 'Pipeline Step name', - icon: 'IconCurrencyDollar', - }) - name: string; - - @FieldMetadata({ - standardId: pipelineStepStandardFieldIds.color, - type: FieldMetadataType.TEXT, - label: 'Color', - description: 'Pipeline Step color', - icon: 'IconColorSwatch', - }) - color: string; - - @FieldMetadata({ - standardId: pipelineStepStandardFieldIds.position, - type: FieldMetadataType.NUMBER, - label: 'Position', - description: 'Pipeline Step position', - icon: 'IconHierarchy2', - defaultValue: { value: 0 }, - }) - @IsNullable() - position: number; - - // Relations - @FieldMetadata({ - standardId: pipelineStepStandardFieldIds.opportunities, - type: FieldMetadataType.RELATION, - label: 'Opportunities', - description: 'Opportunities linked to the step.', - icon: 'IconTargetArrow', - }) - @RelationMetadata({ - type: RelationMetadataType.ONE_TO_MANY, - inverseSideTarget: () => OpportunityObjectMetadata, - }) - @IsNullable() - opportunities: OpportunityObjectMetadata[]; -} diff --git a/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts index 1660025a524d..9669fa414fd8 100644 --- a/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts +++ b/packages/twenty-server/src/modules/view/standard-objects/view.object-metadata.ts @@ -66,6 +66,14 @@ export class ViewObjectMetadata extends BaseObjectMetadata { }) icon: string; + @FieldMetadata({ + standardId: viewStandardFieldIds.kanbanFieldMetadataId, + type: FieldMetadataType.TEXT, + label: 'kanbanfieldMetadataId', + description: 'View Kanban column field', + }) + kanbanFieldMetadataId: string; + @FieldMetadata({ standardId: viewStandardFieldIds.position, type: FieldMetadataType.POSITION, From 1aa48d3bf7c8dd3e1c2816299d1c154f7067ce52 Mon Sep 17 00:00:00 2001 From: Quentin G Date: Thu, 21 Mar 2024 19:22:21 +0100 Subject: [PATCH 39/44] feat: merge front and server dockerfiles and optimize build (#4589) * feat: merge front and server dockerfiles and optimize build * fix: update image label * fix: bring back support for REACT_APP_SERVER_BASE_URL injection at runtime * fix: remove old entries & add nx cache in dockerignore * feat: generate frontend config at runtime using Nest * fix: format and filename * feat: use the EnvironmentService and leave default blank * feat: add support for DB migrations --- .dockerignore | 6 +- packages/twenty-docker/Makefile | 6 ++ packages/twenty-docker/prod/twenty/Dockerfile | 77 +++++++++++++++++++ .../twenty-docker/prod/twenty/entrypoint.sh | 17 ++++ .../start/local-setup/troubleshooting.mdx | 4 + packages/twenty-server/package.json | 3 +- packages/twenty-server/src/main.ts | 4 + .../src/utils/generate-front-config.ts | 31 ++++++++ yarn.lock | 1 + 9 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 packages/twenty-docker/prod/twenty/Dockerfile create mode 100755 packages/twenty-docker/prod/twenty/entrypoint.sh create mode 100644 packages/twenty-server/src/utils/generate-front-config.ts diff --git a/.dockerignore b/.dockerignore index 285200a8b127..f9fc785f92da 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ -server/node_modules/ -server/.env \ No newline at end of file +.git +.env +node_modules +.nx/cache diff --git a/packages/twenty-docker/Makefile b/packages/twenty-docker/Makefile index 6e3324e5482b..e4510047ba9a 100644 --- a/packages/twenty-docker/Makefile +++ b/packages/twenty-docker/Makefile @@ -29,6 +29,12 @@ prod-docs-build: prod-docs-run: @docker run -d -p 3000:3000 --name twenty-docs twenty-docs +prod-build: + @cd ../.. && docker build -f ./packages/twenty-docker/prod/twenty/Dockerfile --tag twenty . && cd - + +prod-run: + @docker run -d -p 3000:3000 --name twenty twenty + prod-front-build: @cd ../.. && docker build -f ./packages/twenty-docker/prod/twenty-front/Dockerfile --tag twenty-front . && cd - diff --git a/packages/twenty-docker/prod/twenty/Dockerfile b/packages/twenty-docker/prod/twenty/Dockerfile new file mode 100644 index 000000000000..526e578c2df4 --- /dev/null +++ b/packages/twenty-docker/prod/twenty/Dockerfile @@ -0,0 +1,77 @@ +# Base image for common dependencies +FROM node:18.17.1-alpine as common-deps + +WORKDIR /app + +# Copy only the necessary files for dependency resolution +COPY ./package.json ./yarn.lock ./.yarnrc.yml ./tsconfig.base.json ./nx.json /app/ +COPY ./.yarn/releases /app/.yarn/releases + +COPY ./packages/twenty-emails/package.json /app/packages/twenty-emails/ +COPY ./packages/twenty-server/package.json /app/packages/twenty-server/ +COPY ./packages/twenty-server/patches /app/packages/twenty-server/patches +COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/ +COPY ./packages/twenty-front/package.json /app/packages/twenty-front/ + +# Install all dependencies +RUN yarn && yarn cache clean && npx nx reset + + +# Build the back +FROM common-deps as twenty-server-build + +# Copy sourcecode after installing dependences to accelerate subsequents builds +COPY ./packages/twenty-emails /app/packages/twenty-emails +COPY ./packages/twenty-server /app/packages/twenty-server + +RUN npx nx run twenty-server:build && \ + mv /app/packages/twenty-server/dist /app/packages/twenty-server/build && \ + npx nx run twenty-server:build:packageJson && \ + mv /app/packages/twenty-server/dist/package.json /app/packages/twenty-server/package.json && \ + rm -rf /app/packages/twenty-server/dist && \ + mv /app/packages/twenty-server/build /app/packages/twenty-server/dist + +RUN yarn workspaces focus --production twenty-emails twenty-server + + +# Build the front +FROM common-deps as twenty-front-build + +ARG REACT_APP_SERVER_BASE_URL + +COPY ./packages/twenty-front /app/packages/twenty-front +COPY ./packages/twenty-ui /app/packages/twenty-ui +RUN yarn nx build twenty-front + + +# Final stage: Run the application +FROM node:18.17.1-alpine as twenty + +# Used to run healthcheck in docker +RUN apk add --no-cache curl jq + +COPY ./packages/twenty-docker/prod/twenty/entrypoint.sh /app/entrypoint.sh +RUN chmod +x /app/entrypoint.sh + +WORKDIR /app/packages/twenty-server + +ARG REACT_APP_SERVER_BASE_URL +ENV REACT_APP_SERVER_BASE_URL $REACT_APP_SERVER_BASE_URL + +# Copy built applications from previous stages +COPY --chown=1000 --from=twenty-server-build /app /app +COPY --chown=1000 --from=twenty-server-build /app/packages/twenty-server /app/packages/twenty-server +COPY --chown=1000 --from=twenty-front-build /app/packages/twenty-front/build /app/packages/twenty-server/dist/front + +# Set metadata and labels +LABEL org.opencontainers.image.source=https://github.com/twentyhq/twenty +LABEL org.opencontainers.image.description="This image provides a consistent and reproducible environment for the backend and frontend, ensuring it deploys faster and runs the same way regardless of the deployment environment." + +RUN mkdir /app/.local-storage +RUN chown -R 1000 /app + +# Use non root user with uid 1000 +USER 1000 + +CMD ["node", "dist/src/main"] +ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/packages/twenty-docker/prod/twenty/entrypoint.sh b/packages/twenty-docker/prod/twenty/entrypoint.sh new file mode 100755 index 000000000000..a6167afcae5b --- /dev/null +++ b/packages/twenty-docker/prod/twenty/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Check if the initialization has already been done and that we enabled automatic migration +if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/${STORAGE_LOCAL_PATH}/db_initialized ]; then + echo "Running database setup and migrations..." + + # Run setup and migration scripts + npx ts-node ./scripts/setup-db.ts + yarn database:migrate:prod + + # Mark initialization as done + echo "Successfuly migrated DB!" + touch /app/${STORAGE_LOCAL_PATH}/db_initialized +fi + +# Continue with the original Docker command +exec "$@" diff --git a/packages/twenty-docs/docs/start/local-setup/troubleshooting.mdx b/packages/twenty-docs/docs/start/local-setup/troubleshooting.mdx index 72eccba95ced..fba34447f57d 100644 --- a/packages/twenty-docs/docs/start/local-setup/troubleshooting.mdx +++ b/packages/twenty-docs/docs/start/local-setup/troubleshooting.mdx @@ -41,3 +41,7 @@ This should work out of the box with the eslint extension installed. If this doe "source.fixAll.eslint": "explicit" } ``` + +## Docker container build + +To successfully build Docker images, ensure that your system has a minimum of 2GB of memory available. For users of Docker Desktop, please verify that you've allocated sufficient resources to Docker within the application's settings. diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 2309ebe441cc..8063537f1622 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -44,7 +44,8 @@ "graphql-middleware": "^6.1.35", "jwt-decode": "^4.0.0", "passport": "^0.7.0", - "psl": "^1.9.0" + "psl": "^1.9.0", + "tsconfig-paths": "^4.2.0" }, "devDependencies": { "@nestjs/cli": "10.3.0", diff --git a/packages/twenty-server/src/main.ts b/packages/twenty-server/src/main.ts index 8546fabe1d3f..25e6f3cff75e 100644 --- a/packages/twenty-server/src/main.ts +++ b/packages/twenty-server/src/main.ts @@ -11,6 +11,7 @@ import '@sentry/tracing'; import { AppModule } from './app.module'; +import { generateFrontConfig } from './utils/generate-front-config'; import { settings } from './engine/constants/settings'; import { LoggerService } from './engine/integrations/logger/logger.service'; import { EnvironmentService } from './engine/integrations/environment/environment.service'; @@ -60,6 +61,9 @@ const bootstrap = async () => { }), ); + // Create the env-config.js of the front at runtime + generateFrontConfig(); + await app.listen(app.get(EnvironmentService).get('PORT')); }; diff --git a/packages/twenty-server/src/utils/generate-front-config.ts b/packages/twenty-server/src/utils/generate-front-config.ts new file mode 100644 index 000000000000..c4d15838a2ab --- /dev/null +++ b/packages/twenty-server/src/utils/generate-front-config.ts @@ -0,0 +1,31 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +import { ConfigService } from '@nestjs/config'; +import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; + +const environmentService = new EnvironmentService(new ConfigService()); + +export function generateFrontConfig(): void { + const configObject = { + window: { + _env_: { + REACT_APP_SERVER_BASE_URL: environmentService.get('SERVER_URL'), + }, + }, + }; + + const configString = `window._env_ = ${JSON.stringify( + configObject.window._env_, + null, + 2, + )};`; + + const distPath = path.join(__dirname, '../..', 'front'); + + if (!fs.existsSync(distPath)) { + fs.mkdirSync(distPath, { recursive: true }); + } + + fs.writeFileSync(path.join(distPath, 'env-config.js'), configString, 'utf8'); +} diff --git a/yarn.lock b/yarn.lock index 0310f5992701..605e0049b9fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45763,6 +45763,7 @@ __metadata: passport: "npm:^0.7.0" psl: "npm:^1.9.0" rimraf: "npm:^5.0.5" + tsconfig-paths: "npm:^4.2.0" typescript: "npm:^5.3.3" languageName: unknown linkType: soft From aee6d49ea950ffe68d55203eb64095a5e9a7d5df Mon Sep 17 00:00:00 2001 From: Quentin G Date: Fri, 22 Mar 2024 09:16:39 +0100 Subject: [PATCH 40/44] feat: add a docker-compose file for production (#4609) * feat: add a docker-compose file for production * fix: remove unused user filed * fix: do not provide default token secrets --- packages/twenty-docker/prod/.env.example | 16 ++++++ .../twenty-docker/prod/docker-compose.yml | 52 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 packages/twenty-docker/prod/.env.example create mode 100644 packages/twenty-docker/prod/docker-compose.yml diff --git a/packages/twenty-docker/prod/.env.example b/packages/twenty-docker/prod/.env.example new file mode 100644 index 000000000000..03628af3f815 --- /dev/null +++ b/packages/twenty-docker/prod/.env.example @@ -0,0 +1,16 @@ +TAG=latest + +POSTGRES_ADMIN_PASSWORD=replace_me_with_a_strong_password + +PG_DATABASE_HOST=db:5432 + +SERVER_URL=http://localhost:3000 +# Uncoment if you are serving your front on another server than the API (eg. bucket) +# FRONT_BASE_URL=http://localhost:3000 + +# Use openssl rand -base64 32 for each secret +# ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access +# LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login +# REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh + +SIGN_IN_PREFILLED=true diff --git a/packages/twenty-docker/prod/docker-compose.yml b/packages/twenty-docker/prod/docker-compose.yml new file mode 100644 index 000000000000..887b820c31d2 --- /dev/null +++ b/packages/twenty-docker/prod/docker-compose.yml @@ -0,0 +1,52 @@ +version: '3.8' +name: twenty + +services: + server: + image: twentycrm/twenty:${TAG} + volumes: + - server-local-data:/app/.local-storage + ports: + - "3000:3000" + environment: + PORT: 3000 + PG_DATABASE_URL: postgres://twenty:twenty@${PG_DATABASE_HOST}/default + SERVER_URL: ${SERVER_URL} + FRONT_BASE_URL: ${FRONT_BASE_URL:-$SERVER_URL} + + ENABLE_DB_MIGRATIONS: true + + SIGN_IN_PREFILLED: ${SIGN_IN_PREFILLED} + STORAGE_TYPE: local + STORAGE_LOCAL_PATH: .local-storage + ACCESS_TOKEN_SECRET: ${ACCESS_TOKEN_SECRET} + LOGIN_TOKEN_SECRET: ${LOGIN_TOKEN_SECRET} + REFRESH_TOKEN_SECRET: ${REFRESH_TOKEN_SECRET} + depends_on: + db: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "curl --silent --fail http://localhost:3000/healthz | jq -e '.status == \"ok\"' > /dev/null || exit 1"] + interval: 5s + timeout: 5s + retries: 10 + restart: always + + db: + image: twentycrm/twenty-postgres:${TAG} + volumes: + - db-data:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD} + #POSTGRES_USER: ${POSTGRES_USER} + #POSTGRES_DB: ${POSTGRES_DB} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U twenty -d default"] + interval: 5s + timeout: 5s + retries: 10 + restart: always + +volumes: + db-data: + server-local-data: From d876b400566ff53f9fe8282e64b25fbb051e60aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Fri, 22 Mar 2024 14:01:16 +0100 Subject: [PATCH 41/44] Logs show page (#4611) * Being implementing events on the frontend * Rename JSON to RAW JSON * Fix handling of json field on frontend * Log user id * Add frontend tests * Update packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts Co-authored-by: Weiko * Move db calls to a dedicated repository * Add server-side tests --------- Co-authored-by: Weiko --- .../src/generated-metadata/graphql.ts | 67 +++++++++++++- .../twenty-front/src/generated/graphql.tsx | 46 +--------- .../events/components/EventList.tsx | 22 +++++ .../activities/events/components/EventRow.tsx | 11 +++ .../activities/events/components/Events.tsx | 25 +++++ .../events/hooks/__tests__/useEvents.test.ts | 91 +++++++++++++++++++ .../activities/events/hooks/useEvents.tsx | 28 ++++++ .../modules/activities/events/types/Event.ts | 12 +++ .../types/CoreObjectNameSingular.ts | 1 + .../utils/mapFieldMetadataToGraphQLQuery.ts | 1 + .../record-field/types/FieldMetadata.ts | 5 + .../record-field/types/FieldType.ts | 3 +- .../types/guards/assertFieldMetadata.ts | 5 +- .../types/guards/isFieldRawJson.ts | 6 ++ .../components/ShowPageRightContainer.tsx | 12 ++- .../jobs/save-event-to-db.job.ts | 54 ++++++----- .../listeners/entity-events-to-db.listener.ts | 10 +- .../workspace-query-runner.module.ts | 7 ++ .../workspace-query-runner.service.ts | 12 ++- .../graphql-types/input/index.ts | 2 +- ...-type.ts => raw-json-filter.input-type.ts} | 4 +- .../services/type-mapper.service.ts | 8 +- .../open-api/utils/components.utils.ts | 2 +- .../types/object-record-update.event.ts | 1 + .../types/object-record.base.event.ts | 1 + .../object-record-changed-values.spec.ts | 65 +++++++++++++ .../utils/object-record-changed-values.ts | 28 ++++++ .../dtos/default-value.input.ts | 2 +- .../field-metadata/field-metadata.entity.ts | 2 +- .../field-metadata-default-value.interface.ts | 4 +- .../utils/generate-target-column-map.util.ts | 2 +- .../validate-default-value-for-type.util.ts | 4 +- ...field-metadata-type-to-column-type.util.ts | 2 +- .../workspace-migration.factory.ts | 2 +- .../metadata-to-repository.mapping.ts | 2 + ...p-field-metadata-type-to-data-type.util.ts | 2 +- .../event/repositiories/event.repository.ts | 30 ++++++ .../standard-objects/event.object-metadata.ts | 2 +- 38 files changed, 488 insertions(+), 95 deletions(-) create mode 100644 packages/twenty-front/src/modules/activities/events/components/EventList.tsx create mode 100644 packages/twenty-front/src/modules/activities/events/components/EventRow.tsx create mode 100644 packages/twenty-front/src/modules/activities/events/components/Events.tsx create mode 100644 packages/twenty-front/src/modules/activities/events/hooks/__tests__/useEvents.test.ts create mode 100644 packages/twenty-front/src/modules/activities/events/hooks/useEvents.tsx create mode 100644 packages/twenty-front/src/modules/activities/events/types/Event.ts create mode 100644 packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRawJson.ts rename packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/{json-filter.input-type.ts => raw-json-filter.input-type.ts} (71%) create mode 100644 packages/twenty-server/src/engine/integrations/event-emitter/utils/__tests__/object-record-changed-values.spec.ts create mode 100644 packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-values.ts create mode 100644 packages/twenty-server/src/modules/event/repositiories/event.repository.ts diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 63d820235287..927fde13800e 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -73,6 +73,7 @@ export type Billing = { export type BillingSubscription = { __typename?: 'BillingSubscription'; id: Scalars['ID']['output']; + interval?: Maybe; status: Scalars['String']['output']; }; @@ -263,7 +264,6 @@ export enum FieldMetadataType { DateTime = 'DATE_TIME', Email = 'EMAIL', FullName = 'FULL_NAME', - Json = 'JSON', Link = 'LINK', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', @@ -272,6 +272,7 @@ export enum FieldMetadataType { Position = 'POSITION', Probability = 'PROBABILITY', Rating = 'RATING', + RawJson = 'RAW_JSON', Relation = 'RELATION', Select = 'SELECT', Text = 'TEXT', @@ -341,6 +342,7 @@ export type Mutation = { renewToken: AuthTokens; signUp: LoginToken; track: Analytics; + updateBillingSubscription: UpdateBillingEntity; updateOneField: Field; updateOneObject: Object; updatePasswordViaResetToken: InvalidatePassword; @@ -545,6 +547,8 @@ export type Query = { fields: FieldConnection; findWorkspaceFromInviteHash: Workspace; getProductPrices: ProductPricesEntity; + getTimelineCalendarEventsFromCompanyId: TimelineCalendarEventsWithTotal; + getTimelineCalendarEventsFromPersonId: TimelineCalendarEventsWithTotal; getTimelineThreadsFromCompanyId: TimelineThreadsWithTotal; getTimelineThreadsFromPersonId: TimelineThreadsWithTotal; object: Object; @@ -591,6 +595,20 @@ export type QueryGetProductPricesArgs = { }; +export type QueryGetTimelineCalendarEventsFromCompanyIdArgs = { + companyId: Scalars['ID']['input']; + page: Scalars['Int']['input']; + pageSize: Scalars['Int']['input']; +}; + + +export type QueryGetTimelineCalendarEventsFromPersonIdArgs = { + page: Scalars['Int']['input']; + pageSize: Scalars['Int']['input']; + personId: Scalars['ID']['input']; +}; + + export type QueryGetTimelineThreadsFromCompanyIdArgs = { companyId: Scalars['ID']['input']; page: Scalars['Int']['input']; @@ -697,7 +715,7 @@ export type Sentry = { export type SessionEntity = { __typename?: 'SessionEntity'; - url: Scalars['String']['output']; + url?: Maybe; }; /** Sort Directions */ @@ -724,6 +742,45 @@ export type Telemetry = { enabled: Scalars['Boolean']['output']; }; +export type TimelineCalendarEvent = { + __typename?: 'TimelineCalendarEvent'; + attendees: Array; + conferenceSolution: Scalars['String']['output']; + conferenceUri: Scalars['String']['output']; + description: Scalars['String']['output']; + endsAt: Scalars['DateTime']['output']; + id: Scalars['ID']['output']; + isCanceled: Scalars['Boolean']['output']; + isFullDay: Scalars['Boolean']['output']; + location: Scalars['String']['output']; + startsAt: Scalars['DateTime']['output']; + title: Scalars['String']['output']; + visibility: TimelineCalendarEventVisibility; +}; + +export type TimelineCalendarEventAttendee = { + __typename?: 'TimelineCalendarEventAttendee'; + avatarUrl: Scalars['String']['output']; + displayName: Scalars['String']['output']; + firstName: Scalars['String']['output']; + handle: Scalars['String']['output']; + lastName: Scalars['String']['output']; + personId?: Maybe; + workspaceMemberId?: Maybe; +}; + +/** Visibility of the calendar event */ +export enum TimelineCalendarEventVisibility { + Metadata = 'METADATA', + ShareEverything = 'SHARE_EVERYTHING' +} + +export type TimelineCalendarEventsWithTotal = { + __typename?: 'TimelineCalendarEventsWithTotal'; + timelineCalendarEvents: Array; + totalNumberOfCalendarEvents: Scalars['Int']['output']; +}; + export type TimelineThread = { __typename?: 'TimelineThread'; firstParticipant: TimelineThreadParticipant; @@ -760,6 +817,12 @@ export type TransientToken = { transientToken: AuthToken; }; +export type UpdateBillingEntity = { + __typename?: 'UpdateBillingEntity'; + /** Boolean that confirms query was successful */ + success: Scalars['Boolean']['output']; +}; + export type UpdateFieldInput = { defaultValue?: InputMaybe; description?: InputMaybe; diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 73da02df1083..3a576f6b2008 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -184,7 +184,6 @@ export enum FieldMetadataType { DateTime = 'DATE_TIME', Email = 'EMAIL', FullName = 'FULL_NAME', - Json = 'JSON', Link = 'LINK', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', @@ -193,6 +192,7 @@ export enum FieldMetadataType { Position = 'POSITION', Probability = 'PROBABILITY', Rating = 'RATING', + RawJson = 'RAW_JSON', Relation = 'RELATION', Select = 'SELECT', Text = 'TEXT', @@ -255,7 +255,6 @@ export type Mutation = { generateJWT: AuthTokens; generateTransientToken: TransientToken; impersonate: Verify; - removeWorkspaceMember: Scalars['String']; renewToken: AuthTokens; signUp: LoginToken; track: Analytics; @@ -314,11 +313,6 @@ export type MutationImpersonateArgs = { }; -export type MutationRemoveWorkspaceMemberArgs = { - memberId: Scalars['String']; -}; - - export type MutationRenewTokenArgs = { refreshToken: Scalars['String']; }; @@ -1098,13 +1092,6 @@ export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', status: string, interval?: string | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null } | null }> } }; -export type RemoveWorkspaceMemberMutationVariables = Exact<{ - memberId: Scalars['String']; -}>; - - -export type RemoveWorkspaceMemberMutation = { __typename?: 'Mutation', removeWorkspaceMember: string }; - export type ActivateWorkspaceMutationVariables = Exact<{ input: ActivateWorkspaceInput; }>; @@ -2311,37 +2298,6 @@ export function useGetCurrentUserLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt export type GetCurrentUserQueryHookResult = ReturnType; export type GetCurrentUserLazyQueryHookResult = ReturnType; export type GetCurrentUserQueryResult = Apollo.QueryResult; -export const RemoveWorkspaceMemberDocument = gql` - mutation RemoveWorkspaceMember($memberId: String!) { - removeWorkspaceMember(memberId: $memberId) -} - `; -export type RemoveWorkspaceMemberMutationFn = Apollo.MutationFunction; - -/** - * __useRemoveWorkspaceMemberMutation__ - * - * To run a mutation, you first call `useRemoveWorkspaceMemberMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveWorkspaceMemberMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [removeWorkspaceMemberMutation, { data, loading, error }] = useRemoveWorkspaceMemberMutation({ - * variables: { - * memberId: // value for 'memberId' - * }, - * }); - */ -export function useRemoveWorkspaceMemberMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(RemoveWorkspaceMemberDocument, options); - } -export type RemoveWorkspaceMemberMutationHookResult = ReturnType; -export type RemoveWorkspaceMemberMutationResult = Apollo.MutationResult; -export type RemoveWorkspaceMemberMutationOptions = Apollo.BaseMutationOptions; export const ActivateWorkspaceDocument = gql` mutation ActivateWorkspace($input: ActivateWorkspaceInput!) { activateWorkspace(data: $input) { diff --git a/packages/twenty-front/src/modules/activities/events/components/EventList.tsx b/packages/twenty-front/src/modules/activities/events/components/EventList.tsx new file mode 100644 index 000000000000..158e3ba1215f --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/components/EventList.tsx @@ -0,0 +1,22 @@ +import { ReactElement } from 'react'; + +import { EventRow } from '@/activities/events/components/EventRow'; +import { Event } from '@/activities/events/types/Event'; +import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; + +type EventListProps = { + targetableObject: ActivityTargetableObject; + title: string; + events: Event[]; + button?: ReactElement | false; +}; + +export const EventList = ({ events }: EventListProps) => { + return ( + <> + {events && + events.length > 0 && + events.map((event: Event) => )} + + ); +}; diff --git a/packages/twenty-front/src/modules/activities/events/components/EventRow.tsx b/packages/twenty-front/src/modules/activities/events/components/EventRow.tsx new file mode 100644 index 000000000000..d7bbc2d7556b --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/components/EventRow.tsx @@ -0,0 +1,11 @@ +import { Event } from '@/activities/events/types/Event'; + +export const EventRow = ({ event }: { event: Event }) => { + return ( + <> +

      + {event.name}:

      {event.properties}
      +

      + + ); +}; diff --git a/packages/twenty-front/src/modules/activities/events/components/Events.tsx b/packages/twenty-front/src/modules/activities/events/components/Events.tsx new file mode 100644 index 000000000000..11536d79ac9d --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/components/Events.tsx @@ -0,0 +1,25 @@ +import { isNonEmptyArray } from '@sniptt/guards'; + +import { EventList } from '@/activities/events/components/EventList'; +import { useEvents } from '@/activities/events/hooks/useEvents'; +import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; + +export const Events = ({ + targetableObject, +}: { + targetableObject: ActivityTargetableObject; +}) => { + const { events } = useEvents(targetableObject); + + if (!isNonEmptyArray(events)) { + return
      No log yet
      ; + } + + return ( + + ); +}; diff --git a/packages/twenty-front/src/modules/activities/events/hooks/__tests__/useEvents.test.ts b/packages/twenty-front/src/modules/activities/events/hooks/__tests__/useEvents.test.ts new file mode 100644 index 000000000000..25c6d5bf1209 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/hooks/__tests__/useEvents.test.ts @@ -0,0 +1,91 @@ +import { renderHook } from '@testing-library/react'; + +import { useEvents } from '@/activities/events/hooks/useEvents'; + +jest.mock('@/object-record/hooks/useFindManyRecords', () => ({ + useFindManyRecords: jest.fn(), +})); + +describe('useEvent', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('fetches events correctly for a given targetableObject', () => { + const mockEvents = [ + { + __typename: 'Event', + id: '166ec73f-26b1-4934-bb3b-c86c8513b99b', + opportunityId: null, + opportunity: null, + personId: null, + person: null, + company: { + __typename: 'Company', + address: 'Paris', + linkedinLink: { + __typename: 'Link', + label: '', + url: '', + }, + xLink: { + __typename: 'Link', + label: '', + url: '', + }, + position: 4, + domainName: 'microsoft.com', + employees: null, + createdAt: '2024-03-21T16:01:41.809Z', + annualRecurringRevenue: { + __typename: 'Currency', + amountMicros: 100000000, + currencyCode: 'USD', + }, + idealCustomerProfile: false, + accountOwnerId: null, + updatedAt: '2024-03-22T08:28:44.812Z', + name: 'Microsoft', + id: '460b6fb1-ed89-413a-b31a-962986e67bb4', + }, + workspaceMember: { + __typename: 'WorkspaceMember', + locale: 'en', + avatarUrl: '', + updatedAt: '2024-03-21T16:01:41.839Z', + name: { + __typename: 'FullName', + firstName: 'Tim', + lastName: 'Apple', + }, + id: '20202020-0687-4c41-b707-ed1bfca972a7', + userEmail: 'tim@apple.dev', + colorScheme: 'Light', + createdAt: '2024-03-21T16:01:41.839Z', + userId: '20202020-9e3b-46d4-a556-88b9ddc2b034', + }, + workspaceMemberId: '20202020-0687-4c41-b707-ed1bfca972a7', + createdAt: '2024-03-22T08:28:44.830Z', + name: 'updated.company', + companyId: '460b6fb1-ed89-413a-b31a-962986e67bb4', + properties: '{"diff": {"address": {"after": "Paris", "before": ""}}}', + updatedAt: '2024-03-22T08:28:44.830Z', + }, + ]; + const mockTargetableObject = { + id: '1', + targetObjectNameSingular: 'Opportunity', + }; + + const useFindManyRecordsMock = jest.requireMock( + '@/object-record/hooks/useFindManyRecords', + ); + useFindManyRecordsMock.useFindManyRecords.mockReturnValue({ + records: mockEvents, + }); + + const { result } = renderHook(() => useEvents(mockTargetableObject)); + + expect(result.current.events).toEqual(mockEvents); + }); +}); diff --git a/packages/twenty-front/src/modules/activities/events/hooks/useEvents.tsx b/packages/twenty-front/src/modules/activities/events/hooks/useEvents.tsx new file mode 100644 index 000000000000..8e37947a6566 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/hooks/useEvents.tsx @@ -0,0 +1,28 @@ +import { Event } from '@/activities/events/types/Event'; +import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getTargetObjectFilterFieldName'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; + +// do we need to test this? +export const useEvents = (targetableObject: ActivityTargetableObject) => { + const targetableObjectFieldIdName = getActivityTargetObjectFieldIdName({ + nameSingular: targetableObject.targetObjectNameSingular, + }); + + const { records: events } = useFindManyRecords({ + objectNameSingular: CoreObjectNameSingular.Event, + filter: { + [targetableObjectFieldIdName]: { + eq: targetableObject.id, + }, + }, + orderBy: { + createdAt: 'DescNullsFirst', + }, + }); + + return { + events: events as Event[], + }; +}; diff --git a/packages/twenty-front/src/modules/activities/events/types/Event.ts b/packages/twenty-front/src/modules/activities/events/types/Event.ts new file mode 100644 index 000000000000..1752b8367c2a --- /dev/null +++ b/packages/twenty-front/src/modules/activities/events/types/Event.ts @@ -0,0 +1,12 @@ +export type Event = { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + opportunityId: string | null; + companyId: string; + personId: string; + workspaceMemberId: string; + properties: any; + name: string; +}; diff --git a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts index 10602b7e3020..9886f09b722e 100644 --- a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts @@ -8,6 +8,7 @@ export enum CoreObjectNameSingular { Comment = 'comment', Company = 'company', ConnectedAccount = 'connectedAccount', + Event = 'event', Favorite = 'favorite', Message = 'message', MessageChannel = 'messageChannel', diff --git a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts index 4603ac0cefc0..e6dc29a1c31e 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts @@ -34,6 +34,7 @@ export const mapFieldMetadataToGraphQLQuery = ({ 'RATING', 'SELECT', 'POSITION', + 'RAW_JSON', ] as FieldMetadataType[] ).includes(fieldType); diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts index 74f8bbe88461..7f228198369d 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts @@ -69,6 +69,11 @@ export type FieldRatingMetadata = { fieldName: string; }; +export type FieldRawJsonMetadata = { + objectMetadataNameSingular?: string; + fieldName: string; +}; + export type FieldDefinitionRelationType = | 'FROM_MANY_OBJECTS' | 'FROM_ONE_OBJECT' diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldType.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldType.ts index e09af18f81cb..d59a6bb84d67 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldType.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldType.ts @@ -17,4 +17,5 @@ export type FieldType = | 'URL' | 'UUID' | 'MULTI_SELECT' - | 'NUMERIC'; + | 'NUMERIC' + | 'RAW_JSON'; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts index 86f1922cbeea..0cf44a152c3e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts @@ -10,6 +10,7 @@ import { FieldNumberMetadata, FieldPhoneMetadata, FieldRatingMetadata, + FieldRawJsonMetadata, FieldRelationMetadata, FieldSelectMetadata, FieldTextMetadata, @@ -47,7 +48,9 @@ type AssertFieldMetadataFunction = < ? FieldTextMetadata : E extends 'UUID' ? FieldUuidMetadata - : never, + : E extends 'RAW_JSON' + ? FieldRawJsonMetadata + : never, >( fieldType: E, fieldTypeGuard: ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRawJson.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRawJson.ts new file mode 100644 index 000000000000..3decadfb864a --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRawJson.ts @@ -0,0 +1,6 @@ +import { FieldDefinition } from '../FieldDefinition'; +import { FieldMetadata, FieldRawJsonMetadata } from '../FieldMetadata'; + +export const isFieldRawJson = ( + field: Pick, 'type'>, +): field is FieldDefinition => field.type === 'RAW_JSON'; diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx index 390e5e9e1020..001904181cf3 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx @@ -3,6 +3,7 @@ import { useRecoilValue } from 'recoil'; import { Calendar } from '@/activities/calendar/components/Calendar'; import { EmailThreads } from '@/activities/emails/components/EmailThreads'; +import { Events } from '@/activities/events/components/Events'; import { Attachments } from '@/activities/files/components/Attachments'; import { Notes } from '@/activities/notes/components/Notes'; import { ObjectTasks } from '@/activities/tasks/components/ObjectTasks'; @@ -65,6 +66,8 @@ export const ShowPageRightContainer = ({ const activeTabId = useRecoilValue(activeTabIdState); const shouldDisplayCalendarTab = useIsFeatureEnabled('IS_CALENDAR_ENABLED'); + const shouldDisplayLogTab = useIsFeatureEnabled('IS_EVENT_OBJECT_ENABLED'); + const shouldDisplayEmailsTab = (emails && targetableObject.targetObjectNameSingular === @@ -101,7 +104,6 @@ export const ShowPageRightContainer = ({ title: 'Emails', Icon: IconMail, hide: !shouldDisplayEmailsTab, - hasBetaPill: true, }, { id: 'calendar', @@ -109,6 +111,13 @@ export const ShowPageRightContainer = ({ Icon: IconCalendarEvent, hide: !shouldDisplayCalendarTab, }, + { + id: 'logs', + title: 'Logs', + Icon: IconTimelineEvent, + hide: !shouldDisplayLogTab, + hasBetaPill: true, + }, ]; return ( @@ -131,6 +140,7 @@ export const ShowPageRightContainer = ({ )} {activeTabId === 'emails' && } {activeTabId === 'calendar' && } + {activeTabId === 'logs' && } ); }; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts index 82cab4e27859..3b0d5a6ba77e 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/jobs/save-event-to-db.job.ts @@ -2,12 +2,16 @@ import { Injectable } from '@nestjs/common'; import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { EventRepository } from 'src/modules/event/repositiories/event.repository'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; +import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; export type SaveEventToDbJobData = { workspaceId: string; recordId: string; + userId: string | undefined; objectName: string; operation: string; details: any; @@ -16,39 +20,47 @@ export type SaveEventToDbJobData = { @Injectable() export class SaveEventToDbJob implements MessageQueueJob { constructor( - private readonly dataSourceService: DataSourceService, - private readonly workspaceDataSourceService: WorkspaceDataSourceService, + @InjectObjectMetadataRepository(WorkspaceMemberObjectMetadata) + private readonly workspaceMemberService: WorkspaceMemberRepository, + @InjectObjectMetadataRepository(EventObjectMetadata) + private readonly eventService: EventRepository, ) {} + // TODO: need to support objects others than "person", "company", "opportunity" async handle(data: SaveEventToDbJobData): Promise { - const dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( - data.workspaceId, - ); - const workspaceDataSource = - await this.workspaceDataSourceService.connectToWorkspaceDataSource( + let workspaceMemberId: string | null = null; + + if (data.userId) { + const workspaceMember = await this.workspaceMemberService.getByIdOrFail( + data.userId, data.workspaceId, ); - const eventType = `${data.operation}.${data.objectName}`; - - // TODO: add "workspaceMember" (who performed the action, need to send it in the event) - // TODO: need to support objects others than "person", "company", "opportunities" + workspaceMemberId = workspaceMember.id; + } if ( data.objectName != 'person' && data.objectName != 'company' && - data.objectName != 'opportunities' + data.objectName != 'opportunity' ) { return; } - await workspaceDataSource?.query( - `INSERT INTO ${dataSourceMetadata.schema}."event" - ("name", "properties", "${data.objectName}Id") - VALUES ('${eventType}', '${JSON.stringify(data.details)}', '${ - data.recordId - }') RETURNING *`, + if (data.details.diff) { + // we remove "before" and "after" property for a cleaner/slimmer event payload + data.details = { + diff: data.details.diff, + }; + } + + await this.eventService.insert( + `${data.operation}.${data.objectName}`, + data.details, + workspaceMemberId, + data.objectName, + data.recordId, + data.workspaceId, ); } } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts index f13047daf9db..b77db9c389c9 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/listeners/entity-events-to-db.listener.ts @@ -15,6 +15,8 @@ import { FeatureFlagEntity, FeatureFlagKeys, } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { objectRecordChangedValues } from 'src/engine/integrations/event-emitter/utils/object-record-changed-values'; +import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event'; @Injectable() export class EntityEventsToDbListener { @@ -31,7 +33,12 @@ export class EntityEventsToDbListener { } @OnEvent('*.updated') - async handleUpdate(payload: ObjectRecordCreateEvent) { + async handleUpdate(payload: ObjectRecordUpdateEvent) { + payload.details.diff = objectRecordChangedValues( + payload.details.before, + payload.details.after, + ); + return this.handle(payload, 'updated'); } @@ -58,6 +65,7 @@ export class EntityEventsToDbListener { this.messageQueueService.add(SaveEventToDbJob.name, { workspaceId: payload.workspaceId, + userId: payload.userId, recordId: payload.recordId, objectName: payload.objectMetadata.nameSingular, operation: operation, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index f2dcdd20397c..9b4efe05b090 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -9,6 +9,9 @@ import { RecordPositionListener } from 'src/engine/api/graphql/workspace-query-r import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata'; +import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata'; +import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { WorkspaceQueryRunnerService } from './workspace-query-runner.service'; @@ -21,6 +24,10 @@ import { EntityEventsToDbListener } from './listeners/entity-events-to-db.listen WorkspaceDataSourceModule, WorkspacePreQueryHookModule, TypeOrmModule.forFeature([Workspace, FeatureFlagEntity], 'core'), + ObjectMetadataRepositoryModule.forFeature([ + WorkspaceMemberObjectMetadata, + EventObjectMetadata, + ]), ], providers: [ WorkspaceQueryRunnerService, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index dd9ae0f08b7e..c3b13e393578 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -216,7 +216,7 @@ export class WorkspaceQueryRunnerService { args: CreateManyResolverArgs, options: WorkspaceQueryRunnerOptions, ): Promise { - const { workspaceId, objectMetadataItem } = options; + const { workspaceId, userId, objectMetadataItem } = options; const computedArgs = await this.queryRunnerArgsFactory.create( args, options, @@ -246,6 +246,7 @@ export class WorkspaceQueryRunnerService { parsedResults.forEach((record) => { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.created`, { workspaceId, + userId, recordId: record.id, objectMetadata: objectMetadataItem, details: { @@ -270,7 +271,7 @@ export class WorkspaceQueryRunnerService { args: UpdateOneResolverArgs, options: WorkspaceQueryRunnerOptions, ): Promise { - const { workspaceId, objectMetadataItem } = options; + const { workspaceId, userId, objectMetadataItem } = options; const existingRecord = await this.findOne( { filter: { id: { eq: args.id } } } as FindOneResolverArgs, @@ -300,6 +301,7 @@ export class WorkspaceQueryRunnerService { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.updated`, { workspaceId, + userId, recordId: (existingRecord as Record).id, objectMetadata: objectMetadataItem, details: { @@ -356,7 +358,7 @@ export class WorkspaceQueryRunnerService { args: DeleteManyResolverArgs, options: WorkspaceQueryRunnerOptions, ): Promise { - const { workspaceId, objectMetadataItem } = options; + const { workspaceId, userId, objectMetadataItem } = options; const maximumRecordAffected = this.environmentService.get( 'MUTATION_MAXIMUM_RECORD_AFFECTED', ); @@ -384,6 +386,7 @@ export class WorkspaceQueryRunnerService { parsedResults.forEach((record) => { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.deleted`, { workspaceId, + userId, recordId: record.id, objectMetadata: objectMetadataItem, details: { @@ -399,7 +402,7 @@ export class WorkspaceQueryRunnerService { args: DeleteOneResolverArgs, options: WorkspaceQueryRunnerOptions, ): Promise { - const { workspaceId, objectMetadataItem } = options; + const { workspaceId, userId, objectMetadataItem } = options; const query = await this.workspaceQueryBuilderFactory.deleteOne( args, options, @@ -422,6 +425,7 @@ export class WorkspaceQueryRunnerService { this.eventEmitter.emit(`${objectMetadataItem.nameSingular}.deleted`, { workspaceId, + userId, recordId: args.id, objectMetadata: objectMetadataItem, details: { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts index 42ddc89099e3..b362a0a1186f 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/index.ts @@ -8,4 +8,4 @@ export * from './string-filter.input-type'; export * from './time-filter.input-type'; export * from './uuid-filter.input-type'; export * from './boolean-filter.input-type'; -export * from './json-filter.input-type'; +export * from './raw-json-filter.input-type'; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/raw-json-filter.input-type.ts similarity index 71% rename from packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts rename to packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/raw-json-filter.input-type.ts index 6161bd86ebea..5b06437dd695 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/json-filter.input-type.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-types/input/raw-json-filter.input-type.ts @@ -2,8 +2,8 @@ import { GraphQLInputObjectType } from 'graphql'; import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type'; -export const JsonFilterType = new GraphQLInputObjectType({ - name: 'JsonFilter', +export const RawJsonFilterType = new GraphQLInputObjectType({ + name: 'RawJsonFilter', fields: { is: { type: FilterIs }, }, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index 6b072c2dfc91..951e63042e73 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -32,7 +32,7 @@ import { IntFilterType, BooleanFilterType, BigFloatFilterType, - JsonFilterType, + RawJsonFilterType, } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input'; import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum'; import { BigFloatScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; @@ -70,7 +70,7 @@ export class TypeMapperService { [FieldMetadataType.PROBABILITY, GraphQLFloat], [FieldMetadataType.RELATION, GraphQLID], [FieldMetadataType.POSITION, PositionScalarType], - [FieldMetadataType.JSON, GraphQLJSON], + [FieldMetadataType.RAW_JSON, GraphQLJSON], ]); return typeScalarMapping.get(fieldMetadataType); @@ -102,7 +102,7 @@ export class TypeMapperService { [FieldMetadataType.PROBABILITY, FloatFilterType], [FieldMetadataType.RELATION, UUIDFilterType], [FieldMetadataType.POSITION, FloatFilterType], - [FieldMetadataType.JSON, JsonFilterType], + [FieldMetadataType.RAW_JSON, RawJsonFilterType], ]); return typeFilterMapping.get(fieldMetadataType); @@ -126,7 +126,7 @@ export class TypeMapperService { [FieldMetadataType.SELECT, OrderByDirectionType], [FieldMetadataType.MULTI_SELECT, OrderByDirectionType], [FieldMetadataType.POSITION, OrderByDirectionType], - [FieldMetadataType.JSON, OrderByDirectionType], + [FieldMetadataType.RAW_JSON, OrderByDirectionType], ]); return typeOrderByMapping.get(fieldMetadataType); diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index 487156e6b9d2..50c72bbf8f74 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -69,7 +69,7 @@ const getSchemaComponentsProperties = ( ), }; break; - case FieldMetadataType.JSON: + case FieldMetadataType.RAW_JSON: type: 'object'; break; default: diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts index ef6a6d387604..7f6dbfd04207 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record-update.event.ts @@ -4,5 +4,6 @@ export class ObjectRecordUpdateEvent extends ObjectRecordBaseEvent { details: { before: T; after: T; + diff?: Partial; }; } diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts index 24b59342749f..a82ed3e0a254 100644 --- a/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts +++ b/packages/twenty-server/src/engine/integrations/event-emitter/types/object-record.base.event.ts @@ -3,6 +3,7 @@ import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metad export class ObjectRecordBaseEvent { workspaceId: string; recordId: string; + userId?: string; objectMetadata: ObjectMetadataInterface; details: any; } diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/utils/__tests__/object-record-changed-values.spec.ts b/packages/twenty-server/src/engine/integrations/event-emitter/utils/__tests__/object-record-changed-values.spec.ts new file mode 100644 index 000000000000..abe8dad89c92 --- /dev/null +++ b/packages/twenty-server/src/engine/integrations/event-emitter/utils/__tests__/object-record-changed-values.spec.ts @@ -0,0 +1,65 @@ +import { objectRecordChangedValues } from 'src/engine/integrations/event-emitter/utils/object-record-changed-values'; + +describe('objectRecordChangedValues', () => { + it('detects changes in scalar values correctly', () => { + const oldRecord = { id: 1, name: 'Original Name', updatedAt: new Date() }; + const newRecord = { id: 1, name: 'Updated Name', updatedAt: new Date() }; + + const result = objectRecordChangedValues(oldRecord, newRecord); + + expect(result).toEqual({ + name: { before: 'Original Name', after: 'Updated Name' }, + }); + }); +}); + +it('ignores changes in properties that are objects', () => { + const oldRecord = { id: 1, details: { age: 20 } }; + const newRecord = { id: 1, details: { age: 21 } }; + + const result = objectRecordChangedValues(oldRecord, newRecord); + + expect(result).toEqual({}); +}); + +it('ignores changes to the updatedAt field', () => { + const oldRecord = { id: 1, updatedAt: new Date('2020-01-01') }; + const newRecord = { id: 1, updatedAt: new Date('2024-01-01') }; + + const result = objectRecordChangedValues(oldRecord, newRecord); + + expect(result).toEqual({}); +}); + +it('returns an empty object when there are no changes', () => { + const oldRecord = { id: 1, name: 'Name', value: 100 }; + const newRecord = { id: 1, name: 'Name', value: 100 }; + + const result = objectRecordChangedValues(oldRecord, newRecord); + + expect(result).toEqual({}); +}); + +it('correctly handles a mix of changed, unchanged, and special case values', () => { + const oldRecord = { + id: 1, + name: 'Original', + status: 'active', + updatedAt: new Date(2020, 1, 1), + config: { theme: 'dark' }, + }; + const newRecord = { + id: 1, + name: 'Updated', + status: 'active', + updatedAt: new Date(2021, 1, 1), + config: { theme: 'light' }, + }; + const expectedChanges = { + name: { before: 'Original', after: 'Updated' }, + }; + + const result = objectRecordChangedValues(oldRecord, newRecord); + + expect(result).toEqual(expectedChanges); +}); diff --git a/packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-values.ts b/packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-values.ts new file mode 100644 index 000000000000..99d82d2bf8bc --- /dev/null +++ b/packages/twenty-server/src/engine/integrations/event-emitter/utils/object-record-changed-values.ts @@ -0,0 +1,28 @@ +import deepEqual from 'deep-equal'; + +export const objectRecordChangedValues = ( + oldRecord: Record, + newRecord: Record, +) => { + const isObject = (value: any) => { + return typeof value === 'object' && value !== null && !Array.isArray(value); + }; + + const changedValues = Object.keys(newRecord).reduce( + (acc, key) => { + // Discard if values are objects (e.g. we don't want Company.AccountOwner ; we have AccountOwnerId already) + if (isObject(oldRecord[key]) || isObject(newRecord[key])) { + return acc; + } + + if (!deepEqual(oldRecord[key], newRecord[key]) && key != 'updatedAt') { + acc[key] = { before: oldRecord[key], after: newRecord[key] }; + } + + return acc; + }, + {} as Record, + ); + + return changedValues; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts index 89830525a159..1d2b5f86fea4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts @@ -17,7 +17,7 @@ export class FieldMetadataDefaultValueString { value: string | null; } -export class FieldMetadataDefaultValueJson { +export class FieldMetadataDefaultValueRawJson { @ValidateIf((_object, value) => value !== null) @IsJSON() value: JSON | null; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts index 11bf1de227f8..e98831cea3a2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts @@ -36,7 +36,7 @@ export enum FieldMetadataType { MULTI_SELECT = 'MULTI_SELECT', RELATION = 'RELATION', POSITION = 'POSITION', - JSON = 'JSON', + RAW_JSON = 'RAW_JSON', } @Entity('fieldMetadata') diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts index 191f077bc2f0..e66e1249ba40 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts @@ -3,7 +3,7 @@ import { FieldMetadataDefaultValueCurrency, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, - FieldMetadataDefaultValueJson, + FieldMetadataDefaultValueRawJson, FieldMetadataDefaultValueLink, FieldMetadataDefaultValueNumber, FieldMetadataDefaultValueString, @@ -51,7 +51,7 @@ type FieldMetadataDefaultValueMapping = { [FieldMetadataType.RATING]: FieldMetadataDefaultValueString; [FieldMetadataType.SELECT]: FieldMetadataDefaultValueString; [FieldMetadataType.MULTI_SELECT]: FieldMetadataDefaultValueStringArray; - [FieldMetadataType.JSON]: FieldMetadataDefaultValueJson; + [FieldMetadataType.RAW_JSON]: FieldMetadataDefaultValueRawJson; }; type DefaultValueByFieldMetadata = [ diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts index e1d469439993..e9d3799d61fe 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-target-column-map.util.ts @@ -35,7 +35,7 @@ export function generateTargetColumnMap( case FieldMetadataType.SELECT: case FieldMetadataType.MULTI_SELECT: case FieldMetadataType.POSITION: - case FieldMetadataType.JSON: + case FieldMetadataType.RAW_JSON: return { value: columnName, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts index 4c436bff8a8c..5da968a42424 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts @@ -9,7 +9,7 @@ import { FieldMetadataDefaultValueCurrency, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, - FieldMetadataDefaultValueJson, + FieldMetadataDefaultValueRawJson, FieldMetadataDefaultValueLink, FieldMetadataDefaultValueNumber, FieldMetadataDefaultValueString, @@ -40,7 +40,7 @@ export const defaultValueValidatorsMap = { [FieldMetadataType.RATING]: [FieldMetadataDefaultValueString], [FieldMetadataType.SELECT]: [FieldMetadataDefaultValueString], [FieldMetadataType.MULTI_SELECT]: [FieldMetadataDefaultValueStringArray], - [FieldMetadataType.JSON]: [FieldMetadataDefaultValueJson], + [FieldMetadataType.RAW_JSON]: [FieldMetadataDefaultValueRawJson], }; export const validateDefaultValueForType = ( diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts index cb309c3a4b08..c413da18c2ec 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts @@ -29,7 +29,7 @@ export const fieldMetadataTypeToColumnType = ( case FieldMetadataType.SELECT: case FieldMetadataType.MULTI_SELECT: return 'enum'; - case FieldMetadataType.JSON: + case FieldMetadataType.RAW_JSON: return 'jsonb'; default: throw new Error(`Cannot convert ${fieldMetadataType} to column type.`); diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts index 8a4faf5a6bbb..bd884e8212e1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts @@ -67,7 +67,7 @@ export class WorkspaceMigrationFactory { [FieldMetadataType.NUMERIC, { factory: this.basicColumnActionFactory }], [FieldMetadataType.NUMBER, { factory: this.basicColumnActionFactory }], [FieldMetadataType.POSITION, { factory: this.basicColumnActionFactory }], - [FieldMetadataType.JSON, { factory: this.basicColumnActionFactory }], + [FieldMetadataType.RAW_JSON, { factory: this.basicColumnActionFactory }], [ FieldMetadataType.PROBABILITY, { factory: this.basicColumnActionFactory }, diff --git a/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts b/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts index 593bde6e5ddf..427b432f24e3 100644 --- a/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts +++ b/packages/twenty-server/src/engine/object-metadata-repository/metadata-to-repository.mapping.ts @@ -5,6 +5,7 @@ import { CalendarEventRepository } from 'src/modules/calendar/repositories/calen import { CompanyRepository } from 'src/modules/company/repositories/company.repository'; import { BlocklistRepository } from 'src/modules/connected-account/repositories/blocklist.repository'; import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository'; +import { EventRepository } from 'src/modules/event/repositiories/event.repository'; import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/repositories/message-channel-message-association.repository'; import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; @@ -22,6 +23,7 @@ export const metadataToRepositoryMapping = { CalendarEventObjectMetadata: CalendarEventRepository, CompanyObjectMetadata: CompanyRepository, ConnectedAccountObjectMetadata: ConnectedAccountRepository, + EventObjectMetadata: EventRepository, MessageChannelMessageAssociationObjectMetadata: MessageChannelMessageAssociationRepository, MessageChannelObjectMetadata: MessageChannelRepository, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts index c8999c7185cb..f5fa6a8936a9 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/utils/map-field-metadata-type-to-data-type.util.ts @@ -22,7 +22,7 @@ export const mapFieldMetadataTypeToDataType = ( return 'boolean'; case FieldMetadataType.DATE_TIME: return 'timestamp'; - case FieldMetadataType.JSON: + case FieldMetadataType.RAW_JSON: return 'jsonb'; case FieldMetadataType.RATING: case FieldMetadataType.SELECT: diff --git a/packages/twenty-server/src/modules/event/repositiories/event.repository.ts b/packages/twenty-server/src/modules/event/repositiories/event.repository.ts new file mode 100644 index 000000000000..1da98ee590be --- /dev/null +++ b/packages/twenty-server/src/modules/event/repositiories/event.repository.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@nestjs/common'; + +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; + +@Injectable() +export class EventRepository { + constructor( + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + ) {} + + public async insert( + name: string, + properties: string, + workspaceMemberId: string | null, + objectName: string, + objectId: string, + workspaceId: string, + ): Promise { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."event" + ("name", "properties", "workspaceMemberId", "${objectName}Id") + VALUES ($1, $2, $3, $4)`, + [name, properties, workspaceMemberId, objectId], + workspaceId, + ); + } +} diff --git a/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts index 78cc91bbf599..ec29cdaa99af 100644 --- a/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts +++ b/packages/twenty-server/src/modules/event/standard-objects/event.object-metadata.ts @@ -39,7 +39,7 @@ export class EventObjectMetadata extends BaseObjectMetadata { @FieldMetadata({ standardId: eventStandardFieldIds.properties, - type: FieldMetadataType.JSON, + type: FieldMetadataType.RAW_JSON, label: 'Event details', description: 'Json value for event details', icon: 'IconListDetails', From 4a493b6ecf5684ba7daf5549205a846ecbc2390d Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 22 Mar 2024 15:04:17 +0100 Subject: [PATCH 42/44] New view picker (#4610) * Implement new view picker * Complete feature * Fixes according to review --- .../components/ObjectMetadataNavItems.tsx | 13 +- .../hooks/internal/useRecordBoardStates.ts | 5 + .../internal/useSetRecordBoardRecordIds.ts | 20 +- .../record-board/hooks/useRecordBoard.ts | 5 + ...rdKanbanFieldMetadataNameComponentState.ts | 7 + .../RecordIndexBoardContainerEffect.tsx | 28 +++ .../components/RecordIndexContainer.tsx | 9 +- .../components/RecordIndexOptionsDropdown.tsx | 4 - .../RecordIndexOptionsDropdownContent.tsx | 71 ++----- .../recordIndexKanbanFieldMetadataIdState.ts | 8 + ...oardColumnDefinitionsFromObjectMetadata.ts | 5 +- .../SignInBackgroundMockContainer.tsx | 2 - .../ui/input/button/components/Button.tsx | 16 +- .../components/LightIconButtonGroup.tsx | 1 + .../ui/input/components/IconPicker.tsx | 3 + .../modules/ui/input/components/Select.tsx | 3 + .../layout/dropdown/components/Dropdown.tsx | 8 +- .../dropdown/components/DropdownMenu.tsx | 5 +- .../components/DropdownMenuHeader.tsx | 9 +- .../dropdown/components/DropdownMenuInput.tsx | 4 +- .../__stories__/DropdownMenu.stories.tsx | 2 +- .../__stories__/DropdownMenuInput.stories.tsx | 2 +- ...ffect.tsx => QueryParamsFiltersEffect.tsx} | 19 +- .../components/QueryParamsViewIdEffect.tsx | 38 ++++ .../components/UpdateViewButtonGroup.tsx | 106 +++++++--- .../src/modules/views/components/ViewBar.tsx | 32 ++- .../views/components/ViewBarEffect.tsx | 18 +- .../views/components/ViewsDropdownButton.tsx | 189 ------------------ .../constants/UpdateViewButtonDropdownId.ts | 1 + .../views/constants/UpdateViewDropdownId.ts | 1 - .../views/constants/ViewsDropdownId.ts | 1 - .../hooks/internal/useViewFromQueryParams.ts | 5 +- .../views/hooks/internal/useViewStates.ts | 5 - .../modules/views/hooks/useGetCurrentView.ts | 15 +- .../src/modules/views/hooks/useHandleViews.ts | 74 +++++-- .../useSaveCurrentViewFiltersAndSorts.ts | 6 +- .../modules/views/hooks/useViewBarEditMode.ts | 14 -- .../src/modules/views/types/GraphQLView.ts | 4 +- .../modules/views/types/ViewsHotkeyScope.ts | 2 +- .../views/utils/getObjectMetadataItemViews.ts | 29 +++ .../ViewPickerCreateOrEditButton.tsx | 81 ++++++++ .../ViewPickerCreateOrEditContent.tsx | 180 +++++++++++++++++ .../ViewPickerCreateOrEditContentEffect.tsx | 65 ++++++ .../components/ViewPickerDropdown.tsx | 100 +++++++++ .../components/ViewPickerListContent.tsx | 93 +++++++++ .../constants/ViewPickerDropdownId.ts | 1 + .../ViewPickerKanbanFieldDropdownId.ts | 1 + .../constants/ViewPickerViewTypeDropdownId.ts | 1 + .../hooks/useCloseAndResetViewPicker.ts | 46 +++++ .../hooks/useGetAvailableFieldsForKanban.ts | 34 ++++ .../view-picker/hooks/useViewPickerMode.ts | 15 ++ .../hooks/useViewPickerPersistView.ts | 125 ++++++++++++ .../view-picker/hooks/useViewPickerStates.ts | 50 +++++ .../viewPickerInputNameComponentState.ts | 6 + .../viewPickerIsPersistingComponentState.ts | 7 + ...ckerKanbanFieldMetadataIdComponentState.ts | 7 + .../states/viewPickerModeComponentState.ts} | 6 +- ...viewPickerReferenceViewIdComponentState.ts | 7 + .../viewPickerSelectedIconComponentState.ts | 7 + .../states/viewPickerTypeComponentState.ts | 7 + .../standard-objects-prefill-data/view.ts | 8 +- 61 files changed, 1215 insertions(+), 421 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState.ts create mode 100644 packages/twenty-front/src/modules/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState.ts rename packages/twenty-front/src/modules/views/components/{FilterQueryParamsEffect.tsx => QueryParamsFiltersEffect.tsx} (60%) create mode 100644 packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx delete mode 100644 packages/twenty-front/src/modules/views/components/ViewsDropdownButton.tsx create mode 100644 packages/twenty-front/src/modules/views/constants/UpdateViewButtonDropdownId.ts delete mode 100644 packages/twenty-front/src/modules/views/constants/UpdateViewDropdownId.ts delete mode 100644 packages/twenty-front/src/modules/views/constants/ViewsDropdownId.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/useViewBarEditMode.ts create mode 100644 packages/twenty-front/src/modules/views/utils/getObjectMetadataItemViews.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditButton.tsx create mode 100644 packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContent.tsx create mode 100644 packages/twenty-front/src/modules/views/view-picker/components/ViewPickerCreateOrEditContentEffect.tsx create mode 100644 packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx create mode 100644 packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx create mode 100644 packages/twenty-front/src/modules/views/view-picker/constants/ViewPickerDropdownId.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/constants/ViewPickerKanbanFieldDropdownId.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/constants/ViewPickerViewTypeDropdownId.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/hooks/useCloseAndResetViewPicker.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/hooks/useGetAvailableFieldsForKanban.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/hooks/useViewPickerMode.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/hooks/useViewPickerPersistView.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/hooks/useViewPickerStates.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerInputNameComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerIsPersistingComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerKanbanFieldMetadataIdComponentState.ts rename packages/twenty-front/src/modules/views/{states/viewEditModeComponentState.ts => view-picker/states/viewPickerModeComponentState.ts} (55%) create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerReferenceViewIdComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerSelectedIconComponentState.ts create mode 100644 packages/twenty-front/src/modules/views/view-picker/states/viewPickerTypeComponentState.ts diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx index 43f5210bdff2..750d3ab418ac 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx @@ -6,6 +6,7 @@ import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useIcons } from '@/ui/display/icon/hooks/useIcons'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { GraphQLView } from '@/views/types/GraphQLView'; +import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews'; export const ObjectMetadataNavItems = () => { const { activeObjectMetadataItems } = useObjectMetadataItemForSettings(); @@ -13,7 +14,9 @@ export const ObjectMetadataNavItems = () => { const { getIcon } = useIcons(); const currentPath = useLocation().pathname; - const { records } = usePrefetchedData(PrefetchKey.AllViews); + const { records: views } = usePrefetchedData( + PrefetchKey.AllViews, + ); return ( <> @@ -45,9 +48,11 @@ export const ObjectMetadataNavItems = () => { : -1; }), ].map((objectMetadataItem) => { - const viewId = records?.find( - (view: any) => view?.objectMetadataId === objectMetadataItem.id, - )?.id; + const objectMetadataViews = getObjectMetadataItemViews( + objectMetadataItem.id, + views, + ); + const viewId = objectMetadataViews[0]?.id; const navigationPath = `/objects/${objectMetadataItem.namePlural}${ viewId ? `?view=${viewId}` : '' diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts index 1c8f8a1849bd..7758ca97fae1 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useRecordBoardStates.ts @@ -8,6 +8,7 @@ import { onRecordBoardFetchMoreVisibilityChangeComponentState } from '@/object-r import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState'; import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState'; import { recordBoardFiltersComponentState } from '@/object-record/record-board/states/recordBoardFiltersComponentState'; +import { recordBoardKanbanFieldMetadataNameComponentState } from '@/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState'; import { recordBoardObjectSingularNameComponentState } from '@/object-record/record-board/states/recordBoardObjectSingularNameComponentState'; import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState'; import { recordBoardSortsComponentState } from '@/object-record/record-board/states/recordBoardSortsComponentState'; @@ -32,6 +33,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => { recordBoardObjectSingularNameComponentState, scopeId, ), + kanbanFieldMetadataNameState: extractComponentState( + recordBoardKanbanFieldMetadataNameComponentState, + scopeId, + ), isFetchingRecordState: extractComponentState( isRecordBoardFetchingRecordsComponentState, scopeId, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts index 90f5a1ad93fd..8ead970305d8 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds.ts @@ -10,6 +10,7 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => { recordIdsByColumnIdFamilyState, columnsFamilySelector, columnIdsState, + kanbanFieldMetadataNameState, } = useRecordBoardStates(recordBoardId); const setRecordIds = useRecoilCallback( @@ -26,8 +27,18 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => { .getLoadable(recordIdsByColumnIdFamilyState(columnId)) .getValue(); + const kanbanFieldMetadataName = snapshot + .getLoadable(kanbanFieldMetadataNameState) + .getValue(); + + if (!kanbanFieldMetadataName) { + return; + } + const columnRecordIds = records - .filter((record) => record.stage === column?.value) + .filter( + (record) => record[kanbanFieldMetadataName] === column?.value, + ) .sort(sortRecordsByPosition) .map((record) => record.id); @@ -36,7 +47,12 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => { } }); }, - [columnsFamilySelector, columnIdsState, recordIdsByColumnIdFamilyState], + [ + columnIdsState, + columnsFamilySelector, + recordIdsByColumnIdFamilyState, + kanbanFieldMetadataNameState, + ], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts index f6a266d4746b..25a358e7ac91 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoard.ts @@ -12,12 +12,16 @@ export const useRecordBoard = (recordBoardId?: string) => { selectedRecordIdsSelector, isCompactModeActiveState, onFetchMoreVisibilityChangeState, + kanbanFieldMetadataNameState, } = useRecordBoardStates(recordBoardId); const { setColumns } = useSetRecordBoardColumns(recordBoardId); const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId); const setFieldDefinitions = useSetRecoilState(fieldDefinitionsState); const setObjectSingularName = useSetRecoilState(objectSingularNameState); + const setKanbanFieldMetadataName = useSetRecoilState( + kanbanFieldMetadataNameState, + ); return { scopeId, @@ -25,6 +29,7 @@ export const useRecordBoard = (recordBoardId?: string) => { setRecordIds, setFieldDefinitions, setObjectSingularName, + setKanbanFieldMetadataName, selectedRecordIdsSelector, isCompactModeActiveState, onFetchMoreVisibilityChangeState, diff --git a/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState.ts b/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState.ts new file mode 100644 index 000000000000..26490c9298b3 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState.ts @@ -0,0 +1,7 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const recordBoardKanbanFieldMetadataNameComponentState = + createComponentState({ + key: 'recordBoardKanbanFieldMetadataNameComponentState', + defaultValue: undefined, + }); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx index 3e7fff5bd0e7..df517ccbe8f4 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainerEffect.tsx @@ -8,7 +8,10 @@ import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoar import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection'; import { useLoadRecordIndexBoard } from '@/object-record/record-index/hooks/useLoadRecordIndexBoard'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; +import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState'; import { computeRecordBoardColumnDefinitionsFromObjectMetadata } from '@/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata'; +import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { isDefined } from '~/utils/isDefined'; type RecordIndexBoardContainerEffectProps = { objectNameSingular: string; @@ -31,6 +34,7 @@ export const RecordIndexBoardContainerEffect = ({ selectedRecordIdsSelector, setFieldDefinitions, onFetchMoreVisibilityChangeState, + setKanbanFieldMetadataName, } = useRecordBoard(recordBoardId); const { fetchMoreRecords, loading } = useLoadRecordIndexBoard({ @@ -43,6 +47,10 @@ export const RecordIndexBoardContainerEffect = ({ onFetchMoreVisibilityChangeState, ); + const recordIndexKanbanFieldMetadataId = useRecoilValue( + recordIndexKanbanFieldMetadataIdState, + ); + useEffect(() => { setOnFetchMoreVisibilityChange(() => () => { if (!loading) { @@ -67,6 +75,7 @@ export const RecordIndexBoardContainerEffect = ({ setColumns( computeRecordBoardColumnDefinitionsFromObjectMetadata( objectMetadataItem, + recordIndexKanbanFieldMetadataId ?? '', navigateToSelectSettings, ), ); @@ -74,6 +83,7 @@ export const RecordIndexBoardContainerEffect = ({ navigateToSelectSettings, objectMetadataItem, objectNameSingular, + recordIndexKanbanFieldMetadataId, setColumns, ]); @@ -85,6 +95,24 @@ export const RecordIndexBoardContainerEffect = ({ setFieldDefinitions(recordIndexFieldDefinitions); }, [objectMetadataItem, setFieldDefinitions, recordIndexFieldDefinitions]); + useEffect(() => { + if (isDefined(recordIndexKanbanFieldMetadataId)) { + const kanbanFieldMetadataName = objectMetadataItem?.fields.find( + (field) => + field.type === FieldMetadataType.Select && + field.id === recordIndexKanbanFieldMetadataId, + )?.name; + + if (isDefined(kanbanFieldMetadataName)) { + setKanbanFieldMetadataName(kanbanFieldMetadataName); + } + } + }, [ + objectMetadataItem, + recordIndexKanbanFieldMetadataId, + setKanbanFieldMetadataName, + ]); + const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 1d9e89b250d0..3fceb3f2cce3 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -10,10 +10,10 @@ import { RecordIndexTableContainer } from '@/object-record/record-index/componen import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect'; import { RecordIndexViewBarEffect } from '@/object-record/record-index/components/RecordIndexViewBarEffect'; import { RecordIndexOptionsDropdown } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdown'; -import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState'; import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState'; +import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState'; import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState'; import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; @@ -65,6 +65,9 @@ export const RecordIndexContainer = ({ const setRecordIndexIsCompactModeActive = useSetRecoilState( recordIndexIsCompactModeActiveState, ); + const setRecordIndexViewKanbanFieldMetadataIdState = useSetRecoilState( + recordIndexKanbanFieldMetadataIdState, + ); const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({ recordTableId: recordIndexId, @@ -129,9 +132,11 @@ export const RecordIndexContainer = ({ mapViewSortsToSorts(view.viewSorts, sortDefinitions), ); setRecordIndexViewType(view.type); + setRecordIndexViewKanbanFieldMetadataIdState( + view.kanbanFieldMetadataId, + ); setRecordIndexIsCompactModeActive(view.isCompact); }} - optionsDropdownScopeId={RECORD_INDEX_OPTIONS_DROPDOWN_ID} /> { - const { setViewEditMode } = useViewBarEditMode(recordIndexId); - return ( } - onClickOutside={() => setViewEditMode('none')} /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx index 19f1e2594736..9d48f624c2cb 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx @@ -1,6 +1,5 @@ -import { useRef, useState } from 'react'; +import { useState } from 'react'; import { Key } from 'ts-key-enum'; -import { v4 } from 'uuid'; import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId'; import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard'; @@ -14,7 +13,6 @@ import { IconTag, } from '@/ui/display/icon'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; -import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; @@ -23,8 +21,6 @@ import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemTog import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; -import { useHandleViews } from '@/views/hooks/useHandleViews'; -import { useViewBarEditMode } from '@/views/hooks/useViewBarEditMode'; import { ViewType } from '@/views/types/ViewType'; type RecordIndexOptionsMenu = 'fields'; @@ -40,9 +36,6 @@ export const RecordIndexOptionsDropdownContent = ({ recordIndexId, objectNameSingular, }: RecordIndexOptionsDropdownContentProps) => { - const { updateCurrentView, createEmptyView, selectView } = - useHandleViews(recordIndexId); - const { viewEditMode, setViewEditMode } = useViewBarEditMode(recordIndexId); const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView(); const { closeDropdown } = useDropdown(RECORD_INDEX_OPTIONS_DROPDOWN_ID); @@ -53,8 +46,6 @@ export const RecordIndexOptionsDropdownContent = ({ const resetMenu = () => setCurrentMenu(undefined); - const viewEditInputRef = useRef(null); - const handleSelectMenu = (option: RecordIndexOptionsMenu) => { setCurrentMenu(option); }; @@ -67,25 +58,6 @@ export const RecordIndexOptionsDropdownContent = ({ TableOptionsHotkeyScope.Dropdown, ); - useScopedHotkeys( - Key.Enter, - async () => { - const name = viewEditInputRef.current?.value; - if (viewEditMode === 'create') { - const id = v4(); - await createEmptyView(id, name ?? ''); - selectView(id); - } else { - updateCurrentView({ name }); - } - - resetMenu(); - setViewEditMode('none'); - closeDropdown(); - }, - TableOptionsHotkeyScope.Dropdown, - ); - const { handleColumnVisibilityChange, handleReorderColumns, @@ -128,37 +100,18 @@ export const RecordIndexOptionsDropdownContent = ({ return ( <> {!currentMenu && ( - <> - + handleSelectMenu('fields')} + LeftIcon={IconTag} + text="Fields" /> - - - handleSelectMenu('fields')} - LeftIcon={IconTag} - text="Fields" - /> - openRecordSpreadsheetImport()} - LeftIcon={IconFileImport} - text="Import" - /> - - + openRecordSpreadsheetImport()} + LeftIcon={IconFileImport} + text="Import" + /> +
      )} {currentMenu === 'fields' && ( <> diff --git a/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState.ts b/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState.ts new file mode 100644 index 000000000000..5ff8ba4feb72 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState.ts @@ -0,0 +1,8 @@ +import { createState } from '@/ui/utilities/state/utils/createState'; + +export const recordIndexKanbanFieldMetadataIdState = createState( + { + key: 'recordIndexKanbanFieldMetadataIdState', + defaultValue: null, + }, +); diff --git a/packages/twenty-front/src/modules/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata.ts b/packages/twenty-front/src/modules/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata.ts index 5af6540aecbb..8e70a4e5c0cb 100644 --- a/packages/twenty-front/src/modules/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata.ts @@ -5,10 +5,13 @@ import { FieldMetadataType } from '~/generated-metadata/graphql'; export const computeRecordBoardColumnDefinitionsFromObjectMetadata = ( objectMetadataItem: ObjectMetadataItem, + kanbanFieldMetadataId: string, navigateToSelectSettings: () => void, ): RecordBoardColumnDefinition[] => { const selectFieldMetadataItem = objectMetadataItem.fields.find( - (field) => field.type === FieldMetadataType.Select, + (field) => + field.id === kanbanFieldMetadataId && + field.type === FieldMetadataType.Select, ); if (!selectFieldMetadataItem) { diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx index 447ca98aa402..699b82af7bff 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx @@ -1,7 +1,6 @@ import styled from '@emotion/styled'; import { RecordIndexOptionsDropdown } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdown'; -import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId'; import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers'; import { SignInBackgroundMockContainerEffect } from '@/sign-in-background-mock/components/SignInBackgroundMockContainerEffect'; import { ViewBar } from '@/views/components/ViewBar'; @@ -32,7 +31,6 @@ export const SignInBackgroundMockContainer = () => { viewType={ViewType.Table} /> } - optionsDropdownScopeId={RECORD_INDEX_OPTIONS_DROPDOWN_ID} /> ) => void; @@ -28,7 +29,13 @@ export type ButtonProps = { const StyledButton = styled.button< Pick< ButtonProps, - 'fullWidth' | 'variant' | 'size' | 'position' | 'accent' | 'focus' + | 'fullWidth' + | 'variant' + | 'size' + | 'position' + | 'accent' + | 'focus' + | 'justify' > >` align-items: center; @@ -177,9 +184,7 @@ const StyledButton = styled.button< `; case 'danger': return css` - background: ${!disabled - ? theme.background.transparent.primary - : 'transparent'}; + background: transparent; border-color: ${variant === 'secondary' ? focus ? theme.color.red @@ -236,6 +241,7 @@ const StyledButton = styled.button< font-weight: 500; gap: ${({ theme }) => theme.spacing(1)}; height: ${({ size }) => (size === 'small' ? '24px' : '32px')}; + justify-content: ${({ justify }) => justify}; padding: ${({ theme }) => { return `0 ${theme.spacing(2)}`; }}; @@ -266,6 +272,7 @@ export const Button = ({ position = 'standalone', soon = false, disabled = false, + justify = 'flex-start', focus = false, onClick, }: ButtonProps) => { @@ -279,6 +286,7 @@ export const Button = ({ position={position} disabled={soon || disabled} focus={focus} + justify={justify} accent={accent} className={className} onClick={onClick} diff --git a/packages/twenty-front/src/modules/ui/input/button/components/LightIconButtonGroup.tsx b/packages/twenty-front/src/modules/ui/input/button/components/LightIconButtonGroup.tsx index ff548e5df72c..adb20d64bcac 100644 --- a/packages/twenty-front/src/modules/ui/input/button/components/LightIconButtonGroup.tsx +++ b/packages/twenty-front/src/modules/ui/input/button/components/LightIconButtonGroup.tsx @@ -31,6 +31,7 @@ export const LightIconButtonGroup = ({ diff --git a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx index 2c4c195164e7..ebc209d63022 100644 --- a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx @@ -30,6 +30,7 @@ type IconPickerProps = { onOpen?: () => void; variant?: IconButtonVariant; className?: string; + disableBlur?: boolean; }; const StyledMenuIconItemsContainer = styled.div` @@ -86,6 +87,7 @@ export const IconPicker = ({ onClose, onOpen, variant = 'secondary', + disableBlur = false, className, }: IconPickerProps) => { const [searchString, setSearchString] = useState(''); @@ -148,6 +150,7 @@ export const IconPicker = ({ /> } dropdownMenuWidth={176} + disableBlur={disableBlur} dropdownComponents={ = { export type SelectProps = { className?: string; disabled?: boolean; + disableBlur?: boolean; dropdownId: string; dropdownWidth?: `${string}px` | 'auto' | number; emptyOption?: SelectOption; @@ -75,6 +76,7 @@ const StyledIconChevronDown = styled(IconChevronDown)<{ disabled?: boolean }>` export const Select = ({ className, disabled: disabledFromProps, + disableBlur = false, dropdownId, dropdownWidth = 176, emptyOption, @@ -141,6 +143,7 @@ export const Select = ({ dropdownMenuWidth={dropdownWidth} dropdownPlacement="bottom-start" clickableComponent={selectControl} + disableBlur={disableBlur} dropdownComponents={ <> {!!withSearchInput && ( diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx index 6d303a54cc31..88d8479be24c 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx @@ -35,6 +35,7 @@ type DropdownProps = { dropdownPlacement?: Placement; dropdownMenuWidth?: `${string}px` | `${number}%` | 'auto' | number; dropdownOffset?: { x?: number; y?: number }; + disableBlur?: boolean; onClickOutside?: () => void; onClose?: () => void; onOpen?: () => void; @@ -50,6 +51,7 @@ export const Dropdown = ({ dropdownHotkeyScope, dropdownPlacement = 'bottom-end', dropdownOffset = { x: 0, y: 0 }, + disableBlur = false, onClickOutside, onClose, onOpen, @@ -109,7 +111,10 @@ export const Dropdown = ({ {clickableComponent && (
      { + toggleDropdown(); + onClickOutside?.(); + }} className={className} > {clickableComponent} @@ -123,6 +128,7 @@ export const Dropdown = ({ )} {isDropdownOpen && ( theme.background.transparent.forBackdropFilter}; + background: ${({ theme, disableBlur }) => + disableBlur + ? theme.background.primary + : theme.background.transparent.secondary}; border: 1px solid ${({ theme }) => theme.border.color.medium}; border-radius: ${({ theme }) => theme.border.radius.md}; diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader.tsx index 68446f9a945b..3c652c86e902 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader.tsx @@ -11,14 +11,11 @@ const StyledHeader = styled.li` display: flex; font-size: ${({ theme }) => theme.font.size.sm}; font-weight: ${({ theme }) => theme.font.weight.medium}; + border-radius: ${({ theme }) => theme.border.radius.sm}; padding: ${({ theme }) => theme.spacing(1)}; user-select: none; - - &:hover { - background: ${({ theme }) => theme.background.transparent.light}; - } `; const StyledChildrenWrapper = styled.span` @@ -46,9 +43,10 @@ export const DropdownMenuHeader = ({ testId, }: DropdownMenuHeaderProps) => { return ( - + {StartIcon && ( {children} {EndIcon && ( ->(({ autoFocus, defaultValue, placeholder, onChange }, ref) => { +>(({ autoFocus, value, placeholder, onChange }, ref) => { return ( - + {optionsMock.map(({ name }) => ( diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuInput.stories.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuInput.stories.tsx index 21e5d765399a..42838fca3b4d 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuInput.stories.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuInput.stories.tsx @@ -8,7 +8,7 @@ const meta: Meta = { title: 'UI/Layout/Dropdown/DropdownMenuInput', component: DropdownMenuInput, decorators: [ComponentDecorator], - args: { defaultValue: 'Lorem ipsum' }, + args: { value: 'Lorem ipsum' }, }; export default meta; diff --git a/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx similarity index 60% rename from packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx rename to packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx index ad9d60800555..25278a77c9c4 100644 --- a/packages/twenty-front/src/modules/views/components/FilterQueryParamsEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx @@ -1,33 +1,24 @@ import { useEffect } from 'react'; -import { isUndefined } from '@sniptt/guards'; import { useSetRecoilState } from 'recoil'; import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; import { useViewStates } from '@/views/hooks/internal/useViewStates'; import { useResetCurrentView } from '@/views/hooks/useResetCurrentView'; -export const FilterQueryParamsEffect = () => { - const { hasFiltersQueryParams, getFiltersFromQueryParams, viewIdQueryParam } = +export const QueryParamsFiltersEffect = () => { + const { hasFiltersQueryParams, getFiltersFromQueryParams } = useViewFromQueryParams(); - const { unsavedToUpsertViewFiltersState, currentViewIdState } = - useViewStates(); + const { unsavedToUpsertViewFiltersState } = useViewStates(); const setUnsavedViewFilter = useSetRecoilState( unsavedToUpsertViewFiltersState, ); - const setCurrentViewId = useSetRecoilState(currentViewIdState); const { resetCurrentView } = useResetCurrentView(); useEffect(() => { - if (isUndefined(viewIdQueryParam) || !viewIdQueryParam) { + if (!hasFiltersQueryParams) { return; } - setCurrentViewId(viewIdQueryParam); - }, [getFiltersFromQueryParams, setCurrentViewId, viewIdQueryParam]); - - useEffect(() => { - if (!hasFiltersQueryParams) return; - getFiltersFromQueryParams().then((filtersFromParams) => { if (Array.isArray(filtersFromParams)) { setUnsavedViewFilter(filtersFromParams); @@ -44,5 +35,5 @@ export const FilterQueryParamsEffect = () => { setUnsavedViewFilter, ]); - return null; + return <>; }; diff --git a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx new file mode 100644 index 000000000000..a7130fb3bf17 --- /dev/null +++ b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx @@ -0,0 +1,38 @@ +import { useEffect } from 'react'; +import { isUndefined } from '@sniptt/guards'; +import { useRecoilState } from 'recoil'; + +import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; +import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; +import { isDefined } from '~/utils/isDefined'; + +export const QueryParamsViewIdEffect = () => { + const { getFiltersFromQueryParams, viewIdQueryParam } = + useViewFromQueryParams(); + const { currentViewIdState } = useViewStates(); + + const [currentViewId, setCurrentViewId] = useRecoilState(currentViewIdState); + const { viewsOnCurrentObject } = useGetCurrentView(); + + useEffect(() => { + const indexView = viewsOnCurrentObject.find((view) => view.key === 'INDEX'); + + if (isUndefined(viewIdQueryParam) && isDefined(indexView)) { + setCurrentViewId(indexView.id); + return; + } + + if (isDefined(viewIdQueryParam)) { + setCurrentViewId(viewIdQueryParam); + } + }, [ + currentViewId, + getFiltersFromQueryParams, + setCurrentViewId, + viewIdQueryParam, + viewsOnCurrentObject, + ]); + + return <>; +}; diff --git a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx index d4dac54f45a4..0bc6c43164f4 100644 --- a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx +++ b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx @@ -7,14 +7,18 @@ import { Button } from '@/ui/input/button/components/Button'; import { ButtonGroup } from '@/ui/input/button/components/ButtonGroup'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; -import { UPDATE_VIEW_DROPDOWN_ID } from '@/views/constants/UpdateViewDropdownId'; +import { UPDATE_VIEW_BUTTON_DROPDOWN_ID } from '@/views/constants/UpdateViewButtonDropdownId'; import { useViewStates } from '@/views/hooks/internal/useViewStates'; +import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; import { useSaveCurrentViewFiltersAndSorts } from '@/views/hooks/useSaveCurrentViewFiltersAndSorts'; +import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId'; +import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode'; +import { useViewPickerStates } from '@/views/view-picker/hooks/useViewPickerStates'; const StyledContainer = styled.div` - background: ${({ theme }) => theme.color.blue}; border-radius: ${({ theme }) => theme.border.radius.md}; display: inline-flex; margin-right: ${({ theme }) => theme.spacing(2)}; @@ -23,25 +27,50 @@ const StyledContainer = styled.div` export type UpdateViewButtonGroupProps = { hotkeyScope: HotkeyScope; - onViewEditModeChange?: () => void; }; export const UpdateViewButtonGroup = ({ hotkeyScope, - onViewEditModeChange, }: UpdateViewButtonGroupProps) => { - const { canPersistViewSelector, viewEditModeState } = useViewStates(); + const { canPersistViewSelector, currentViewIdState } = useViewStates(); const { saveCurrentViewFilterAndSorts } = useSaveCurrentViewFiltersAndSorts(); - const setViewEditMode = useSetRecoilState(viewEditModeState); + const { setViewPickerMode } = useViewPickerMode(); + const { viewPickerReferenceViewIdState } = useViewPickerStates(); const canPersistView = useRecoilValue(canPersistViewSelector()); - const handleCreateViewButtonClick = useCallback(() => { - setViewEditMode('create'); - onViewEditModeChange?.(); - }, [setViewEditMode, onViewEditModeChange]); + const { closeDropdown: closeUpdateViewButtonDropdown } = useDropdown( + UPDATE_VIEW_BUTTON_DROPDOWN_ID, + ); + const { openDropdown: openViewPickerDropdown } = useDropdown( + VIEW_PICKER_DROPDOWN_ID, + ); + const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView(); + + const currentViewId = useRecoilValue(currentViewIdState); + + const setViewPickerReferenceViewId = useSetRecoilState( + viewPickerReferenceViewIdState, + ); + + const handleViewCreate = useCallback(() => { + if (!currentViewId) { + return; + } + openViewPickerDropdown(); + setViewPickerReferenceViewId(currentViewId); + setViewPickerMode('create'); + + closeUpdateViewButtonDropdown(); + }, [ + closeUpdateViewButtonDropdown, + currentViewId, + openViewPickerDropdown, + setViewPickerMode, + setViewPickerReferenceViewId, + ]); - const handleViewSubmit = async () => { + const handleViewUpdate = async () => { await saveCurrentViewFilterAndSorts(); }; @@ -51,27 +80,42 @@ export const UpdateViewButtonGroup = ({ return ( - -

      +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

yfY8j)9#ao7$x0VR!E$8 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 Jz^ma^+OqVjOGQ4&O>5VZ^d7mmdE)R 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�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 z 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%0AeS_ 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