Commit Graph
10346 Commits
Author SHA1 Message Date
8e6b267ff3 Allow DATE_TIME IS operand to filter on a whole day (#17529)
Fixes:  https://github.com/twentyhq/core-team-issues/issues/2027

We've replaced the DATE_TIME picker with DATE picker, and changed the
logic to filter for complete day period.



https://github.com/user-attachments/assets/ba7e1078-bab3-4c62-a803-d6a851f14b7d

---------

Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-18 13:44:05 +00:00
neo773andGitHub 88146c2170 Fix Gmail thread awareness for custom labels (#18031)
This fixes two edge cases for Gmail

- When policy was set to `SELECTED_FOLDERS` excluding root INBOX, it
missed label changes, so messages with newly applied labels weren't
imported until a full resync.

- Gmail thread replies by default by default do no inherit parent
message's label properties so thread context was also lost because only
individually labeled messages were returned, dropping earlier parts of
the conversation.

Fixed by subscribing to `labelAdded`/`labelRemoved` history events and
fetching full thread context when at least one message in a thread
carries a synced label. `ALL_FOLDERS` path is untouched.
2026-02-18 14:10:38 +01:00
EtienneandGitHub 3706da9bcb v1.18 - Fix command (#18032)
Same as here https://github.com/twentyhq/twenty/pull/18016
2026-02-18 13:52:13 +01:00
9bac8f15d4 i18n - translations (#18029)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 13:26:54 +01:00
Charles BochetandGitHub 7332379d26 Improve API Client usage and add Typescript check (#18023)
## Summary


https://github.com/user-attachments/assets/1e75cc9d-d9d2-4ef2-99f9-34450f5d8de7



Add background incremental type checking (`tsc --watch`) to the SDK dev
mode, so type regressions are caught when the generated API client
changes — without requiring a full rebuild of source files.

Previously, removing a field from the data model would regenerate the
API client, but existing front components/logic functions referencing
the removed field wouldn't surface type errors (since their source
didn't change, esbuild wouldn't rebuild them).

## What changed

- **Background `tsc --watch`**: a long-lived TypeScript watcher runs
alongside esbuild watchers, incrementally re-checking all files when the
generated client changes. Only logs on state transitions (errors appear
/ errors clear) to stay quiet.
- **Atomic client generation**: API client is now generated into a temp
directory and swapped in atomically, avoiding a race condition where
`tsc --watch` could see an empty `generated/` directory
mid-regeneration.
- **Step decoupling**: orchestrator steps no longer receive
`uploadFilesStep` directly. Instead, they use callbacks (`onFileBuilt`,
`onApiClientGenerated`), and each step manages its own `builtFileInfos`
state.
- **`apiClientChecksum` omitted from `ApplicationConfig`**: it's a
build-time computed value, same as `packageJsonChecksum`.
<img width="327" height="177" alt="image"
src="https://github.com/user-attachments/assets/02bd25bb-fa41-42b0-8d96-01c51bd4580c"
/>

<img width="529" height="452" alt="image"
src="https://github.com/user-attachments/assets/61f6e968-365b-4a5b-8f2b-a8419d6b1bd3"
/>
2026-02-18 13:26:30 +01:00
Raphaël BosiandGitHub 2455c859b4 Add SSE for metadata and plug front components (#17998)
Create the necessary tooling to listen to metadata events and plug it to
the front components. Now we have a hot reload like experience when we
edit a component in an app.

## Backend

- Split `EventWithQueryIds` into `ObjectRecordEventWithQueryIds` and
`MetadataEventWithQueryIds`
- Publish metadata event batches to active SSE streams in
`MetadataEventsToDbListener`

## Frontend

- Create a metadata event dispatching pipeline: SSE metadata events are
grouped by metadata name, transformed into
`MetadataOperationBrowserEventDetail` objects, and dispatched as browser
`CustomEvents`
- Add `useListenToMetadataOperationBrowserEvent` hook for consuming
metadata operation events filtered by metadata name and operation type
- Rename `useListenToObjectRecordEventsForQuery` to
`useListenToEventsForQuery`, now accepting both
`RecordGqlOperationSignature` and `MetadataGqlOperationSignature`
- Implement `useOnFrontComponentUpdated` which subscribes to front
component metadata events and updates the Apollo cache when the
component is modified
- Add `builtComponentChecksum` to the front component query and appends
it to the component URL for browser cache invalidation
2026-02-18 11:26:20 +00:00
martmullandGitHub e3753bf822 App feedbacks (#18028)
as title
2026-02-18 11:04:54 +00:00
WeikoandGitHub f3faa11dd2 New field creates fields widget field (#18022)
## Context
Introducing "NewFieldDefaultConfiguration" to FIELDS widget
configurations
```typescript
{
  isVisible: boolean;
  viewFieldGroupId: string | null;
}
```

This configuration will define where a new field should be added (which
section) and its default visibility inside FIELDS widget views.
The new field position should always be at the end (meaning the last
position for the view fields OR the last position of a viewFieldGroup)

See "New fields" on this screenshot
<img width="401" height="724" alt="Layout V1"
src="https://github.com/user-attachments/assets/4969bcaa-f244-4504-8947-778a02c24c47"
/>
2026-02-18 11:03:27 +00:00
nitinandGitHub 477fbc0865 fixes: loosen up front validation, add resolveEntityRelationUniversalIdentifiers to update and restore (#18015)
closes https://github.com/twentyhq/private-issues/issues/419
2026-02-18 10:35:08 +00:00
EtienneGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
08a3d983cb Date & DateTime validation fixes / improvements (#18009)
Fixes https://github.com/twentyhq/twenty/issues/17138

- Backend should have strict date/dateTime format validation
- FE in import csv is more permissive

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-18 10:13:18 +00:00
EtienneandGitHub ee15e034b5 Files command - fixes (#18016)
- Fixed "property entity not found" error when updating/creating a new
field and querying the same object repository just after
- Downgraded log type for unnecessary migration
2026-02-18 09:09:52 +00:00
b7274da8fa i18n - docs translations (#18020)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 08:12:20 +01:00
4a485aecb0 i18n - docs translations (#18017)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 01:06:14 +01:00
BOHEUSGitHubneo773neo773greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
5ae1d94f23 Fix connected account permissions (#17598)
Fixes #17411

---------

Co-authored-by: neo773 <neo773@protonmail.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-18 01:05:56 +01:00
Abdul RahmanGitHubCopilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>DevessierFélix Malfait
015ccbf0a7 Navbar customization improvements (#17863)
- Add folder icon editing support
- And other navbar customization fixes/improvements.

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 19:53:52 +00:00
3d362e6e01 i18n - docs translations (#18014)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 19:33:21 +01:00
Charles BochetGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
d7f025157b Migrate more to Jotai (#17968)
As per title

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-17 19:24:36 +01:00
98482f3a01 i18n - translations (#18013)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 19:18:53 +01:00
BOHEUSandGitHub 171efe2a19 New onboarding plan (#17776)
Fixes github.com/twentyhq/core-team-issues/issues/637
2026-02-17 19:11:47 +01:00
Baptiste DevessierandGitHub 7512b9f9bb Load view field groups (#18010) 2026-02-17 17:22:48 +00:00
Charles BochetandGitHub c0cc0689d6 Add Client Api generation (#17961)
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline

### Why

The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.

### How

- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.
2026-02-17 18:45:52 +01:00
0891886aa0 i18n - translations (#18012)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 18:35:35 +01:00
Thomas TrompetteandGitHub f768bbe512 Replace country code by calling code in workflows (#18008)
Long overdue PR: replacing deprecated country code in workflows.
Will allow to use variables.

We keep storing the country code since it allows to display the right
flag in picker when there are multiple countries for one calling code.
But we do not store country for variables.

<img width="477" height="254" alt="Capture d’écran 2026-02-17 à 17 25
23"
src="https://github.com/user-attachments/assets/dc67c41c-33cf-4021-b7bb-490827b2aa3c"
/>
2026-02-17 17:06:09 +00:00
610c0ebc9d Move secure HTTP client IP validation to connection level (#18006)
## Summary
- Refactors SSRF protection from a request-level adapter to
connection-level agents, validating resolved IPs in `createConnection` +
socket `lookup` events
- Sets both `httpAgent` and `httpsAgent` so validation applies
regardless of protocol switches during redirects
- Caps `maxRedirects` to 10 as defense in depth

## Test plan
- [x] All 59 existing + new unit tests pass (agent util, isPrivateIp,
service)
- [x] No linter errors
- [ ] Verify webhook delivery still works with URLs that redirect
- [ ] Verify image upload from external URLs still works (relies on
redirect following)


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes core outbound HTTP security behavior and redirect handling,
which could impact webhook/image-fetch flows and connection semantics
despite improved SSRF coverage.
> 
> **Overview**
> Refactors outbound SSRF protection from a custom axios `adapter` to
connection-level `httpAgent`/`httpsAgent` created by new
`createSsrfSafeAgent`, which blocks private IP literals up front and
validates DNS-resolved IPs via the socket `lookup` event.
> 
> When safe mode is enabled, `SecureHttpClientService.getHttpClient` now
always installs both agents and enforces a capped `maxRedirects`
(default `5`), and the old `getSecureAxiosAdapter`
implementation/tests/types are removed. `isPrivateIp` is
tightened/expanded to treat `0.0.0.0/8` as private and avoid
misclassifying bare IPv4 decimals as IPv6.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8261da4ff0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 16:59:38 +00:00
Lucas BordeauandGitHub e4aad7751f Fixed group by query order by inside group (#18005)
Fixes https://github.com/twentyhq/core-team-issues/issues/2229

This PR fixes a bug on board, that we thought was due to dev seeds, but
that was in fact a conflict of `ORDER BY` clauses at the SQL level in
group by queries.

The problem was that an ORDER BY was applied on top of a sub-query ORDER
BY, thus breaking the initial ordering of each group.

# Before

<img width="1117" height="1033" alt="Capture d’écran 2026-02-17 à 16
32 56"
src="https://github.com/user-attachments/assets/764183ae-4058-498b-9fe0-919e9511e67d"
/>

# After 

<img width="1101" height="1007" alt="Capture d’écran 2026-02-17 à 16
32 27"
src="https://github.com/user-attachments/assets/b3100b30-25b5-4568-a9cf-0760f42ceb88"
/>
2026-02-17 16:18:23 +00:00
7c5a13852b i18n - translations (#18007)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 17:27:50 +01:00
EtienneandGitHub 163c1175cb File - Migrate core pictures (workspace and member logo) + workflow attachments (#17924)
- Create a common file-by-id download controller
- Create core picture module with resolver and logic to handle
workspaceLogo and workspaceMemberProfilePicture update
- Create workflow file module (same)
- Data migration
2026-02-17 15:42:50 +00:00
Baptiste DevessierandGitHub 963f2de864 Translate page layout tab title (#17975)
> [!NOTE]
> The improvement will only fully work once all tabs get translated. 

## When using the front-end mocks


https://github.com/user-attachments/assets/cf7dc0fb-9438-4e18-841e-47558ff71474

## When loading page layout information from database


https://github.com/user-attachments/assets/d2c9d98b-97e2-4629-aa6c-53f3f3713733

## When editing dashboard


https://github.com/user-attachments/assets/c6ae3a7a-f05f-48ea-8b33-8f689e3f71f7

Closes
https://github.com/twentyhq/twenty/issues/17950#issuecomment-3902782952
2026-02-17 15:26:28 +00:00
martmullandGitHub e3fcff00b0 Fix initial code step functionInput (#18002)
At code step creation

## before
<img width="623" height="816" alt="image"
src="https://github.com/user-attachments/assets/0aed5ed8-8d56-4988-9d31-fe80942191bb"
/>

## after
<img width="627" height="528" alt="image"
src="https://github.com/user-attachments/assets/9e2a5cb9-7480-4734-8e41-25b45edcec07"
/>
2026-02-17 16:45:00 +01:00
Thomas TrompetteandGitHub b4e924b671 Sync views and navigation items (#18003)
Both objects are necessary to fully enjoy objects within applications

<img width="770" height="311" alt="Capture d’écran 2026-02-17 à 15 19
43"
src="https://github.com/user-attachments/assets/48c51fa4-63f4-45b2-a40a-df73f3aa79be"
/>
2026-02-17 16:32:41 +01:00
Lakshay ManchandaandGitHub 63a3f93a78 Emitting the correct event based on whether the record is being soft deleted or restored. (#17953)
fix for #17262 
This change ensures that when the record is restored, instead of
emitting a database event of "DELETED", a database event of "RESTORED"
will be emitted, as it is happening in the inner working of TypeORM.

This ensures that the DELETED event are not fired on RESTORED, for
example, triggering a workflow.

The screen recording shows that restoring the soft deleted records does
not trigger the workflow set to to run on "Record Deleted"


https://github.com/user-attachments/assets/90e0184f-2e08-466c-a40d-1592b60e64ff
2026-02-17 15:05:44 +00:00
Lucas BordeauandGitHub 8938dd637f Added relations to SSE events (#17683)
Fixes https://github.com/twentyhq/core-team-issues/issues/2192

This PR implements what is necessary to re-create the query that we
build on the frontend to obtain the returned object record from a
mutation, but on the backend, which was only partially implemented for
REST API.

Usually we want to have relations with only their id and label
identifier field to have lighter payloads.

In the event we only had depth 0 fields, with this PR we have all events
with depth 1 relations.

We have depth 2 for many-to-many cases, like updateOne or updateMany
result :
- Junction tables
- Activity target tables
2026-02-17 13:57:26 +00:00
WeikoandGitHub 20977428a1 Page layout various fixes (#17996)
## Context
- Add missing fields widget and FIELDS_WIDGET view for workflow run and
workflow version standard objects
- Fix FIELDS_WIDGET configuration fieldId universalIdentifier not being
converted to id when migration is executed.
2026-02-17 15:12:04 +01:00
Baptiste DevessierandGitHub 347298902d Fix dashboard new tab creation (#17971)
## Before


https://github.com/user-attachments/assets/cbc60013-8a5e-4af8-b02c-7dfbaf0c15e5


## After 


https://github.com/user-attachments/assets/1fd6f9f7-e774-4c63-aa80-50b33d2a4c59
2026-02-17 14:46:19 +01:00
5750c9be0c i18n - translations (#17997)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:36:47 +01:00
08feb6f651 i18n - translations (#17995)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:29:21 +01:00
Félix MalfaitGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Charles Bochet
c9c3b2b691 fix: improve clipboard copy for non-HTTPS self-hosted deployments (#17989)
Closes #8305

The Clipboard API (`navigator.clipboard`) requires a secure context
(HTTPS or localhost). Self-hosted deployments on plain HTTP silently
fail when copying.

This PR:
- Adds a `document.execCommand('copy')` fallback for insecure contexts
- Shows a descriptive error message explaining HTTPS is required when
the fallback also fails
- Consolidates 3 components that were using `navigator.clipboard`
directly (without error handling) to use the centralized
`useCopyToClipboard` hook

Generated with [Claude Code](https://claude.ai/code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Scoped to frontend clipboard UX with a defensive fallback and clearer
errors; minimal impact outside copy flows.
> 
> **Overview**
> Improves copy-to-clipboard behavior in non-HTTPS/self-hosted
deployments by enhancing `useCopyToClipboard` to use
`navigator.clipboard` only in secure contexts and otherwise fall back to
`document.execCommand('copy')`.
> 
> Updates 2FA setup screens and the view visibility dropdown to use the
centralized `copyToClipboard` helper (with consistent snackbars), and
shows a more descriptive error (longer duration) when copying fails due
to an insecure context.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
30944e63eb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2026-02-17 14:24:00 +01:00
09e1684300 feat: show auto-generated conversation title for AI chat. (#17922)
## Summary
Replaces the static "Ask AI" header in the command menu with the
conversation’s auto-generated title once it’s set after the first
message.

## Changes
- **Backend:** Title is generated after the first user message (existing
behavior).
- **Frontend:** After the first stream completes, we fetch the thread
title and sync it to:
- `currentAIChatThreadTitleState` (persists across command menu
close/reopen)
- Command menu page info and navigation stack (so the title survives
back navigation)
- **Entry points:** Opening Ask AI from the left nav or command center
uses the same title resolution (explicit `pageTitle` → current thread
title → "Ask AI" fallback).
- **Race fix:** Title sync only runs when the thread that finished
streaming is still the active thread, so switching threads mid-stream
doesn’t overwrite the current thread’s title.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 12:46:35 +00:00
nitinandGitHub e80e9a6a25 fix: on charts newly added multi split values toggle wasnt being saved (#17990)
:)
2026-02-17 14:01:11 +01:00
c2fe18af53 i18n - translations (#17993)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:00:47 +01:00
EtienneandGitHub 2b702b2b45 Navigation Menu Item - Migration in v1.18 (#17991)
Add navigation menu item data migration command in 1.18
2026-02-17 14:00:24 +01:00
EtienneandGitHub dc167b2d3d File - Disable file upload in standalone rich text widget (#17934)
File's url are not signed, in standalone rich text. We choose to disable
file upload to prevent unauthorised file upload links.
2026-02-17 13:46:28 +01:00
1e6c5b57b2 fix: use pickMorphGroupSurvivor in relation loader to match field metadata deduplication (#17988)
## Summary

- Fixes "Target field metadata full object not found" error thrown
during optimistic effects (e.g., bulk delete) on workspaces with custom
objects
- The relation loader was using a simple sort-by-ID to pick the
representative morph field, while `filterMorphRelationDuplicateFields`
uses `pickMorphGroupSurvivor` which prefers active non-system fields.
When a custom object's auto-created morph field (`isSystem: true`)
happened to have the smallest UUID, the two loaders would disagree — the
relation DTO pointed to that system field's ID, but the field metadata
loader filtered it out in favor of a standard field, causing the
frontend lookup to fail.
- Now both code paths use `pickMorphGroupSurvivor` so they always agree
on which morph field represents the group.

## Test plan

- [ ] Create a custom object on a workspace that already has standard
objects with morph relations (e.g., noteTarget, taskTarget)
- [ ] Bulk-select and delete records (e.g., People) — should no longer
throw "Target field metadata full object not found"

Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, localized change to morph-relation selection logic in a
dataloader; main risk is altered field choice for edge-case morph
groups, but behavior now matches existing deduplication.
> 
> **Overview**
> Ensures the relation dataloader picks the representative
morph-relation target field using `pickMorphGroupSurvivor` (preferring
active non-system fields) instead of the previous sort-by-id approach.
> 
> This aligns `createRelationLoader` with
`filterMorphRelationDuplicateFields`, preventing mismatches where
relation DTOs could reference a morph field that gets filtered out
elsewhere (e.g., triggering “Target field metadata full object not
found”).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c3a6d86126. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 13:46:05 +01:00
3516be2cf4 i18n - translations (#17987)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 13:43:13 +01:00
9477bb3677 Improve AI chat UX (#17974)
## Summary
- update AI chat message typography and list line-height for readability
- apply richer markdown-section styling for headings, spacing,
separators, and inline code
- keep links non-underlined by default with underline on hover, using
accent11 for link color
- preserve previous AI chat table design while keeping other markdown
improvements

## Validation
- yarn eslint
packages/twenty-front/src/modules/ai/components/LazyMarkdownRenderer.tsx
packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 11:24:33 +01:00
aac032e517 i18n - translations (#17986)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 11:14:14 +01:00
Paul RastoinandGitHub 5544b5dcfe Fix and refactor all metadata relation (#17978)
# Introduction
The initial motivation was that in the workspace migration create action
some universal foreign key aggregators weren't correctly deleted before
returned due to constant missconfiguration
<img width="2300" height="972" alt="image"
src="https://github.com/user-attachments/assets/9401eb02-2bb2-4e69-9c5f-9a354ff61079"
/>
It also meant that under the hood some optimistic behavior wasn't
correctly rendered for some aggregators

## Solution
Refactored the `ALL_METADATA_RELATIONS` as follows:

This way we can infer the FK and transpile it to a universalFK, also the
aggregators are one to one instead of one versus all available
Making the only manual configuration to be defined the `foreignKey` and
`inverseOneToManyProperty`

```
┌──────────────────────────────────────┐      ┌─────────────────────────────────────────────┐
│  ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY│      │      ALL_ONE_TO_MANY_METADATA_RELATIONS     │
│──────────────────────────────────────│      │─────────────────────────────────────────────│
│  Derived from: Entity types          │      │  Derived from: Entity types                 │
│                                      │      │                                             │
│  Provides:                           │      │  Provides:                                  │
│   • foreignKey                       │      │   • metadataName                            │
│                                      │      │   • flatEntityForeignKeyAggregator          │
│  Standalone low-level primitive      │      │   • universalFlatEntityForeignKeyAggregator │
└──────────────┬───────────────────────┘      └──────────────┬──────────────────────────────┘
               │                                             │
               │ foreignKey type +                           │ inverseOneToManyProperty
               │ universalForeignKey derivation              │ keys (type constraint)
               │                                             │
               ▼                                             ▼
       ┌───────────────────────────────────────────────────────────────┐
       │              ALL_MANY_TO_ONE_METADATA_RELATIONS              │
       │───────────────────────────────────────────────────────────────│
       │  Derived from:                                               │
       │   • Entity types (metadataName, isNullable)                  │
       │   • ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY (FK → universalFK)  │
       │   • ALL_ONE_TO_MANY_METADATA_RELATIONS (inverse keys)        │
       │                                                              │
       │  Provides:                                                   │
       │   • metadataName                                             │
       │   • foreignKey (replicated from FK constant)                 │
       │   • inverseOneToManyProperty                                 │
       │   • isNullable                                               │
       │   • universalForeignKey                                      │
       └──────────────────────────┬────────────────────────────────────┘
                                  │
               ┌──────────────────┼──────────────────┐
               │                  │                  │
               ▼                  ▼                  ▼
   ┌───────────────────┐ ┌────────────────┐ ┌──────────────────────┐
   │  Type consumers   │ │  Atomic utils  │ │  Optimistic utils    │
   │───────────────────│ │────────────────│ │──────────────────────│
   │ • JoinColumn      │ │ • resolve-*    │ │ • add/delete flat    │
   │ • RelatedNames    │ │ • get-*        │ │   entity maps        │
   │ • UniversalFlat   │ │                │ │ • add/delete         │
   │   EntityFrom      │ │                │ │   universal flat     │
   │                   │ │                │ │   entity maps        │
   └───────────────────┘ └────────────────┘ │                      │
                                            │  (bridge via         │
                                            │   inverseOneToMany   │
                                            │   Property →         │
                                            │   ONE_TO_MANY for    │
                                            │   aggregator lookup) │
                                            └──────────────────────┘
```

### Previously
```
┌─────────────────────────────────────────────────────────────────────┐
│                       ALL_METADATA_RELATIONS                       │
│─────────────────────────────────────────────────────────────────────│
│  Derived from: Entity types                                        │
│                                                                    │
│  Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...},│
│               serializedRelations?: {...} } }                      │
│                                                                    │
│  manyToOne provides:                                               │
│   • metadataName                                                   │
│   • foreignKey                                                     │
│   • flatEntityForeignKeyAggregator (nullable, often wrong/null)    │
│   • isNullable                                                     │
│                                                                    │
│  oneToMany provides:                                               │
│   • metadataName                                                   │
│                                                                    │
│  Monolithic single source of truth                                 │
└──────────────────────────┬──────────────────────────────────────────┘
                           │
                           │ manyToOne entries transformed via
                           │ ToUniversalMetadataManyToOneRelationConfiguration
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  ALL_UNIVERSAL_METADATA_RELATIONS                   │
│─────────────────────────────────────────────────────────────────────│
│  Derived from: ALL_METADATA_RELATIONS (type-level transform)       │
│                                                                    │
│  Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...} │
│  } }                                                               │
│                                                                    │
│  manyToOne provides:                                               │
│   • metadataName                                                   │
│   • foreignKey                                                     │
│   • universalForeignKey (derived: FK → replace Id → UniversalId)   │
│   • universalFlatEntityForeignKeyAggregator (derived from          │
│     flatEntityForeignKeyAggregator → replace Ids → UniversalIds)   │
│   • isNullable                                                     │
│                                                                    │
│  oneToMany: passthrough from ALL_METADATA_RELATIONS                │
│                                                                    │
│  Duplicated monolith with universal key transforms                 │
└──────────────────────────┬──────────────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────────┐
        │                  │                      │
        ▼                  ▼                      ▼
┌───────────────┐ ┌────────────────────┐ ┌──────────────────────┐
│ Type consumers│ │   Atomic utils     │ │  Optimistic utils    │
│───────────────│ │────────────────────│ │──────────────────────│
│ • JoinColumn  │ │ • resolve-entity-  │ │ • add/delete flat    │
│ • RelatedNames│ │   relation-univ-id │ │   entity maps        │
│ • Universal   │ │   (ALL_METADATA_   │ │   (ALL_METADATA_     │
│   FlatEntity  │ │    RELATIONS       │ │    RELATIONS         │
│   From        │ │    .manyToOne)     │ │    .manyToOne)       │
│               │ │                    │ │                      │
│ Mixed usage   │ │ • resolve-univ-    │ │ • add/delete univ    │
│ of both       │ │   relation-ids     │ │   flat entity maps   │
│ constants     │ │   (ALL_UNIVERSAL_  │ │   (ALL_UNIVERSAL_    │
│               │ │    METADATA_REL    │ │    METADATA_REL      │
│               │ │    .manyToOne)     │ │    .manyToOne)       │
│               │ │                    │ │                      │
│               │ │ • resolve-univ-    │ │ universalFlatEntity  │
│               │ │   update-rel-ids   │ │ ForeignKeyAggregator │
│               │ │   (ALL_UNIVERSAL_  │ │ read directly from   │
│               │ │    METADATA_REL    │ │ the constant         │
│               │ │    .manyToOne)     │ │                      │
│               │ │                    │ │                      │
│               │ │ • regex hack:      │ │                      │
│               │ │   foreignKey       │ │                      │
│               │ │   .replace(/Id$/,  │ │                      │
│               │ │   'UniversalId')   │ │                      │
└───────────────┘ └────────────────────┘ └──────────────────────┘
```
2026-02-17 11:13:54 +01:00
8244610bdc i18n - translations (#17983)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 11:05:36 +01:00
e3db73ef46 Change condition for multi-workspace check (#17938)
When deploying with
```
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
IS_MULTIWORKSPACE_ENABLED=true
```
The first workspace can be created successfully. However, any attempt to
create additional workspaces as admin fails with the error: `Workspace
creation is restricted to admins` because `canAccessFullAdminPanel` is
**false**

If these flags are set to false during the initial deployment and
restarting the Docker container, workspace creation works normally.

Problem is caused by `canAccessFullAdminPanel`

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 09:29:59 +01:00
7523143f12 i18n - docs translations (#17981)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 09:29:37 +01:00