This PR brings more UX fixes for table.
Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- Fix any field filter chip formatting
- Empty placeholder should be centered on screenwidth and not scrollable
width on table
- First cell is automatically active on table but we can't move => We
now allow focus position to be null as it is a portal
Fixes https://github.com/twentyhq/twenty/issues/14573
### Description
Field values in RecordInlineCell were disappearing on hover even when
read-only.
This was caused by the hover CSS being applied unconditionally and
readonly prop not used properly.
Fixes#14582
---
### Changes
- Added $readonly prop to StyledValueContainer to conditionally apply
hover opacity.
- Read-only fields now display values normally;
---
### Video ->
[Screencast from 2025-09-18
06-17-20.webm](https://github.com/user-attachments/assets/d1ad8a0a-5903-4709-b02a-77ae2e1315f1)
This PR fixes the focused row that was making the group section border
bottom disappear if collapsed.
In https://github.com/twentyhq/core-team-issues/issues/1490, fixes :
- Section border-bottom disappear if the focus is on the first row of a
collapsed section
Fixes:
- relation one to many cannot be set (we have deprecated limit: keyword
in graphql at it was not use, we should only use first or last)
- https://github.com/twentyhq/twenty/issues/14556
This PR fixes a few z-index issues on table with groups.
Once the z-index issues will have been stabilized, we'll refactor this
big constant file which is hard to maintain.
In https://github.com/twentyhq/core-team-issues/issues/1490, fixes :
- Aggregate footer label identifier is hidden
- Bug sticky footer label identifier on table with groups has not the
right z-index
It was in setup-db.ts but that's not enough for instances that are
already live
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Fixes https://github.com/twentyhq/twenty/issues/14548.
When creating a field metadata through the api, the field's icon can be
null (from twenty UI, a default icon is always added by default and it
is not possible to remove it). Then this value is turned into an empty
string in the payload - i don't know why we don't send the null value.
When updating the field through the UI, we run a zod validation that
either accepts a null value for Icon, or a value that starts with
`"Icon".` In our case, the value for Icon was `""` (an empty string),
which is not valid. Therefore the form was considered not valid until an
icon was added.
While the fix suggested works, we should probably sort out the `null`
conversion to `""`, as it is prone to errors.
## Summary
- Fixed nested scrolls and sticky tabs in dashboard view
- Drag select now auto-scrolls via ScrollWrapper context
## Changes
- Wrapped content in ScrollWrapper which provides context ID
automatically
- Removed overflow from grid container to fix nested scrolls
## Introduction
https://github.com/twentyhq/twenty/pull/14363
In this PR we're creating builder and runner for index metadata
Removing its previous integration within object builder
## Next:
- implem index impact on field and object metadata api
- Add integration testing coverage add integration test on index
- Implement uniqueness toggle in field metadata api
- add integration test on uniqueness
related to https://github.com/twentyhq/core-team-issues/issues/1344
This PR fixes the column resize handle issues.
Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- We see the pointer blink when resizing => Already here before
refactor, this is because the mouse enter / leave events shouldn't be
triggered while resizing.
- Resizing handle sometimes cannot be clicked anymore / does not appear
anymore (see if another listener doesn't prevent this)
The code will need to be cleaned after all fixes have been done though
has it duplicates logic between the different header components.
Tested :
- workspace needs to flush cache after activating feature flag
- workspace does not need to flush cache if ff false and coming from
previous version (before gql schema gen updates)
This PR fixes the last column of a table with groups that was wrapping
on a new line on a empty table or its filtering equivalent (filter
without result)
Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- Fixes most urgent : Empty table with groups header wraps
- Fixes less urgent : Resizing a table with groups makes some filling
resize in the wrong direction
## ✨ Add accent-insensitive search functionality
### 🎯 Overview
Implements accent-insensitive search across all searchable fields in
Twenty CRM.
Users can now search for "jose" to find "José", "muller" to find
"Müller", "cafe" to find "café", etc.
### 🔍 Problem
Twenty's search functionality was accent-sensitive, requiring users to
type exact accented characters to find records.
This created a poor user experience, especially for international names
and content.
### 💡 Solution
Added PostgreSQL `unaccent` extension with a custom immutable wrapper
function to enable accent-insensitive full-text search across all
searchable field types.
### 📋 Changes Made
**Modified Files:**
- `packages/twenty-server/scripts/setup-db.ts`
-
`packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts`
-
`packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util.ts`
### 🗄️ Database Setup (`setup-db.ts`)
```sql
-- Added unaccent extension
CREATE EXTENSION IF NOT EXISTS "unaccent";
-- Created immutable wrapper function
CREATE OR REPLACE FUNCTION unaccent_immutable(text) RETURNS text AS $$
SELECT public.unaccent($1)
$$ LANGUAGE sql IMMUTABLE;
```
### 🔍 Search Vector Generation
(`get-ts-vector-column-expression.util.ts`)
Applied `public.unaccent_immutable()` to all searchable field types:
- TEXT fields (job titles, names, etc.)
- FULL_NAME fields (first/last names)
- EMAILS fields (both email address and domain)
- ADDRESS fields
- LINKS fields
- RICH_TEXT and RICH_TEXT_V2 fields
### 🔎 Query Processing (`compute-where-condition-parts.ts`)
Enhanced search queries to use `public.unaccent_immutable()` for both:
- Full-text search (`@@` operator with `to_tsquery`)
- Pattern matching (`ILIKE` operator)
### 🧠 Technical Rationale: Why the Wrapper Function?
**The Challenge:**
PostgreSQL's built-in `unaccent()` is marked as **STABLE**, but
`GENERATED ALWAYS AS` expressions (used for search vector columns)
require **IMMUTABLE** functions.
**The Solution:**
Created an IMMUTABLE wrapper function that calls the underlying
`unaccent()` function:
- ✅ Satisfies PostgreSQL's immutability requirements for generated
columns
- ✅ Maintains the exact same functionality as the original `unaccent()`
- ✅ Uses fully qualified `public.unaccent_immutable()` to ensure
function resolution from workspace schemas
**Alternative Approaches Considered:**
- ❌ Modifying `search_path`: would affect workspace isolation
- ❌ Computing unaccent at query time: would hurt performance
- ❌ Using triggers: would complicate data consistency
### 🎯 Impact
For **Person** records, accent-insensitive search now works on:
- Name (first/last name): `"jose garcia"` finds `"José García"`
- Email: `"jose@cafe.com"` finds `"josé@café.com"`
- Job Title: `"manager"` finds `"Managér"` or `"Gerente de Café"`
Applies to all searchable standard objects:
- Companies, People, Opportunities, Notes, Tasks, etc.
- Any custom fields of searchable types (TEXT, EMAILS, etc.)
### ✅ Testing
- Database reset completes successfully
- Workspace seeding works without errors
- Search vectors generate with unaccent functionality
- All searchable field types properly handle accented characters
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
In the case of DB events, id field will be prefixed with
'property.after'. This is why we need to use the fieldIdName when
provided.
Before: When providing only id, Company variable is {{trigger.id}}.
Which does not exists on DB event output schema
<img width="939" height="462" alt="Capture d’écran 2025-09-16 à 17 57
42"
src="https://github.com/user-attachments/assets/c46dc00a-bb0e-45b9-af42-e9ddd0a08aea"
/>
After: Company variable is {{trigger.property.after.id}}
<img width="939" height="578" alt="Capture d’écran 2025-09-16 à 17 57
14"
src="https://github.com/user-attachments/assets/ede11de0-b98e-40df-89a1-9b283a2692ff"
/>
This is the third PR from the split of
https://github.com/twentyhq/twenty/pull/14458 - refactoring only the
PieChart widget.
Plus small performance improvements on already refactored widgets
In this PR:
- Refactored the page layout renderer
- Converted all the states to component states
- Removed the page layout edition in settings
TODOs in next PRs:
- Fix bug with the drag selector not taking the scroll into account to
display the dragged area
- Readd the tab edition in edit mode