Commit Graph

403 Commits

Author SHA1 Message Date
f6bfec882a Improve lazy loading (#12393)
Creating manual chunk was a bad idea, we should always solve lazy
loading problem at the source instance.

Setting a 4.5MB for the index bundle size, CI will fail if we go above.

There is still a lot of room for optimizations!
- More agressive lazy loading (e.g. xyflow and tiptap are still loaded
in index!)
- Add a  prefetch mechanism
- Add stronger CI checks to make sure libraries we've set asides are not
added back
- Fix AllIcons component with does not work as intended (loaded on
initial load)
2025-06-01 09:33:16 +02:00
d4fac6793a Left menu and chip links (#12294)
Small optimization for faster loading (gaining ~80ms - average time of a
click)

It might seem a little over-engineered but there are a lot of edge cases
and I couldn't find a simpler solution

I also tried to tackle Link Chips but it's more complex so this will be
for another PR
2025-05-28 12:32:49 +02:00
d133055609 Fix Client Config async loading (#12308)
Fix ClientConfig async loading

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-28 10:40:20 +02:00
01b40e173b Refactored dropdown content and fixed all dropdown width bugs (#12334)
This PR refactors all the dropdown content wrapping mechanism across the
entire app.

It refactors the internals of the `Dropdown` component and introduces a
new generic `DropdownContent` component that is a generic wrapper used
for each dropdown.

## Why this PR ?

Because we’ve been experiencing continuous regressions for months on the
dropdown content width, with weird scrolling behaviors in some and not
in others, and every time a solution was found for a particular set of
dropdowns, it broke another set of dropdowns, which wasn’t noticed
because doing the QA of all dropdowns of the app is very difficult for
fixing an apparently small bug.

## Don’t we already have a `DropdownMenu` component ?

Indeed, this new `DropdownContent` is almost like `DropdownMenu` and
took inspiration from it but `DropdownContent` acts as a generic content
container that sets the width of the whole dropdown, whether we have a
menu or not.

## Why don’t we put it directly in Dropdown internals ?

Because the Dropdown component is using a complex logic with floating-ui
middleware to compute its position and size, and for this logic to work
correctly, it cannot be responsible for the “wanted” width of its
content, because the children components, which the dropdown is not
aware of, can request different widths after the dropdown has been
mounted.

A good example with multiple use cases inside the same dropdown can be
found in `AdvancedFilterDropdownFilterInput`

Thus, it is the responsibility of the content of the dropdown to
determine the width it wants to have.

## What is the difference with DropdownMenuItemsContainer ?

We can have multiple `DropdownMenuItemsContainer` in a dropdown,
alongside other components like `DropdownMenuSeparator` or
`DropdownMenuHeader`, and each of those components behaves differently
regarding to its width, paddings, etc. Therefore it is logical that the
`DropdownMenuItemsContainer` cannot be responsible for the whole
dropdown content width, and trying to do so has been the cause of many
regressions for months.

Now `DropdownMenuItemsContainer` is taking a width of `auto` by default,
which is the best to adapt to a parent which has a defined width.

## How do I set the width of my dropdown now ?

By passing a pixel width to the props `widthInPixels` of
`DropdownContent`, which only accepts numbers to avoid any confusion
with `auto` , `100%` or `160px` and other specific width variables.

The `dropdownWidth` props has been removed from `<Dropdown>` to avoid
any confusion.

Also the `DropdownMenuItemsContainer` is now using `auto` as its default
width to fill the available space inside `DropdownContent` .

It is highly recommended to use the enum `GenericDropdownContentWidt` to
define your width.

## Where to use this new `DropdownContent` component ?

There are two main use cases.

If the dropdown content is defined directly inline in the Dropdown
props, then it is recommended to use it here too.

On the other hand if the dropdown content is abstracted in another
component, it’s recommended to use this new component alongside the
others components like `DropdownMenuItemsContainer`.

A good rule of thumb is to place `DropdownContent` where
`DropdownMenuItemsContainer`, `DropdownMenuSearchInput`, etc. are
placed.

## What if I have a custom width ?

Just define a constant like `ICON_PICKER_DROPDOWN_CONTENT_WIDTH` and use
it with the props `widthInPixels` .

Otherwise there’s a `GenericDropdownContentWidth` enum. The default
value being `GenericDropdownContentWidth.Medium` (or 200px), which most
dropdowns use.

## QA 


Component | Comment
-- | --
AttachmentDropdown | Fixed overflowing (thanks to DropdownContent)
RecordIndexActionMenuDropdown |  
CommandMenuActionMenuDropdown |  
SupportDropdown | Fixed overflowing (thanks to DropdownContent)
MessageThreadSubscribersDropdownButton | Removed because unused
FavoriteFolderNavigationDrawerItemDropdown | Set width at Narrow
FavoriteFolderPicker |  
ViewPickerOptionDropdown |  
PageFavoriteFolderDropdown | Removed because unused
AdvancedFilterAddFilterRuleSelect |  
AdvancedFilterAddFilterRuleSelect |  
AdvancedFilterFieldSelectMenu |  
AdvancedFilterRecordFilterGroupOptionsDropdown |  
AdvancedFilterRecordFilterOperanceSelect | Set width at Narrow
AdvancedFilterLogicalOperatorDropdown | Set width at Narrow
AdvancedFilterRecordFilterOptionsDropdown |  
AdvancedFilterRootRecordFilterGroup | Fixed broken horizontal scrolling
behavior
AdvancedFilterSubFieldSelectMenu |  
AdvancedFilterDropdownFilterInput |  
ObjectFilterDropdownBooleanSelect |  
ObjectFilterDropdownCountrySelect | Fixed broken menu items container
ObjectFilterDropdownCurrencySelect | Set width to Large
ObjectFilterDropdownFilterInput |  
ObjectFilterDropdownOperandDropdown | Fixed width that was not fixed
ObjectFilterDropdownFilterInput | Fixed width that wasn’t the same for
EditableFilterChip
ObjectFilterDropdownOperandSelect | Refactored
ObjectOptionsDropdownRecordGroupFieldsContent | Added missing separator
ObjectOptionDropdownFieldsContent |  
ObjectOptionsDropdownHiddenFieldsContent |  
ObjectOptionsDropdownLayoutContent |  
ObjectOptionsDropdownLayoutOpenInContent |  
ObjectOptionsDropdownMenuContent |  
ObjectOptionsDropdownRecordGroupFieldsContent |  
ObjectOptionsDropdownRecordGroupsContent |  
ObjectOptionsDropdownRecordGroupSortContent |  
ObjectOptionsDropdownHiddenRecordGroupsContent | Removed unnecessary
DropdownMenuItemsContainer
RecordBoardColumnHeaderAggregateDropdown | Fixed overflowing (thanks to
DropdownContent)
RecordBoardColumnHeaderAggregateDropdownFieldsContent | Fixed
overflowing (thanks to DropdownContent)
RecordBoardColumnHeaderAggregateDropdownMenuContent | Fixed overflowing
(thanks to DropdownContent)
RecordBoardColumnHeaderAggregateDropdownOptionsContent | Fixed
overflowing (thanks to DropdownContent)
MultiItemFieldInput | Fixed overflowing (thanks to DropdownContent)
MultiItemFieldMenuItem |  
MultipleRecordPicker | Fixed overflowing (thanks to DropdownContent)
SingleRecordPicker |  
RecordTableColumnAggregateDropdownSubmenuContent |  
RecordTableColumnAggregateFooterMenuContent |  
RecordTableColumnHeadDropdownMenu | Fixed overflowing (thanks to
DropdownContent)
RecordTableHeaderPlusButtonContent |  
MultipleSelectDropdown | Broken width fixed
ObjectSortDropdownButton |  
RecordDetailRelationRecordsListItem |  
ConfigVariableDatabaseInput |  
ConfigVariableOptionsDropdownContent |  
SettingsObjectFieldActiveActionDropdown | Fixed overflowing (thanks to
DropdownContent)
SettingsObjectFieldDisabledActionDropdown | Set width at Narrow
SettingsObjectSummaryCard | Removed because unused
SettingsDataModelFieldSelectFormOptionRow |  
SettingsDataModelNewFieldBreadcrumbDropdown |  
SettingsObjectInactiveMenuDropDown |  
SettingsRoleAssignementWorkspaceMemberPickerDropdown |  
SettingsRolePermissionObjectLevelObjectPickerDropdownContent |  
SettingsSecurityApprovedAccessDomainRowDropdownMenu | Couldn’t test
SettingsSecuritySSORowDropdownMenu | Couldn’t test
SettingsAccountsRowDropdownMenu | Fixed overflowing (thanks to
DropdownContent)
SettingsIntegrationDatabaseConnectionSummaryCard | Couldn’t test
SettingsServerlessFunctionTablEnvironmentVariableTableRow | Deactivated
scope
MatchColumnSelectFieldSelectDropdownContent | Removed now unnecessary
width on DropdownMenuItemsContainer
MatchColumnSelectSubFieldSelectDropdownContent |  
SubMatchingSelectInput |  
CurrencyPickerDropdownSelect |  
IconPicker | Fixed overflowing (thanks to DropdownContent)
PhoneCountryPickerDropdownSelect |  
Select | Refactored to drilldown wanted width of content, in this case
it’s intended
ExpandedListDropdown |  
ShowPageAddButton | Removed because unused
MultiWorkspaceDropdownDefaultComponent |  
MultiWorkspaceDropdownThemesComponent |  
MultiWorkspaceDropdownWorkspacesListComponent |  
AdvancedFilterDropdownButton |  
EditableFilterChip |  
EditableFilterDropdownButton |  
UpdateViewButtonGroup |  
ViewBarFilterDropdown |  
ViewBarFilterDropdownFieldSelectMenu |  
ViewPickerContentCreateMode |  
ViewPickerContentEditMode |  
ViewPickerListContent |  
WorkflowEditTriggerDatabaseEventForm |  
WorkflowVariablesDropdownFieldItems |  
WorkflowVariablesDropdownObjectItems |  
WorkflowVariablesDropdownWorkflowStepItems |  
CommandMenuContextChipGroups |  
RecordBoardColumnDropdownMenu |  
MultiSelectInput |  
SelectInput |  
CustomSlashMenu |  
DropdownMenu | Removed and replaced by DropdownContent
OverlayContainer and around |  


<!-- notionvc: 1e23bdb8-2dda-4f8d-a64d-ecc829a768a2 -->

## Miscellaneous 

Side notes : 

- The `Select` component is now wrapping the `DropdownContent` because
it computes a dynamic width.
- The advanced filter dropdown has been fixed, it was broken when
resizing the window horizontally, we couldn’t scroll. This specific edge
case was taken into account when refactoring the whole dropdown content
system
- As discussed with Nitin, data-select-disable will probably be removed
entirely, so I let it as is, because right now it is not used by the
refactored d&d selection.
- Duplicate separators under DropdownMenuHeader have been removed.

Fixes : https://github.com/twentyhq/twenty/issues/12327
Fixes : https://github.com/twentyhq/core-team-issues/issues/951
2025-05-27 19:44:13 +02:00
9cdd0fdac0 Revert "Client config not render blocking (#12300)" (#12302)
This reverts commit 4ce7fc6987, to take
more time to address PR comments
2025-05-27 09:04:47 +02:00
4ce7fc6987 Client config not render blocking (#12300)
Changes for performance improvement.
The primary improvements include replacing GraphQL queries with
REST-based client configuration fetching and making the client config
non render-blocking
2025-05-27 00:06:48 +02:00
aa58259019 11744 emails broken image in emails (#12265)
- refactor file tokens
- update file token management
  - generate one token per file per workspaceId
  - move token from query params to url path
2025-05-26 22:05:21 +02:00
362d540aac Misc. of sentry improvements (#12233)
This PR mixes various initiatives to improve visibility on sentry 

**1. Catch errors on workflow jobs**
commit [catch workflowTriggerExceptions in job
handle](1dbba8c9e2)
@thomtrp 

**2. Fix type in messagingImportExceptionHandler** 
commit [fix type issue on
messagingImportExceptionHandler](919bb3844c)
@guillim 

**3. Catch invalid uuid errors thrown by Postgres by rightfully typing
expected id as uuid**
commits [use UUIDFilter instead of IDFilter to get graphqlError in case
of malformed
id](57cc315efe),
[use UUIDFilter
(2)](304553d770),
[fix ids typed as UUID instead of
ID](f95d6319cf)
@Weiko 
⚠️⚠️⚠️ when we deploy this PR we need to flush the schema types from
redis as this PR changes them ⚠️⚠️⚠️


**4. Do not group UNKNOWN errors together**
commit [do not group unknown errors
together](c299b39c8f)
Some CustomException classes have introduced UNKNOWN error codes as a
default fallback error code. We use CustomException codes to group
issues together, but we don't want to do it with UNKNOWN error as they
may not have anything in common. For exemple [this sentry for UNKNOWN
code](https://twenty-v7.sentry.io/issues/6605750776/events/a72272d8941b4fa2add9b1f39c196d3f/?environment=prod&environment=prod-eu&project=4507072499810304&query=Unknown&referrer=next-event&stream_index=0)
groups together "Unknown error importing calendar events for calendar
channel...", "Insufficent permissions...", to name a few.

**5. Improve postgres error grouping**
commit [group together postgres
errors](567c25495e)
Postgres error are thrown by typeORM as QueryFailedError. we have a lot
of them on sentry where they are badly grouped They are currently
grouped on sentry according to the stack trace, which leads them to
sometimes be grouped even if they don't have anything in common : for
exemple [this sentry for
QueryFailedError](https://twenty-v7.sentry.io/issues/6563624590/events/2d636821e27a448595b647b4b5a7d6a8/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=previous-event&sort=date&stream_index=0)
groups together "user mapping not found for "postgres" and "invalide
type for uuid: 'fallback-id'" to name a few. I attempted to improve the
grouping by grouping them with a new custom fingerPrint composed of the
[code returned by
Postgres](https://www.postgresql.org/docs/current/errcodes-appendix.html)
+ the truncated operation name (Find, Aggregate, Check...). This is
still not ideal as postgres code are quite broad - we could have the
same error code for two Find operations with different causes. let's
give this a try !
2025-05-23 13:36:02 +00:00
ddab513c0b patch messages in thread (#12191)
closes https://github.com/twentyhq/twenty/issues/12190
2025-05-23 10:24:13 +00:00
79b4b3f783 Improve lazy loading (#12186)
WIP, using preview app to test performance (which was very bad)
2025-05-22 15:07:01 +02:00
4e7a7ce893 Remove calendar cursor (#12200)
Fixes https://github.com/twentyhq/twenty/issues/12125

The root cause of the infinite loop was the calendar cursor. In some
cases, it was not properly displayed and was causing the loop because of
its animation that was always restarting.

We agreed with @FelixMalfait and @Bonapara that given the current
importance of the feature and the amount of issues associated, we remove
the cursor for now.
2025-05-22 13:35:30 +02:00
c982bcdb52 Introduce focus stack to handle hotkeys (#12166)
# Introduce focus stack to handle hotkeys

This PR introduces a focus stack to track the order in which the
elements are focused:
- Each focused element has a unique focus id
- When an element is focused, it is pushed on top of the stack
- When an element loses focus, we remove it from the stack 

This focus stack is then used to determine which hotkeys are available.
The previous implementation lead to many regressions because of race
conditions, of wrong order of open and close operations and by
overwriting previous states. This implementation should be way more
robust than the previous one.

The new api can be incrementally implemented since it preserves
backwards compatibility by writing to the old hotkey scopes states.
For now, it has been implemented on the modal components.

To test this PR, verify that the shortcuts still work correctly,
especially for the modal components.
2025-05-21 15:52:40 +02:00
76a8a644a2 fix mail thread design (#12167)
## Before
METADATA
<img width="400" alt="Screenshot 2025-05-21 at 11 34 51"
src="https://github.com/user-attachments/assets/b057dd3f-3ba1-4597-86a4-84157941f10a"
/>
SUBJECT
<img width="400" alt="Screenshot 2025-05-21 at 11 34 38"
src="https://github.com/user-attachments/assets/c41bc102-a84d-443f-bf8c-a77ca9eacd2c"
/>
SHARE_EVERYTHING
<img width="400" alt="Screenshot 2025-05-21 at 11 34 04"
src="https://github.com/user-attachments/assets/0ed39c88-3516-4ebf-9950-5ceabbc38f13"
/>


## After
SHARE_EVERYTHING
<img width="400" alt="Screenshot 2025-05-21 at 11 29 18"
src="https://github.com/user-attachments/assets/72efbf0f-021b-4012-8516-8b7b8318a1e8"
/>
METADAT
<img width="400" alt="Screenshot 2025-05-21 at 11 28 49"
src="https://github.com/user-attachments/assets/73065e89-c5ab-4938-ae71-e557aa3fe8f3"
/>
SUBJECT
<img width="400" alt="Screenshot 2025-05-21 at 11 28 35"
src="https://github.com/user-attachments/assets/10487afb-602d-41fc-bb66-15d71e2fb90f"
/>

Design :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=23338-52430&t=9NbeB5idQaaOWPAq-0
2025-05-21 12:07:17 +02:00
0553f58c52 Removed use-context-selector completely (#12139)
This PR removes use-context-selector completely, so that any bug
associated with state synchronization between recoil and
use-context-selector disappears.

There might be a slight performance decrease on the table, but since we
have already improved the average performance per line by a lot, and
that the performance bottleneck right now is the fetch more logic and
the windowing solution we use, it is not relevant.

Also the DX has become so hindered by this parallel state logic recently
(think [cache
invalidation](https://martinfowler.com/bliki/TwoHardThings.html)), that
the main benefit we gain from this removal is the DX improvement.

Fixes https://github.com/twentyhq/twenty/issues/12123
Fixes https://github.com/twentyhq/twenty/issues/12109
2025-05-20 13:35:28 +02:00
9ba24b3654 Fix: Editing a task assignee relation from the list opens both the command menu and the multi item picker (#12138)
Fixes https://github.com/twentyhq/twenty/issues/12129

To fix this, we need to stop the click event from propagating up from
the ActivityTargetsInlineCell

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-20 12:14:19 +02:00
42c69dd11a fix: Ensure attachment modal appears above Command Menu button using createPortal (#12112)
<img width="1509" alt="Screenshot 2025-05-19 at 12 50 48 AM"
src="https://github.com/user-attachments/assets/fba95ecb-015a-4742-bda2-4d515d168c16"
/>


Closes #12092
2025-05-19 23:08:31 +02:00
85e2a2a92b fix: prevent unwanted newlines in note editor when typing (#12128)
https://github.com/user-attachments/assets/16706d7a-fe0e-4979-bd72-00f4bfec594b

Closes #12119

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-05-19 22:43:49 +02:00
bb4fed5a5e Fix Identifier chips in Timeline Activities are broken (#12122)
Fixes https://github.com/twentyhq/twenty/issues/12114
Fixes https://github.com/twentyhq/core-team-issues/issues/856

Links were in the wrong format. This is because the timeline activity
code is re-using FieldDisplay which expects a context with a specific
recordId that we can't have (since this is not a true record but simply
the result of a diff and each row in the diff needs to be unique)
Today we build the artificial record ID like this `eventId + '--' +
fieldMetadataItem.id` to keep it unique.
However, in case the event concerns a labelIdentifier field, it uses the
ChipDisplay which creates a link to the record using the artificial ID
which results in a 404 when using the link.
We don't really need that link since it points to the record itself (the
one that is already opened) so I'm simply removing the
isLabelIdentifierField set in
[EventFieldDiffValue.tsx](https://github.com/twentyhq/twenty/compare/c--fix-identifier_chips_in_timeline_activities_are_broken?expand=1#diff-af17142141c5334214f43840460a142d531c61be7c3cff55bd8a495eb831bc69)
so even if it's one labelIdentifierField, it won't try to display it as
such.

Ideally we should refactor this logic and not try to reuse FieldDisplay
imho, we probably did that to avoid duplicating logic but that's a lot
of "fake" context to get the desired result

Before
<img width="423" alt="Screenshot 2025-05-19 at 15 23 46"
src="https://github.com/user-attachments/assets/b9573f4c-e205-4fdb-bdee-65b890da7810"
/>

After
<img width="428" alt="Screenshot 2025-05-19 at 15 23 33"
src="https://github.com/user-attachments/assets/96f29842-b9aa-4230-8125-dd7d1a56baed"
/>
2025-05-19 16:21:29 +02:00
58b40b1f89 Removed value setter effect completely (#12101)
This PR removes the effect component that was synchronizing the record
store recoil state with the context selector equivalent state that is
used for performance on the tables.

Now we only set the context selector in parallel with the recoil state,
thus avoiding any synchronization side-effect between those two states.
2025-05-17 15:41:01 +02:00
6554947671 Modal API Refactoring (#12062)
# Modal API Refactoring

This PR refactors the modal system to use an imperative approach for
setting hotkey scopes, addressing race conditions that occurred with the
previous effect-based implementation.

Fixes #11986
Closes #12087

## Key Changes:

- **New Modal API**: Introduced a `useModal` hook with `openModal`,
`closeModal`, and `toggleModal` functions, similar to the existing
dropdown API
- **Modal Identification**: Added a `modalId` prop to uniquely identify
modals
- **State Management**: Introduced `isModalOpenedComponentState` and
removed individual boolean state atoms (like
`isRemoveSortingModalOpenState`)
- **Modal Constants**: Added consistent modal ID constants (e.g.,
`FavoriteFolderDeleteModalId`, `RecordIndexRemoveSortingModalId`) for
better maintainability
- **Mount Effects**: Created mount effect components (like
`AuthModalMountEffect`) to handle initial modal opening where needed

## Implementation Details:

- Modified `Modal` and `ConfirmationModal` components to accept the new
`modalId` prop
- Added a component-state-based approach using
`ModalComponentInstanceContext` to track modal state
- Introduced imperative modal handlers that properly manage hotkey
scopes
- Components like `ActionModal` and `AttachmentList` now use the new
`useModal` hook for better control over modal state

## Benefits:

- **Race Condition Prevention**: Hotkey scopes are now set imperatively,
eliminating race conditions
- **Consistent API**: Modal and dropdown now share similar patterns,
improving developer experience

## Tests to do before merging:

1. Action Modals (Modal triggered by an action, for example the delete
action)

2. Auth Modal (`AuthModal.tsx` and `AuthModalMountEffect.tsx`)
   - Test that auth modal opens automatically on mount
   - Verify authentication flow works properly

3. Email Verification Sent Modal (in `SignInUp.tsx`)
   - Verify this modal displays correctly

4. Attachment Preview Modal (in `AttachmentList.tsx`)
   - Test opening preview modal by clicking on attachments
   - Verify close, download functionality works
   - Test modal navigation and interactions

5. Favorite Folder Delete Modal (`CurrentWorkspaceMemberFavorites.tsx`)
   - Test deletion confirmation flow
- Check that modal opens when attempting to delete folders with
favorites

6. Record Board Remove Sorting Modal (`RecordBoard.tsx` using
`RecordIndexRemoveSortingModalId`)
- Test that modal appears when trying to drag records with sorting
enabled
   - Verify sorting removal works correctly

7. Record Group Reorder Confirmation Modal
(`RecordGroupReorderConfirmationModal.tsx`)
   - Test group reordering with sorting enabled
   - Verify confirmation modal properly handles sorting removal

8. Confirmation Modal (base component used by several modals)
   - Test all variants with different confirmation options

For each modal, verify:
- Opening/closing behavior
- Hotkey support (Esc to close, Enter to confirm where applicable)
- Click outside behavior
- Proper z-index stacking
- Any modal-specific functionality
2025-05-16 15:04:22 +00:00
09d92c9113 Fixes infinite loop on record data update in command menu (#12072)
This PR fixes the infinite loop that was happening in `RecordShowEffect`
component due to a useEffect on `recordStoreFamilyState` which was
creating a non-deterministic open loop.

The fix was to use a recoilCallback to avoid reading a stale state from
Recoil with `useRecoilValue`, useRecoilCallback always gets the most
fresh data and commits everything before React goes on with rendering,
thus avoiding any stale value in a useEffect.

Fixes https://github.com/twentyhq/twenty/issues/11079
Fixes https://github.com/twentyhq/core-team-issues/issues/957
2025-05-15 18:26:01 +02:00
aa424c6680 Make workflow custom fields editable (#12063)
Fixes https://github.com/twentyhq/twenty/issues/11989

<img width="1267" alt="Capture d’écran 2025-05-15 à 14 05 15"
src="https://github.com/user-attachments/assets/fbb22f52-2c76-424f-8b8c-fb030fef9fa8"
/>

`isCustom` was not properly set everywhere because it was not mandatory
in `isFieldValueReadOnly`. Removing the default value and adding it to
missing places
2025-05-15 12:28:13 +00:00
c0a0214879 delete attachment when file is removed from activity body (#11952)
Using useEffect triggered at ActivityRichTextEditor unmount, to delete
attachments only when note is closed (and not when file block is deleted
during note update to keep command + z shortcut)

closes : https://github.com/twentyhq/twenty/issues/11229
2025-05-13 19:18:38 +02:00
a2388d2dc7 chunk csv file before preview (#11886)
closes https://github.com/twentyhq/twenty/issues/10971
2025-05-06 17:43:32 +02:00
a60711c808 Ej/fix message visibility (#11874)
<img width="257" alt="Screenshot 2025-05-05 at 15 30 09"
src="https://github.com/user-attachments/assets/5a8e18e0-efc5-4521-9c3a-bf73277ecdf9"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 29 05"
src="https://github.com/user-attachments/assets/c1a784af-a744-497a-b6ce-ec3a9e8b851a"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 33 06"
src="https://github.com/user-attachments/assets/c5fabd1d-a125-49d7-aade-0a208a0eff95"
/>

related to PR https://github.com/twentyhq/twenty/pull/11840 and issue
https://github.com/twentyhq/twenty/issues/9826
2025-05-05 17:23:27 +02:00
521e75981a Fix calendar events & messages fetching + fix timeline design (#11840)
Preview : 

<img width="501" alt="Screenshot 2025-05-02 at 16 24 34"
src="https://github.com/user-attachments/assets/0c649df1-0e26-4ddc-8e13-ebd78af7ec09"
/>


Done : 
- Fix getCalendarEventsFromPersonIds and getCalendarEventsFromCompanyId
(include accountOwner check)
- Fix permission check on pre-hook - Pre-hook seems useless, calendar
events are always on METADATA or SHARE_EVERYTHING visibility, else post
hook always has the responsibility of returning the data user can
access. >> To delete or to keep in case other visibility options are
added ?
- Add post hook to secure finOne / findMany calendarEvents resolver
- Update design

To do :
- same on messages (PR to arrive)

closes : https://github.com/twentyhq/twenty/issues/9826
2025-05-05 13:12:16 +02:00
ee1fe3564a fix: Restoring record results in blank line in TimelineActivity (#11679) (#11856)
Fixes issue #11679 
There were no case of restored so it was defaulting to null thus showing
the blank line

Handled case for restored so it doesn't default to null 

Image shows record restored by the user and restored by other user
![Screenshot 2025-05-03
011257](https://github.com/user-attachments/assets/8b848992-4250-4266-9a3e-1ca89e1a06b8)

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-05 10:25:12 +02:00
6b9128d1ae fix rich text focus (#11821)
Before 


https://github.com/user-attachments/assets/419227fb-fc0e-4d6e-b89a-932b4b76666f

After


https://github.com/user-attachments/assets/e4db323c-2f98-46f6-84e7-8b9bb452e900


Tested in command Menu + table cell edit mode + "plain text" command
menu
2025-04-30 17:28:12 +02:00
457c6ed113 Improve storybook stories (#11694)
## Improvements

### TaskGroups

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/0dbd71fe-3999-4cf5-870e-565b8e2df1b9"
/>

### EventCardMessage

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b41cddc1-3ff2-411f-9ac6-8d4035579e54"
/>

### Blocklist stories

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/e997a0c1-e7e2-4ea4-9253-f31609ee44df"
/>

### WorkflowEditActionUpdateRecord

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/275dab17-ad33-4174-8671-31ba455c20a4"
/>
2025-04-23 13:20:13 +02:00
fa5f758228 Fix storybook / chromatic tests flakyness and integration tests (#11687)
## Storybook flakyness

### Actor Display image flakyness

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/875c0738-5e31-4aba-9231-4ba5f78d1355"
/>

**Fix:** stop using a random usage

### Task Groups broken

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/c67e47a1-a027-43f1-9601-68d61a8052b4"
/>

**Fix:** add missing TabListComponentInstance

## Flaky dates

Add https://github.com/k35o/storybook-addon-mock-date

## Integration tests

Fix broken tests due to relation refactoring
2025-04-23 01:57:36 +02:00
de1489aabb Time line activity wrong type (#11673)
# Introduction
Closes https://github.com/twentyhq/core-team-issues/issues/874

`TimeLineActivity` fields `` and `` were typed as required whereas in
reality are nullable, resulting in the related sentry error.
Refactored the type then the related components in order to handle
nullable use case
2025-04-22 15:17:08 +00:00
d34ec7b253 Fix: "Not shared" label not visible due to extra long email subject (#11492)
Closes #11408 

- Added `min-width: 100px` in `EmailThreadNotShared`
- Added `isShared` prop to `StyledSubject` for better subject handling
in shared visibility scenarios

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-11 10:13:33 +02:00
6f5118c677 Remove fixed width for dropdown variables, fix optimistic on file upload (#11507)
As title
2025-04-10 16:07:32 +02:00
a7e6564017 Make token update synchronous on FE (#11486)
1. Removing tokenPair internal variable of ApolloFactory. We will relay
on cookieStorage
2. setting the cookie explicitely instead of only relaying on recoil
cookieEffect which is too late
2025-04-10 01:39:25 +02:00
17474a0e1e Remove cell hotkey scope (#11435)
Remove FieldContext hotkey scope as:
- each Field should set its own hotkey scope (ex:
emails-field-input-{recordId} or emails-field-input for now)
- while opening a fieldInput, we should synchronously set the
corresponding hotkey scope

To cut this refactoring in half, I'm allowing all input to use
TableHotkeyScope.CellEditMode
2025-04-08 11:18:23 +02:00
3d90eb4eb9 Fix broken dropdown auto resize behavior (#11423)
This PR was originally about fixing advanced filter dropdown auto resize
to avoid breaking the app main container, but the regression is not
limited to advanced filter dropdown, so this PR fixes the regression for
every dropdown in the app.

This PR adds a max dropdown max width to allow resizing dropdowns
horizontally also, which can happen easily for the advanced filter
dropdown.

In this PR we also start removing `fieldMetadataItemUsedInDropdown` in
component `AdvancedFilterDropdownTextInput` because it has no impact
outside of this component which is used only once.

The autoresize behavior determines the right padding-bottom between
mobile and PC.

Mobile : 

<img width="604" alt="Capture d’écran 2025-04-07 à 16 03 12"
src="https://github.com/user-attachments/assets/fbdd8020-1bfc-4e01-8a05-3a9f114cdd40"
/>

PC :

<img width="757" alt="Capture d’écran 2025-04-07 à 16 03 30"
src="https://github.com/user-attachments/assets/f80a5967-8f60-40bb-ae3c-fa9eb4c65707"
/>

Fixes https://github.com/twentyhq/core-team-issues/issues/725
Fixes https://github.com/twentyhq/twenty/issues/11409

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-08 11:03:10 +02:00
2308091b13 Remove overlay-scroll-bar (#11258)
## What

- Deprecate overlayscrollbars as we decided to follow the native
behavior
- rework on performances (avoid calling recoil states too much at field
level which is quite expensive)
- Also implements:
https://github.com/twentyhq/core-team-issues/issues/569

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-04 16:13:48 +02:00
4a4e65fe4a [REFACTOR] Twenty UI multi barrel (#11301)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/591
Same than for `twenty-shared` made in
https://github.com/twentyhq/twenty/pull/11083.

## TODO
- [x] Manual migrate twenty-website twenty-ui imports

## What's next:
- Generate barrel and migration script factorization within own package
+ tests
- Refactoring using preconstruct ? TimeBox
- Lint circular dependencies
- Lint import from barrel and forbid them

### Preconstruct
We need custom rollup plugins addition, but preconstruct does not expose
its rollup configuration. It might be possible to handle this using the
babel overrides. But was a big tunnel.
We could give it a try afterwards ! ( allowing cjs interop and stuff
like that )
Stuck to vite lib app

Closed related PRs:
- https://github.com/twentyhq/twenty/pull/11294
- https://github.com/twentyhq/twenty/pull/11203
2025-04-03 09:47:55 +00:00
9a2f7d8b71 Fix: Timeline responsiveness (#11288)
Fixes #11136


[recording.webm](https://github.com/user-attachments/assets/328afab8-511a-4090-bdb0-e1cdb42565be)
2025-04-02 10:07:05 +02:00
5bd10d40cb Fix deactivate objects impacts (#11185)
In this PR:
- Remove deactivated objects from ActivityTargetInlineCell record picker
- Prevent users to deactivate createdAt, updatedAt, deletedAt fields on
any objects

Still left:
- write unit tests on the assert utils
- write integration tests on field metadata service
- prevent users to deactivate createdAt, updatedAt, deletedAt on FE
2025-03-26 20:45:46 +01:00
0084946b76 608 fix hotkey scope and dropdown issues in the command menu (#11121)
Closes https://github.com/twentyhq/core-team-issues/issues/608

- Introduces a new hotkey scope `CommandMenuFocused`
- Fixes hotkey scopes issues in the side panel
2025-03-24 14:34:09 +00:00
6898a40ac3 Fix relation from many notes (#11120)
Fixes https://github.com/twentyhq/twenty/issues/3415
2025-03-24 15:19:05 +01:00
6e7d2db58f Fix From Many relation for deleted notes crashing (#11117)
In this PR, I'm: 
- fixing the root cause (we should not try to render a RecordChip if the
record is not defined in RelationFromMany Display)
- fixing related typing issues
- we won't be able to catch the issue from TS perspective as
ObjectRecord is a Record of string, any
2025-03-24 13:29:44 +01:00
9ad8287dbc [REFACTOR] twenty-shared multi barrel and CJS/ESM build with preconstruct (#11083)
# Introduction

In this PR we've migrated `twenty-shared` from a `vite` app
[libary-mode](https://vite.dev/guide/build#library-mode) to a
[preconstruct](https://preconstruct.tools/) "atomic" application ( in
the future would like to introduce preconstruct to handle of all our
atomic dependencies such as `twenty-emails` `twenty-ui` etc it will be
integrated at the monorepo's root directly, would be to invasive in the
first, starting incremental via `twenty-shared`)

For more information regarding the motivations please refer to nor:
- https://github.com/twentyhq/core-team-issues/issues/587
-
https://github.com/twentyhq/core-team-issues/issues/281#issuecomment-2630949682

close https://github.com/twentyhq/core-team-issues/issues/589
close https://github.com/twentyhq/core-team-issues/issues/590

## How to test
In order to ease the review this PR will ship all the codegen at the
very end, the actual meaning full diff is `+2,411 −114`
In order to migrate existing dependent packages to `twenty-shared` multi
barrel new arch you need to run in local:
```sh
yarn tsx packages/twenty-shared/scripts/migrateFromSingleToMultiBarrelImport.ts && \
npx nx run-many -t lint --fix -p twenty-front twenty-ui twenty-server twenty-emails twenty-shared twenty-zapier
```
Note that `migrateFromSingleToMultiBarrelImport` is idempotent, it's atm
included in the PR but should not be merged. ( such as codegen will be
added before merging this script will be removed )

## Misc
- related opened issue preconstruct
https://github.com/preconstruct/preconstruct/issues/617

## Closed related PR
- https://github.com/twentyhq/twenty/pull/11028
- https://github.com/twentyhq/twenty/pull/10993
- https://github.com/twentyhq/twenty/pull/10960

## Upcoming enhancement: ( in others dedicated PRs )
- 1/ refactor generate barrel to export atomic module instead of `*`
- 2/ generate barrel own package with several files and tests
- 3/ Migration twenty-ui the same way
- 4/ Use `preconstruct` at monorepo global level

## Conclusion
As always any suggestions are welcomed !
2025-03-22 19:16:06 +01:00
8a21c19f03 Fix missing record field component instanceId 2025-03-22 18:52:57 +01:00
ccf60284cf Various fixes (#11108)
Fixes many bug regarding TableCell and InlineCells
2025-03-22 14:19:10 +01:00
e624e8deee replace search resolvers by global search in front (#11086)
Done
- Replace global search in multi record picker and single record picker

To do
- refactor SingleRecordPicker to match MultipleRecordPicker - next 1:1
- items in this issue
https://github.com/twentyhq/core-team-issues/issues/643



closes https://github.com/twentyhq/core-team-issues/issues/535
2025-03-21 17:25:00 +01:00
d7dabe5826 Update timeline empty state in the side panel (#11093)
Fixes https://github.com/twentyhq/twenty/issues/10914

Before:


https://github.com/user-attachments/assets/83764543-06bf-455e-8b07-fa2822691005


After:


https://github.com/user-attachments/assets/09afa15d-6352-4024-a6b9-2cccf5991d8a
2025-03-21 15:30:14 +01:00
99438a810c Error invalid link (#10288)
Don't have access to push on
https://github.com/twentyhq/twenty/pull/9942, so close it and open new
PR here

<img width="244" alt="Screenshot 2025-02-18 at 11 09 39"
src="https://github.com/user-attachments/assets/4bc1b436-147a-4d17-88c8-2aff0fffd06a"
/>
<img width="246" alt="Screenshot 2025-02-18 at 11 09 51"
src="https://github.com/user-attachments/assets/3d7b2972-ab7e-4e3b-a177-658325a3bb70"
/>

Ok for RecordInlineCell / RecordTableCell and EmailsFieldInput /
LinksFieldInput.
I think it's too complex for a so small issue (agree with you khuddite)

closes https://github.com/twentyhq/twenty/issues/9778
on top of https://github.com/twentyhq/twenty/pull/9942 from @khuddite

---------

Co-authored-by: khuddite <khuddite@gmail.com>
Co-authored-by: khuddite <62555977+khuddite@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-21 10:18:55 +01:00
cfdb3f5778 584 Refactor Tabs (#11008)
Closes https://github.com/twentyhq/core-team-issues/issues/584

This PR:
- Migrates the component state `activeTabIdComponentState` from the
deprecated V1 version to V2.
- Allows the active tab state to be preserved during navigation inside
the side panel and reset when the side panel is closed.
- Allows the active tab state to be preserved when we open a record in
full page from the side panel


https://github.com/user-attachments/assets/f2329d7a-ea15-4bd8-81dc-e98ce11edbd0


https://github.com/user-attachments/assets/474bffd5-29e0-40ba-97f4-fa5e9be34dc2
2025-03-19 15:53:22 +00:00