Commit Graph

3380 Commits

Author SHA1 Message Date
aede38000e feat: SMTP Driver Integration (#12993)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-10 15:17:26 +02:00
fe9de195c3 Fix record table click outside (#13149)
Fixes https://github.com/twentyhq/twenty/issues/13139 introduced by
https://github.com/twentyhq/twenty/pull/13127

The record table click outside was triggered when it shouldn't have been
(clicking inside a dropdown in the side panel).
This PR fixes it by checking the type of the focused element before
triggering the click outside.
Before, we had a check on the current hotkey scope but I removed this
part during the refactoring and I didn't replace it thinking that it
wasn't useful anymore.

Video QA:



https://github.com/user-attachments/assets/68baa9e6-2593-4840-923b-d631c806d9ea
2025-07-10 14:40:05 +02:00
50e402af07 Use view filters operands in step filters + migrate to twenty-shared (#13137)
Step operand will more or less be the same as view filter operand. 

This PR:
- moves `ViewFilterOperand` to twenty-shared
- use it as step operand
- check what operand should be available based on the selected field
type in filter action
- rewrite the function that evaluates filters so it uses
ViewFilterOperand instead

ViewFilterOperand may be renamed in a future PR.
2025-07-10 08:36:37 +00:00
d808cbeed9 i18n - translations (#13143)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-10 07:48:51 +02:00
8310b4ff01 Show tool execution messages in AI agent chat (#13117)
https://github.com/user-attachments/assets/c0a42726-50ac-496e-a993-9d6076a84a6a

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-10 07:45:05 +02:00
e6cdae5c27 feat: add auto-scroll to selected menu items in CustomSlashMenu (#13048)
to resolve the issue #13047 

It's my first contribution, I hope it's good enough!

When using the slash command (/) in the notes editor, a menu of commands
appears. When navigating this menu with the up and down arrow keys, the
selection changes, but the menu itself does not scroll. This means that
as the list of commands is long, items outside the visible area cannot
be seen when selected.


The issue was located in the [CustomSlashMenu.tsx] component. The menu
container didn't have vertical scrolling enabled, and there was no logic
to scroll the active item into the visible area.

The fix involved:

Adding overflow-y: auto to the menu's styled container in
[CustomSlashMenu.tsx].
Modifying the [DropdownMenuItemsContainer] component to accept and
forward a ref using React.forwardRef.
Implementing a useEffect hook in [CustomSlashMenu.tsx] that triggers on
selection change. This hook uses a ref to the items container to call
scrollIntoView({ block: 'nearest' }) on the currently selected menu
item.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-09 17:01:07 +00:00
eba997be98 Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes 🫳🎤) (#13127)
# Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes)

This PR is the last part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933
Part 5: https://github.com/twentyhq/twenty/pull/13106

In this part, we completely remove the hotkey scopes.
2025-07-09 17:21:14 +02:00
a0e7c57a6b i18n - translations (#13134)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 17:14:28 +02:00
c13bc60dad Improve error handling (#13130)
In the BE we throw custom errors with precise error codes (e.g.
"LABEL_ALREADY_EXISTS") before catching them in filters and rethrowing
BaseGraphQLErrors (standard errors such as NotFoundError, UserInputError
etc.).
In the FE we were grouping sentries based on the error codes but we were
actually grouping by very broad codes such as "NOT_FOUND" or
"BAD_USER_INPUT", extracted from the BaseGraphQLErrors.

To fix that, we update the BaseGraphQLError constructor api to allow to
pass on the CustomError directly and retrieve from it the original code
and store it in existing property `subCode` that we will use in the FE
to send errors to sentry.
This new api also eases usage of `userFriendlyMessage` that is passed on
to the api response and therefore to the FE when CustomError is passed
on directly to the BaseGraphQLError constructor.
2025-07-09 17:13:44 +02:00
484c267aa6 Api keys and webhook migration to core (#13011)
TODO: check Zapier trigger records work as expected

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-07-09 17:03:54 +02:00
fce33004bc Connect logic in Workspace Entity Manager (#13078)
Large PR, sorry for that. Don't hesitate to reach me to have full
context (env. 500lines for integration and unit tests)

- Add connect logic in Workspace Entity Manager
- Update QueryDeepPartialEntity type to enable dev to use connect
- Add integration test on createOne / createMany
- Add unit test to cover main utils
- Remove feature flag on connect

closes https://github.com/twentyhq/core-team-issues/issues/1148
closes https://github.com/twentyhq/core-team-issues/issues/1147
2025-07-09 12:16:28 +00:00
a95ca10f29 i18n - translations (#13126)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 14:01:40 +02:00
6e79339e64 Add first filter step version (#13093)
I rebuilt the advanced filters used in views and workflow search for a
specific filter step.

Components structure remains the same, using `stepFilterGroups` and
`stepFilters`. But those filters are directly sent to backend.

Also re-using the same kind of states we use for advanced filters to
share the current filters used. And a context to share what's coming
from workflow props (function to update step settings and readonly)

⚠️ this PR only focusses on the content of the step. There is still a
lot to do on the filter icon behavior in the workflow



https://github.com/user-attachments/assets/8a6a76f0-11fa-444a-82b9-71fc96b18af4
2025-07-09 13:52:07 +02:00
0316c857d8 Remove unwanted workflow fetch on right drawer open (#13122)
There was a mistake in the ActionConfig load, we were trying to fetch a
workflow with the opened recordId (which is not always a workflow)
2025-07-09 13:12:46 +02:00
44b9990ba7 Fix refetch cached views after field creation (#13120)
This PR fixes a bug that happened when adding a field to a table right
after a field creation in the data model settings.

This happened because the backend adds the newly created field to all
relevant views without telling the frontend (because we don't have web
sockets yet), so the frontend ended up in a stale state, and when the
user added the field manually to a view the backend rightly threw an
error telling that the view field it already existed.

So the fix is just to refetch all views after a field creation, sparing
us the difficult work of manually updating the Apollo cache.

Fixes https://github.com/twentyhq/twenty/issues/13071
2025-07-09 10:18:15 +00:00
19555aeca8 i18n - translations (#13121)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 11:35:53 +02:00
41c737703c Refactor data model settings new field folder (#13119)
Folder renaming
2025-07-09 11:26:05 +02:00
1cb60f943e [field-level permissions] Upsert fieldPermission + use fieldPermission to compute permissions (#13050)
In this PR

- introduction of fieldPermission entity
- addition of upsertFieldPermission in role resolver
- computing of permissions taking fieldPermission into account. In order
to limit what is stored in Redis we only store fields restrictions. For
instance for objectMetadata with id XXX with a restriction on field with
id YYY we store:
`"XXX":{"canRead":true,"canUpdate":false,"canSoftDelete":false,"canDestroy":false,"restrictedFields":{"YYY":{"canRead":false,"canUpdate":null}}}`

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-07-09 08:47:59 +00:00
6ba6860e1c Frontend tests improvements (#13115)
Fix warnings and lower coverage by 0.1%
2025-07-09 09:23:26 +02:00
6057bdd389 Create custom StreamingRestLink for streaming API requests using @stream directive (#13114)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Dmitry Moiseenko <36731450+cxdima@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Niklas Korz <niklas@niklaskorz.de>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-07-08 22:59:04 +02:00
39f6f3c4bb Prevent relation update from settings (#13099)
## Expected behavior

Described behavior regarding: (update | create) x (custom | standard) x
(icon, label, name, isSynced)

**Custom:**
- Field RELATION create: name, label, isSynced, icon should be editable
- Field RELATION update: name should not, icon label, isSynced should
- For other fields, icon, label, name, isSynced should be editable at
field creation | update

To simplify: Field RELATION name should not be editable at update

**Standards**
- Field: create does not makes sense
- Field: name should not, icon label, isSynced should (this will end up
in overrides)

To simplify, no Field RELATION edge case, name should not be editable at
update

**Note:** the FE logic is quite different as the UI is hiding some
details behind the syncWithLabel. See my comments and TODO there


## What I've tested:
(update | create) x (custom | standard) x (icon, label, name, isSynced,
description)
2025-07-08 21:03:38 +02:00
c8ec44eeaf Agent chat code cleanup (#13088)
This PR addresses feedback from
[PR-13061](https://github.com/twentyhq/twenty/pull/13061).

- Removed redundant type assertion from `apollo.factory.ts`.
- Removed redundant tests: Eliminated test cases that were specifically
added to boost coverage metrics rather than testing meaningful
functionality
2025-07-08 20:48:22 +02:00
9eaa8ad517 Replace hotkey scopes by focus stack (Part 5 - Form field Inputs, Pages, Dialog ...) (#13106)
# Replace hotkey scopes by focus stack (Part 5 - Form field Inputs,
Pages, Dialog ...)

This PR is the 5th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933

In this part, all the last components using hotkey scopes were
refactored.
In the 6th and final part of this refactoring we will be able to
completely remove the hotkey scopes from the codebase.
2025-07-08 20:18:32 +02:00
66b633e08e Removed useDropdown and its legacy states (#13111)
This PR removes useDropdown barrel hook and refactors the legacy
useDropdown states to the last version of our recoil component state
management.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-07-08 20:16:15 +02:00
ccf1d703bf Import - fixes (#13097)
- Fixes : https://github.com/twentyhq/twenty/issues/11623
- Design fix :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=61976-118483&t=z12YCJg7W7PFMcmg-4

After
<img width="600" alt="Screenshot 2025-07-08 at 11 52 26"
src="https://github.com/user-attachments/assets/744fd40b-bba1-4ed1-b44c-48766a20384d"
/>

Before
<img width="600" alt="Screenshot 2025-07-08 at 11 23 08"
src="https://github.com/user-attachments/assets/b5ef81a8-f4dc-4ba1-8741-b8edec579cc1"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-08 13:17:08 +02:00
4a3a897a65 Set createdAt and updatedAt as readonly on the frontend (#13096)
This is not the prettiest fix but it's the 5th time I get the feedback
from a user that these fields should be readonly, let's have a special
case for them

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 10:29:46 +00:00
a5deddaffd fieldmetadatatype + featurelfag creation (#13021)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-08 12:23:28 +02:00
56607c0449 Billing - fix duplicate customer in stripe + subscription constraint violation (#13091)
closes https://github.com/twentyhq/core-team-issues/issues/982
2025-07-08 11:17:59 +02:00
67f0b98002 Pass dropdownId to all closeDropdown calls in MatchColumnToFieldSelect (#13087)
Pass the dropdownId into every closeDropdown() call so the instance ID
is always defined and the error no longer occurs.

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 09:17:42 +00:00
f5835a77e5 fix: prevent LinkAvatarChip from triggering page reload when table cells or inline cells are in edit mode (#12734)
resolve #11075
The issue was that when inline cells or table cells are in edit mode, a
click outside event listener is active, and its callback calls
event.stopImmediatePropagation(). This prevents the onClick of LinkChip
from firing, allowing the browser's default behavior to trigger the 'to'
link and cause a full page reload.

To fix this, I added event.preventDefault() inside each click outside
callback to stop the browser from reloading.

Another possible solution: check if currentTableCellInEditModePosition
or isInlineCellInEditMode is true, and if so:

Either convert the StyledLink in LinkChip into a div

Or set forceDisableClick = true, which falls back to AvatarChip.

Before:


https://github.com/user-attachments/assets/7ffd76fd-988e-484b-bad6-10e0147502c2

After:


https://github.com/user-attachments/assets/18cfbc0e-8af6-4ecc-862e-a2b8f02e2535

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 09:15:08 +00:00
ebaec00cce fix: blockquote icon in slash menu (#13068)
This PR fixes a UI bug where the "Quote" item in the slash command menu
was displayed without an icon.


The root cause was that the IconBlockquote component, while available in
the icons library, was not being exported from the internal twenty-ui
package.

## Before / After


![Before](https://github.com/user-attachments/assets/afd5e848-b6a4-4af9-a01d-15c6128f8535)


![After](https://github.com/user-attachments/assets/2468371f-fdd6-42a0-b04b-61a51d286746)


## Changes:

- Exported IconBlockquote from TablerIcons.ts in the twenty-ui package.
- Updated getSlashMenu.ts in the twenty-front package to import and use
the IconBlockquote for the "Quote" menu item.
2025-07-08 10:09:42 +02:00
65686d7d8a i18n - translations (#13085)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-07 23:01:00 +02:00
51d02c13bf Feat - Agent chat tab (#13061)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-07-07 22:47:41 +02:00
29f7b74756 fix(ci): reorganize workflow steps and move cache saving to correct s… (#13083)
…tage
2025-07-07 16:06:25 +00:00
e4120cdce3 Silent harmless AbortError (#13080) 2025-07-07 15:26:20 +00:00
c6e5bab4e9 Replace hotkey scopes by focus stack (Part 4 - Inputs) (#12933)
# Replace hotkey scopes by focus stack (Part 4 - Inputs)

This PR is the 4th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910

In this part, I refactored all inputs in the app so that each input has
a unique id which can be used to track the focused element.
2025-07-07 15:42:12 +02:00
f32bebf7b4 Fix stories (#13069)
As per title
2025-07-06 20:48:02 +02:00
ee8e223aed fix: fixed the update of field metadata label, icon & object (#13064)
This PR is raised to close the issue #13044 

But there are some doubts that needs to be approved.
If the fields are not custom then we were saving the changes in
**standardOverrides** obj in which only three fields are
overridableFields **label, icon & description** can be updated for a
field.

You can see this in _before-update-one-field.hook.ts_ on line 85 
```ts
    const overridableFields = ['label', 'icon', 'description'];
```
If the field to be updated are from these three we are putting this in a
**standardOverrides** obj and passing it

However in our _field-metadata.service.ts_ file. We have **updateOne**
function inside it we have wrote a condition if **isCustom** is false
then the purpose was to build the updatableFields from the
**standardOverrides** obj that we got in **fieldMetadataInput** but
there was an error in it. As you can see below
```ts
 const updatableFieldInput =
        existingFieldMetadata.isCustom === false
          ? this.buildUpdatableStandardFieldInput(
              fieldMetadataInput,
              existingFieldMetadata,
            )
          : fieldMetadataInput;
```
However, the issue was that we were placing the entire
**standardOverrides** object inside **updatableFieldInput** again —
instead of merging its individual fields (label, icon, description)
directly into the update payload.

This PR fixes that by correctly applying the overrides into the
top-level object.

Please refer to the file changes for the full context.

But the thing i don't know. 
[ ] - Is this the correct expected flow?? 
[ ]- Will this change break anything elsewhere?

I still have doubts on these two. Let me know if I missed something.

---------

Co-authored-by: Jagss24 <btwitsjagannat12@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-06 12:47:33 +02:00
70bdb56b4e i18n - translations (#13057)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 23:20:18 +02:00
d4620a3fc4 i18n - translations (#13055)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 23:07:37 +02:00
e8905be71a Import - Improve phone validation (#12901)
Context : 
- Phones import is a bit complex if not all subfields are provided.
- Phones subfield validation are absent or different from BE validation.

Solution : 
- Normalize callingCode and countryCode validation (BE/FE)
- Ease phone import if only phoneNumber is provided
2025-07-04 23:07:24 +02:00
1386f344dd fix: align workspace switcher button in collapsed navigation drawer (#12893) (#12902)
## Summary
- Fixes #12893 - Workspace switcher button now aligns properly with
record index headers when navigation drawer is collapsed
- Maintains consistent button height in both expanded and collapsed
states
- Simple CSS fix that improves visual consistency

## Fix Details
The issue was caused by the workspace switcher button changing height
from 20px (expanded) to 16px (collapsed). This created misalignment with
the page headers.

Changed in `MultiWorkspacesDropdownStyles.tsx`:
```tsx
// Before - height changed based on drawer state
height: ${({ theme, isNavigationDrawerExpanded }) =>
  isNavigationDrawerExpanded ? theme.spacing(5) : theme.spacing(4)};

// After - consistent height
height: ${({ theme }) => theme.spacing(5)};
```

## Visual Alignment
- Workspace switcher button: 20px height (theme.spacing(5))
- Maintains alignment with record index headers in collapsed state
- Consistent with Figma design requirements

## Test Plan
- [x] Collapsed navigation drawer - workspace switcher aligns with
headers
- [x] Expanded navigation drawer - no visual regression
- [x] Button functionality remains unchanged

---

🤖 This fix was implemented using [Claude Code](https://claude.ai/code)
by Jez (Jeremy Dawes) and Claude working together\!

Thanks to the Twenty team for the great project\! 🚀

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-04 23:06:02 +02:00
324dadca63 feat: enable export of deleted records (#12776)
resolve #12662
This PR enables exporting deleted records by detecting when deleted view
mode is active and adding deletedAt: { is: 'NOT_NULL' } to
graphqlFilter.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-04 22:58:24 +02:00
1729970836 Fix circular structure error in useFetchMoreRecordsWithPagination (#13042)
Fixes:  
TypeError: Converting circular structure to JSON crashing opportunities
pagination.

Issue: 
useFetchMoreRecordsWithPagination was putting an Apollo client object in
React's dependency array. React tried to serialize it for memoization,
hit circular refs in InMemoryCache, and was throwing the error.

Fix: 
Removed unnecessary Apollo client import. The fetchMore from the
original useQuery is already bound to the correct client.

before: 


https://github.com/user-attachments/assets/0422c57b-5cd2-4c0f-9828-fb7bbd7f94c1

after:



https://github.com/user-attachments/assets/20112fb7-3990-4c34-bf39-8c53b7b48e45
2025-07-04 21:53:18 +02:00
b24588d648 Fix workflow title cell not opening (#13052)
This PR fixes a bug that forced all title cell to behave as if they were
in a show page, but we have workflow page breadcrumb that is not a show
page title.

Fixes https://github.com/twentyhq/twenty/issues/13041
2025-07-04 18:43:05 +02:00
f272394595 i18n - translations (#13049)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 16:35:17 +02:00
0dcfca2ba3 Fixes greater than or equal and less than and equal filters (#13033)
This PR fixes a mismatch between the filter operation we have on NUMBER
and RATING field types, and the labels we use for those filters in the
application.

What is actually used is : 
- Greater than or equal
- Less than or equal

But unfortunately, until now we display "less than" and "greater than"
everywhere.

This PR fixes that.

We would still have to change the value that is saved in viewFilter
table from `greaterThan` to `greaterThanOrEqual` and likewise for less
than, but it would require a careful migration, and for now just
changing the display labels is enough.

See follow-up issue for migration of the DB values :
https://github.com/twentyhq/core-team-issues/issues/1196

Fixes https://github.com/twentyhq/twenty/issues/13000
2025-07-04 16:26:19 +02:00
7a2b6bd4d6 Prevent testing malformed workflows and allow testing workflows with cron trigger (#13045)
## Before


https://github.com/user-attachments/assets/ca0c50af-f759-4466-a262-ad8bdd548b89

## After



https://github.com/user-attachments/assets/647a2181-bf28-4a0b-ab3f-faaf13a0f1d6
2025-07-04 15:59:38 +02:00
333b51b18c i18n - translations (#13040)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 12:01:02 +02:00
43c3d114bb Pretty format webhook payload example + unify expected body validation (#13034)
## Webhook Expected Body is automatically pretty formatted


https://github.com/user-attachments/assets/0ca7d621-0c6e-4bef-903f-859efd02f9cc

## Expected body fields can't contain spaces in keys' name


https://github.com/user-attachments/assets/b68d36a6-acd4-4ba2-a99a-5857e30c8582

Closes https://github.com/twentyhq/core-team-issues/issues/1117
2025-07-04 11:45:14 +02:00