Commit Graph

6644 Commits

Author SHA1 Message Date
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
45c89a46d6 FieldMetadata ENUM CREATE UPDATE server validation and integration tests (#12121)
# Introduction

Big diff a lot of tests and snapshots ( real diff < 500+ )

close https://github.com/twentyhq/twenty/issues/12117
close https://github.com/twentyhq/twenty/issues/12133

## What has been done here
Implemented a strong integration coverage on both fieldmetadata`SELECT`
`UPDATE` and `CREATE`.
Implemented server side validation for the options `value` `label` `id`
and collision issue with also `position`

We could improve:
- Position validation
- DefaultValue validation

## Update
```ts
 PASS  test/integration/metadata/suites/field-metadata/update-one-field-metadata-select.integration-spec.ts (41.054 s)
  Field metadata select update tests group
    ✓ Update should succeed with provided option id (2565 ms)
    ✓ Update should succeed with valid default value (1469 ms)
    ✓ Update should succeed with various options id (1257 ms)
    ✓ Update should succeed without option id (1286 ms)
    ✓ Update should trim option values (1366 ms)
    ✓ Update should succeed with default value and no options (1122 ms)
    ✓ Update should fail with unknown default value and no options (1075 ms)
    ✓ Update should fail with only white spaces id (1195 ms)
    ✓ Update should fail with empty string id (1058 ms)
    ✓ Update should fail with null id (1066 ms)
    ✓ Update should fail with not a string id (1098 ms)
    ✓ Update should fail with too long id (1373 ms)
    ✓ Update should fail with only white spaces label (1034 ms)
    ✓ Update should fail with empty string label (1057 ms)
    ✓ Update should fail with null label (1100 ms)
    ✓ Update should fail with not a string label (1144 ms)
    ✓ Update should fail with too long label (1273 ms)
    ✓ Update should fail with only white spaces value (1385 ms)
    ✓ Update should fail with empty string value (1035 ms)
    ✓ Update should fail with null value (1068 ms)
    ✓ Update should fail with not a string value (1021 ms)
    ✓ Update should fail with too long value (1134 ms)
    ✓ Update should fail with invalid option id (1137 ms)
    ✓ Update should fail with empty options (1238 ms)
    ✓ Update should fail with invalid option value format (1104 ms)
    ✓ Update should fail with comma in option label (1004 ms)
    ✓ Update should fail with duplicated option values (1015 ms)
    ✓ Update should fail with duplicated option ids (1079 ms)
    ✓ Update should fail with duplicated option positions (1266 ms)
    ✓ Update should fail with duplicated trimmed option values (1220 ms)
    ✓ Update should fail with undefined option label (1029 ms)
    ✓ Update should fail with an invalid default value (1142 ms)
    ✓ Update should fail with an unknown default value (1081 ms)
    ✓ Update should fail with undefined option value (1086 ms)

Test Suites: 1 passed, 1 total
Tests:       34 passed, 34 total
Snapshots:   28 passed, 28 total
Time:        41.079 s
```


## Create
```ts
 PASS  test/integration/metadata/suites/field-metadata/create-one-field-metadata-select.integration-spec.ts (38.292 s)
  Field metadata select creation tests group
    ✓ Create should succeed with provided option id (2096 ms)
    ✓ Create should succeed with valid default value (1316 ms)
    ✓ Create should succeed with various options id (1113 ms)
    ✓ Create should succeed without option id (1378 ms)
    ✓ Create should trim option values (1296 ms)
    ✓ Create should fail with only white spaces id (1000 ms)
    ✓ Create should fail with empty string id (1325 ms)
    ✓ Create should fail with null id (1060 ms)
    ✓ Create should fail with not a string id (1142 ms)
    ✓ Create should fail with too long id (1321 ms)
    ✓ Create should fail with only white spaces label (999 ms)
    ✓ Create should fail with empty string label (1163 ms)
    ✓ Create should fail with null label (1198 ms)
    ✓ Create should fail with not a string label (1678 ms)
    ✓ Create should fail with too long label (1527 ms)
    ✓ Create should fail with only white spaces value (1200 ms)
    ✓ Create should fail with empty string value (1102 ms)
    ✓ Create should fail with null value (1037 ms)
    ✓ Create should fail with not a string value (1462 ms)
    ✓ Create should fail with too long value (896 ms)
    ✓ Create should fail with invalid option id (997 ms)
    ✓ Create should fail with empty options (1058 ms)
    ✓ Create should fail with invalid option value format (1190 ms)
    ✓ Create should fail with comma in option label (1142 ms)
    ✓ Create should fail with duplicated option values (872 ms)
    ✓ Create should fail with duplicated option ids (860 ms)
    ✓ Create should fail with duplicated option positions (1002 ms)
    ✓ Create should fail with duplicated trimmed option values (1336 ms)
    ✓ Create should fail with undefined option label (754 ms)
    ✓ Create should fail with an invalid default value (696 ms)
    ✓ Create should fail with an unknown default value (678 ms)
    ✓ Create should fail with undefined option value (699 ms)
    ✓ Create should fail with null options (720 ms)
    ✓ Create should fail with undefined options (686 ms)

Test Suites: 1 passed, 1 total
Tests:       34 passed, 34 total
Snapshots:   29 passed, 29 total
Time:        38.314 s
```

## Conclusion
As always any suggestions are welcomed ! Please let me know


## Discussion about validation governance
### Front
Front side will be dealing with zod validations schema that he will
handle and maintain by himself

### Back validation instances
- Validation hold through DTO declarations ( run by yoga through the
resolvers )
- Server programmatic validation and exceptions handling ( run through
the services )

For this refactor/fix we decided to stick to the current implementation
only touching the `Server programmatic validation and exceptions
handling` we will handle validation centralization when we will onboard
the `nestjs-query` deprecation/integration refactor.

### Vision
In the best of the world we could think of an intermediary model that
will handle and take responsibility of the validation decorators that
would be run programmatically through the service, Yoga would still
consume it ? then we would need to have enough grain in the service to
know the input has already validated

## Notes
Introduced zod back side in order to handle very atomic and primitive
validation
2025-05-22 17:58:59 +02:00
7cc0a7ae72 add checkFileExists method in file storage service (#12229) 2025-05-22 15:09:21 +00:00
08e32017fb Fix + column header in tables (#12221)
Fixes https://github.com/twentyhq/twenty/issues/12213



https://github.com/user-attachments/assets/1eb675f0-c8ba-4601-bcf7-c80c27a03d40
2025-05-22 16:32:07 +02:00
aeee04415d add more logs to cleaning command (#12219) 2025-05-22 13:25:19 +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
4ac47c2a1b Improve logs in workflow trigger (#12215)
- distinguish logs coming from webhook and job triggers
- add workspace and workflow ids to help debugging

Hard to debug sentry issue:

https://twenty-v7.sentry.io/issues/6605607134/?project=4507072499810304&query=&referrer=issue-stream&stream_index=7
2025-05-22 14:56:30 +02:00
0f9cdd9d39 i18n - translations (#12214)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-22 14:22:54 +02:00
b5544b6853 Fix timezone display + translate dates (#12147)
Fixes https://github.com/twentyhq/twenty/issues/11566 + translates dates

- Date display bug: We had an issue with date (not date time) display
depending on the timezone the user had selected. The date is stored in
the db as yyyy-mm-dd, eg. 2025-05-01 for **May 1st, 2025**. When
returned this date is formatted in a UTC DateTime at midnight, so
2025-05-1 00:00:00. Then when displaying the date we were converting
this date using the timeZone, so 2025-04-30 17:00:00, thus displaying
**April 30th, 2025**. The fix chosen is that we should not take into
account the timezone for date (not date time!) displays as we always
want to show the same date.
- Date translation: dates were not translated, not in their default
display (_May 1st, 2025_) nor in their relative display (_about a month
ago_). The lib we use for date formatting, date-fns, offers a
translation option with pre-built `Locale`s from their lib.
Unfortunately and surprisingly we cannot just use directly string locale
codes (like `fr-FR`), cf [open issue on
date-fns](https://github.com/date-fns/date-fns/issues/3660). A util was
introduced to offset this by dynamically importing the right date-fns
Locale based on the locale code.
2025-05-22 12:04:44 +00:00
0ac4cc6899 captcha - keep consistency with token send to validation (#12195)
[Sentry
error](https://twenty-v7.sentry.io/issues/6494360796/events/322590f8af5c4475beebb66e5f22a2f7/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=previous-event&seerDrawer=true&sort=date&stream_index=6)
raised because of invalid argument type (undefined in some case when
string is expected)

closes https://github.com/twentyhq/core-team-issues/issues/869 and
closes https://github.com/twentyhq/twenty/issues/12208
2025-05-22 13:49:23 +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
9753637693 Fix upgrade command (#12210) 2025-05-22 12:22:21 +02:00
ffdedf7af3 Fix "PageChangeEffect does not run when changing view on the same object" (#12196)
Fixes https://github.com/twentyhq/core-team-issues/issues/950

This issue was due to the memoization inside `useIsMatchingLocation`,
which was rerendered only if the pathname changed but not the search
params.

After discussion with @lucasbordeau, we decided to remove the hook
`useIsMatchingLocation` and to create an equivalent util function which
takes the location as an argument.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-22 12:06:07 +02:00
6466f3fb45 add cursor rule for nx (#12199)
Adding a cursor rule for nx

## Changes
- Added `.cursor/rules/nx-rules.mdc`
- The rule provides structured guidelines for AI assistants to better
help developers
2025-05-22 12:05:52 +02:00
c6627f1e99 fix: prevent empty state from scrolling in table view (#12197)
https://github.com/user-attachments/assets/334ffd15-a639-4947-8142-c19bc231c9bd



Closes #12132
2025-05-22 11:59:32 +02:00
1365c202d9 Increase auto subdomain generation cardinality (#12206)
Fixes https://github.com/twentyhq/twenty/issues/12204
2025-05-22 11:55:20 +02:00
891758bb89 Fix docker setup (#12209)
For fresh install, we need the migrations to happen before the upgrade
command is triggered as the upgrade command is a NestJS command and the
app will try to load env variables from db
2025-05-22 11:32:00 +02:00
342583e891 Fix stacking multiple time the same record in the side panel (#12192)
Fixes #12043 

This bug had two distinct root causes:
- The command menu closing wasn't triggering correctly because of a
hotkey scope issue. We reset the hotkey scope to record index inside
`useLeaveTableFocus` but we should do it only when needed
- The portal on top of the table cell didn't stop the propagation of the
click so the table cell was opened twice (once in the portal and once in
the underlying cell)

Before:


https://github.com/user-attachments/assets/16c41135-fff9-4f89-a512-6a7c0e143190


After:


https://github.com/user-attachments/assets/865b6063-5f82-4f44-b0c8-d03f5955d685
2025-05-22 11:13:20 +02:00
1404513ec5 docs(website): upgrade guide 0.54 (#12194) 2025-05-21 23:57:37 +02:00
786ad088b3 clean not found file - add logs (#12198) 2025-05-21 23:56:02 +02:00
8d105417ba Add forgotten 054 commands (#12193)
Wrongly named branch
2025-05-21 17:59:17 +02:00
d38f448d05 Move fieldMetadata migration from metadata to core 2025-05-21 16:36:04 +02:00
dc2d7f7c94 Fix upgrade command for 0.54 2025-05-21 16:25:39 +02:00
6c9d17eee7 i18n - translations (#12189)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-21 16:20:48 +02:00
578f07374b 922 remove todos from 11809 after release (#12183)
- remove todos
- remove workflow-event-listener.workspace-entity.ts
2025-05-21 16:15:48 +02:00
85a17a54b3 Do not upgrade if no migrate (#12187) 2025-05-21 16:01:03 +02:00
a5b212369b Set findOneServerlessFunction result nullable (#12179)
solves https://github.com/twentyhq/twenty/issues/11819
remove fetch query when deleting code step
2025-05-21 13:59:20 +00:00
8c6569be3b Add relation exceptions (#12185)
Introducing a class of RelationException extending CustomException to
help grouping those exception in sentries by ExceptionCode.
I did not introduce a filter as these are thrown in utils that can be
used in multiple places now or in the future, and filters are to be
added at resolver-level.
2025-05-21 15:53:25 +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
7f1d6f5c7f Continue migration schema from metadata to core (#12168)
2nd part of the migration - this time we're migrating all the tables

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-21 15:44:13 +02:00
8c20bada79 Fix Scalar preload (#12184)
Chrome doesn't really respect preloading and was loading it before other
important assets, slowing down the app while in 99% of sessions people
don't check the REST API playground
2025-05-21 15:27:46 +02:00
5c16b2752d Fix workflow sub objects updates validation (#12169)
Fixes https://github.com/twentyhq/core-team-issues/issues/983

- Enabling workflow version name update, even if not in draft status
- Assert draft when updating steps
- Enabling workflow run name update
2025-05-21 13:11:32 +00:00
23ebd69541 Add Approved access domain exception filter (#12180)
We have approvedAccessDomain custom exceptions, but they were never
filtered while some of them reflects 4xx errors which we don't want to
be captured as 5xx errors
2025-05-21 14:36:14 +02:00
4f4d216a21 Use null as the default value for link fields when persisting (#12173)
Follow up for https://github.com/twentyhq/twenty/pull/12113

I created stories for the LinksFieldInput component.
2025-05-21 14:11:38 +02:00
fdde7651a4 Fix email verification exception are not caught (#12174)
cf
[sentry](https://twenty-v7.sentry.io/issues/6606375182/?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&referrer=issue-stream&sort=date&stream_index=4)

Email verification exception were not caught when thrown outside of
email-verification resolver, which be the case at authentication step.
2025-05-21 14:09:11 +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
3702fefc89 Move defaultAvatarUrl on userWorkspace + migration command (#12100)
closes https://github.com/twentyhq/core-team-issues/issues/883
2025-05-21 12:07:02 +02:00
8e2d0139ed Emit proper event on createOrUpdate csv import operation (#12163)
- use proper event emitter when upserting records with csv import
- After:


https://github.com/user-attachments/assets/8303da38-2e35-4f4c-bb13-8a7a222971b7
2025-05-21 11:59:50 +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
c29ed1c0c9 Consider null values as empty values for link fields (#12113)
This pull request introduces changes to improve handling of nullable
values in link-related data structures and simplifies field value
generation logic. Key updates include adjustments to type definitions,
utility functions, and component logic to support `null` values for
links, along with the removal of the `generateDefaultFieldValue`
function in favor of `generateEmptyFieldValue`.

There will be a few more follow-up Pull Requests.

---

Closes https://github.com/twentyhq/twenty/issues/11844
2025-05-21 11:30:15 +02:00
7461b7ac58 lowercase user and invitation emails (#12130)
### Solution

> After discussion with charles & weiko, we chose the long term
solution.
> 
> Fix FE to request checkUserExists resolver with lowercased emails
> Add a decorator on User (and AppToken for invitation), to lowercase
email at user (appToken) creation. ⚠️ It works for TypeOrm .save method
only (there is no user email update in codebase, but in future it
could..)
> Add email lowercasing logic in external auth controller
> Fix FE to request sendInvitations resolver with lowercased emails
> Add migration command to lowercase all existing user emails and
invitation emails

> For other BE resolvers, we let them permissive. For example, if you
made a request on CheckUserExists resolver with uppercased email, you
will not found any user. We will not transform input before checking for
existence.

[link to comment
](https://github.com/twentyhq/twenty/pull/12130#discussion_r2098062093)

### Test 🚧 
- sign-in and up from main subdomain and workspace sub domain > Google
Auth (lowercased email) ✔️ | Microsoft Auth (uppercased email ✔️ &
lowercased email) | LoginPassword (uppercased email ✔️& lowercased
email✔️)
- invite flow with uppercased and lowercased ✔️
- migration command + sign-in ( former uppercased microsoft email ✔️) /
sign-up ( former uppercased invited email ✔️)

closes https://github.com/twentyhq/private-issues/issues/278, closes
https://github.com/twentyhq/private-issues/issues/275, closes
https://github.com/twentyhq/private-issues/issues/279
2025-05-21 11:06:29 +02:00
6ff5a5bafa fixing a microsoft graph api error (#12154)
The issue is "Microsoft Graph API unknown error: TypeError: Cannot read
properties of undefined (reading 'emailAddress')"

Sentry :
https://twenty-v7.sentry.io/issues/6605750776/events/7feb4f5949a64ab78bb429cffb7f0fea/?project=4507072499810304

Fixes https://github.com/twentyhq/core-team-issues/issues/981
2025-05-21 11:04:43 +02:00
91e487dd63 Catching "no licence" microsoft account (#12143)
Catching "no licence - removed" microsoft message channels. 

Current behabiour 
> ` MessageImportException [Error]: The mailbox is either inactive,
soft-deleted, or is hosted on-premise.`

Goal:
better track errors VS user mistakes

Context: 
A similar logic was already implemented for the calendar channels. I
just replicated it to message channels
2025-05-21 11:04:11 +02:00
fe25557337 Fix send email connected account (#12149)
Fixes https://github.com/twentyhq/twenty/issues/12144

Account owner id is not fetched anymore by default in find many
connected accounts.
This is coming from the relation migration, since account owner id is
not a basic field anymore.

Enforcing the fetch of account owner id + adding tests

<img width="251" alt="Capture d’écran 2025-05-20 à 18 23 44"
src="https://github.com/user-attachments/assets/3e3105a0-d3e8-4b5d-87b0-80d3e97ab034"
/>
2025-05-21 09:02:04 +00:00
ca78fc3f27 i18n - translations (#12148)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-20 17:21:01 +02:00
538f831fc1 Prevent webhook trigger from enabling keys with spaces (#12146)
Fixes https://github.com/twentyhq/core-team-issues/issues/984

Variables do not support spaces. Preventing those in webhook triggers

<img width="501" alt="Capture d’écran 2025-05-20 à 16 22 19"
src="https://github.com/user-attachments/assets/563e4068-583f-4802-9309-a12c00143509"
/>
2025-05-20 17:04:48 +02:00
5f333ccd65 Fixes RelationFromManyFieldDisplay story (#12141)
This PR adds back and fixes the story for RelationFromManyFieldDisplay,
which was broken due to the removal of use-context-selector state.

The story was also setting unnecessary states, we now only keep one
state set in the recoil state.
2025-05-20 15:30:43 +02:00
ad136b5246 better logging errors in messages (#12136) 2025-05-20 13:37:24 +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