Commit Graph

210 Commits

Author SHA1 Message Date
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
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
af5762c8ba Infinite scrolling in relation picker menu (#12051)
https://github.com/user-attachments/assets/4be785e0-ea8a-4c8e-840e-6fa0a663d7ba

Closes #11938

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-05-23 17:23:09 +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
051f0fc83f Use data attributes for click outside instead of classNames (#12228)
We previously used classnames to exclude elements from the click outside
listener.

With this PR we can now use `data-click-outside-id` instead of
`classNames` to target the elements we want to exclude from the click
outside listener.

We can also add `data-globally-prevent-click-outside` to a component to
globally prevent triggering click outside listeners for other
components. This attribute is especially useful for confirmation modals
and snackbar items.

Fixes #11785:


https://github.com/user-attachments/assets/318baa7e-0f82-4e3a-a447-bf981328462d
2025-05-22 18:10:51 +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
819b3c6c0d followup #12033 (#12150)
follow up #12033

in #12033, SettingsDataModelFieldRelationForm I changed the the use of
objectMetadataItems to activeObjectMetadataItems, which filtered out
system objects. The naming was one factor for this confusion
Renaming it everywhere to specify that they don't include system objects

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-21 11:45:33 +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
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
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
4d352cb4e4 Keyboard Navigation and Shortcuts Implementation on the board (#11930)
# Keyboard Navigation and Shortcuts Implementation on the board

This PR implements keyboard navigation and shortcuts for the Record
Board component, enabling users to navigate and interact with board
cards using keyboard inputs.

## Key changes

### Navigation Architecture
- Added `useBoardCardNavigation` hook for directional navigation (arrow
keys)
- Implemented scroll behavior to automatically focus visible cards
- Created card focus/active states with component-level management

### State Management
- Added new component states: `focusedBoardCardIndexesComponentState`,
`activeBoardCardIndexesComponentState`,
`isBoardCardActiveComponentFamilyState`
- Extended index tracking with column/row position indicators
- Create hooks to manage these states

### Hotkey Implementation
- Created new `RecordBoardHotkeyEffect` component for hotkey handling
- Added `BoardHotkeyScope`
- Implemented Escape key handling to clear selections
- Replaced table-specific `TableHotkeyScope` with more generic
`RecordIndexHotkeyScope`. This is because, before, the hotkey scope was
always set to Table inside the page change effect, and we used the table
hotkey scope for board shortcuts, which doesn't make a lot of sense.
Since we don't know upon navigation on which type of view we are
navigating, I introduced this generic hotkey scope which can be used on
the table and on the board.

### Page Navigation Integration
- Modified `PageChangeEffect` to handle both table and board view types
- Added cleanup for board state upon navigating away from record pages

### Component Updates
- Updated `RecordBoardColumn` to track indexes for position-based
navigation
- Added `RecordBoardScrollToFocusedCardEffect` for auto-scrolling to
focused cards
- Added `RecordBoardDeactivateBoardCardEffect` for cleanup

This implementation maintains feature parity with table row navigation
while accounting for the 2D navigation needs of the board view.

## New behaviors

### Arrow keys navigation


https://github.com/user-attachments/assets/929ee00d-2f82-43b9-8cde-f7bc8818052f


### Record selection with X


https://github.com/user-attachments/assets/0b534c4d-2865-43ac-8ba3-09cb8c121f06


### Command + Enter opens the record


https://github.com/user-attachments/assets/0df01d1c-0437-4444-beb1-ce74bcfb91a4


### Escape unselect the records and unfocus the card



https://github.com/user-attachments/assets/e2bb176b-b6f7-49ca-9549-803eb31bfc23
2025-05-12 19:02:14 +02:00
da0c7e679e Blocknote editor fix (#11823)
After reading the blocknote documentation :

- we decided to increase to 100% the lines width
- we decided to reduce as much as possible inner padding
- we decided it's on the parent to decide the padding of the richtext
The two last points are recommended in a discussion on the project
blocknote. This way clicking on padding won't trigger weird behaviour on
Chrome.

Fixes
https://github.com/twentyhq/core-team-issues/issues/827#issuecomment-2842350359
2025-05-05 17:22:49 +02:00
1543c900ae Migrate workflow states to component states (#11773)
- Migrated all workflow Recoil states to component states to isolate
each workflow visualizer instance. The use case of having two workflow
visualizers displayed at the same time appeared recently and will grow
in the near future.
- We chose to use the `recordId` as the value for the `instanceId` of
the component states. Currently, there are a few cases where two
workflows or two workflow runs are rendered at the same time. As a
consequence, relying on the `recordId` is enough for the moment.
- However, there is one case where it's necessary to have a component
state scoped to a workflow visualizer instance: the
`workflowVisualizerStatusState`. This component is tightly coupled to
the `<Reactflow />` component instance rendered in the workflow
visualizer, and it must be set to its default value when the component
first renders. I achieved that by using another component instance
context whose instanceId is an identifier returned by the `useId()` hook
in the Workflow Run Card component.
2025-05-05 10:58:11 +02:00
0881e35d64 Throw error if attempting to open RecordPage without recordId (#11768)
Closes https://github.com/twentyhq/core-team-issues/issues/857

The issue was caused by the fact that the preview chip was accidentally
made clickable while not linked to any record id:
<img width="763" alt="Capture d’écran 2025-04-28 à 15 17 32"
src="https://github.com/user-attachments/assets/c1d9bf61-edcb-442f-a914-eccc627ee190"
/>
this was fixed by [this
PR](https://github.com/twentyhq/twenty/pull/11745) (@etiennejouan)

It was causing the side panel to open while the record id was empty,
while this recordId is used in query filters (as it should be to fetch
record data), leading the queries to fail.
Let's early return with an error instead as it does not make sense to
open the record page with an empty recordId.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-28 13:36:19 +00:00
f201091c68 512 Ability to navigate dropdown menus with keyboard (#11735)
# Ability to navigate dropdown menus with keyboard

The aim of this PR is to improve accessibility by allowing the user to
navigate inside the dropdown menus with the keyboard.
This PR refactors the `SelectableList` and `SelectableListItem`
components to move the Enter event handling responsibility from
`SelectableList` to the individual `SelectableListItem` components.
Closes [512](https://github.com/twentyhq/core-team-issues/issues/512)

## Key Changes:
- All dropdowns are now navigable with arrow keys

## Technical Implementation:
- Each `SelectableListItem` now has direct access to its own `Enter` key
handler, improving component encapsulation
- Removed the central `Enter` key handler logic from `SelectableList`
- Added `SelectableList` and `SelectableListItem` to all `Dropdown`
components inside the app
- Updated all component implementations to adapt to the new pattern:
  - Action menu components (`ActionDropdownItem`, `ActionListItem`)
  - Command menu components
  - Object filter, sort and options dropdowns
  - Record picker components
  - Select components

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-25 18:55:39 +02:00
cc211550ae Workflow runs in side panel (#11669)
Vidéo explicative : https://share.cleanshot.com/VsvWknlW

Closes https://github.com/twentyhq/core-team-issues/issues/810
Closes https://github.com/twentyhq/core-team-issues/issues/806

Known issues to fix later:

- https://github.com/twentyhq/core-team-issues/issues/879
2025-04-24 11:33:17 +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
8a3f8ef324 Chip untitled modification (#11498)
Fixes https://github.com/twentyhq/core-team-issues/issues/663
2025-04-14 15:33:41 +00:00
85d94822b3 Fix the Command menu items right padding #11484 (#11489)
Screenshot:
![Screenshot 2025-04-10 at 1 07
24 AM](https://github.com/user-attachments/assets/1e7ed8e7-594f-4ead-9b04-0c7dab636fbd)

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-14 14:12:15 +02:00
abecdbafc1 Add Edit Rich Text functionality to table view (#11390)
Fixes https://github.com/twentyhq/core-team-issues/issues/729


[recording.webm](https://github.com/user-attachments/assets/ea95d67b-64a3-4fef-91ed-b06318099a78)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-14 11:46:22 +00:00
0de8140b3a CreateComponentFamilyState -> createComponentFamilyStateV2 (#11546)
Refacto of createComponentFamilyState

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 10:31:30 +02:00
fe98deef4e Fixed command menu hotkey listener refactor (#11534)
This PR fixes a refactor that was done recently to avoid having
clickoutside listeners on the closed command menu.

The useScopedHotkey hook should have stayed in the command menu
container, because it should always listen.

This has been fixed.
2025-04-11 14:59:48 +02:00
e8488e1da0 Only display Flow for Workflow Runs and display Output tab for triggers (#11520)
> [!WARNING]
> I refactored a bunch of components into utility functions to make it
possible to display the `WorkflowStepHeader` component for **triggers**
in the `CommandMenuWorkflowRunViewStep` component. Previously, we were
asserting that we were displaying the header in `Output` and `Input`
tabs only for **actions**. Handling triggers too required a bunch of
changes. We can think of making a bigger refactor of this part.

In this PR:

- Only display the Flow for Workflow Runs; removed the Code Editor tab
- Allows users to see the Output of trigger nodes
- Prevent impossible states by manually setting the selected tab when
selecting a node

## Demo

### Success, Running and Not Executed steps


https://github.com/user-attachments/assets/c6bebd0f-5da2-4ccc-aef2-d9890eafa59a

### Failed step


https://github.com/user-attachments/assets/e1f4e13a-2f5e-4792-a089-928e4d6b1ac0

Closes https://github.com/twentyhq/core-team-issues/issues/709
2025-04-11 14:31:34 +02:00
446919bc72 Remove onboarding flashes + close all dropdowns on CommandMenu close (#11483)
## Remove onboarding flashes

Tested:
- sign in with credentials
- sign in with social oAuth
- sign up with credentials
- multidomain
- single domain
- reset password

No more flashes, and code logic simplified!

## Close all dropdowns on CommandMenu close

Before:


https://github.com/user-attachments/assets/244ff935-3d40-47d5-a097-12d4cc3810dd


After:


https://github.com/user-attachments/assets/1de692f8-5032-404a-be74-025ebca67138

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-11 14:15:14 +02:00
2b77f598b2 Fixed (#11482)
This PR fixes many small bugs around the recent hotkey scope refactor.

- Removed unused ActionBar files
- Created components CommandMenuOpenContainer and
KeyboardShortcutMenuOpenContent to avoid mounting listeners when not
needed
- Added DEFAULT_CELL_SCOPE where missing in some field inputs
- Called setHotkeyScopeAndMemorizePreviousScope instead of
setHotkeyScope in new useOpenFieldInputEditMode hook
- Broke down RecordTableBodyUnselectEffect into multiple simpler effect
components that are mounted only when needed to avoid listening for
keyboard and clickoutside event
- Re-implemented recently deleted table cell soft focus component logic
into RecordTableCellDisplayMode
- Created component selector isAtLeastOneTableRowSelectedSelector
- Drill down hotkey scope when opening a dropdown
- Improved debug logs
2025-04-09 18:34:31 +02:00
5d9cd257ae Command menu mobile - Prevent overflow on navigation bar (#11480)
Fix https://github.com/twentyhq/twenty/issues/11413
2025-04-09 17:16:46 +02:00
9e0402e691 Action menu refactoring (#11454)
# Description

Closes [#696](https://github.com/twentyhq/core-team-issues/issues/696)

- `useAction` hooks have been removed for all actions
- Every action can now declare a react component
- Some standard action components have been introduced: `Action`,
`ActionLink` and `ActionModal`
- The `ActionDisplay` component uses the new `displayType` prop of the
`ActionMenuContext` to render the right component for the action
according to its container: `ActionButton`, `ActionDropdownItem` or
`ActionListItem`
- The `ActionDisplayer` wraps the action component inside a context
which gives it all the information about the action
-`actionMenuEntriesComponenState` has been removed and now all actions
are computed directly using `useRegisteredAction`
- This computation is done inside `ActionMenuContextProvider` and the
actions are passed inside a context
- `actionMenuType` gives information about the container of the action,
so the action can know wether or not to close this container upon
execution
2025-04-09 13:12:49 +00: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
5e43839efb Fix CSV import select field matching (#11361)
This PR fixes a bug that prevented to do the matching of an imported CSV
file that contains a SELECT type column.

Fixes https://github.com/twentyhq/twenty/issues/11220

## Stacking context improvement 

During the development it was clear that we lacked a reliable way to
understand our own z indices for components like modal, portaled
dropdown, overlay background, etc.

So in this PR we introduce a new enum RootStackingContextZIndices, this
enum allows to keep track of our root stacking context component
z-index, and because it is an enum, it prevents any conflict.

See
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Stacking_context
for reference.

## Component cleaning

Components have been reorganized in a SubMatchingSelectRow component

The Dropdown component has been used to replace the SelectInput
component which doesn't fit this use case because we are not in a cell,
we just need a simple standalone dropdown, though it would be
interesting to extract the UI part of the SelectInput, to share it here,
the benefit is not obvious since we already have good shared components
like Tag and Dropdown to implement this specific use case.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-03 16:28:15 +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
256a5c1a2b Remove form feature flag (#11369)
As title. Workflows are still in the lab and forms are starting to be
usable
2025-04-03 08:38:19 +00:00
5e905180c8 690 extract shouldberegistered from the useaction hooks (#11355)
Closes https://github.com/twentyhq/core-team-issues/issues/690

This PR is the first part of a refactoring on the actions system
https://github.com/twentyhq/core-team-issues/issues/683. It:
- Removes `shouldBeRegistered` from the useAction hook
- Instead `shouldBeRegistered` becomes a function to which we can pass
parameters which describe the context of the app (the object, the
selected record, information about favorites ...). It returns a boolean.
- `useShouldActionBeRegisteredParams` returns the parameters to pass to
the `shouldBeRegistered`
- Introduces a way to inherit actions from the default config and to
overwrite its properties, closing
https://github.com/twentyhq/core-team-issues/issues/72

Some tests testing if an action was registered correctly have been
removed, we should add them back at the end of the global refactoring.
2025-04-02 17:58:14 +02:00
a24e96ae0e 685 Move all navigation actions inside the actions configs (#11303)
Move all navigation actions inside the actions configs
2025-04-01 11:23:28 +02:00
352cf3d38e Update previousHotkeyScopeState to be a family state (#11270)
Fixes #11259
2025-03-28 17:59:05 +01:00
c294d967a3 reset main context store viewId and current view type on settings page (#11206)
closes https://github.com/twentyhq/core-team-issues/issues/588

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-03-28 09:26:59 +01:00
3660bec01d New TitleInput UI component for side panel (#11192)
# Description

I previously introduced the `RecordTitleCell` component, but it was
coupled with the field context, so it was only usable for record fields.
This PR:
- Introduces a new component `TitleInput` for side panel pages which
needed to have an editable title which wasn't a record field.
- Fixes the hotkey scope problem with the workflow step page title
- Introduces a new hook `useUpdateCommandMenuPageInfo`, to update the
side panel page title and icon.
- Fixes workflow side panel UI
- Adds jest tests and stories

# Video



https://github.com/user-attachments/assets/c501245c-4492-4351-b761-05b5abc4bd14
2025-03-26 17:31:48 +01:00
b24046b1bb Various design fixes on side panel (#11165)
- Fix background color
- Fix Menu Item height
- Fix Input design
- Fix show page summary card design
2025-03-25 15:21:10 +00:00
bc1b55ddc3 Add see runs and see workflows actions (#11131)
On default objects:
- Add see workflows

On workflows:
- Add see all runs (no selection)

On workflow runs:
- Add see workflows (no selection)
- Add see linked workflow (single record selection)
- Add see run version (single record selection)

On workflows versions
- Add see all runs (no selection)
- Add see workflows (no selection)
- Add see linked workflow (single record selection)
- Add see linked runs (single record selection)
2025-03-24 18:12:32 +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
e6dec51ca6 Display workflow step header in workflow run input and output tabs (#11102)
- Wrap the content of Workflow View, Workflow Edit, and Workflow Run
side panels with a container making them take all the available height
- Remove the `StyledContainer` of code steps as it's redundant with the
global container
- Add the WorkflowStepHeader to the input and output tabs
- Make the JSON visualizer take all the available height in input and
output tabs
- Reuse the WorkflowStepBody component in the input and output tabs as
it applies proper background color

## Demo

![CleanShot 2025-03-21 at 18 30
26@2x](https://github.com/user-attachments/assets/c3fa512b-c371-4d0b-9bf6-a5f84d333dda)

Fixes
https://discord.com/channels/1130383047699738754/1351906809417568376

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-03-24 13:06:26 +00:00
1c5f3ef5fa clean searchResolvers in server (#11114)
Introduces break in change

- remove search... resolvers
- rename globalSearch to search
- rename searchRecord.objectSingularName > objectNameSingular
closes https://github.com/twentyhq/core-team-issues/issues/643
2025-03-24 13:42:51 +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
ccf60284cf Various fixes (#11108)
Fixes many bug regarding TableCell and InlineCells
2025-03-22 14:19:10 +01:00
c50cdd9510 Execute workflow form action (#11099)
- create a form filler component
- send the response on submit
- put back a field name. We need it for the step output
- validate a form is well set before activation

TODO:
- we need to refresh to see the form submitted. We need to discuss about
a strategy
- the response is not saved in the step settings. We need a new endpoint
to update workflow run step



https://github.com/user-attachments/assets/0f34a6cd-ed8c-4d9a-a1d4-51455cc83443
2025-03-21 17:38:14 +00: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
3328998e61 Remove hotkey scope from useListenClickOutside (#11098)
The old `useListenClickOutside` API allowed us to pass a hotkeyScope as
a parameter, the click outside was triggered only if the current hotkey
scope matched the parameter. We don't want this anymore. This fixes a
few bugs related to hotkey scopes inside the side panel.
2025-03-21 16:27:58 +01:00
3af5cde170 Reorder commands (#11084)
Put workflows on top of navigation commands in the command menu.
2025-03-21 11:10:30 +01:00
3876cb8250 Separate workflow step details and run step details (#11069)
Workflows step details in workflows and versions should be different
from the node tab in run. For most cases, it was using the same
component. But for forms, it will be a different one.

This PR:
- renames form action into formBuilder. formFiller is coming
- put code into a separated folder
- creates a new component for node details
2025-03-20 16:22:55 +00:00
7dac60cfee Fix useFindManyRecords withSoftDeleterFilter (#11056)
Fixes #11038

# Fix useFindManyRecords withSoftDeleterFilter

The error came from a faulty implementation of the `withSoftDeleted`
parameter inside `useFindManyRecords` and from the fact that
`withSoftDeleted: true` was added to access deleted records actions.
However, this parameter was always set in
`useFindManyRecordsSelectedInContextStore` instead of considering
whether the filter was active or not.

```
const withSoftDeleterFilter = {
  or: [{ deletedAt: { is: 'NULL' } }, { deletedAt: { is: 'NOT_NULL' } }],
};
```

The final filter was incorrectly doing an `or` operation between the
base filter and `withSoftDeleterFilter` when it should have been an
`and`:

```
filter: {
  ...filter,
  ...(withSoftDeleted ? withSoftDeleterFilter : {}),
}
```

The correct implementation should be:

```
filter:
  filter || withSoftDeleted
    ? {
        and: [
          ...(filter ? [filter] : []),
          ...(withSoftDeleted ? [withSoftDeleterFilter] : []),
        ],
      }
    : undefined,
```

# Fix useFindManyRecordsSelectedInContextStore

- Check if the soft deleted filter is active before using the
`withSoftDeleterFilter` parameter
2025-03-20 16:27:55 +01:00