Commit Graph

3295 Commits

Author SHA1 Message Date
9256a7f234 Add empty option to select form field (#12898)
## Before

New option selected, but not taken into account

<img width="744" alt="image"
src="https://github.com/user-attachments/assets/880421e2-5582-40f3-809a-ef443517b510"
/>


## After

<img width="750" alt="image"
src="https://github.com/user-attachments/assets/d5114712-a08a-4867-a93c-da5240f81472"
/>
2025-06-26 14:31:51 +02:00
041f2dff4a Enable the opening of email threads and calendar events from the timeline (#12873)
Fixes https://github.com/twentyhq/core-team-issues/issues/1123



https://github.com/user-attachments/assets/18a23d3f-c8c7-4c77-8b81-3685220343a5
2025-06-25 18:07:03 +02:00
22b4595b0b Refactor useDropdownV2 (#12875)
# What this PR does

This PR introduces what’s needed to progressively refactor the
useDropdown hooks we have.

It removes useDropdownV2 and renames useDropdown used for multi-page
dropdowns to useDropdownContextStateManagement

## The 3 useDropdown hooks

There are currently 3 useDropdown hooks : 

One is used for managing states in some dropdowns that have multiple
inner pages with contexts and without recoil. It is limited and would
need a separate refactoring, thus I just renamed it.

Then we have useDropdown and useDropdownV2, which followed our multiple
versions of recoil state management wrappers.

Now that the state management has been stabilized, we can merge
everything on the last version.

## What this refactor will allow next

This refactor will allow to refactor the legacy recoil state management,
because useDropdown is depending on legacy recoil states with scopeId.

Because there are only a dozen of those legacy states left, and the
dropdown’s ones are the harder to refactor, because swapping them as-is
causes a big QA, and if we have a big QA to do on all dropdowns, better
refactor the whole dropdown management and have everything clean.

After this refactor, we will be able to delete the legacy dropdown
states, and proceed with the other legacy states, then removing all the
legacy recoil state mangament.

## How do we allow progressive refactoring ?

There are many places where useDropdown is used.

To have an easier refactoring process, we want to merge multiple small
pull requests so that it is easier to QA and review.

For this we will maintain both legacy component state and component
state V2 in parallel for isDropdownOpen, so that the new hooks
`useOpenDropdown` , `useCloseDropdown` are doing the same thing than
`useDropdown` and `useDropdownV2` .

Thus for the moment, whether we use the legacy hooks or the new ones,
the effects are the same.

And we can have dropdowns operating on the old states and the new states
living side by side in the app.

## QA

Component | Status | Comments
-- | -- | --
CommandMenuActionMenuDropdown | Ok |  
RecordIndexActionMenuDropdown | Ok |  
RecordShowRightDrawerOpenRecordButton | Ok |  
useCloseActionMenu | Ok |  
CommandMenuContextChipGroups | Ok |  
useCommandMenuCloseAnimationCompleteCleanup | Ok |  
ObjectOptionsDropdown | Ok |  
ObjectOptionsDropdownContent | Ok |  
ObjectOptionsDropdownFieldsContent | Ok |  
ObjectOptionsDropdownHiddenFieldsContent | Ok |  
ObjectOptionsDropdownHiddenRecordGroupsContent | Ok |  
ObjectOptionsDropdownLayoutContent | Ok |  
ObjectOptionsDropdownLayoutOpenInContent | Ok |  
ObjectOptionsDropdownMenuContent | Ok |  
ObjectOptionsDropdownRecordGroupFieldsContent | Ok |  
ObjectOptionsDropdownRecordGroupsContent | Ok |  
ObjectOptionsDropdownRecordGroupSortContent | Ok |  
RecordBoardColumnHeaderAggregateDropdown | Ok |  
AggregateDropdownContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownFieldsContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownOptionsContent | Ok |  
RecordBoard | Ok | Used closeAnyOpenDropdown instead for a better UX
RecordBoardCard | Ok |  
useRecordBoardSelection | Ok |  
RecordTableColumnAggregateFooterDropdownContent | Ok |  
RecordTableColumnFooterWithDropdown | Ok |  
useOpenRecordFilterChipFromTableHeader | Ok |  
useCloseAnyOpenDropdown | Ok |  
useCloseDropdownFromOutside | Removed | Removed because unused
useDropdownV2 | Removed | Removed because all calls have been removed
useOpenDropdownFromOutside | Removed | Removed because unused
useCloseAndResetViewPicker | Ok |  
WorkflowVariablesDropdown | Ok |
2025-06-25 17:16:56 +02:00
048075f5e3 i18n - translations (#12877)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-25 16:20:52 +02:00
8056a5abc3 permissions - fix cancel button in create mode (#12870)
before - 


https://github.com/user-attachments/assets/9cbdc57d-40d6-42e3-ad5c-827a6602fbb5

after - 



https://github.com/user-attachments/assets/76e854eb-d809-4156-a386-b95c62461031
2025-06-25 16:09:22 +02:00
e2febbccea onboarding - signout button on Choose your workspaces modal (#12794)
@AMoreaux changes - 
- Added secondary background color to `StyledWorkspaceContainer`.
- Updated border styles for child elements to handle bottom borders
correctly.
- Removed redundant border styling from `StyledWorkspaceItem`.
Fix #12859 

my changes - 
- Add a logout button on the `Choose your Workspace` modal
- Remove the footer from the `Choose your Workspace` modal

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
2025-06-25 16:06:56 +02:00
1ab51d41aa Replace hotkey scopes by focus stack (Part 2 - Record Table, Rows and Cells) (#12798)
# Replace hotkey scopes by focus stack (Part 2 - Record Table, Rows and
Cells)

This PR is the second 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

The record table shortcuts are no longer centralized in the record
table, they now split and the focused element is in charge of applying
the desired shortcuts. (For instance: The rows are in charge of the row
navigation and the cells of the cells navigation).

## Video QA:


https://github.com/user-attachments/assets/f0bb9eed-8a2a-4b6d-a82f-1998e929f122


## Bugfixes:

### Fix record table click outside not working after opening and closing
a cell

Introduced by https://github.com/twentyhq/twenty/pull/11644

#### Before


https://github.com/user-attachments/assets/d28deda8-15e9-4ffe-b60a-e8b54625f8e5


#### After


https://github.com/user-attachments/assets/3f7e1ffc-15d9-4336-aeb0-bebd8ae0cbe0


### Fix ObjectFilterDropdownFilterInput hotkeys

Introduced by https://github.com/twentyhq/twenty/pull/12673

#### Before


https://github.com/user-attachments/assets/ab2039bd-ebe1-49ba-8377-a6b300664469


#### After


https://github.com/user-attachments/assets/90597453-dab2-426b-a134-0a24b0de0a6b
2025-06-25 13:18:51 +00:00
6450e11f1e Fix page change effect being rerun after changes on views (#12869)
`useDefaultHomePagePath` was rerendered each time a view was changed, so
the PageChangeEffect reran every time a view was updated, but we only
want this effect to run on page change.
2025-06-25 13:09:00 +00:00
2fc300a63c Remove number from label identifier list (#12831) 2025-06-24 18:05:27 +00:00
3cef6c9048 Force readonly for deletedAt field (#12840)
Fixes https://github.com/twentyhq/twenty/issues/12839

## Context
We now force readonly mode for deletedAt datepicker as permissions don't
handle well this use case. The frontend should call softDelete endpoint
in this case. For a user, they should select the record and click on the
trash icon instead

<img width="467" alt="Screenshot 2025-06-24 at 17 30 03"
src="https://github.com/user-attachments/assets/0a8a0709-305b-440f-91c2-d5e3f23ca213"
/>
2025-06-24 17:34:17 +02:00
d7c6806ad4 fix confirmation modal on subdomain settings (#12845)
before - 


https://github.com/user-attachments/assets/ff063912-0c1e-41e4-b01d-15081ecb04a1

after - 



https://github.com/user-attachments/assets/0ee6022d-f0a8-4243-a108-c4295d0fb560
2025-06-24 17:34:03 +02:00
77f0ed2208 Fix recordTableCells being displayed several time on record group tables (#12843)
As per title!
2025-06-24 17:29:50 +02:00
b8fd10e9e8 Add logging for recaptcha token (#12834) 2025-06-24 16:12:39 +02:00
08f8302148 Import - add duplicate check on import (#12810)
<img width="1217" alt="Screenshot 2025-06-24 at 11 43 03"
src="https://github.com/user-attachments/assets/de2bc12e-5e25-484f-a034-f52b0f237a3e"
/>

Test : 
- Add duplicate on id or on primaryEmail for people or primaryUrlLink on
companies

closes https://github.com/twentyhq/core-team-issues/issues/909
2025-06-24 16:12:20 +02:00
cc489f971d fix type (#12832) 2025-06-24 15:58:28 +02:00
251a19b87d i18n - translations (#12828)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 15:15:50 +02:00
8cf7649a4c Add object level form to role creation (#12826)
## Context
- Add object-level form to role creation
- Add isSaving props for save button isLoading state
<img width="594" alt="Screenshot 2025-06-24 at 15 03 59"
src="https://github.com/user-attachments/assets/77d9d399-4e1a-4e35-be45-c19100ef06c1"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-24 15:15:37 +02:00
2da66af26a Improve onboarding experience (#12824)
https://github.com/user-attachments/assets/365c1618-e9d5-46d5-9b54-bed2cdeb7c02
2025-06-24 15:06:50 +02:00
b4f7b547f1 i18n - translations (#12820)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 14:43:14 +02:00
480f135282 i18n - translations (#12818)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 14:22:44 +02:00
6f1107eecd Revert "[Permissions] Force open title input for role label when empty" (#12817)
Reverts twentyhq/twenty#12710
2025-06-24 14:08:16 +02:00
074cd22a67 [Permissions] Force open title input for role label when empty (#12710)
- Fix empty title in breadcrumb 
- Enforce role label input open if empty
2025-06-24 14:06:50 +02:00
4ac208cf1c Query dynamic cache key computation (#12814)
In this PR:
- add query hashKey to ObjectMetadataItems query graphql cache to avoid
caching outdated queries
- improve performance by removing ResolveField at FieldLevel and adding
this at resolver level
2025-06-24 12:04:00 +00:00
48347095d2 Fixed ACTOR advanced filter recent regressions (#12813)
This PR fixes recent regressions on advanced filters for the ACTOR field
type.

- The new `isFilterable` props on
`SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS` wasn't taken into account for
sub field picker in advanced filter.
- A wrong component instance id was passed to
`subFieldNameUsedInDropdownComponentState`
2025-06-24 13:57:18 +02:00
81d70e6fa3 Fixed relative date filter initalization (#12811)
This PR fixes problems with date filter : 
- Filter chip shows the label with plural, ex : `This weeks` 
- Using a relative filter now initializes to `This day`
- Switching between the different relative sub-operands (This, Past,
Next) now initializes with a value so we're never in an "empty" state.
2025-06-24 13:57:05 +02:00
3cee2b796f Fixed record picker loading flickering (#12736)
This PR solves a flickering effect on record pickers on the different
loading state they can be in.

It was designed with @Bonapara to settle on a nice UX feeling.

## Before

With fast network (local) :


https://github.com/user-attachments/assets/58899934-c705-4b44-b7f6-289045032c11

With slow network : 


https://github.com/user-attachments/assets/9fb18d86-9da6-4e5d-a83f-00c810fab2dc

## After


https://github.com/user-attachments/assets/f4abb40f-5d42-4c46-88ab-aaef4f883f7f

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

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-24 12:15:50 +02:00
c56ccf7ed9 Fixes date filter chip bugs (#12788)
This PR fixes a bug that occurs during filter operand changes.

As a date filter can contain values that have a different shape, mainly
date ISO string and hard-coded relative dates, changing the operand
without resetting the value to its default was causing a crash.

This PR also extracts the logic that computes the right part of a filter
chip into a util instead of a difficult to understand ternary, thus
solving small bugs in the value displayed also.

Fixes https://github.com/twentyhq/twenty/issues/12778
2025-06-24 09:29:28 +00:00
84b204dcab i18n - translations (#12809)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 10:38:44 +02:00
d0126e22ee feat: ability to switch currency format (#12542)
Fixes #11927

I have added 'format' in the zod schema of currency, and for using it, I
am separately passing 'format' to 'currencyDisplay.'
The feature is working correctly.

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-06-24 10:28:50 +02:00
6651abae18 i18n - translations (#12807)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-23 23:33:18 +02:00
d8f4e7e233 Add loader on workspace creation (#12806)
Not my most brillant design but it should work!
                  


https://github.com/user-attachments/assets/b89ae6d8-84ca-43c4-a010-d0686d522183
2025-06-23 23:23:13 +02:00
4eb859256c feat(settings): add loading state to save buttons (#11639)
Introduce a loading state to SaveButton and SaveAndCancelButtons
components to enhance user feedback during save operations. Update
SettingsNewObject to manage the loading state while submitting the form.

Fix https://github.com/twentyhq/core-team-issues/issues/572

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-23 22:49:38 +02:00
d248e536f3 Fix CombinedFindManyRecords with permissions (#12805)
## Context
This was already for relations but not the root object. This caused
issues with pages where we query multiple objects with the
CombinedFindManyRecords such as the data model

In the example below, we don't have access to rockets so we don't see
the real number of instances (now displays 0) and the FE shouldn't query
it.
<img width="557" alt="Screenshot 2025-06-23 at 19 23 51"
src="https://github.com/user-attachments/assets/2ee769b6-c108-466e-93ef-a17a6b092fcc"
/>

Diff
<img width="1232" alt="Screenshot 2025-06-23 at 19 39 05"
src="https://github.com/user-attachments/assets/6c841d4f-2a64-4908-8423-dc040893dfac"
/>
<img width="1224" alt="Screenshot 2025-06-23 at 19 38 57"
src="https://github.com/user-attachments/assets/bb3ff3bc-e9e4-40a6-b72f-18b4dc109df9"
/>
2025-06-23 21:27:58 +02:00
d5c974054d Improve performance on metadata computation (#12785)
In this PR:

## Improve recompute metadata cache performance. We are aiming for
~100ms

Deleting relationMetadata table and FKs pointing on it
Fetching indexMetadata and indexFieldMetadata in a separate query as
typeorm is suboptimizing

## Remove caching lock

As recomputing the metadata cache is lighter, we try to stop preventing
multiple concurrent computations. This also simplifies interfaces

## Introduce self recovery mecanisms to recompute cache automatically if
corrupted

Aka getFreshObjectMetadataMaps

## custom object resolver performance improvement:  1sec to 200ms

Double check queries and indexes used while creating a custom object
Remove the queries to db to use the cached objectMetadataMap

## reduce objectMetadataMaps to 500kb
<img width="222" alt="image"
src="https://github.com/user-attachments/assets/2370dc80-49b6-4b63-8d5e-30c5ebdaa062"
/>

We used to stored 3 fieldMetadataMaps (byId, byName, byJoinColumnName).
While this is great for devXP, this is not great for performances.
Using the same mecanisme as for objectMetadataMap: we only keep byIdMap
and introduce two otherMaps to idByName, idByJoinColumnName to make the
bridge

## Add dataloader on IndexMetadata (aka indexMetadataList in the API)

## Improve field resolver performances too

## Deprecate ClientConfig
2025-06-23 21:06:17 +02:00
00eb93463c [permissions V2] Fix - filter objects to search (#12803)
In morph relation pickers, we were not taking into account permissions
when computing the list of objects to search for, while we should not
search for objects we don't have read permissions on (permission denied
error)
2025-06-23 19:35:08 +02:00
37b48e2b21 i18n - translations (#12804)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-23 19:20:12 +02:00
85c50f149d [Permissions][FE] Design followup 5 (#12793)
## Context
- We now display workspace member full name and email in role assignment
picker
- Replaced Forbidden by "Not shared" with lock icon
- Fix Disabled for Danger accent
- Fix avatar URL

<img width="575" alt="Screenshot 2025-06-23 at 16 38 56"
src="https://github.com/user-attachments/assets/08430bfe-29c4-4ac4-821c-9062dfad7150"
/>
<img width="756" alt="Screenshot 2025-06-23 at 16 21 36"
src="https://github.com/user-attachments/assets/c19f31bd-fe9d-415d-aa55-62fa3e228c49"
/>
<img width="373" alt="Screenshot 2025-06-23 at 17 13 08"
src="https://github.com/user-attachments/assets/e2f7878c-7c5a-40b4-a482-8e99292257c3"
/>
<img width="342" alt="Screenshot 2025-06-23 at 17 37 49"
src="https://github.com/user-attachments/assets/04169e85-14dd-4aed-bd71-7aefd601a894"
/>
<img width="434" alt="Screenshot 2025-06-23 at 17 37 35"
src="https://github.com/user-attachments/assets/7caf0967-c4dd-4d0f-90c8-259a85182b19"
/>
2025-06-23 19:15:58 +02:00
f05da75bb5 Set error message not absolute (#12802)
Before
<img width="485" alt="Capture d’écran 2025-06-23 à 18 52 50"
src="https://github.com/user-attachments/assets/19c60cd1-f241-4419-9d03-d16d019f2c04"
/>

After
<img width="485" alt="Capture d’écran 2025-06-23 à 18 48 01"
src="https://github.com/user-attachments/assets/85b68984-11e0-456b-aacb-5a0661818b9c"
/>
<img width="485" alt="Capture d’écran 2025-06-23 à 18 48 38"
src="https://github.com/user-attachments/assets/7380d537-e8d0-411c-b4f8-7b38b6550e20"
/>
2025-06-23 17:08:40 +00:00
06fddc2ae0 Remove ID field + fix relations + remove runs (#12796)
- id field should only be available for search records action
- create record action does not work for relations. Requires to send
`accountOwner: { id: string }` instead of `accountOwner: string`
- hidding `runs` for version views as we did for workflows
2025-06-23 18:03:11 +02:00
d99bff983e Fix styling inconsistency for FormSingleRecordFieldChip placeholder (#12795)
## Before

![CleanShot 2025-06-23 at 17 01
16@2x](https://github.com/user-attachments/assets/8fb40b91-a17a-48dc-8d5e-6657bdcf8434)



## After


![CleanShot 2025-06-23 at 17 01
01@2x](https://github.com/user-attachments/assets/a9781e13-200c-4aa2-9907-a0c8f4a1dd67)
2025-06-23 17:32:51 +02:00
4c94fc2803 [permissions V2] Remove feature flag (#12790) 2025-06-23 15:22:57 +00:00
b6787c6fcd Record filter greaterThan becomes inclusive as lowerThan (#12786)
# Introduction
Greater than filtering wasn't inclusive whereas lower than was,
resulting in sending empty array to filtering resolver

Also refactored the transpilation methods to avoid asserting on the
`RATING_VALUES` order

closes https://github.com/twentyhq/twenty/issues/12779
2025-06-23 15:15:30 +00:00
b2a560e08d Fix rating field default value (#12792)
close https://github.com/twentyhq/twenty/issues/12789
2025-06-23 16:56:09 +02:00
2e296e775e Fix export to pdf (#12782)
Export to PDF was throwing an error due to fonts not being registered.
Maybe linked to the async loading changes or blocknote upgrades.


I wasn't a fan of hardcoding the fonts here (makes a second source of
truth for Inter), but after a few tests this seemed like the best
compromise
2025-06-23 16:27:21 +02:00
2cb2f528df [permissions - seeds] Give tim@apple.dev restricted rights (#12768)
Let's introduce an object-limited role for Tim, to test and/or spot
incompatibilities with restricted permissions in the future.
Our main user tim@apple.dev is now assigned a role that has all settings
permissions, and all object permissions except for update on Pets (to
test read-only view) and read on Rockets.
Since we still need an admin user for each workspace we are introducing
a new member, Jane, who has the admin role

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-06-23 13:46:53 +00:00
bec4a98ae7 add firstname and lastname on current user state and sync it while cr… (#12781)
…eating profile and pass it to cal.com's embed
2025-06-23 15:25:35 +05:30
b76dac2ca1 BREAKING CHANGE: Fix graphql errors (#12775)
We were using a global ValidationPipe in main.ts. This is an issue as
@Controllers should return HttpExecption and @Resolvers should return
GraphqlErrors

Removing the global pipe and creating a ResolverValidationPipe able to
generate GraphqlError. We also need to handle the exception in a filter
to avoid nest to think it's unhandled and make it flow to logs


Next step:
- it would be nice to have both @UsePipes(ResolverValidationPipe) +
@UseFilters(GraphqlValidationExceptionFilter) come together. This should
be possible if we create a @GraphQLResolver annotation
2025-06-23 11:23:16 +02:00
8e30da99e9 i18n - translations (#12777)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-22 22:01:09 +02:00
65df511179 feat: Add AI Agent workflow action node (#12650)
https://github.com/user-attachments/assets/8593e488-cb00-4fd2-b903-5ba5766e0254

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
Co-authored-by: Joseph Chiang <josephj6802@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: prastoin <paul@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: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Ajay A Adsule <103304466+AjayAdsule@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Marty <91310557+real-marty@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-06-22 21:42:04 +02:00
22e126869c Allow json in workflow run's error field (#12762)
We can now inspect errors even if they contain complex data as objects.
Only the first line of the error is put in red.



![CleanShot 2025-06-20 at 18 31
54@2x](https://github.com/user-attachments/assets/a3fd41fb-0063-4fe1-8185-54137c2a0d6e)


![image](https://github.com/user-attachments/assets/833a2851-e7d5-4985-9e42-07a1899cd3de)
2025-06-20 19:07:24 +02:00