Commit Graph
4610 Commits
Author SHA1 Message Date
Abdul RahmanandGitHub 270069c3e3 Add search to Fields dropdown (#19750)
Issue link:
https://discord.com/channels/1130383047699738754/1489198502998315100


https://github.com/user-attachments/assets/7d0a859e-c33e-4f9e-bdb3-5867fc0dd80f
2026-04-16 12:59:01 +00:00
2b5b8a8b13 Link command menu items to specific page layout (#19706)
- Add a `pageLayoutId` foreign key to `CommandMenuItem`, allowing
command menu items to be scoped to a specific page layout instead of
being globally available
- Filter command menu items by the current page layout on the frontend.
Items with a `pageLayoutId` only appear when viewing that layout, while
items without one remain globally visible
- Create an effect to track the current page layout ID
- Include a seed example: a "Show Notification" command pinned to the
Star history standalone page layout

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-16 12:07:36 +00:00
9beb1ca326 Support Select All for workflow manual triggers (#19734)
## Summary
- Move record fetching and payload building from the enrichment hook
into `TriggerWorkflowVersionEngineCommand`, following the same
component-based pattern as `DeleteRecordsCommand` and
`RestoreRecordsCommand`
- The enrichment hook now only stores workflow metadata (`trigger`,
`availabilityType`, `availabilityObjectMetadataId`); the component uses
`useLazyFetchAllRecords` for exclusion mode (Select All) with full
pagination
- `buildTriggerWorkflowVersionPayloads` is now a pure function accepting
`selectedRecords: ObjectRecord[]` instead of reading from the Jotai
store

Fixes the issue introduced by #19718 which blocked Select All with a
warning toast instead of implementing it.

## Test plan
- [ ] Select individual records → run workflow trigger from command menu
→ works as before
- [ ] Click Select All → run workflow trigger from command menu →
fetches all matching records and runs the workflow
- [ ] Select All with some records deselected → correctly excludes those
records
- [ ] Global workflows (no object context) → run without payload as
before
- [ ] Bulk record triggers → payload wraps records in `{namePlural:
[records]}`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:33:03 +00:00
d54092b0e2 fix: add missing LayoutRenderingProvider in SettingsApplicationCustomTab (#19679)
## Summary

- `SettingsApplicationCustomTab` renders `FrontComponentRenderer` which
calls `useFrontComponentExecutionContext` →
`useLayoutRenderingContext()`, but the settings page never provided a
`LayoutRenderingProvider`
- Every other render site (side panel, command menu, record pages) wraps
`FrontComponentRenderer` with this provider — it was just missed here
- Opening the "Custom" tab in Settings → Applications crashes with:
`LayoutRenderingContext Context not found`
- Fix: wrap with `LayoutRenderingProvider` using `DASHBOARD` layout type
and no target record, matching the pattern used in
`SidePanelFrontComponentPage`

## Test plan

- [ ] Open Settings → Applications → any app with a custom settings tab
- [ ] Click the "Custom" tab — should render the front component without
crashing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-16 10:01:28 +00:00
martmullandGitHub 381f3ba7d9 Fix app design 1/2 (#19735)
comply with
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=96977-349627&m=dev

## After
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 40
37"
src="https://github.com/user-attachments/assets/6d80191a-79a9-4f0f-aa4f-0e447fff4f6d"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 40
22"
src="https://github.com/user-attachments/assets/4f763272-027e-4246-b455-7d46babf7d8c"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39
11"
src="https://github.com/user-attachments/assets/b9b35e18-8068-447e-821d-5ec28bb5bd16"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39
05"
src="https://github.com/user-attachments/assets/57d9318a-902f-4fd7-a2a3-5795ebe0b9dc"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39
02"
src="https://github.com/user-attachments/assets/78a33fa8-6bdd-484e-a82d-bd0f7592a623"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38
58"
src="https://github.com/user-attachments/assets/f7987aed-c6e1-4032-a611-86817655137d"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38
55"
src="https://github.com/user-attachments/assets/d1c451ab-1d2d-41e4-a059-cf4303ecabe7"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38
48"
src="https://github.com/user-attachments/assets/593cae36-2320-443f-a955-93b211a6ee3f"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 37
40"
src="https://github.com/user-attachments/assets/c9f602b1-8de3-4e82-a3a6-344594a0c153"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 37
34"
src="https://github.com/user-attachments/assets/b54ddddf-5dda-46c8-ace3-cffe6015825a"
/>

## before

<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42
18"
src="https://github.com/user-attachments/assets/c0976a0a-0124-48ec-8e7c-78627cea7063"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42
16"
src="https://github.com/user-attachments/assets/d2db926c-4040-411d-9091-8b60e7c519e6"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42
13"
src="https://github.com/user-attachments/assets/2d69f2ff-f26e-4249-91a3-2cf3d261e840"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42
07"
src="https://github.com/user-attachments/assets/1028aabc-77ac-4c51-a8c3-9a194faba87f"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42
01"
src="https://github.com/user-attachments/assets/1caa9f5e-3eaa-433c-9d3b-e0f094f16e8e"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41
56"
src="https://github.com/user-attachments/assets/f42b6976-3a8f-4591-9283-bda79bdb424b"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41
53"
src="https://github.com/user-attachments/assets/93d00df8-0091-4dfa-9ac0-f6f376be5962"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41
43"
src="https://github.com/user-attachments/assets/9deae7e5-39c1-4518-a463-6d79bc5bf132"
/>
<img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41
37"
src="https://github.com/user-attachments/assets/3e21b521-c47d-482c-ad41-66abfe973772"
/>
2026-04-16 09:47:44 +00:00
Abdul RahmanandGitHub 7ce3e2b065 Fix spacing between workspace domain cards (#19742)
https://discord.com/channels/1130383047699738754/1492113564138344468
2026-04-16 08:43:54 +00:00
Abdul RahmanandGitHub a49d8386aa Fix calendar event "Not shared" content alignment and background (#19743)
Issue link:
https://discord.com/channels/1130383047699738754/1491712714848866424

<img width="1287" height="419" alt="Screenshot 2026-04-16 at 9 50 34 AM"
src="https://github.com/user-attachments/assets/ba2143df-7957-4aee-8994-80c0392b6086"
/>
2026-04-16 08:38:09 +00:00
Thomas TrompetteandGitHub 7adab8884b Add isUnique update in query + invalidate cache on rollback (#19746)
Fix isUnique not sent in field update mutation: Added isUnique and
settings to the Pick type in useUpdateOneFieldMetadataItem, which
previously silently dropped these properties from the GraphQL payload.

Invalidate cache on failed migration rollback: Added invalidateCache()
call in the migration runner's catch block so that a failed migration
(e.g., unique index creation failing due to duplicate data) regenerates
the Redis hash, preventing stale metadata from persisting in frontend
localStorage indefinitely. Was
2026-04-16 07:44:59 +00:00
5eda10760c Fix navbar folder opening lag by deferring navigation until expand animation completes (#19686)
### Before


https://github.com/user-attachments/assets/7d57aa55-8d4c-43e1-8835-f40206e5e453



### After


https://github.com/user-attachments/assets/2457c8ee-fcb9-41ae-a8f7-08f8c7b4a233

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2026-04-15 16:31:33 +00:00
b9605a3003 Refactor SnackBar duration handling and progress bar visibility logic (#19712)
## Summary

Fixes error snackbars disappearing too quickly by **disabling
auto-dismiss for error variants by default**. Error snackbars now remain
visible until the user closes them.

Closes #19694

## What changed

- Error snackbars no longer default to a 6s timeout (they only
auto-dismiss if an explicit `duration` is provided).
- Non-error snackbars keep the existing default auto-dismiss behavior
(6s).
- Progress bar animation/visibility is tied to auto-dismiss (no progress
bar when there’s no duration).

**Files**
-
packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx

## How to test

1. Trigger a long error snackbar (example: spreadsheet/CSV import error
with a long message).
2. Confirm the snackbar **stays visible** until clicking **Close**.
3. Trigger a success/info snackbar and confirm it **still
auto-dismisses** after ~6s.

## Notes

- Call sites that explicitly pass `options.duration` for error snackbars
will continue to auto-dismiss (intentional).

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-15 16:22:28 +00:00
WeikoandGitHub 56d6e13b5d Fix fields widget flash during reset (#19726)
Summary

- Remove the evictViewMetadataForViewIds step from the page-layout reset
flow. It synchronously cleared viewFields/viewFieldGroups rows from the
metadata store, leaving a window where
useFieldsWidgetGroups saw a view with no fields and fell back to
buildDefaultFieldsWidgetGroups, briefly rendering a synthetic "General"
+ "Other" layout before the real reset defaults
arrived.
- invalidateMetadataStore() alone is sufficient: it marks the
collections stale and triggers MinimalMetadataLoadEffect to refetch,
which replaces current atomically. The UI now
transitions old-layout → new-default with no synthetic flash.
- Simplified refreshPageLayoutAfterReset to no longer take a
collectAffectedViewIds callback, and updated both tab/widget reset call
sites plus ObjectLayout.tsx accordingly.
- Deleted the now-unused evictViewMetadataForViewIds and
collectViewIdsFromWidgets utils.
2026-04-15 16:08:24 +00:00
Raphaël BosiandGitHub 3b85747d3f Go back to the original command K button (#19727)
## Before


https://github.com/user-attachments/assets/868e5293-8843-44c8-8011-b7130e97fa95


## After


https://github.com/user-attachments/assets/89cf46cc-1fb1-4e78-bfef-53e1d04e8ebf
2026-04-15 15:53:26 +00:00
Raphaël BosiandGitHub 0f8152f536 Fix command menu item edit record selection dropdown icons (#19725)
## Before
<img width="816" height="126" alt="CleanShot 2026-04-15 at 17 20 11@2x"
src="https://github.com/user-attachments/assets/647d6aa6-1000-41d9-9351-c1489bc095c6"
/>


## After
<img width="808" height="120" alt="CleanShot 2026-04-15 at 17 19 05@2x"
src="https://github.com/user-attachments/assets/e7685370-b6eb-4720-a5dd-401dfae8dc6b"
/>
2026-04-15 15:31:59 +00:00
Baptiste DevessierandGitHub 8cb803cedf Various bug fixes Record page layouts (#19719)
Fixes:

- Can't add multiple widgets in a row
- Ensure newly created is always focused
2026-04-15 15:12:57 +00:00
Thomas TrompetteandGitHub 8a968d1e31 Hide workflow manual trigger from command menu on "Select All" (#19718)
https://github.com/user-attachments/assets/e19c6d23-03c1-49c8-8b83-5c8f5f0f1135
2026-04-15 13:55:38 +00:00
EtienneandGitHub 94b8e34362 Object view widget - Introduce new TABLE_WIDGET view type (#19545)
closes
https://discord.com/channels/1130383047699738754/1491549365263667230/1491804729397743666
2026-04-15 13:30:37 +00:00
MarieandGitHub 2fccd194f3 [Billing for self host] End dummy enterprise key validity (#19560)
<img width="1504" height="755" alt="Screenshot 2026-04-10 at 16 40 07"
src="https://github.com/user-attachments/assets/68a12e40-a077-48df-9e18-885493520a32"
/>


Re-using hasValidEnterpriseKey to avoid breaking changes. 
This will be entirely removed in the next versions.
2026-04-15 13:26:38 +00:00
762fb6fd64 Fix active navigation item disambiguation (#19664)
## Summary

- Introduce a `activeNavigationMenuItemState` Jotai atom (persisted via
localStorage) to disambiguate active navigation items when multiple
items share the same URL
- Add active item evaluation for record show pages with three scenarios:
1. Navigating from a nav item → parent stays active + dedicated RECORD
item also active
  2. Clicking a dedicated RECORD nav item → only that item active
3. Navigating via search/direct link → OBJECT nav item fallback, or
Opened section if none exists
- Extract shared active logic into `isNavigationMenuItemActive` utility
to eliminate duplication between orphan items and folder items
- Support multiple simultaneously active items within folders via
`Set<number>` instead of a single index

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2026-04-15 13:00:47 +00:00
Raphaël BosiandGitHub 7956ecc7b2 Invert pinned and dots icon buttons in command menu items edit mode (#19717)
## Before
<img width="804" height="158" alt="CleanShot 2026-04-15 at 14 22 22@2x"
src="https://github.com/user-attachments/assets/65c4d4f1-6f17-47e2-b964-f3b7132d2f18"
/>

## After
<img width="804" height="168" alt="CleanShot 2026-04-15 at 14 21 38@2x"
src="https://github.com/user-attachments/assets/2f1d4fff-5f07-4df0-833e-129ad85391a9"
/>
2026-04-15 12:38:52 +00:00
WeikoandGitHub e12b55a951 Fix duplicate Fields widget (#19696)
## Context
Tab duplication was broken after the view creation logic was deferred
and moved to the FE.

- Duplicating a tab or a FIELDS widget now produces a fully independent
copy: new view, new view field groups, new view fields — all with fresh
IDs — while preserving any unsaved edits
  from the source widget.
- Removed the backend auto-seed of default view fields / view field
groups in ViewService.createOne for FIELDS_WIDGET views. The frontend
always sends the complete layout via
upsertFieldsWidget, so the auto-seed was both redundant and the source
of potential bugs.
- Extracted a shared useDuplicateFieldsWidgetForPageLayout hook used by
both tab and widget duplication paths, plus a small
useCloneViewInMetadataStore helper that clones the FlatView
in the metadata store and returns the copied flat view fields/groups for
the caller.
2026-04-15 12:29:44 +00:00
Raphaël BosiandGitHub 2df32f7003 Hide fallback command menu items in edit mode (#19700)
Hide fallback command menu items in edit mode
2026-04-15 09:38:54 +00:00
Baptiste DevessierandGitHub c805a351ab Reactivate disabled full tab widgets (#19702)
https://github.com/user-attachments/assets/14a48c7d-e731-4a15-883f-c53beb4943de
2026-04-15 09:11:55 +00:00
MarieandGitHub bc28e1557c Introduce updateWorkspaceMemberSettings and clarify product (#19441)
## Summary

Introduces a dedicated **metadata** mutation to update **standard
(non-custom)** workspace member settings, moves profile-related UI to
use it, and aligns **workspace member** record permissions with the rest
of the CRM so users cannot escalate visibility via RLS by editing their
own member record.

## Product behaviour

### Profile and appearance (standard fields)

- Users can still update **their own** standard workspace member fields
that the product exposes in **Settings / Profile** (e.g. name, locale,
color scheme, avatar flow) via the new
**`updateWorkspaceMemberSettings`** mutation.
- The mutation returns a **boolean**; the app **merges** the updated
fields into local state so the UI stays in sync without refetching the
full workspace member record.
- **Locale** changes also keep **`userWorkspace`** in sync when a locale
is present in the payload (including from the workspace `updateOne` path
when applicable).

### Custom fields on workspace members

- The dedicated metadata mutation **rejects** any **custom** workspace
member field (and unknown keys). Those updates must go through the
normal **object** `updateOne` pipeline, which is subject to **object-
and field-level** permissions like other records. But since we don't
have object- and field-level permission configuration for system objects
yet, this permission is derived from Workspace member settings
permission.
- **Workspace member** is no longer exempt from ORM permission
validation for updates merely because it is a **system** object. Users
who **do not** have workspace member access (e.g. no **Workspace
members** settings permission and no equivalent broad settings access on
the role) **cannot** use `updateOne` on `workspaceMember` to change
**custom** (or other) fields on their own row—even though that row is
used for RLS predicates.
- This closes a path where someone could widen what they can see by
writing to fields that drive row-level rules.

### Who can change another member

- Updating **another** user’s workspace member still requires
**Workspace members** (or equivalent) settings permission, consistent
with admin tooling.
2026-04-14 16:29:00 +00:00
307b6c94de Align GraphQL error handling for billing and AI chat (#19690)
## What changed

This refactor fixes AI chat error surfacing by aligning both the backend
and frontend with the existing GraphQL error architecture instead of
adding AI-local error translation.

On the backend:
- add a dedicated GraphQL billing exception path
- register billing GraphQL handling globally for GraphQL requests
- reuse the existing AI GraphQL interceptor path for agent/chat
exceptions
- keep billing status classification shared between REST and GraphQL
- remove the earlier attempt to preserve `CustomException` metadata in
the global GraphQL fallback

On the frontend:
- keep the original Apollo GraphQL error object in AI chat state
- reuse shared Apollo/GraphQL helpers for user-facing messages and
error-type checks
- delete AI-specific error extraction helpers that duplicated generic
GraphQL parsing
- replace a few direct `extensions.subCode` call sites with a shared
predicate

## Why it changed

The original bug was that `BillingException` and AI exceptions thrown
from chat were not being translated into GraphQL errors with the
expected `extensions.subCode` and `extensions.userFriendlyMessage`, so
the AI chat UI had nothing structured to inspect.

An intermediate fix worked mechanically but pushed `CustomException`
handling into the global GraphQL fallback, which blurred the intended
layering. This PR moves the behavior back to explicit GraphQL edges.

## Root cause

`AgentChatResolver` could throw `BillingException` and `AgentException`,
but:
- billing had a REST exception filter and no shared GraphQL equivalent
- AI chat was not consistently using the same GraphQL exception
translation path as the sibling AI resolver
- the frontend chat UI had drifted into AI-specific error parsing
instead of consuming the same structured Apollo errors as the rest of
the app

## Impact

- `BILLING_CREDITS_EXHAUSTED` is now preserved through GraphQL and can
render the existing credits-exhausted UI in chat
- `API_KEY_NOT_CONFIGURED` is preserved through the AI GraphQL path
- AI chat now follows the same general GraphQL error consumption pattern
as the rest of the frontend
- billing GraphQL handling is less dependent on individual resolver
authors remembering to add a filter

## Validation

- `yarn jest --config packages/twenty-server/jest.config.mjs
packages/twenty-server/src/engine/core-modules/billing/utils/__tests__/billing-graphql-api-exception-handler.util.spec.ts
packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/__tests__/agent-graphql-api-exception-handler.util.spec.ts`
- `yarn jest --config packages/twenty-front/jest.config.mjs
packages/twenty-front/src/utils/__tests__/is-graphql-error-of-type.util.test.ts`
- `npx oxlint --type-aware ...` on touched backend/frontend files
- `npx prettier --check ...` on touched backend/frontend files

## Follow-up ideas

- consolidate frontend GraphQL error helpers further so more existing
direct `extensions.subCode` checks move to shared utilities
- consider whether common GraphQL exception filter registration should
live in a more explicit GraphQL-specific module instead of
`CoreEngineModule`
- add an end-to-end test for a real `sendChatMessage` GraphQL failure
path in AI chat

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 18:31:59 +02:00
Raphaël BosiandGitHub a88d1f4442 Introduce standalone page (#19675)
Add support for standalone pages: a new `PageLayout` type
(`STANDALONE_PAGE`) that can be rendered independently at
`/page/:pageLayoutId`, not tied to any record or object context.

- New `STANDALONE_PAGE` page layout type
- New `PAGE_LAYOUT` navigation menu item type: adds a `pageLayoutId`
foreign key to `NavigationMenuItemEntity`, allowing sidebar items to
link directly to standalone pages
- New `GLOBAL_OBJECT_CONTEXT` command menu availability type: separates
object-context-dependent commands (Create Record, Import, Export, See
Deleted, Create View, Hide Deleted) from truly global ones, so
standalone pages only show relevant commands
- Frontend routing & rendering: adds a `/page/:pageLayoutId` route with
its own page component, header, and command menu
- Widget rendering refactor
- Instance commands: two fast 1.22 migrations: `pageLayoutId` column +
`STANDALONE_PAGE` enum, and `GLOBAL_OBJECT_CONTEXT` availability type
enum
- Workspace command: backfills existing command menu items from `GLOBAL`
to `GLOBAL_OBJECT_CONTEXT` where appropriate
- Dev seeds: adds a sample "Star History" standalone page with an iframe
widget for local development
2026-04-14 15:52:45 +00:00
martmullandGitHub b3354ab6e7 Fix multi-workspace-registration (#19685)
## Before

<img width="1512" height="915" alt="image"
src="https://github.com/user-attachments/assets/5cb05f76-b672-404e-b31d-ca455802f97a"
/>


## After

<img width="1512" height="726" alt="image"
src="https://github.com/user-attachments/assets/58229c4c-3ac6-4428-9c4d-3586a2b9ee36"
/>
2026-04-14 12:41:19 +00:00
Thomas TrompetteandGitHub c8a3de6c65 Test workflow with webhook expected body (#19688)
As title. Currently payload is always undefined when testing
2026-04-14 12:21:48 +00:00
WeikoandGitHub edba7fe085 Reset to default page layout (#19682)
- Add resetPageLayoutToDefault GraphQL mutation that resets an entire
page layout (all tabs, widgets, view field groups, and view fields) to
their default state in a single operation
- Add a "Reset to default" button in the settings Layout tab
(/settings/objects/:object#layout) with a confirmation modal


<img width="673" height="426" alt="Screenshot 2026-04-14 at 13 13 53"
src="https://github.com/user-attachments/assets/002d33c9-9ea1-49f2-bef6-179ce034c126"
/>
2026-04-14 12:19:48 +00:00
WeikoandGitHub 1e42be5a44 Expend field widget field supported types (#19684)
## Context
Expending field widget supported types to all field types. They will all
by default fallback to "FIELD" displaymode which is the inline display
mode (same as the one used in FIELDS widget) and can be extended to
other displayMode such as CARD or EDITOR in the future if needed. Most
of the work was already done in the previous PR and was unnecessary
filter out until this was properly tested

<img width="951" height="757" alt="Screenshot 2026-04-14 at 13 24 24"
src="https://github.com/user-attachments/assets/a08a1855-21ea-4e75-8032-4f970b3ff50d"
/>
<img width="915" height="595" alt="Screenshot 2026-04-14 at 13 23 34"
src="https://github.com/user-attachments/assets/8b420c1f-0496-4c1c-91b8-b266c40b3772"
/>
2026-04-14 11:51:01 +00:00
b194b67ac4 fix(address): populate street line from place details (#19326)
## Summary
- extract and expose `street` from Google place details (`street_number`
+ `route`) on the server DTO
- request and type `street` in front-end geo-map place details query
- use `placeData.street` as the preferred value for `addressStreet1` in
address autofill
- add regression coverage for query fields and street-line precedence
behavior

## Why
Address autocomplete selection currently writes full place text
(including city/state/postcode/country) into `addressStreet1`,
duplicating values already mapped to dedicated fields.

Fixes #18860

---------

Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-14 11:44:36 +00:00
WeikoandGitHub 47bdcb11d8 Move is active to fe (#19649)
## Context
Moving isActive filtering to the frontend for page layout tabs and
widgets, hiding inactive entities from the UI while keeping them in
state for future reactivation

Next we will implement deactivated standard tab re-activation during tab
creation (cc @Devessier)
<img width="234" height="303" alt="📋 Menu (Slots)"
src="https://github.com/user-attachments/assets/17a25ac6-55e2-4778-b7f0-e7554ed69704"
/>
2026-04-14 10:18:09 +00:00
Baptiste DevessierandGitHub b817bdca02 Rpl various fixes (#19668) 2026-04-14 09:46:15 +00:00
EtienneandGitHub 9c07ecd363 Fix view filter/sort deletion (#19567)
fixes https://github.com/twentyhq/twenty/issues/19543

+ bonus bug : when deleting an advanced filter, it triggers a destroy
which cascade-deletes associated view filters. Then, view filters
deletion throws.
2026-04-14 09:43:52 +00:00
49aac04b84 fix: edit button not coming up on avatar right after image upload (#19596)
## Summary

After uploading an image/file to the empty avatar field in the person
tab, the edit icon next to the field would not appear until the browser
was refreshed or another field was clicked.

### Root cause

- When user clicks over the avatar field,
`recordFieldListCellEditModePosition` is set to `globalIndex`
- That is fine when a avatar already exists. But when there is no avatar
already set, the native file picker is opened with no `onClose` handler
attached.
- So after the file upload is completed,
`recordFieldListCellEditModePosition` is never reset to null.
- `FieldsWidgetCellEditModePortal` stays anchored to the avatar file
element
- When the user hovers over the same field again, its hover portal tries
to compete to anchor for the same element
- So, `RecordInlineCellDisplayMode ` (the edit button) doesn't render

### Fix

- Pass the `onClose` function through `openFieldInput` to
`openFilesFieldInput`
- `onClose` resets `recordFieldListCellEditModePosition` back to null,
when the upload completes.

## Before


https://github.com/user-attachments/assets/ac9318e9-5471-434c-8af3-5c20d0112460

## After


https://github.com/user-attachments/assets/0d064a7f-95ad-4b92-a9ee-d9570f360972

Fixes #19595

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-14 08:54:14 +00:00
5fa3094800 test: fix failing useColorScheme test and remove FIXME (#19593)
Summary
This PR fixes a bug in the `useColorScheme` test suite and removes a
lingering `FIXME` comment where the color scheme was unexpectedly
unsetting during state updates.

Root Cause
Previously, the Jotai state was being initialized *inside* the
`renderHook` callback using `useSetAtomState`. When the `setColorScheme`
function was called, it triggered a hook re-render, which caused the
callback to execute again and overwrite the new state with the hardcoded
`'System'` initial state.

The Fix
- Removed the state initialization from inside the render cycle.
- Bootstrapped the state on a fresh store using `resetJotaiStore()` and
`store.set()` *before* rendering the hook.
- Updated the mock `workspaceMember` to correctly use the
`CurrentWorkspaceMember` type.
- Removed the `FIXME` comment and successfully asserted that the color
scheme updates to `'Dark'`.

Testing
Ran tests locally to confirm the fix works as expected:
`corepack yarn jest --config packages/twenty-front/jest.config.mjs
--testPathPattern=useColorScheme.test.tsx`

---------

Co-authored-by: Srabani Ghorai <subhojit04ghorai@gmail.com>
2026-04-14 06:40:40 +00:00
d88fb2bd65 Clean event creation exception (#19561)
https://twenty-v7.sentry.io/issues/7351816489/?environment=prod&project=4507072499810304&query=is%3Aunresolved&referrer=issue-stream

Those are expected error that should not reach sentry. These happen when
stream TTL expires or user session ends

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 22:11:57 +00:00
69d228d8a1 Deprecate IS_RECORD_TABLE_WIDGET_ENABLED feature flag (#19662)
## Summary
- Removes the `IS_RECORD_TABLE_WIDGET_ENABLED` feature flag, making the
record table widget unconditionally available in dashboard widget type
selection
- The flag was already seeded as `true` for all new workspaces and only
gated UI visibility in one component
(`SidePanelPageLayoutDashboardWidgetTypeSelect`)
- Cleans up the flag from `FeatureFlagKey` enum, dev seeder, and test
mocks

## Analysis
The flag only controlled whether the "View" (Record Table) widget option
appeared in the dashboard widget type selector. The entire record table
widget infrastructure (rendering, creation hooks, GraphQL types,
`RECORD_TABLE` enum in `WidgetType`) is independent of the flag and
fully implemented. No backend logic depends on this flag.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 21:13:15 +00:00
martmullGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
64a7725ac7 Add banner for not vetted apps (#19655)
https://github.com/user-attachments/assets/4038e21a-d5d9-4b93-8589-7a4baf35ef5b

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-04-13 17:28:50 +00:00
Raphaël BosiandGitHub fb772c7695 Sync command menu with main context store (#19650)
## PR description

- The command menu in the side panel now reads directly from
`MAIN_CONTEXT_STORE_INSTANCE_ID` instead of snapshotting the main
context store into a separate side-panel instance when opening. This
keeps the command menu always in sync with the current page state
(selection, filters, view, etc.).
- Removed the broadening/reset-to-selection feature (Backspace to clear
context, "Reset to" button) since the command menu no longer maintains
its own copy of the context.

## Video QA


https://github.com/user-attachments/assets/5d5bc664-b6d4-431d-a271-6ce23d8a4ae0
2026-04-13 16:08:15 +00:00
neo773andGitHub d2a99ef72d Fix VariablePicker and Fullscreen Icon overlap in FormAdvancedTextFieldInput (#19614)
fixes 

<img width="659" height="386" alt="image"
src="https://github.com/user-attachments/assets/c9755574-6830-464d-8abf-7741188f84dd"
/>
2026-04-13 16:01:50 +00:00
Abdul RahmanandGitHub 96959b43ba Fix: Filter out deactivated objects from navigation sidebar (#19620) 2026-04-13 15:54:30 +00:00
Abdul RahmanandGitHub 3f495124a5 Fix navbar folder not opening on page refresh when it has an active child item (#19619)
### Before


https://github.com/user-attachments/assets/b76e6184-0299-4240-a1f7-8651b69885ec

### After


https://github.com/user-attachments/assets/e7e9061b-98a1-4781-b882-eef87b83597a
2026-04-13 15:53:28 +00:00
353d1e89d5 Fix merge with null value + reset data virtualization before init load (#19633)
**Merge records fix:**

selectPriorityFieldValue throws when merging records if the priority
record has no value for a field (e.g., null/empty) but 2+ other records
do. The recordsWithValues array is pre-filtered to only records with
non-empty values, so the priority record isn't in the list. The fix:
instead of throwing, fall back to null since this is the priority record
actual value


**Duplicated IDs fix**


https://github.com/user-attachments/assets/bd6d7d08-d079-49a5-aad4-740b59a3c246


When applying a filter that reduces the record count, the virtualized
table's record ID array keeps stale entries from the previous larger
result set. loadRecordsToVirtualRows clones the old array (e.g., 60
entries) and only overwrites the first N positions (e.g., 9) with the
new filtered results, leaving positions 9-59 with old IDs. If any old ID
matches a new one, it appears twice in the selection, causing "-> 2
selected" for a single click and a duplicate ID in the merge mutation
payload. The fix: clear the record IDs array in
useTriggerInitialRecordTableDataLoad before repopulating it with fresh
data.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 15:50:58 +00:00
Raphaël BosiandGitHub 1382790c80 Fix side panel close button title (#19638)
## Before
<img width="830" height="1486" alt="CleanShot 2026-04-13 at 15 07 19@2x"
src="https://github.com/user-attachments/assets/757a52bb-f06e-4f04-950a-087cbdec0653"
/>


## After
<img width="838" height="1478" alt="CleanShot 2026-04-13 at 15 06 56@2x"
src="https://github.com/user-attachments/assets/ed9d99ab-fbda-4548-b09a-e7825d86b5dd"
/>
2026-04-13 13:39:51 +00:00
Baptiste DevessierandGitHub 6829fc315a Implement full tab widget frontend (#19568)
https://github.com/user-attachments/assets/488e0145-ff49-4205-8fd3-0eb4f614c054
2026-04-13 13:24:20 +00:00
martmullandGitHub bf5cc68f25 Rename standard and custom apps (#19631)
as title
no migration for existing apps, changes only apply on new workspaces
2026-04-13 13:13:59 +00:00
09806d7d8c Add admin panel workspace detail page with chat viewer (#19579)
## Overview
Adds comprehensive admin panel functionality for viewing workspace
details and AI chat threads.

## Changes

### Frontend
- **New Routes**: Added `AdminPanelWorkspaceDetail` and
`AdminPanelWorkspaceChatThread` pages with lazy loading
- **New Queries**: 
  - `getAdminWorkspaceChatThreads` - fetch chat threads for a workspace
  - `getAdminChatThreadMessages` - fetch messages for a specific thread
  - `workspaceLookupAdminPanel` - lookup workspace info and users
- **New Components**:
- `SettingsAdminWorkspaceDetail` - displays workspace info and chat
sessions tabs
- `SettingsAdminWorkspaceChatThread` - renders chat conversation with
message bubbles
- **Navigation**: Updated AI admin panel to link to workspace detail
pages
- **Settings Paths**: Added `AdminPanelWorkspaceDetail` and
`AdminPanelWorkspaceChatThread` paths

### Backend
- **New DTOs**:
  - `AdminWorkspaceChatThreadDTO` - workspace chat thread data
  - `AdminChatThreadMessagesDTO` - thread with messages
  - `AdminChatMessageDTO` - individual message with parts
- **New Resolvers**: Added three queries to `AdminPanelResolver`
- **New Service Methods**:
  - `workspaceLookup()` - fetch workspace info
  - `getWorkspaceChatThreads()` - list chat threads
  - `getChatThreadMessages()` - fetch thread messages with validation
- **Module Updates**: Added entity imports for workspace, user, AI chat,
and feature flag data

### Security
- Added `allowImpersonation` check before accessing chat data
- Validates workspace ownership and access permissions

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 09:47:34 +02:00
150c326369 fix: prevent image upload panel from being clipped in side panel (#19613)
fixes: #19571

## What's happening
BlockNote's `.bn-panel` (the Upload/Embed popup for images, videos,
audio) has a hardcoded `width: 500px` in the upstream
`blocknoteStyles.css`. When you open it inside the side panel (~350px
wide), it overflows past the container's `overflow: hidden` and gets
clipped.
## Why percentage-based fixes don't work here
I initially tried `max-width: 100%` on `.bn-panel` but it doesn't work
the panel sits inside a Floating UI popover that's absolutely positioned
with no explicit width. Its width comes from its content (the 500px
panel), so `max-width: 100%` just resolves to that same 500px. It's a
circular reference.
## The fix
```css
& .bn-mantine {
  container-type: inline-size;
}
& .bn-mantine .bn-panel {
  width: min(500px, 100cqi);
  box-sizing: border-box;
}
```
container-type: inline-size on .bn-mantine lets us reference the
editor's actual width using cqi units. min(500px, 100cqi) keeps the
panel at 500px in wide containers (main note view) and shrinks it to fit
in narrow ones (side panel).

I scoped container-type to .bn-mantine (BlockNote's own root wrapper)
rather than the outer StyledEditor div, so the containment context stays
within BlockNote's own tree.

#Before
<img width="373" height="530" alt="image"
src="https://github.com/user-attachments/assets/63fb407c-79d1-4faa-afb4-15a98fe4ba22"
/>

#After
<img width="332" height="597" alt="image"
src="https://github.com/user-attachments/assets/f7e91c28-ad35-44a5-9450-0b6d52714977"
/>
<img width="599" height="579" alt="image"
src="https://github.com/user-attachments/assets/20fd457b-2d06-4799-9164-f993ef37d833"
/>


Tested
Side panel: panel fits correctly, matches "Add image" button width 
Full-width editor: panel stays at 500px 
Slash menu, formatting toolbar, drag handles: all unaffected

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-04-13 09:08:28 +02:00
BugIsGodandGitHub c73cdd0844 fix: prevent image upload panel from being clipped in side panel (#19572)
fixes:   #19571 
## Summary:
- BlockNote's file upload/embed panel (.bn-panel) has a hardcoded width:
500px that overflows the side panel's overflow: hidden containers,
causing the Upload/Embed UI to be cut off
<img width="636" height="364" alt="image"
src="https://github.com/user-attachments/assets/4ec501c6-409c-4a86-a5b3-2c5f104c94f1"
/>

## Before
<img width="464" height="660" alt="image"
src="https://github.com/user-attachments/assets/3364e20e-6194-4c5d-b16f-9541cc11bfd7"
/>

## After
**Same width with "Add Image" button** ( same in the video,audio upload
<img width="444" height="665" alt="image"
src="https://github.com/user-attachments/assets/369a6974-a986-44ab-a38a-a717a8f978c0"
/>
2026-04-13 09:01:07 +02:00
WeikoandGitHub 9e385e44f9 Fields widget draft view (#19562)
- Defer backend view creation for FIELDS widgets to prevent orphan views
when users cancel or leave before saving. Views are now created
optimistically in Jotai state (client-side UUID) and only persisted to
the database when the page layout is saved.
- Align the frontend's default field groups fallback with the backend
logic: split into General/Other groups, hide relation fields by default,
and filter invisible fields consistently across all code paths.
2026-04-12 20:26:47 +02:00