9437 Commits

Author SHA1 Message Date
Félix Malfait
b27a97f2c5 feat: enforce @/ alias for imports and fix all relative parent imports (#16787)
## Summary
This PR enforces the use of `@/` alias for imports instead of relative
parent imports (`../`).

## Changes

### ESLint Configuration
- Added `no-restricted-imports` pattern in `eslint.config.react.mjs` to
block `../*` imports with the message "Relative parent imports are not
allowed. Use @/ alias instead."
- Removed the non-working `import/no-relative-parent-imports` rule
(doesn't work properly in ESLint flat config)

### VS Code Settings
- Added `javascript.preferences.importModuleSpecifier: non-relative` to
`.vscode/settings.json` (TypeScript setting was already there)

### Code Fixes
- Fixed **941 relative parent imports** across **706 files** in
`packages/twenty-front`
- All `../` imports converted to use `@/` alias

## Why
- Consistent import style across the codebase
- Easier to move files without breaking imports
- Better IDE support for auto-imports
- Clearer understanding of where imports come from
2025-12-23 22:57:51 +01:00
github-actions[bot]
781b96e80b i18n - docs translations (#16790)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 21:18:37 +01:00
github-actions[bot]
17e923b908 i18n - translations (#16788)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 19:01:31 +01:00
Lucas Bordeau
0b5be7caa3 Refactored Date to Temporal in critical date zones (#16544)
Fixes https://github.com/twentyhq/twenty/issues/16110

This PR implements Temporal to replace the legacy Date object, in all
features that are time zone sensitive. (around 80% of the app)

Here we define a few utils to handle Temporal primitives and obtain an
easier DX for timezone manipulation, front end and back end.

This PR deactivates the usage of timezone from the graph configuration,
because for now it's always UTC and is not really relevant, let's handle
that later.

Workflows code and backend only code that don't take user input are
using UTC time zone, the affected utils have not been refactored yet
because this PR is big enough.

# New way of filtering on date intervals

As we'll progressively rollup Temporal everywhere in the codebase and
remove `Date` JS object everywhere possible, we'll use the way to filter
that is recommended by Temporal.

This way of filtering on date intervals involves half-open intervals,
and is the preferred way to avoid edge-cases with DST and smallest time
increment edge-case.

## Filtering endOfX with DST edge-cases

Some day-light save time shifts involve having no existing hour, or even
day on certain days, for example Samoa Islands have no 30th of December
2011 : https://www.timeanddate.com/news/time/samoa-dateline.html, it
jumps from 29th to 31st, so filtering on `< next period start` makes it
easier to let the date library handle the strict inferior comparison,
than filtering on `≤ end of period` and trying to compute manually the
end of the period.

For example for Samoa Islands, is end of day `2011-12-29T23:59:59.999`
or is it `2011-12-30T23:59:59.999` ? If you say I don't need to know and
compute it, because I want everything strictly before
`2011-12-29T00:00:00 + start of next day (according to the library which
knows those edge-cases)`, then you have a 100% deterministic way of
computing date intervals in any timezone, for any day of any year.

Of course the Samoa example is an extreme one, but more common ones
involve DST shifts of 1 hour, which are still problematic on certain
days of the year.

## Computing the exact _end of period_

Having an open interval filtering, with `[included - included]` instead
of half-open `[included - excluded)`, forces to compute the open end of
an interval, which often involves taking an arbitrary unit like minute,
second, microsecond or nanosecond, which will lead to edge-case of
unhandled values.

For example, let's say my code computes endOfDay by setting the time to
`23:59:59.999`, if another library, API, or anything else, ends up
giving me a date-time with another time precision `23:59:59.999999999`
(down to the nanosecond), then this date-time will be filtered out,
while it should not.

The good deterministic way to avoid 100% of those complex bugs is to
create a half-open filter :

`≥ start of period` to `< start of next period` 

For example : 

`≥ 2025-01-01T00:00:00` to `< 2025-01-02T00:00:00` instead of `≥
2025-01-01T00:00:00` to `≤ 2025-01-01T23:59:59.999`

Because, `2025-01-01T00:00:00` = `2025-01-01T00:00:00.000` =
`2025-01-01T00:00:00.000000` = `2025-01-01T00:00:00.000000000` => no
risk of error in computing start of period

But `2025-01-01T23:59:59` ≠ `2025-01-01T23:59:59.999` ≠
`2025-01-01T23:59:59.999999` ≠ `2025-01-01T23:59:59.999999999` =>
existing risk of error in computing end of period

This is why an half-open interval has no risk of error in computing a
date-time interval filter.

Here is a link to this debate :
https://github.com/tc39/proposal-temporal/issues/2568

> For this reason, we recommend not calculating the exact nanosecond at
the end of the day if it's not absolutely necessary. For example, if
it's needed for <= comparisons, we recommend just changing the
comparison code. So instead of <= zdtEndOfDay your code could be <
zdtStartOfNextDay which is easier to calculate and not subject to the
issue of not knowing which unit is the right one.
>
> [Justin Grant](https://github.com/justingrant), top contributor of
Temporal

## Application to our codebase

Applying this half-open filtering paradigm to our codebase means we
would have to rename `IS_AFTER` to `IS_AFTER_OR_EQUAL` and to keep
`IS_BEFORE` (or even `IS_STRICTLY_BEFORE`) to make this half-open
interval self-explanatory everywhere in the codebase, this will avoid
any confusion.

See the relevant issue :
https://github.com/twentyhq/core-team-issues/issues/2010

In the mean time, we'll keep this operand and add this semantic in the
naming everywhere possible.

## Example with a different user timezone 

Example on a graph grouped by week in timezone Pacific/Samoa, on a
computer running on Europe/Paris :

<img width="342" height="511" alt="image"
src="https://github.com/user-attachments/assets/9e7d5121-ecc4-4233-835b-f59293fbd8c8"
/>

Then the associated data in the table view, with our **half-open
date-time filter** :

<img width="804" height="262" alt="image"
src="https://github.com/user-attachments/assets/28efe1d7-d2fc-4aec-b521-bada7f980447"
/>

And the associated SQL query result to see how DATE_TRUNC in Postgres
applies its internal start of week logic :

<img width="709" height="220" alt="image"
src="https://github.com/user-attachments/assets/4d0542e1-eaae-4b4b-afa9-5005f48ffdca"
/>

The associated SQL query without parameters to test in your SQL client :

```SQL
SELECT "opportunity"."closeDate" as "close_date", TO_CHAR(DATE_TRUNC('week', "opportunity"."closeDate", 'Pacific/Samoa') AT TIME ZONE 'Pacific/Samoa', 'YYYY-MM-DD') AS "DATE_TRUNC by week start in timezone Pacific/Samoa", "opportunity"."name" FROM "workspace_1wgvd1injqtife6y4rvfbu3h5"."opportunity" "opportunity" ORDER BY "opportunity"."closeDate" ASC NULLS LAST
```

# Date picker simplification (not in this PR)

Our DatePicker component, which is wrapping `react-datepicker` library
component, is now exposing plain dates as string instead of Date object.
The Date object is still used internally to manage the library
component, but since the date picker calendar is only manipulating plain
dates, there is no need to add timezone management to it, and no need to
expose a handleChange with Date object.

The timezone management relies on date time inputs now.

The modification has been made in a previous PR :
https://github.com/twentyhq/twenty/issues/15377 but it's good to
reference it here.

# Calendar feature refactor

Calendar feature has been refactored to rely on Temporal.PlainDate as
much as possible, while leaving some date-fns utils to avoid re-coding
them.

Since the trick is to use utils to convert back and from Date object in
exec env reliably, we can do it everywhere we need to interface legacy
Date object utils and Temporal related code.

## TimeZone is now shown on Calendar :

<img width="894" height="958" alt="image"
src="https://github.com/user-attachments/assets/231f8107-fad6-4786-b532-456692c20f1d"
/>

## Month picker has been refactored 

<img width="503" height="266" alt="image"
src="https://github.com/user-attachments/assets/cb90bc34-6c4d-436d-93bc-4b6fb00de7f5"
/>

Since the days weren't useful, the picker has been refactored to remove
the days.

# Miscellaneous 
- Fixed a bug with drag and drop edge-case with 2 items in a list.

# Improvements 

## Lots of chained operations
It would be nice to create small utils to avoid repeated chained
operations, but that is how Temporal is designed, a very small set of
primitive operations that allow to compose everything needed. Maybe
we'll have wrappers on top of Temporal in the coming years.

## Creation of Temporal objects is throwing errors

If the input is badly formatted Temporal will throw, we might want to
adopt a global strategy to avoid that.

Example : 

```ts
const newPlainDate = Temporal.PlainDate.from('bad-string'); // Will throw
```
2025-12-23 17:40:26 +00:00
Félix Malfait
4d5d2233bc fix: update date-utils test to expect French translation
Lingui translations work correctly for plural() macro,
so the short format returns French 'an' not English 'year'
2025-12-23 17:32:43 +01:00
github-actions[bot]
e3757f300a i18n - docs translations (#16779)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 17:06:38 +01:00
Raphaël Bosi
1bc344c6fa [DASHBOARDS] Fix filter parsing (#16782)
## Fix filter parsing for charts

Fixes https://github.com/twentyhq/twenty/issues/16606
Fixes https://github.com/twentyhq/private-issues/issues/396

When clicking on a chart slice/bar grouped by certain field types, the
filter value was passed as a plain string instead of a JSON array,
causing a JSON parse error on navigation.

This happens because `arrayOfStringsOrVariablesSchema` in the filter
parsing logic expects JSON array format for certain field types, but the
values weren't wrapped correctly for all cases.

Extracted the util `formatChartFilterValue` and renamed it to
`serializeChartBucketValueForFilter` and modified it to handle JSON
array wrapping for:
- CURRENCY fields with currencyCode subfield (IS operand)
- MULTI_SELECT fields (CONTAINS operand)
- ADDRESS fields with addressCountry subfield (CONTAINS operand)

Added unit tests for the new utility

### Before


https://github.com/user-attachments/assets/9a52572b-e896-445a-9f5c-e21963f78441

### After


https://github.com/user-attachments/assets/12eed5e5-a49c-4557-a45c-ac7e00b3422a
2025-12-23 17:00:38 +01:00
github-actions[bot]
b1aaf21356 i18n - translations (#16784)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 16:47:52 +01:00
Raphaël Bosi
19e77f9dd7 [DASHBOARDS] Update iFrame error message (#16777)
`Invalid URL` instead of `no data` for iFrame widgets.

<img width="1142" height="638" alt="CleanShot 2025-12-23 at 14 13 17@2x"
src="https://github.com/user-attachments/assets/22621e57-c4ba-4e1f-91d0-5c4ef435c649"
/>
2025-12-23 15:33:55 +00:00
github-actions[bot]
67f511bae3 i18n - translations (#16776)
Created by Github action

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Broad i18n refresh touching email and front-end locales, with
new/updated strings and some path/key adjustments.
> 
> - Adds "Updates" settings page strings (e.g., `Updates`, `Early
access`, `Read changelog`, "Check out our latest releases") and
removes/replaces prior "Releases/Changelog" entries
> - Introduces chart color palette label (`Default palette`) and page
layout field widget messages (`No field configured`, `Select a field to
display…`, `No related records`)
> - Updates locale files for many languages (af-ZA, ar-SA, ca-ES, cs-CZ,
da-DK, de-DE, el-GR, es-ES, fi-FI, aa-ER) with new or corrected
translations and component path changes
> - Email (vi-VN): adjusts generated translations; leaves some strings
untranslated and clears one obsolete translation in `vi-VN.po`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0246b729af. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-12-23 14:32:25 +01:00
Félix Malfait
3dd858c91e i18n - docs translations (#16774)
Created by Github action

Pulls the latest documentation translations from Crowdin for all
supported languages:
- French (fr)
- Arabic (ar)  
- Czech (cs)
- German (de)
- Spanish (es)
- Italian (it)
- Japanese (ja)
- Korean (ko)
- Portuguese (pt)
- Romanian (ro)
- Russian (ru)
- Turkish (tr)
- Chinese (zh-CN)

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 14:26:11 +01:00
Raphaël Bosi
7b6071619c Refactor command menu input (#16773)
- Open input on item click
- `CommandMenuItemNumberInput` and `CommandMenuItemTextInput` don't only
define the input but the whole menu item now
- Fixed behavior on escape

## Video QA


https://github.com/user-attachments/assets/bf2f03e9-d07c-4a1e-9bc8-6606839269ff
2025-12-23 14:00:04 +01:00
Abdul Rahman
81918e8720 Increase hover target area for workflow node dots (#16750)
Closes #14137 



https://github.com/user-attachments/assets/99f756be-ff8e-47ed-98fc-8672c2522d8f
2025-12-23 11:49:52 +01:00
Abdul Rahman
42ad4630ea Auto-focus workflow title field when creating new workflow (#16765)
Closes #14135 



https://github.com/user-attachments/assets/4170c33d-4a2e-450a-98c0-20163d4b2382
2025-12-23 11:36:23 +01:00
Lucky Goyal
1dbb326fd6 fix: prevent workflow step title from transferring between steps. (#16762)
fixes (#16754)

Solution:
Add key prop to CommandMenuWorkflowStepInfo to force React to remount
the component when switching between steps, ensuring fresh state.



https://github.com/user-attachments/assets/77f51f5b-6b25-4c05-aaf7-8704ab8bee0f
v1.14.0
2025-12-23 10:35:53 +01:00
Félix Malfait
c2c8f6e41c fix: prevent API keys from creating UNLISTED views (#16770)
## Summary
UNLISTED views are personal views tied to a specific user, so API keys
should not be able to create them.

## Changes
- Added check in `canUserCreateView` to block API keys from creating
UNLISTED views
- Refactored the service to use smaller functions with early returns (no
nested if/else)

## Behavior Matrix

### Creating Views
| Caller | Visibility | Has VIEWS Permission | Result |
|--------|------------|---------------------|--------|
| User | UNLISTED | (not checked) |  Allow |
| User | WORKSPACE | Yes |  Allow |
| User | WORKSPACE | No |  Denied |
| **API Key** | **UNLISTED** | (not checked) | ** Denied** |
| API Key | WORKSPACE | Yes |  Allow |
| API Key | WORKSPACE | No |  Denied |
2025-12-23 10:13:00 +01:00
Abdul Rahman
ba76cf4fed Fix: Record label identifier setting not saving on first attempt (#16769) 2025-12-23 09:17:31 +01:00
eeeggg
65dced14ff fix: enable API key management of workspace views + fix permission bypass vulnerability (#16768)
Fixes #16739

- Remove empty string coercion in createCoreView that caused PostgreSQL
UUID errors for API keys
- Add permission check allowing API keys with VIEWS permission to manage
workspace views they created

API keys with 'Manage Views' permission can now create, update, and
delete workspace views via both GraphQL and REST APIs.
2025-12-23 09:06:47 +01:00
BOHEUS
79998ef8fc Allow creation date import (#16764)
PR for #15313 

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enables importing timestamp fields that were previously filtered out.
> 
> - Removes explicit exclusions of `createdAt` and `updatedAt` in
`spreadsheetImportFilterAvailableFieldMetadataItems`
> - Keeps existing constraints: only active fields, system fields
limited (except `id`), exclude `deletedAt`, and only allow `RELATION`
fields that are `MANY_TO_ONE`; sorting unchanged
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a2b36e4cc0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-12-23 08:05:01 +00:00
github-actions[bot]
99d5aa2589 i18n - docs translations (#16767)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-23 01:40:21 +01:00
Abdullah.
c6ea7ae288 Allow custom fields to be editable for system objects and prevent the error for timeline activity on system object pages. (#16268)
Solves #16015 

- Added a check in `useTimelineActivities.ts` to see if the system
object page we're viewing has timelineActivity being tracked before
querying to get the activity history.
- Removed @WorkspaceIsObjectUIReadOnly decorator from system objects and
added @WorkspaceIsFieldUIReadOnly to standard and system fields to allow
custom field edits as requested in the issue.
- Did not add calendarEvents or other system objects to timelineActivity
just yet since keeping track of timeline activity for every one of them
felt counter-intuitive and bloated. In order to determine which objects
need timelineActivity, I think we need to fix the broken views of system
objects first, such as the one in the attached screenshots - a good
number of them are broken. The check I added to
`useTimelineActivities.ts` hook displays timeline activity as empty for
the time - error would not be shown as suggested by Thomas.

<img width="1062" height="858" alt="image"
src="https://github.com/user-attachments/assets/e877e0fe-b665-46e3-b785-e84f2af7f833"
/>

<br />

<img width="1061" height="858" alt="image"
src="https://github.com/user-attachments/assets/0eba8c1c-444a-4b13-beda-64b95cf39077"
/>

- Editing custom fields on calendar events (and other objects without
position fields) crashed with TypeError: Cannot convert undefined or
null to object in sortCachedObjectEdges. This happened because some
cached queries had empty orderBy arrays ([]), and the optimistic effect
tried to sort with them. Objects without position fields returned
empty orderBy arrays when there were no sorts, while objects with
position fields automatically got [{ position: 'AscNullsFirst' }].
The backend always adds { id: 'AscNullsFirst' } as a fallback, but
the frontend didn't match this. So, I added { id: 'AscNullsFirst' } to
the Frontend as default orderBy when there are no sorts and no position
field.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Apply per-field UI read-only to system/standard fields and skip
timeline activity fetching when the target object isn’t related; refine
record-table cell open/navigation behavior.
> 
> - Server: Replace object-level UI read-only with per-field
`isUIReadOnly` across many standard objects (e.g., `calendarEvent`,
`workspaceMember`, messaging, calendar, favorites, attachments,
workflows, etc.), and mirror this via `@WorkspaceIsFieldUIReadOnly` on
workspace entities.
> - Frontend: In `useTimelineActivities.ts`, check object metadata for a
relation to `timelineActivity` and `skip` the query when absent,
preventing errors on system object pages.
> - Frontend: Simplify/adjust record-table cell logic—remove unused
args, allow navigation from first column when non-empty, block editing
for read-only records (while still allowing navigation), and update
button handlers/hover styles accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dac1262d70. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-12-22 22:22:30 +00:00
github-actions[bot]
5003fc4196 i18n - docs translations (#16761)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-22 19:22:30 +01:00
StephanieJoly4
60897b255a Adding one How To article to the workflow section (#16760)
- added an image, one article
- updated the 2 files under the Navigation folder but not the docs.json
- no need to redirect the links given this is a new article
2025-12-22 19:10:54 +01:00
Félix Malfait
0dec4b9b67 docs: add IS_MULTIWORKSPACE_ENABLED documentation (#16758)
## Summary

Adds comprehensive documentation for the `IS_MULTIWORKSPACE_ENABLED`
configuration variable, which was previously undocumented despite being
a fundamental configuration option that significantly changes how Twenty
behaves.

## Changes

### Self-Host Setup Guide (`setup.mdx`)

Added a new **Multi-Workspace Mode** section that explains:

- **Single-workspace mode (default)**: Only one workspace allowed, first
user gets admin privileges, signups disabled after first workspace
- **Multi-workspace mode**: Multiple workspaces with subdomain-based
URLs (e.g., `sales.your-domain.com`)
- **Related config variables**: `DEFAULT_SUBDOMAIN` and
`IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS`
- **DNS configuration**: Wildcard DNS setup for dynamic subdomains
- **Workspace creation restrictions**: How to limit workspace creation
to server admins

### Local Setup Guide (`local-setup.mdx`)

Added an info callout in the environment variables section to make
contributors aware of multi-workspace mode, useful when testing
subdomain-based features.

## Why This Matters

The `IS_MULTIWORKSPACE_ENABLED` variable controls:
- Whether multiple workspaces can exist on a single instance
- URL structure (plain domain vs subdomains)
- First user privileges
- Sign-up behavior after initial setup
- SSO workspace resolution logic

This is critical knowledge for self-hosters who want to run Twenty as a
multi-tenant SaaS.
2025-12-22 18:10:41 +01:00
Félix Malfait
6a31f0667e fix: remove invalid crowdin flag 2025-12-22 17:43:27 +01:00
Félix Malfait
354c43988d fix(i18n): allow updating existing docs files in Crowdin
- Add upload_sources_args: '--update-strings' to update existing files
- Remove duplicate steps in workflow
2025-12-22 17:38:34 +01:00
dependabot[bot]
cf51baedae Bump tsx from 4.20.5 to 4.21.0 (#16738)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.20.5 to 4.21.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/privatenumber/tsx/releases">tsx's
releases</a>.</em></p>
<blockquote>
<h2>v4.21.0</h2>
<h1><a
href="https://github.com/privatenumber/tsx/compare/v4.20.6...v4.21.0">4.21.0</a>
(2025-11-30)</h1>
<h3>Features</h3>
<ul>
<li>upgrade esbuild (<a
href="https://redirect.github.com/privatenumber/tsx/issues/748">#748</a>)
(<a
href="048fb62387">048fb62</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.21.0"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.20.6</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.20.5...v4.20.6">4.20.6</a>
(2025-09-26)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>properly hide relaySignal from process.listeners() (<a
href="https://redirect.github.com/privatenumber/tsx/issues/741">#741</a>)
(<a
href="710a42473e">710a424</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.20.6"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f6284cd505"><code>f6284cd</code></a>
ci: lock in semantic-release v24</li>
<li><a
href="048fb62387"><code>048fb62</code></a>
feat: upgrade esbuild (<a
href="https://redirect.github.com/privatenumber/tsx/issues/748">#748</a>)</li>
<li><a
href="710a42473e"><code>710a424</code></a>
fix: properly hide relaySignal from process.listeners() (<a
href="https://redirect.github.com/privatenumber/tsx/issues/741">#741</a>)</li>
<li><a
href="20b91c44bb"><code>20b91c4</code></a>
docs: make sponsors dynamic</li>
<li><a
href="08dcd59a3a"><code>08dcd59</code></a>
chore: move vercel settings to root</li>
<li>See full diff in <a
href="https://github.com/privatenumber/tsx/compare/v4.20.5...v4.21.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tsx&package-manager=npm_and_yarn&previous-version=4.20.5&new-version=4.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-22 17:35:42 +01:00
dependabot[bot]
5b69173c44 Bump ts-loader from 9.5.1 to 9.5.4 (#16737)
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 9.5.1 to
9.5.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/ts-loader/releases">ts-loader's
releases</a>.</em></p>
<blockquote>
<h2>v9.5.4</h2>
<ul>
<li><a
href="https://redirect.github.com/TypeStrong/ts-loader/pull/1676">chore:
typescript 5.9 upgrade</a> - thanks <a
href="https://github.com/johnnyreilly"><code>@​johnnyreilly</code></a></li>
</ul>
<p>Skipping 9.5.3 due to a publishing issue</p>
<h2>v9.5.3</h2>
<ul>
<li><a
href="https://redirect.github.com/TypeStrong/ts-loader/pull/1665">fix:
add more detailed error messages</a> - thanks <a
href="https://github.com/hai-x"><code>@​hai-x</code></a></li>
</ul>
<h2>v9.5.2</h2>
<ul>
<li><a
href="https://redirect.github.com/TypeStrong/ts-loader/pull/1665">fix:
add more detailed error messages</a> - thanks <a
href="https://github.com/hai-x"><code>@​hai-x</code></a></li>
</ul>
<p><em>This release is actually v9.5.2 but due to a problem with the
initial release workflow we incremented to v9.5.3</em></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/ts-loader/blob/main/CHANGELOG.md">ts-loader's
changelog</a>.</em></p>
<blockquote>
<h2>9.5.4</h2>
<ul>
<li><a
href="https://redirect.github.com/TypeStrong/ts-loader/pull/1676">chore:
typescript 5.9 upgrade</a> - thanks <a
href="https://github.com/johnnyreilly"><code>@​johnnyreilly</code></a></li>
</ul>
<p>Skipping 9.5.3 due to a publishing issue</p>
<h2>9.5.2</h2>
<ul>
<li><a
href="https://redirect.github.com/TypeStrong/ts-loader/pull/1665">fix:
add more detailed error messages</a> - thanks <a
href="https://github.com/hai-x"><code>@​hai-x</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f7d022f79d"><code>f7d022f</code></a>
Update changelog for version 9.5.4 (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1677">#1677</a>)</li>
<li><a
href="ba825c2520"><code>ba825c2</code></a>
chore: TypeScript 5.9 upgrade (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1676">#1676</a>)</li>
<li><a
href="847a24936a"><code>847a249</code></a>
feat: stub for 5.8 (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1668">#1668</a>)</li>
<li><a
href="0ee403558e"><code>0ee4035</code></a>
feat: Update push.yml with workflow_dispatch</li>
<li><a
href="d7352989b8"><code>d735298</code></a>
chore: update lockfile (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1666">#1666</a>)</li>
<li><a
href="e652315dde"><code>e652315</code></a>
fix: add more detailed error messages (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1665">#1665</a>)</li>
<li><a
href="36b6bf24c6"><code>36b6bf2</code></a>
Upgrade TypeScript to 5.7 (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1661">#1661</a>)</li>
<li><a
href="6a4e29c729"><code>6a4e29c</code></a>
Create SECURITY.md</li>
<li><a
href="5379bb1fc4"><code>5379bb1</code></a>
Update testpack for TypeScript 5.6 (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1656">#1656</a>)</li>
<li><a
href="95110c67b9"><code>95110c6</code></a>
Ts 55 (<a
href="https://redirect.github.com/TypeStrong/ts-loader/issues/1651">#1651</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/ts-loader/compare/v9.5.1...v9.5.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ts-loader&package-manager=npm_and_yarn&previous-version=9.5.1&new-version=9.5.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-22 17:35:26 +01:00
Félix Malfait
e6491d6a80 feat(i18n): fix translation QA issues and add automation (#16756)
## Summary

This PR fixes translation QA issues and adds automation to prevent
future issues.

### Translation Fixes
- Fixed **escaped Unicode sequences** in translations (e.g.,
`\u62db\u5f85` → `招待`)
- Removed **corrupted control characters** from .po files (null bytes,
invalid characters)
- Fixed **missing/incorrect placeholders** in various languages
- Deleted **35 problematic translations** via Crowdin API that had
variable mismatches

### New Scripts (in `packages/twenty-utils/`)
- `fix-crowdin-translations.ts` - Auto-fixes encoding issues and syncs
to Crowdin
- `fix-qa-issues.ts` - Fixes specific QA issues via Crowdin API
- `translation-qa-report.ts` - Generates weekly QA report from Crowdin
API

### New Workflow
- `i18n-qa-report.yaml` - Weekly workflow that creates a PR with
translation QA issues for review

### Other Changes
- Moved GitHub Actions from `.github/workflows/actions/` to
`.github/actions/`
- Fixed `date-utils.ts` to avoid nested `t` macros in plural expressions
(root cause of confusing placeholders)

### QA Status After Fixes
| Category | Count | Status |
|----------|-------|--------|
| variables | 0  | Fixed |
| tags | 1 | Minor |
| empty | 0  | Fixed |
| spaces | 127 | Low priority |
| numbers | 246 | Locale-specific |
| special_symbols | 268 | Locale-specific |
2025-12-22 17:30:46 +01:00
Abdullah.
ede261abf4 fix: storybook manager bundle may expose environment variables during build (#16747)
Resolves [Dependabot Alert
348](https://github.com/twentyhq/twenty/security/dependabot/348).

Updated the patch version - 8.6.14 to 8.6.15.
2025-12-22 16:53:52 +01:00
Baptiste Devessier
1324ad1ee3 Edit simple values in Field widget (#16749)
https://github.com/user-attachments/assets/116b8259-b366-47bf-8068-b5276b138e03
2025-12-22 14:21:39 +00:00
martmull
bb73cbc380 1774 extensibility v1 create an exhaustive documentation readme or dedicated section in twenty contributing doc (#16751)
As title

<img width="1108" height="894" alt="image"
src="https://github.com/user-attachments/assets/e2dc7e12-72e3-4ca3-ac7b-a94de547f82a"
/>
2025-12-22 15:19:11 +01:00
Marie
50b0665c44 Enable read on replica for all (#16740)
Removing the feature flag to enable read on replica for all workspaces.
It will still be possible to toggle off the feature by removing the env
variable `PG_DATABASE_REPLICA_URL`.
2025-12-22 14:32:04 +01:00
Abdullah.
869608327e feat: validator is vulnerable to incomplete filtering of one or more instances of special elements (#16748)
Resolves [Dependabot Alert
336](https://github.com/twentyhq/twenty/security/dependabot/336).

Used `yarn up validator --recursive` since minor version upgrades are
allowed by definition of packages.
2025-12-22 14:28:38 +01:00
Félix Malfait
ea6d497c3b fix(docs): configure target languages in crowdin.yml (#16745)
## Summary
Fixes the Crowdin GitHub Action failure by properly configuring target
languages.

## Problem
The previous PR (#16744) used `download_language` parameter, but that
only accepts a **single language**, not a comma-separated list. This
caused the error:
```
Language 'fr,ar,cs,de,es,it,ja,ko,pt,ro,ru,tr,zh-CN' doesn't exist in the project
```

## Solution
- Added `languages` array to `crowdin.yml` to specify target languages
for download
- Removed the broken `download_language` parameter from the workflow

The languages list matches `supported-languages.ts`:
- fr, ar, cs, de, es, it, ja, ko, pt, ro, ru, tr, zh-CN
2025-12-22 14:03:38 +01:00
Félix Malfait
4bfc0a79c7 I18n Docs (#16746)
Attempt to fix translations...

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-22 14:03:22 +01:00
Félix Malfait
0731a616b7 Restore navigation structure from PR #16705 (#16742)
## Summary
The merge conflict resolution from PR #16705 incorrectly discarded the
new documentation structure changes. This PR updates the navigation JSON
files (the correct approach) to restore the intended changes.

## Changes restored
- New 'Capabilities' and 'How-Tos' subgroups organization
- Renamed sections (e.g., 'Getting Started' → 'Discover Twenty')
- New sections: Data Migration, Calendar & Emails, AI, Views &
Pipelines, Dashboards, Permissions & Access, Billing
- Reorganized Developers section with Extend, Self-Host, and Contribute
groups

## Files updated
- `navigation/base-structure.json`
- `navigation/navigation-schema.json`
- `navigation/navigation.template.json`

## Context
PR #16705 was merged but the merge conflict was incorrectly resolved,
causing all the structural changes to be lost. The previous fix (PR
#16741) updated docs.json directly, but the correct approach is to
update the navigation JSON files instead. This PR properly restores
those changes from the final commit of PR #16705
(`c856e0d598a0056c2bdaf528502e08261daf7c7c`).

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-22 13:29:25 +01:00
Félix Malfait
df3d34e16b fix(docs): only download translations for supported languages (#16744)
## Summary
The Crowdin GitHub Action was failing at ~54% progress with the error:
> Failed to build translation. Please contact our support team for help

## Root Cause
The build was attempting to process all target languages configured in
Crowdin, including languages not supported by Mintlify (as defined in
`supported-languages.ts`). Some of these unsupported languages had
translation issues causing the build to fail.

## Fix
Added the `download_language` parameter to the Crowdin GitHub Action to
restrict downloads to only the languages supported by Mintlify:
- fr, ar, cs, de, es, it, ja, ko, pt, ro, ru, tr, zh-CN

## Testing
Verified via Crowdin API that builds succeed when specifying only these
supported languages, while the full build fails.
2025-12-22 13:25:11 +01:00
Félix Malfait
57517d687e Restore docs.json user guide structure from PR #16705 (#16741)
## Summary
The merge conflict resolution from PR #16705 incorrectly discarded the
new documentation structure changes. This PR restores the intended
changes.

## Changes restored
- New 'Capabilities' and 'How-Tos' subgroups organization
- Renamed sections (e.g., 'Getting Started' → 'Discover Twenty')
- New sections: Data Migration, Calendar & Emails, AI, Views &
Pipelines, Dashboards, Permissions & Access, Billing
- Reorganized Developers section with API subsection
- URL redirects for SEO and user experience continuity

## Context
PR #16705 was merged but the merge conflict was incorrectly resolved,
causing all the structural changes to be lost. This PR brings back those
changes from the final commit of PR #16705
(`c856e0d598a0056c2bdaf528502e08261daf7c7c`).
2025-12-22 10:45:58 +01:00
StephanieJoly4
183d034716 User guide structure update (#16705)
Reorganizing by Feature sections

Capabilities folders to give an overview of each feature

How-Tos folders to give guidance for advanced customizations

Reorganized the Developers section as well, moving the API sub section
there

added some new visuals and videos to illustrate the How-Tos articles

checked the typos, the links and added a section at the end of the
doc.json file to redirect existing links to the new ones (SEO purpose +
continuity of the user experience)

What I have not updated is the "l" folder that, per my understanding,
contains the translation of the User Guide - that I only edited in
English

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
5301502a32. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Abdul Rahman <ar5438376@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-12-22 09:07:06 +01:00
Charles Bochet
9c49f4ba82 Fix Global workflows not pinned (#16728)
A bug was reported where workflow actions marked as Pinned were actually
not pinned in the top right

In workflow edit:
<img width="400" height="379" alt="image"
src="https://github.com/user-attachments/assets/adea9b4e-c898-4395-8cbf-d21282770fac"
/>

Consequence on Header:
<img width="400" height="53" alt="image"
src="https://github.com/user-attachments/assets/a39e4201-2450-4566-978a-7f464d3a64f0"
/>
2025-12-20 12:29:45 +01:00
Baptiste Devessier
9984981e82 Field widget edit relations (#16714)
- Let the user edit their relations
- Create a `useCurrentWidget` that returns the widget information in the
context of a rendered widget. Relies on a component instance context.


https://github.com/user-attachments/assets/e908364f-2d53-4adb-97a1-4d950f51976a

Follow up:

- Show pen button for all Field widgets
2025-12-19 21:21:00 +01:00
github-actions[bot]
f9744ef245 i18n - docs translations (#16721)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-19 19:22:08 +01:00
Thomas Trompette
9aa77ab991 Fix composite upsert (#16718)
Doing an upsert on existing value, composite field not updated properly.

```
Input: {
  id: "08ca34fe-fc39-474f-adac-4d89f844e922",
  name: "tom",
  linkedinLink: {
    primaryLinkUrl: "https://www.linkedin.com/in/etienneyaouni1982",
    primaryLinkLabel: "etienne",
    secondaryLinks: null,
  },
}
```

Building `overwrites` for upsert forgets `linkedinLink` because column
names are not flattened yet.
We don't want to call formatData yet on the input, because this is
heavy.

Overriding `overwrites` on execute.
2025-12-19 18:28:28 +01:00
neo773
0849dda153 Gmail error handling fixes (#16719)
- Replaced direct instance checks for GaxiosError with a utility
function isGmailApiError for better error handling consistency across
services.
-  Debug logs
2025-12-19 18:23:14 +01:00
neo773
d30580fc4e remove IMAP_SMTP_CALDAV feature flag (#16695)
To be merged after 
https://github.com/twentyhq/twenty/pull/16479
https://github.com/twentyhq/twenty/pull/16694
2025-12-19 18:20:12 +01:00
Thomas Trompette
6355557356 [POC] Real-Time (#16633)
https://github.com/user-attachments/assets/3ad7a4f3-d08b-4a1c-b3c2-bb42ef9f3575

Real time POC.

Next steps:
- find out the correct API for subscription. Should be triggered
directly in query hooks (useFindManyRecords, useLazy...)
- improve query matching
2025-12-19 07:17:02 -10:00
github-actions[bot]
b587cde216 i18n - translations (#16720)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-19 18:02:03 +01:00
neo773
024ee152a0 Add useUpdateManyRecords hook and message folders sync status mutation (#16694)
- Added new `useUpdateManyRecords` hook for batch record updates with
optimistic cache updates
- Added `updateMessageFoldersSyncStatus` hook for managing message
folder sync state
- Redesigned Message Folders List with BreadCrumb and Animations
2025-12-19 17:22:59 +01:00
github-actions[bot]
a19b9e1cb8 i18n - docs translations (#16717)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-19 17:22:06 +01:00