Commit Graph

472 Commits

Author SHA1 Message Date
Thomas des Francs 5d1c2a3348 Let single notes take the full width (both side panel & desktop) (#16108)
# Current behavior

<img width="932" height="1040" alt="CleanShot 2025-11-26 at 19 10 32@2x"
src="https://github.com/user-attachments/assets/309fc2f4-b9ef-481c-b550-74c1c5cfeaf4"
/>

<img width="2618" height="1352" alt="CleanShot 2025-11-26 at 19 10
56@2x"
src="https://github.com/user-attachments/assets/f57348e9-2e09-4c91-bcf6-e776aa26598a"
/>


# Desired Behavior

<img width="2634" height="1304" alt="CleanShot 2025-11-26 at 19 11
32@2x"
src="https://github.com/user-attachments/assets/d8e13ab5-65d7-4449-9d8d-7a2356f71160"
/>

<img width="1048" height="1146" alt="CleanShot 2025-11-26 at 19 11
50@2x"
src="https://github.com/user-attachments/assets/8a062717-18c1-41c7-a52c-1904738cd145"
/>
2025-11-26 22:34:44 +01:00
Balaji Krishnamurthy 98e44ed92a feat: use relative and absolute dates in email (#15827)
Closes #15322

Used `formatToHumanReadableDate` to show absolute dates, rather than
only relative dates. When the date is clicked, it flips between relative
and absolute. The click on the date, doesn't show or hide the email
body. Attaching a recording of the same below.



https://github.com/user-attachments/assets/77adcd3e-8efe-4af9-a57e-6317c93bcf22



https://github.com/user-attachments/assets/0731de02-60bb-42b1-a28c-55a94cff24b8

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-20 10:09:44 +00:00
Thomas des Francs f6cd51ba97 feat: Support custom fields in calendar event detail panel (#15853)
## Overview
This PR refactors the `CalendarEventDetails` component to dynamically
display both standard and custom fields added via the metadata API,
instead of using a hardcoded field list.

## Changes
- Replaced hardcoded `fieldsToDisplay` array with dynamic field fetching
using `useFieldListFieldMetadataItems` hook
- Split fields into `standardFields` (maintaining original order) and
`customFields`
- Introduced `renderField` helper function to eliminate code duplication
- Custom fields now automatically appear at the bottom of the detail
panel after standard fields
- Maintained exact field order and all existing functionality including
participant response status display

## Technical Details
- Uses existing `useFieldListFieldMetadataItems` pattern already
established in the codebase
- Standard field order explicitly defined: startsAt, endsAt,
conferenceLink, location, description
- Participant response status (Yes/Maybe/No) correctly positioned
between first 2 and last 3 standard fields
- All fields respect permissions and visibility settings from metadata

## Testing
-  Verified all standard fields display in correct order
-  Added custom field `mycustomfieldtest` via metadata API - displays
correctly at bottom
-  Participant responses (Yes/Maybe/No) render correctly with avatars
-  Event title, creation date, and event chip display properly
-  Canceled event styling (strikethrough) works
-  No console errors or regressions detected
-  Read-only behavior maintained (calendar events sync from external
sources)

## Screenshots

<img width="1401" height="746" alt="CleanShot 2025-11-17 at 11 23 57"
src="https://github.com/user-attachments/assets/3d967ec5-6d31-4fc3-b971-c73ea521c87d"
/>


## Related
This enables users to extend calendar events with custom metadata fields
that will automatically display in the UI without code changes.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-18 18:11:07 +01:00
Lucas Bordeau 5f3253d5a5 Fix issues with one to many activity targets (#15656)
This PR fixes issues with one to many activity target bugs described
here :
https://github.com/twentyhq/twenty/issues/14280#issuecomment-3490170714

It also improves the request that fetches notes and tasks in index
pages, to only fetch the notes and tasks identifier fields, thus
reducing the amount of network load.

Fixes https://github.com/twentyhq/twenty/issues/14280
2025-11-11 17:19:20 +01:00
Félix Malfait cff17db6cb Enhance role-check system with stricter checks (#15392)
## Overview

This PR strengthens our permission system by introducing more granular
role-based access control across the platform.

## Changes

### New Permissions Added
- **Applications** - Control who can install and manage applications
- **Layouts** - Control who can customize page layouts and UI structure
- **AI** - Control access to AI features and agents
- **Upload File** - Separate permission for file uploads
- **Download File** - Separate permission for file downloads (frontend
visibility)

### Security Enhancements
- Implemented whitelist-based validation for workspace field updates
- Added explicit permission guards to core entity resolvers
- Enhanced ESLint rule to enforce permission checks on all mutations
- Created `CustomPermissionGuard` and `NoPermissionGuard` for better
code documentation

### Affected Components
- Core entity resolvers: webhooks, files, domains, applications,
layouts, postgres credentials
- Workspace update mutations now use whitelist validation
- Settings UI updated with new permission controls

### Developer Experience
- ESLint now catches missing permission guards during development
- Explicit guard markers make permission requirements clear in code
review
- Comprehensive test coverage for new permission logic

## Testing
-  All TypeScript type checks pass
-  ESLint validation passes
-  New permission guards properly enforced
-  Frontend UI displays new permissions correctly

## Migration Notes
Existing workspaces will need to assign the new permissions to roles as
needed. By default, all new permissions are set to `false` for non-admin
roles.
2025-11-07 15:37:17 +01:00
Etienne 037663ddcd RichText editor fixes (#15678)
closes https://github.com/twentyhq/twenty/issues/15474
closes https://github.com/twentyhq/twenty/issues/15677
2025-11-06 16:21:57 +01:00
Raphaël Bosi 198bf5a333 Complete color refactoring (#15414)
# Complete color refactoring

Closes https://github.com/twentyhq/core-team-issues/issues/1779

- Updated all colors to use Radix colors with P3 color space allowing
for brighter colors
- Created our own gray scale interpolated on Radix's scale to have the
same values for grays as the old ones in the app
- Introduced dark and light colors as well as there transparent versions
- Added many new colors from radix that can be used in the tags or in
the graphs
- Updated multiple color utilities to match new behaviors
- Changed the computation of Avatar colors to return only colors from
the theme (before it was random hsl)

These changes allow the user to use new colors in tags or charts, the
colors are brighter and with better contrast. We have a full range of
color variations from 1 to 12 where before we only had 4 adaptative
colors.
All these changes will allow us to develop custom themes for the user
soon, where users can choose their accent colors, background colors and
there contrast.
2025-10-29 18:08:51 +00:00
Raphaël Bosi d2a47f9bab Fix Cmd + K conflict in note when adding a link (cmd+k shortcut) and opening right drawer (#15257)
Closes https://github.com/twentyhq/twenty/issues/14949


https://github.com/user-attachments/assets/c63e95a8-33ad-4307-ad35-4e4464336004
2025-10-22 17:17:14 +02:00
Abdullah. 793dc3d6fc Remove dependency on lodash.pick. (#15213)
Fixes [Dependabot Alert
85](https://github.com/twentyhq/twenty/security/dependabot/85) -
prototype pollution in lodash.

Added a shared pick helper (with unit tests) in twenty-shared and
refactored front-end/server code to import { pick } from the shared
barrel instead of lodash.pick.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
2025-10-21 08:19:49 +00:00
twill-hq[bot] 187cf400aa Fix author attachment field (#15065)
# Migrate Attachment Author to CreatedBy Field

**Twill Task**: https://twill.ai/twentyhq/ENG/tasks/7

## Summary

This PR implements a migration to transition the `Attachment` object
from using an `author` relation field to using the standard `createdBy`
field, addressing issue
https://github.com/twentyhq/core-team-issues/issues/1594.

## Changes

- **Added migration command**
(`1-8-migrate-attachment-author-to-created-by.command.ts`):
- Migrates existing attachment data to use `createdBy` instead of
`author`
- Ensures data integrity during the transition to the standard field
pattern

- **Updated Attachment workspace entity**:
  - Added `createdBy` relation field to the `Attachment` standard object
  - Registered new field ID in `standard-field-ids.ts` constants

- **Integrated migration into upgrade pipeline**:
  - Added migration module for version 1.8
  - Registered in the main upgrade version command module

This change aligns the `Attachment` object with Twenty's standard field
conventions by using the built-in `createdBy` field instead of a custom
`author` field.

---

Fixes https://github.com/twentyhq/core-team-issues/issues/1594

---------

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-21 09:56:28 +02:00
Baptiste Devessier 23de047787 Extract DashboardCard from ShowPageSubContainer (#15073)
This PR determines the minimal setup required to render dashboards
without errors while extracting them from the record show page. The
ultimate goal is to create a `PageLayoutRenderer` component that takes
any page layout configuration and correctly renders dashboards or record
pages.

Currently, the `DashboardCard` component renders itself the
`PageLayoutRenderer` component. The next step is to reverse the flow of
control and make `PageLayoutRenderer` take a configuration and decide
whether it should render a dashboard or something else.

This PR takes into consideration two comments left by Charles on [the
first PR scaffolding the
refactor](https://github.com/twentyhq/twenty/pull/15021): renaming
`targetRecord` to `targetRecordIdentifier` and adding tests to
`evaluateTabVisibility()`.

## Demo to assert this PR doesn't break everything


https://github.com/user-attachments/assets/b5b99cf3-08fa-43d3-8da1-79018bc63641
2025-10-14 16:09:44 +02:00
Thomas Trompette 7b84db4708 Only fetch steps and trigger for the current workflow version (#15003)
Avoid fetching full steps and trigger for versions that are not the
current version. Because those won't be used anyway. Better for
performances.

Only difficulty was for the `createDraft` mutation. I needed to return
the full created version so I can store it in cache and use it as new
`currentVersion`. Otherwise the current version is considered as
incomplete for a short time, since workflow is fetched separately from
the current version.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-12 18:06:12 +02:00
Lucas Bordeau 68c86871dd 🦣🦣🦣 Table virtualization (#14743)
This big PR implements table virtualization with an offset paging,
allowing a way more fluid UX.

It is a v1 that should be improved in the future with partial data
loading and optimization of the browser display performance of a row.

But with this PR we have the solid enough technical foundation, both
frontend and backend, to get to a smooth table UX.

Fixes and improvements after first successful round of development
(needed to have main clean) :

- [x] Delete should refresh virtualized portion only and reset all table
- [x] Fix add new : top and bottom
- [x] Table empty shouldn’t show when first loading
- [x] Fix d&d
- [x]  Fix sorts
- [x] Fix drag when scrolling after a full virtual page (it throws an
error)
- [x] Si update mais qu’on a un sort ou filter, alors il faut trigger le
refresh
- [x]  Reset scroll position between tables
- [x]  Reset scroll shadows between tables
- [x] Setup d&n for virtual list :
https://github.com/hello-pangea/dnd/blob/main/docs/patterns/virtual-lists.md
- [x]  Full table re-render when entering edit mode
- [x] Clean code and prepare for merge

Fixes https://github.com/twentyhq/core-team-issues/issues/1613 that
contains other bugs to be fixed before merge

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-11 12:08:10 +02:00
Félix Malfait 938debd83e Refactor record layouts for backend-driven configuration (#15021)
## Refactor: Prepare frontend record layouts for backend-driven
configuration

This PR simplifies and prepares the frontend record layout system for
eventual migration to backend-driven layouts, aligning the architecture
with the existing PageLayout system used for dashboards.

### Key Changes

**Architecture Improvements:**
- Created unified LayoutRenderingContext that works for both record
pages (with targetRecord) and dashboards (standalone)
- Replaced prop drilling with context-based data flow - cards access
targetRecord and isInRightDrawer via context hooks
- Introduced useTargetRecord() helper hook that provides type-safe
access to the current record
- Created generic CardRenderer component that handles configuration
injection and context guards uniformly

**Configuration System:**
- Converted all tab icons from React components to JSON-serializable
strings (e.g., Icon: IconCheckbox → icon: 'IconCheckbox')
- Added configuration field to cards, matching the widget configuration
pattern on the backend
- Created CardConfiguration types system similar to WidgetConfiguration
on the backend
- Moved widget-specific props (like showDuplicatesSection) into
configuration objects

**Code Organization:**
- Extracted visibility evaluation logic into reusable
evaluateTabVisibility() utility
- Organized layouts into dedicated files (one per object:
base-record-layout.ts, company-record-layout.ts, etc.)
- Renamed components to match their purpose: Notes → NotesCard,
Attachments → FilesCard, etc.
- Consolidated card rendering from registry object to direct
getCardComponent() function

**API Alignment:**
- Made ifNoReadPermissionObject an explicit part of TabVisibilityConfig
(follows if* naming convention)
- Removed redundant targetObjectNameSingular from tab-level (now derived
from visibility config)
- Card API now mirrors Widget API (both use type, configuration,
accessed via context)
2025-10-10 16:26:17 +02:00
Charles Bochet 37473175a0 Reduce relation loading overload on FE graphql queries (#14991)
## Problem

With Twenty usage growing, we are facing challenges on server side to
respond to the demand. The current bottleneck we are facing is server
CPU.
While investigating CPU performances, we figured out that loading all
relation fields was the biggest issue.

### About graphql query response size

**Example:** on `People Index` Table page:
we query: `person.company` and we query **all non relation fields** on
company relation field.
`{ person { company { id, name, domainName, employees, address ... } }`
 
 
However we only need **company.id, company.name and company.domainName**
to be able to render the Company Chip in the company column (RELATION)
in the table.
`{ person { company { id, name, domainName } }`

We initially assumed that the querying all non relation fields was not
an issue because it was not adding additional load on database (which is
also partially true: if a field is containing a huge json this will add
load on postgres as data needs to be transfered)
This assumption is wrong on CPU side:
- when loading one to many relations (company.people), this quickly ads
up and we end up with response of 20kB quite quickly, even without
adding any custom field on person.
- even when loading a many to one relation, if the user is storing big
data in a given field (note.body for instance, or workflowRun.state),
this starts also being an issue.
- Worst case scenario are starting to happen: on a production workspace
with 20 active workflows. Loading workflow table while displaying
workflow runs commands (20 workflows x 60 workflowRuns x
workflowRun.state which is a big JSON) result in a response of... 125MB.

### Why is it an issue?

When yoga (graphql engine) parses a response to send it back in server
response, it's using `JSON.parse `(or stringify depending on the case).
Parsing data is CPU instensive (as you need to validate, transform) and
this is more or less `O(n)`.
This means returning 125MB is very intense on the CPU and will likely
use 100% of the CPU for ~1sec in our production servers.

NodeJs (nodeV8) is single threaded. It's able to process multiple
requests in parallel but to do that, it will cut them in "microTasks"
and process each microTasks (that can belong to different requests) one
after the other. Exactly like a single threaded CPU would allocate some
time to a process and then to the next one, etc.

This means that this big response request will actually block the other
request.
As a result, all requests are slow and our infrastructure is multi
tenant so some customers are impacting others.

This is even a bigger issue when our health checks start to fail and
containers are starting being considered as unhealthy and killed by the
orchestrator


## How to fix this

1. On Front end side, we should only query what we need. In this PR, I'm
forcing the relations to only query: `id`, `labelIdentifier`,
`imageIdentifier`
2. (later) as we are API first, we also need to do something to protect
the servers from this side too. To do that, Graphql APIs can associate a
cost to each graphql field (maybe 1 for a test fixed, 2 for a JSON
field, 10 for relations, etc...) and we can throttle based on that.

## Changes in this PR

It's mainly about refactor the tooling to generate `RecordGqlFields`
(`generateDepthOneGqlFields`). this tooling is used to generate the list
of fields we want to query. Most of the time we want to query a record
with one level of nesting.
1) Refactor to remove duplicate code => `generateDepthOne` become
`generateDepth` and can handle both `depth = 0 | 1`

2) Introduce `generateDepthRecordGqlFieldsFromFields.ts` which is the
base and can give you a list of gqlFields based on FieldMetadataItems

3) Introduce `generateDepthRecordGqlFieldsFromObject` which is a
shortcut for an object
4) Introduce `generateDepthRecordGqlFieldsFromRecords` which is the
intersection between `generateDepthRecordGqlFieldsFromObject` and a
given record (useful for cache tooling)
5) Replace all usages + introduce a hook
`useGenerateDepthRecordGqlFieldsFromObject` to ease usage
2025-10-10 14:31:12 +02:00
Charles Bochet 84f1559832 Refactor SingleRecordPicker to handle morphs (#14956)
## Scope

- Refactor SingleRecordPicker to handle morphItem and match Multiple one
- fix query generation to take morph into account


Left: 
- double check SingleRecordPicker in Workflows / Form
- Fix tests / stories
2025-10-07 20:07:27 +02:00
Marie da3c3d2b9d [GroupBy] Add views filters to groupBy query (#14762)
Closes https://github.com/twentyhq/core-team-issues/issues/1560

If viewId is defined in a groupBy query, we want to apply all filters of
the view to the query.
This required to move a lot of code from twenty-front to twenty-shared
to convert the filters as stored in the db into graphql filters,
applying the right combinations between filters etc., which was
previously only done in the FE.

This PR does not handle any field filters, it will be done in a later pr
2025-09-30 09:58:55 +02:00
Félix Malfait d5f88e566c Get ready for 1000+ members (#14313)
The goal of this PR is to test if Twenty can support a large number of
members, a question which was raised by a large company that is
considering moving away from Salesforce.

I was expecting the currentWorkspaceMembersState to cause a lot more
issue. It would be very hard to get rid of it in the context of actors,
I think that would require a big refactoring. I thought we'd have to do
it but it turns out the perf are pretty good. One thing we need to
improve is the pagination on the roles page, we'll wait for @Bonapara to
update that
2025-09-05 12:37:22 +02:00
Balaji Krishnamurthy 7a999c8476 Format date displayed in Releases section (#14183)
Closes #14177 

I noticed a `formatDisplayDate` file being used in `twenty-website` and
created the same one for `twenty-front` as well. Unit tests for the same
have been added.

<img width="1438" height="770" alt="image"
src="https://github.com/user-attachments/assets/5aa6eef5-19c5-4108-bf3f-c582d0ca1b59"
/>
<img width="1275" height="785" alt="image"
src="https://github.com/user-attachments/assets/20a87ba6-fca4-472c-a691-362901505303"
/>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-04 17:27:31 +02:00
Lucas Bordeau bfad5b0477 Cleaned FieldDefinition props and removed recoil calls (#14220)
This PR removes some unused props from FieldDefinition type and put some
recoil calls higher up in the hierarchy.

This PR fixes a regression on Chip introduced by
https://github.com/twentyhq/twenty/pull/11498, where we don't want
"Untitled" to be displayed in compact mode.

# FieldDefinition refactor

Removed `isLabelIdentifierCompact` and `labelIdentifierLink` which can
be derived directly in the chip component or computed in the record
table context.

Removed `disableTooltip` and `infoTooltipContent` because they were not
used.

Introduced `fieldMetadataItemId`, as optional for now, to have the
ability to progressively refactor the different things that could be
derived from this and `recordId`.

# Performance improvements

There's not a great deal to be gained for now on those modifications,
which specifically concern the identifier column.
2025-09-02 08:49:55 +00:00
neo773 3ef94f6e8c Refactor read only object and fields (#13936)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-19 18:10:35 +02:00
Charles Bochet 5c61daa201 Refactor board inline-cell input (#13928)
Makes board use the Input portals for Inline Cells
2025-08-14 17:43:27 +02:00
Charles Bochet 8c78314b52 Refactor inline-cell inputs on board (#13921)
Refactor FieldsCard (aka RecordFieldList) and RecordDetailSection so
they re-use the same components
2025-08-14 14:52:38 +02:00
Charles Bochet 6528038e9e Refactor inline-cell-input hover on field-list (#13906)
This is first step toward separating the path between display mode and
input mode for inline-cells like we have done for tableCell.

The idea is to have 1 floating or anchored field input shared between
all cells. This should be done for field-list, board and task/note row +
for hover and edit mode.

This PR is only about field-list and hover
2025-08-13 17:51:11 +02:00
Lucas Bordeau 3f0ee0139c Refactor record-field into ui sub-folder (#13888)
This PR prepares the refactor of record field definition and column
definition.

We need to separate the two concepts of FieldInput and FieldContext at
the cell level, and the new RecordField concept that will replace
FieldDefinition at the metadata and state level.

So we create a new ui sub-folder in the already existing record-field
folder, in order to separate those two concepts that are still very
close.
2025-08-13 11:31:39 +02:00
Lucas Bordeau 3a1c94147f Refactor usePersistField (#13775)
This PR introduces refactors and tradeoffs in the API around the events
of field input.

# Refactored usePersistField

The hook `usePersistField` has been refactored to be used anywhere in
the app, not just inside a FieldContext.

This was meant to solve a bug at the beginning but now it is just used
once in `RecordDetailRelationSection` outside of the context, still this
is better to have this hook like that for future use cases.

We also introduce `usePersistFieldFromFieldInputContext`, for an easier
API inside a FieldContext.

# Introduced a new `FieldInputEventContext`

To remove the drill-down of events, we introduce
`FieldInputEventContext`, this allows to set only once the handlers /
events. In practice it allows to have an easier time maintaining the
events for the many different field inputs, because it matches the
pattern we already use of taking everything from a context
(`FieldContext`).

# Removed drill-down from FieldInput

The heavy drill-down in FieldInput has been completely removed, since
everything can be derived from `FieldContext` and
`FieldInputEventContext`.

Also there was some readonly and other specific props, but they were all
drilled down from FieldContext, so it was easier to just use
FieldContext where needed.

# Refactored events of `MultiItemFieldInputProps` 

The component `MultiItemFieldInputProps` has a contrived API, here we
just remove the complex part that was persisting from inside.

We now only give a classic API with `onChange` and `onEscape` the rest
is left to higher levels, where it should be, because this generic
component shouldn't be aware of persisting things.

# Extracted the parsing logic of persisted values

For each input field component, we now have a clear util that was before
bound to the persist call,

# Tradeoff with persist times

The tradeoff before was that persistField was called anywhere, before
exiting the component sometimes, now it is only called by the higher
levels like table or show page, which handles this abstraction.

This could be challenged, however I think that having a lot of different
events, and not just `handleSubmit` and `handleCancel`, convey enough
meaning for the higher levels to decide what to do in each case.

A `skipPersist` argument was added in events in the rare edge cases
where we want to voluntarily skip persisting even with a submit or
escape, but that could be challenged because we could also say that we
should use cancel for that and stick to that convention.

# Handling of the bug in `ActivityRichTextEditor`

Initially this refactor was prioritized for solving this bug, which was
very annoying for the users.

But while fixing it with the new persistField hook I just understood
that the problem is not just for record title cells but for anything
that is open when we click on a rich text editor.

The issue is described here :
https://github.com/twentyhq/core-team-issues/issues/1317

So right now I just let it as is.

# Stories

The stories were checking that a request was sent in some cases where
persist was called before a component exiting, now that persist is only
called by higher-levels I just removed those tests from the stories,
because that should be the responsibility of higher levels.

Also a helper `getFieldInputEventContextProviderWithJestMocks` was
created that exposes a context and jest mock functions for testing this
new API in stories.

# Miscellaneous

Deactivated tui with nx by default, because it can be annoying.
2025-08-12 10:42:13 +02:00
Charles Bochet b14063fe06 Re-add prettier (#13812)
Re add prettier in eslint.configs
2025-08-11 14:10:04 +02:00
Félix Malfait d29dbd473b Upgrade SWC Core and Storybook to v8 (#13799)
This is is a blocker for various sub-migrations
2025-08-11 12:02:33 +02:00
Félix Malfait 464a480043 Continue ESLINT9 Migration (#13795)
Might already fix #13793
2025-08-10 23:25:58 +02:00
Félix Malfait 5fae14377a Eslint migration 4 (#13773)
A new attempt to migrate!
2025-08-08 16:21:57 +02:00
Félix Malfait b44b46109c Update try/catch syntax (#13732)
Update try/catch syntax to prepare for eslint migration
2025-08-07 22:19:43 +02:00
Marie ee19ee5119 [permissions] QA fixes (#13698)
In this PR

- Introduction of readableFields and updatableFields in
objectMetadataItem selector to ease filtering from a developer
experience perspective ( + to help developers think to do it). In
discussion @lucasbordeau @charlesBochet
- Remove non-updatable field from CSV import process (@etiennejouan)
- QA fix / Non-readable fields should not show on show page
- QA fix / It should not be offered to create a kanban view on a
non-readable field
- QA fix / It should not be offered to create view groups on a
non-readable field
- QA fix / Rating field should have a readonly mode

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-07 18:21:59 +02:00
Lucas Bordeau de802b1447 Removed all v2 in naming of state management logic (#13675)
This PR removes any V2 naming in state management logic and some minor
utils and hooks.

It has a lot of changes but nearly all of them were made by the rename
functionality of vscode which is deterministic, so it shouldn't
introduce any regression.

QA has been made on this PR on the main features of the app without any
noticeable issue.

Also renamed some other v2 naming related items : 
- TextInputV2 => TextInput
- TextInput => SettingsTextInput
- ObjectFilterDropdownFilterSelectMenuItemV2 =>
ObjectFilterDropdownFilterSelectMenuItem
- useInitDraftValueV2 => useInitDraftValue
- useOpenRecordTableCellV2 => useOpenRecordTableCell
2025-08-06 12:09:15 +02:00
neo773 19dbe28786 feat: email and calendar events for opportunities (#13613) 2025-08-04 21:43:09 +00:00
Félix Malfait 69f2f94f50 Upgrade Vite6 to Vite7 (#13610)
As described in title
2025-08-04 22:01:32 +02:00
Marie 932910e71e Refactor isReadOnly + introduce restrictedFields (#13533)
Closes https://github.com/twentyhq/core-team-issues/issues/1276 

We now need to take fields permissions into account when determining if
a cell is editable or not.

a record field (= a cell) is read only if one of the condition is met:
- the object of the record is read-only (can be determined at table
level) by permission setting
- the field of the object is read-only (can be determined at column
level) - either by permission settings or by system (some workflows
fields for intance)
- the record is deleted (can be determined at row level) 

we reorganized the code to avoid re-computing known information as much
as possible.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-04 18:42:27 +02:00
Charles Bochet 42045667a4 Fix id typing in metadata generated schema (#13596)
In our Graphql schema, ids are typed as UUID.

Our FE codegen is typing it as 'any', unless we say otherwise. Fixing it
and fixing the impacts in the codebase
2025-08-04 18:40:26 +02:00
Lucas Bordeau d61eb1a951 Remove all legacy state management (#13476)
This PR removes every legacy state management logic left in the code
base, we only keep our last component state management logic.

Removed : 
- Scoped states logic
- Dropdown scope logic
- Scope id naming
- Component state v1
- Component state v2_alpha


# QA

| Component | Comments |
| --- | --- |
| AttachementDropdown | Ok |
| ObjectTasks | Ok |
| ActivityRichTextEditor | Ok |
| App | Ok dialogs work |
| AppRouterProviders | Ok dialogs work |
| RecordBoardScrollToFocusedCardEffect | Ok |
| RecordBoard | Ok |
| RecordBoardCard | OK |
| useSelectAllCards | Ok |
| RecordInlineCell | Ok |
| useInlineCell | Ok |
| RecordDetailRelationRecordsListItem | Ok |
| RecordDetailRelationSectionDropdownToMany | Ok |
| RecordDetailRelationSectionDropdownToOne | Ok |
| useHandleContainerMouseEnter | Ok |
| useResetTableRowSelection | Ok |
| useSelectAllRows | Ok |
| useSetRecordTableData | Ok |
| useRecordTable | Ok |
| useRecordTableMoveFocusedCell | Ok |
| useRecordTableMoveFocusedRow | Ok |
| useMoveHoverToCurrentCell | OK |
| useTriggerActionMenuDropdown | Ok |
| RecordTableBodyDragDropContextProvider | Ok |
| RecordTableHeaderCell | Ok |
| useSetCurrentRowSelected | Ok |
| useRecordTitleCell | Ok |
| SettingsObjectFieldActiveActionDropdown | Ok |
| SettingsObjectFieldInactiveActionDropdown | Ok |
| SettingsObjectFieldItemTableRow | Ok |
| SettingsObjectInactiveMenuDropDown | Ok |
| SettingsRoleEditEffect | Ok |
| SettingsRolesQueryEffect | Ok |
| Dropdown | Ok |
| useSelectableList | Ok |
| useSelectableListHotKeys | Ok |
| useSelectableListListenToEnterHotkeyOnItem | Ok |
| useNavigationSection | Ok |
| useCreateViewFromCurrentState | Ok |
| useDeleteViewFromCurrentState | Ok |
| useUpdateViewFromCurrentState | Ok |
| ViewPickerFavoriteFoldersDropdown | Ok |
| useCreateViewFromCurrentView | Ok |
| ViewBarDetails | Ok |
| WorkflowRunVisualizer | Ok |
| useHandleWorkflowRunDiagramCanvasInit | Ok |
| WorkflowDiagramCanvasBase | Ok |
| WorkflowRunVisualizerEffect | Ok |
| useRemoveStepFilter | Ok |
| useRemoveStepFilterGroup | Ok |
| useUpsertStepFilterSettings | Ok |
| WorkflowFindRecordsFilters | Ok |
| SettingsObjects | Ok |
2025-07-29 09:52:24 +00:00
Marie 16ba72edab [permissions] Adapt FE to non-readable fields (#13440)
Fixes https://github.com/twentyhq/core-team-issues/issues/1261 and
https://github.com/twentyhq/core-team-issues/issues/1153

In this PR we
- remove fields user do not have read access on from queries (findMany,
findDuplicates, returned fields from create or update etc.)
- remove fields user do not have read access on from views 

This is behind a feature flag
2025-07-28 16:24:08 +00:00
Lucas Bordeau a818a70e40 Cleanup remaining old component states (#13435)
This PR cleans up the remaining legacy component states.

Everything that is on the v1 of component states, scoped states,
dropdown scope, scoped id, etc.
2025-07-28 14:35:36 +00:00
Naifer dd5ae66449 Fix: deletion and name updates of attachments in body reflected in Files (#13169)
resolve #13168 , #8501 

This PR fixes an issue where the onChange trigger was deleting all
attachments by removing the JWT token from their paths (if it existed)
and comparing the new body with the old body to identify deleted
attachments. It ensures that only attachments actually removed from the
body get deleted, preventing unintended deletion of attachments not
added directly through the body. It also handles updating attachment
names in the body so changes are reflected in Files, with related tests
updated accordingly.


https://github.com/user-attachments/assets/8d824a24-b257-4794-942e-3b2dceb9907d

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-23 14:36:02 +02:00
vishwas babar 0b5bdf1c93 feat: support multiple file upload in Attachments component (#13283)
Closes #13277

## What I Did

- Enabled `multiple` attribute in the file input
- Updated the `handleFileChange` handler to loop through files
- Confirmed that each file is sent via `uploadAttachmentFile`

## Why

This change allows users to upload multiple files at once instead of
doing it one by one.

## Screenshot / Video (Optional)
[Screencast From 2025-07-18
23-58-36.webm](https://github.com/user-attachments/assets/ea191f25-1904-4643-afe2-7029785eebcb)


---
Let me know if you'd like any changes! 💪

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-22 13:49:47 +02:00
Charles Bochet fdc6705a75 Remove old body on note and tasks (#13290)
Fixes: https://github.com/twentyhq/twenty/issues/13110

I'm deprecating note.body and task.body to remove confusion between body
and bodyV2

What will be left but should be done later to avoid breaking changes:
- re-add a body field in the graphql API only that points to the same
bodyV2 field in SQL (need to be handled in fields and filter for note
and task)
- (wait some time)
- remove bodyV2 field
2025-07-19 11:25:49 +02:00
Abdul Rahman 72fd3b07e7 Add file support to agent chat (#13187)
https://github.com/user-attachments/assets/911d5d8d-cc2e-4c18-9f93-2663d84ff9ef

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.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>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: MD Readul Islam <99027968+readul-islam@users.noreply.github.com>
Co-authored-by: readul-islam <developer.readul@gamil.com>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-15 08:57:10 +02:00
Lucas Bordeau bba1b296c1 Refactor snackbar old component scoped state (#13183)
This PR refactors the snackbar modules that was using legacy versions of
our state management.

We replace the old states with new ones and also the old scoped context
with component instance context.
2025-07-11 16:05:09 +00:00
Raphaël Bosi eba997be98 Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes 🫳🎤) (#13127)
# Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes)

This PR is the last part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933
Part 5: https://github.com/twentyhq/twenty/pull/13106

In this part, we completely remove the hotkey scopes.
2025-07-09 17:21:14 +02:00
Félix Malfait 6ba6860e1c Frontend tests improvements (#13115)
Fix warnings and lower coverage by 0.1%
2025-07-09 09:23:26 +02:00
Raphaël Bosi 9eaa8ad517 Replace hotkey scopes by focus stack (Part 5 - Form field Inputs, Pages, Dialog ...) (#13106)
# Replace hotkey scopes by focus stack (Part 5 - Form field Inputs,
Pages, Dialog ...)

This PR is the 5th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933

In this part, all the last components using hotkey scopes were
refactored.
In the 6th and final part of this refactoring we will be able to
completely remove the hotkey scopes from the codebase.
2025-07-08 20:18:32 +02:00
Jean-Baptiste Ronssin ebaec00cce fix: blockquote icon in slash menu (#13068)
This PR fixes a UI bug where the "Quote" item in the slash command menu
was displayed without an icon.


The root cause was that the IconBlockquote component, while available in
the icons library, was not being exported from the internal twenty-ui
package.

## Before / After


![Before](https://github.com/user-attachments/assets/afd5e848-b6a4-4af9-a01d-15c6128f8535)


![After](https://github.com/user-attachments/assets/2468371f-fdd6-42a0-b04b-61a51d286746)


## Changes:

- Exported IconBlockquote from TablerIcons.ts in the twenty-ui package.
- Updated getSlashMenu.ts in the twenty-front package to import and use
the IconBlockquote for the "Quote" menu item.
2025-07-08 10:09:42 +02:00
Raphaël Bosi c6e5bab4e9 Replace hotkey scopes by focus stack (Part 4 - Inputs) (#12933)
# Replace hotkey scopes by focus stack (Part 4 - Inputs)

This PR is the 4th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910

In this part, I refactored all inputs in the app so that each input has
a unique id which can be used to track the focused element.
2025-07-07 15:42:12 +02:00