Commit Graph

479 Commits

Author SHA1 Message Date
Charles Bochet c53a13417e Remove all styled(Component) patterns in favor of parent wrappers and props (#18430)
## Summary

Eliminates all ~350 `styled(Component)` usages across `twenty-front` and
`twenty-ui` (212 files changed). Each was replaced following these
rules:

- **Margin/layout CSS** (margin, padding, flex, align-self, width) →
wrapped in a `styled.div`/`styled.span` parent container
- **Third-party components** (Link, TextareaAutosize,
ReactPhoneNumberInput, Handle, etc.) → parent container with child CSS
selectors (`> a`, `> textarea`, `> input`, etc.)
- **Intrinsic behavior via existing props** (TableRow
`gridTemplateColumns`, TableCell `color`/`align`) → replaced
`styled(TableRow)` / `styled(TableCell)` with direct prop usage
- **Other visual overrides on twenty-ui components** (Card, Section,
TabList, Button, MenuItem, ScrollWrapper, etc.) → parent wrappers with
`> div` / `> *` child selectors
- **Extending styled.div/span** → merged all CSS into a single
`styled.div`/`styled.span`

Also adds `overflow: hidden` to parent containers wrapping
`ScrollWrapper` so scroll activates correctly with the new wrapper
structure.

### Migration patterns

| Before | After |
|--------|-------|
| `styled(Avatar)` with `margin-right` | `<StyledAvatarContainer><Avatar
/></StyledAvatarContainer>` |
| `styled(Link)` with `text-decoration: none` |
`<StyledLinkContainer><Link /></StyledLinkContainer>` with `> a { ... }`
|
| `styled(TableRow)` with `grid-template-columns` | `<TableRow
gridTemplateColumns="..." />` |
| `styled(TableCell)` with `color` / `align` | `<TableCell color={...}
align="right" />` |
| `styled(Card)` with `margin-top` | `<StyledCardContainer><Card
/></StyledCardContainer>` |
| `styled(TabList)` with `background` |
`<StyledTabListContainer><TabList /></StyledTabListContainer>` with `>
div { ... }` |
| `styled(StyledBase)` extending a `styled.div` | Single merged
`styled.div` with all styles inlined |
2026-03-05 18:16:25 +01:00
nitin 5853891b02 refactor!: rename Command Menu page/navigation layer to Side Panel (#18393) 2026-03-05 15:46:31 +01:00
Charles Bochet 647c32ff3e Deprecate runtime theme objects in favor of CSS variables (#18402)
## Summary

- **Eliminate `ICON_SIZES` / `ICON_STROKES` constants**: all icon
dimensions are now resolved at runtime via
`resolveThemeVariableAsNumber(themeCssVariables.icon.size.X)`, ensuring
values always come from computed CSS variables
- **No more consumer imports from `twenty-ui/theme`**: moved
`ColorSchemeContext`, `ColorSchemeProvider`, `ThemeColor`,
`MAIN_COLOR_NAMES`, `getNextThemeColor`, `AnimationDuration` to
`twenty-ui/theme-constants`
- **Remove `ThemeContext` / `ThemeContextProvider` / `ThemeProvider` /
`ThemeType`**: replaced across ~300 files with `themeCssVariables` (for
CSS contexts) or `resolveThemeVariable` / `resolveThemeVariableAsNumber`
(for JS runtime values)
- **Simplify provider chain**: only `ColorSchemeProvider` remains — it
toggles `light`/`dark` class on `document.documentElement` and provides
`colorScheme` via React context
- **Fix pre-existing test failures**: `useIcons.test.ts`
(non-configurable ES module spy) and
`turnRecordFilterGroupIntoGqlOperationFilter.test.ts`
(`Omit<RecordFilter, 'id'>` type mismatch)

### Theme access pattern (before → after)

| Context | Before | After |
|---------|--------|-------|
| CSS (Linaria) | `${({ theme }) => theme.font.color.primary}` |
`${themeCssVariables.font.color.primary}` |
| JS runtime (icon size, animation) | `theme.icon.size.md` /
`ICON_SIZES.md` |
`resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)` |
| Color scheme check | `theme.name === 'dark'` |
`useContext(ColorSchemeContext).colorScheme === 'dark'` |
2026-03-05 14:39:01 +01:00
Etienne 26f0a416a1 File storage cleaning (#18381)
- Remove feature flag
- Remove legacy methods in file-upload and file-service
- Migrate AI Chat to new file management

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-03-04 23:46:03 +01:00
Charles Bochet c41a8e2b23 [DevXP] Simplify twenty-ui theme system: replace auto-generated files with static CSS variables (#18389)
## Summary

Now that Twenty has fully migrated from Emotion to Linaria, the theme
system has been simplified to remove unnecessary complexity that existed
only to support the old runtime injection pattern.

### What changed

- **Deleted** `generateThemeConstants.ts` script and the entire
`generated/` directory — no more auto-generation
- **Added** `theme-light.css` and `theme-dark.css`: static CSS files
with 991 custom properties each, scoped under `.light` and `.dark`
selectors respectively
- **Moved** `themeCssVariables.ts` out of `generated/` and hand-maintain
it as a static `as const` object of `var(--t-*)` references (Linaria can
statically evaluate these at build time)
- **Extracted** numeric constants (`MOBILE_VIEWPORT`, `ICON_SIZES`,
`ICON_STROKES`) into a new `constants.ts` — CSS variables can't be used
in media queries or as numeric icon size props
- **Simplified** `ThemeContextProvider`: removed
`ThemeCssVariableInjectorEffect` entirely; now uses a single
`useLayoutEffect` to toggle `.light`/`.dark` class on `<html>`
- **Added** `class="light"` to `index.html` as default to prevent FOUC
before React hydration

### Why

The previous setup maintained a dual system: JS theme objects
(`THEME_LIGHT`/`THEME_DARK`) used at runtime, plus a generation script
that produced CSS variable entry arrays, which were then injected into
the DOM by `ThemeCssVariableInjectorEffect`. With Linaria, theme values
only need to be CSS custom properties — the JS objects were redundant.
This PR removes ~250 lines of infrastructure while keeping the same
theming capabilities.
2026-03-04 23:30:25 +01:00
Raphaël Bosi b11f77df2a [FRONT COMPONENTS] Introduce conditionalAvailabilityExpression to command menu items (#18319)
## PR Description

- Uses `expr-eval` to enable front components (SDK plugins) to define
conditional availability as declarative expressions.
- Moves shared types and constants to `twenty-shared`
- Introduces a `conditionalAvailabilityExpression` field on
`CommandMenuItemEntity`, allowing command menu items to store an
`expr-eval` compatible expression string that is evaluated against a
CommandMenuContext to determine if the item should be shown.
- Creates an esbuild transform plugin
`conditional-availability-transform-plugin` in `twenty-sdk` that
converts TypeScript conditional availability expressions into
`expr-eval` compatible syntax at build time, so SDK developers can write
natural TS expressions that get transformed to evaluable strings.
- Removes deprecated `forceRegisteredActionsByKey` state and its usage.
- Creates `useCommandMenuContext` hook that builds the full
`CommandMenuContext` object from React state, which is then passed to
`useCommandMenuItemFrontComponentActions` for evaluating conditional
availability expressions.
2026-03-04 16:33:58 +01:00
Paul Rastoin 845a1934d3 Tt call recording app (#18281)
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Weiko <corentin@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: Charles Bochet <charles@twenty.com>
2026-03-04 14:11:57 +00:00
Charles Bochet 7a2e397ad1 Complete linaria migration (#18361)
## Summary

Completes the migration of the frontend styling system from **Emotion**
(`@emotion/styled`, `@emotion/react`) to **Linaria** (`@linaria/react`,
`@linaria/core`), a zero-runtime CSS-in-JS library where styles are
extracted at build time.

This is the final step of the migration — all ~494 files across
`twenty-front`, `twenty-ui`, `twenty-website`, and `twenty-sdk` are now
fully converted.

## Changes

### Styling Migration (across ~480 component files)
- Replaced all `@emotion/styled` imports with `@linaria/react`
- Converted runtime theme access patterns (`({ theme }) => theme.x.y`)
to build-time `themeCssVariables` CSS custom properties
- Replaced `useTheme()` hook (from Emotion) with
`useContext(ThemeContext)` where runtime theme values are still needed
(e.g., passing colors to non-CSS props like icon components)
- Removed `@emotion/react` `css` helper usages in favor of Linaria
template literals

### Dependency & Configuration Changes
- **Removed**: `@emotion/react`, `@emotion/styled` from root
`package.json`
- **Added**: `@wyw-in-js/babel-preset`, `next-with-linaria` (for
twenty-website SSR support)
- Updated Nx generator defaults from `@emotion/styled` to
`@linaria/react` in `nx.json`
- Simplified `vite.config.ts` (removed Emotion-specific configuration)
- Updated `twenty-website/next.config.js` to use `next-with-linaria` for
SSR Linaria support

### Storybook & Testing
- Removed `ThemeProvider` from Emotion in Storybook previews
(`twenty-front`, `twenty-sdk`)
- Now relies solely on `ThemeContextProvider` for theme injection

### Documentation
- Removed the temporary `docs/emotion-to-linaria-migration-plan.md`
(migration complete)
- Updated `CLAUDE.md` and `README.md` to reflect Linaria as the styling
stack
- Updated frontend style guide docs across all locales

## How it works

Linaria extracts styles at build time via the `@wyw-in-js/vite` plugin.
All expressions in `styled` template literals must be **statically
evaluable** — no runtime theme objects or closures over component state.

- **Static styles** use `themeCssVariables` which map to CSS custom
properties (`var(--theme-color-x)`)
- **Runtime theme access** (for non-CSS use cases like icon `color`
props) uses `useContext(ThemeContext)` instead of Emotion's `useTheme()`
2026-03-04 00:50:06 +01:00
Charles Bochet 3bfdc2c83f chore(twenty-front): migrate command-menu, workflow, page-layout and UI modules from Emotion to Linaria (PR 4-6/10) (#18342)
## Summary

Continues the Emotion → Linaria migration (PR 4-6 from the [migration
plan](docs/emotion-to-linaria-migration-plan.md)). Migrates **311
files** across four module groups:

| Module | Files |
|---|---|
| command-menu | 53 |
| workflow | 84 |
| page-layout | 84 |
| UI (partial - first ~80 files) | ~80 |
| twenty-ui (TEXT_INPUT_STYLE) | 1 |
| misc (hooks, keyboard-shortcut-menu, file-upload) | ~9 |

### Migration patterns applied

- `import styled from '@emotion/styled'` → `import { styled } from
'@linaria/react'`
- `import { useTheme } from '@emotion/react'` → `import { useContext }
from 'react'` + `import { ThemeContext } from 'twenty-ui/theme'`
- `${({ theme }) => theme.X.Y.Z}` → `${themeCssVariables.X.Y.Z}` (static
CSS variables)
- `theme.spacing(N)` → `themeCssVariables.spacing[N]`
- `styled(motion.div)` → `motion.create(StyledBase)` (11 components)
- `styled(Component)<TypeParams>` → wrapper div approach for non-HTML
elements
- Multi-declaration interpolations split into one CSS property per
interpolation
- Interpolation return types fixed (`&&` → ternary `? : ''`)
- `TEXT_INPUT_STYLE` converted from function to static string constant
(backward compatible)
- Emotion `<Global>` replaced with `useEffect` style injection
- Complex runtime-dependent styles use CSS custom properties via
`style={}` prop

### After this PR

- **Remaining files**: ~400 (object-record: ~160, settings: ~200, UI:
~44)
- **No breaking changes**: CSS variables resolve identically to the
previous Emotion theme values
2026-03-03 16:42:03 +01:00
Abdul Rahman ae291c99ba fix: record does not open in side panel after returning from fullscreen (#17131)
Closes #17089 

### 1. Can't reopen record after having navigated to its show page
After opening a record in the show page from the command menu and going
back to the index, clicking the same record again did nothing. The
command menu navigation stack was not cleared when opening in the show
page, so the "already open" check skipped reopening. We now clear the
command menu navigation stack before navigating to the show page (in
`RecordShowRightDrawerOpenRecordButton`), so the same record can be
reopened from the index.

### 2. Row doesn't highlight when opening command menu after return from
show page
After returning from the record show page to the index, the first row
click opened the command menu but the row did not highlight. The "side
panel close" event was emitted not only when the panel actually closed,
but also when opening the command menu (cleanup ran with
`isCommandMenuClosing` and always emitted the event). Listeners like
`RecordTableDeactivateRecordTableRowEffect` then deactivated the row. We
now emit the side panel close event only when the close animation
actually completes (`CommandMenuSidePanelForDesktop`), and skip emitting
it when cleanup is run from the open path (`useNavigateCommandMenu`
passes `emitSidePanelCloseEvent: false`). The table still deactivates
the row when the user closes the panel, but no longer when they open the
command menu by clicking a row.
2026-03-02 23:25:11 +00:00
BugIsGod 7809f83e72 fix: [Note] Title not filled by default #13838 (#18297)
Fixes #13838 
When creating a note from the command menu side panel (e.g. clicking
"Add Note" in a related notes section on an Opportunity/company/people
page), the title field was not auto-focused — focus point went to body
instead.

## Root Cause

When a record opens in the side panel, there is no page navigation, so
`PageChangeEffect` (which handles title auto-focus for full-page views)
never runs. `openNewRecordTitleCell()` was simply never called for the
side-panel path.

## Fix

`openRecordInCommandMenu` is the single entry point for all side-panel
record opens, so title auto-focus is handled there once for all callers.
Previously, `useCreateNewIndexRecord` called `openRecordInCommandMenu`
and then called `openNewRecordTitleCell` separately, which would have
caused a double invocation after this fix. The redundant call has been
removed.

## Before


https://github.com/user-attachments/assets/df0d9e4f-dc25-4a0d-a49e-898a14f9c0a0

## After


https://github.com/user-attachments/assets/1a5044f7-6bb7-4333-8934-c1081b935e97

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 20:09:36 +00:00
nitin 1eb284c87f Fix command menu text/number inputs to commit on blur and cancel cleanly on Escape (#18283)
closes https://github.com/twentyhq/twenty/issues/18264




https://github.com/user-attachments/assets/7b576a00-78bc-46a2-9528-d8b3bcbdd530




https://github.com/user-attachments/assets/4102468e-e85f-46a0-8b23-e7abd77bfc95



### PR description -
This fixes flaky persistence in command menu text and number inputs.

- moved commit logic to onBlur (single commit path)
- Enter now blurs, so it uses the same commit path
- Escape now cancels edit (restores draft + exits) without persisting
- removed dependency on input click-outside commit timing

### Outcome -

- clicking anywhere outside the input now reliably persists edits
- Escape consistently discards edits
2026-03-02 15:30:51 +00:00
Abdul Rahman 9fe2a07c55 Navbar customization v2 (#18026)
Adds color support for navigation menu items.

---------

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: Charles Bochet <charles@twenty.com>
2026-02-28 11:48:28 +01:00
Abdul Rahman e806d36099 Navbar with AI chats (#18161)
## Summary
Add Home/Chat tabs and a dedicated threads list in the navigation
drawer.

## Changes
- **Navbar tabs:** Tabs in the drawer to switch between Home and Chat
(with “New chat” button). Shown on desktop when expanded and on mobile
below the workspace selector.
- **Navbar threads list:** New `NavigationDrawerAIChatThreadsList` for
the Chat tab with date groups (Today / Yesterday / Older), thread rows
as `NavigationDrawerItem` (IconComment, title, timestamp). Shared
`useAIChatThreadClick` hook used by navbar and command menu; navbar
passes `resetNavigationStack: true`.
- **NavigationDrawerItem:** New `alwaysShowRightOptions` prop so the
timestamp is always visible (no hover-only).

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-27 23:37:14 +01:00
Charles Bochet 86fbf69e95 Fix more tests (#18287)
Improve mock in front tests
2026-02-27 14:06:18 +01:00
Charles Bochet 8a7a19f312 Improve test tooling (#18259)
## Summary

Unifies test mocking tooling across Jest and Storybook, replaces
handcrafted mock data with auto-generated server-fetched data, and
restructures the mock data generation script for maintainability.

### Mock data generation

- Split `generate-mock-data.ts` into three focused modules under
`scripts/mock-data/`:
  - `utils.ts` — shared authentication, GraphQL client, and file writer
  - `generate-metadata.ts` — fetches object metadata from `/metadata`
- `generate-record-data.ts` — fetches record data from `/graphql` using
metadata-driven dynamic queries
- The orchestrator (`generate-mock-data.ts`) authenticates once and
passes the token to both generators
- Company records are now fetched from the actual server (limited to 10
records) instead of being handcrafted
- Generated files are organized under `generated/metadata/objects/` and
`generated/data/companies/`

### Unified test utilities

- Consolidated Jest and MSW mocking into shared utilities that compose
production code (`prefillRecord`, `getRecordNodeFromRecord`,
`getRecordConnectionFromRecords`) with mock metadata
- Renamed `generateEmptyJestRecordNode` → `generateMockRecordNode` and
moved to `testing/utils/`
- Extracted `generateMockRecordConnection` into its own file
- Removed `sanitizeInputForPrefill` workaround (no longer needed with
correctly shaped generated data)
2026-02-26 14:31:54 +01:00
Charles Bochet 2674589b44 Remove any recoil reference from project (#18250)
## Remove all Recoil references and replace with Jotai

### Summary

- Removed every occurrence of Recoil from the entire codebase, replacing
with Jotai equivalents where applicable
- Updated `README.md` tech stack: `Recoil` → `Jotai`
- Rewrote documentation code examples to use
`createAtomState`/`useAtomState` instead of `atom`/`useRecoilState`, and
removed `RecoilRoot` wrappers
- Cleaned up source code comment and Cursor rules that referenced Recoil
- Applied changes across all 13 locale translations (ar, cs, de, es, fr,
it, ja, ko, pt, ro, ru, tr, zh)
2026-02-26 10:28:40 +01:00
Charles Bochet bc4ae35bc4 Rework atom naming (#18240)
## Summary

- **Enhanced the `matching-state-variable` ESLint rule** to enforce
consistent naming for `ComponentState`, `FamilyState`, and
`ComponentFamilyState` hooks — previously it only covered `useAtomState`
and `useAtomStateValue`
- **The rule now checks 12 hooks** across three categories: value hooks
(`useAtomComponentStateValue`, `useAtomFamilyStateValue`, etc.), state
hooks (`useAtomComponentState`, `useAtomComponentFamilyState`), and
setter hooks (`useSetAtomState`, `useSetAtomComponentState`,
`useSetAtomFamilyState`, `useSetAtomComponentFamilyState`)
- **Fixed all 225 resulting lint violations** across 151 files, renaming
variables to match their state atom names (e.g. `currentViewId` →
`contextStoreCurrentViewId`, `selectedRecord` → `recordStore`). Cases
where the same state is accessed with different family keys/instance IDs
are suppressed with `eslint-disable-next-line`.

## Naming convention

| Hook | State argument | Valid | Invalid |
|------|---------------|-------|---------|
| `useAtomStateValue` | `fooState` | `const foo = ...` | `const bar =
...` |
| `useAtomComponentStateValue` | `fooComponentState` | `const foo = ...`
| `const bar = ...` |
| `useAtomFamilyStateValue` | `fooFamilyState` | `const foo = ...` |
`const bar = ...` |
| `useAtomComponentFamilyStateValue` | `fooComponentFamilyState` |
`const foo = ...` | `const bar = ...` |
| `useAtomState` | `fooState` | `const [foo, setFoo] = ...` | `const
[bar, setBar] = ...` |
| `useAtomComponentState` | `fooComponentState` | `const [foo, setFoo] =
...` | `const [bar, setBar] = ...` |
| `useAtomComponentFamilyState` | `fooComponentFamilyState` | `const
[foo, setFoo] = ...` | `const [bar, setBar] = ...` |
| `useSetAtomState` | `fooState` | `const setFoo = ...` | `const setBar
= ...` |
| `useSetAtomComponentState` | `fooComponentState` | `const setFoo =
...` | `const setBar = ...` |
| `useSetAtomFamilyState` | `fooFamilyState` | `const setFoo = ...` |
`const setBar = ...` |
| `useSetAtomComponentFamilyState` | `fooComponentFamilyState` | `const
setFoo = ...` | `const setBar = ...` |
2026-02-25 22:28:25 +01:00
Charles Bochet e01b641a05 Introduce npx nx mock:generate twenty-front (#18237)
## Add codegen script for frontend test mock data

### Summary

- Adds a new `npx nx mock:generate twenty-front` and
`generate-mock-data.ts` script that fetches object metadata from a
running server's `/metadata` endpoint, authenticates with default seeds,
and writes the result to a generated TypeScript file
(`src/testing/mock-data/generated/mock-metadata-query-result.ts`). This
replaces hand-maintained mock metadata with server-sourced data,
ensuring tests always reflect the real schema.
- Updates all frontend tests to be compatible with the newly generated
metadata, fixing hard-coded GraphQL queries, Zod validation schemas,
snapshot expectations, and Apollo mock mismatches.

### What changed

**New files**
- `scripts/generate-mock-data.ts` — codegen script that authenticates
against the server, queries `/metadata` for all object metadata (with
explicit `__typename` at every level), and writes a typed `.ts` file.
- `project.json` — added `mock:generate` Nx target (`dotenv npx tsx
scripts/generate-mock-data.ts`).

**Schema validation updates**
- `objectMetadataItemSchema.ts` — added `universalIdentifier`, made
`duplicateCriteria` nullable.
- `fieldMetadataItemSchema.ts` — added `universalIdentifier`, `morphId`,
`morphRelations`, restructured relation schema.
- `indexMetadataItemSchema.ts` — added optional `isCustom` field.
2026-02-25 21:40:05 +01:00
Charles Bochet 1fa55bfd02 Fix bugs tied to jotai migration (#18227)
Fixing a few bugs:
- CommandMenu not reactive
- Filtering on index view infinite loop
2026-02-25 17:11:12 +01:00
Charles Bochet 121788c42f Fully deprecate old recoil (#18210)
## Summary

Removes the `recoil` dependency entirely from `package.json` and
`twenty-front/package.json`, completing the migration to Jotai as the
sole state management library.

Removes all Recoil infrastructure: `RecoilRoot` wrapper from `App.tsx`
and test decorators, `RecoilDebugObserver`, Recoil-specific ESLint rules
(`use-getLoadable-and-getValue-to-get-atoms`,
`useRecoilCallback-has-dependency-array`), and legacy Recoil utility
hooks/types (`useRecoilComponentState`, `useRecoilComponentValue`,
`createComponentState`, `createFamilyState`, `getSnapshotValue`,
`cookieStorageEffect`, `localStorageEffect`, etc.).

Renames all `V2`-suffixed Jotai state files and types to their canonical
names (e.g., `ComponentStateV2` -> `ComponentState`,
`agentChatInputStateV2` -> `agentChatInputState`, `SelectorCallbacksV2`
-> `SelectorCallbacks`), and removes the now-redundant V1 counterparts.

Updates ~433 files across the codebase to use the renamed Jotai imports,
remove Recoil imports, and clean up test wrappers (`RecoilRootDecorator`
-> `JotaiRootDecorator`).
2026-02-25 12:26:42 +01:00
Charles Bochet d81f006979 Rename Jotai state hooks and utilities to consistent Atom-based naming (#18209)
## Summary

Rename all Jotai-based state management hooks and utilities to a
consistent naming convention that:
1. Removes legacy Recoil naming (`useRecoilXxxV2`, `createXxxV2`)
2. Always includes `Atom` in the name to distinguish from jotai native
hooks
3. Follows a consistent ordering: `Atom` → `Component` → `Family` →
`Type` (`State`/`Selector`)
4. Includes the type qualifier (`State` or `Selector`) in all
value-reading hooks to avoid naming conflicts with jotai's native
`useAtomValue`

## Naming Convention

**Hooks**:
`use[Set]Atom[Component][Family][State|Selector][Value|State|CallbackState]`
**Utils**: `createAtom[Component][Family][State|Selector]`

## Changes

### Hooks renamed (definition files + all usages across ~1,500 files):

| Old Name (Recoil) | Intermediate (Atom) | Final Name |
|---|---|---|
| `useRecoilValueV2` | `useAtomValue` | **`useAtomStateValue`** |
| `useRecoilStateV2` | `useAtomState` | `useAtomState` |
| `useSetRecoilStateV2` | `useSetAtomState` | `useSetAtomState` |
| `useFamilyRecoilValueV2` | `useFamilyAtomValue` |
**`useAtomFamilyStateValue`** |
| `useSetFamilyRecoilStateV2` | `useSetFamilyAtomState` |
**`useSetAtomFamilyState`** |
| `useFamilySelectorValueV2` | `useFamilySelectorValue` |
**`useAtomFamilySelectorValue`** |
| `useFamilySelectorStateV2` | `useFamilySelectorState` |
**`useAtomFamilySelectorState`** |
| `useRecoilComponentValueV2` | `useAtomComponentValue` |
**`useAtomComponentStateValue`** |
| `useRecoilComponentStateV2` | `useAtomComponentState` |
`useAtomComponentState` |
| `useSetRecoilComponentStateV2` | `useSetAtomComponentState` |
`useSetAtomComponentState` |
| `useRecoilComponentFamilyValueV2` | `useAtomComponentFamilyValue` |
**`useAtomComponentFamilyStateValue`** |
| `useRecoilComponentFamilyStateV2` | `useAtomComponentFamilyState` |
`useAtomComponentFamilyState` |
| `useSetRecoilComponentFamilyStateV2` |
`useSetAtomComponentFamilyState` | `useSetAtomComponentFamilyState` |
| `useRecoilComponentSelectorValueV2` | `useAtomComponentSelectorValue`
| `useAtomComponentSelectorValue` |
| `useRecoilComponentFamilySelectorValueV2` |
`useAtomComponentFamilySelectorValue` |
`useAtomComponentFamilySelectorValue` |
| `useRecoilComponentStateCallbackStateV2` |
`useAtomComponentStateCallbackState` |
`useAtomComponentStateCallbackState` |
| `useRecoilComponentSelectorCallbackStateV2` |
`useAtomComponentSelectorCallbackState` |
`useAtomComponentSelectorCallbackState` |
| `useRecoilComponentFamilyStateCallbackStateV2` |
`useAtomComponentFamilyStateCallbackState` |
`useAtomComponentFamilyStateCallbackState` |
| `useRecoilComponentFamilySelectorCallbackStateV2` |
`useAtomComponentFamilySelectorCallbackState` |
`useAtomComponentFamilySelectorCallbackState` |

### Utilities renamed:

| Old Name (Recoil) | Final Name |
|---|---|
| `createStateV2` | **`createAtomState`** |
| `createFamilyStateV2` | **`createAtomFamilyState`** |
| `createSelectorV2` | **`createAtomSelector`** |
| `createFamilySelectorV2` | **`createAtomFamilySelector`** |
| `createWritableSelectorV2` | **`createAtomWritableSelector`** |
| `createWritableFamilySelectorV2` |
**`createAtomWritableFamilySelector`** |
| `createComponentStateV2` | **`createAtomComponentState`** |
| `createComponentFamilyStateV2` | **`createAtomComponentFamilyState`**
|
| `createComponentSelectorV2` | **`createAtomComponentSelector`** |
| `createComponentFamilySelectorV2` |
**`createAtomComponentFamilySelector`** |

## Details

- All definition files renamed to match new convention
- All import paths and usages updated across the entire `twenty-front`
package
- Jotai's native `useAtomValue` is aliased as `useJotaiAtomValue` in the
wrapper hook to avoid collision
- Legacy Recoil files in `state/utils/` and `component-state/utils/`
left untouched (separate naming scope)
- Typecheck passes cleanly
2026-02-25 01:55:46 +01:00
Charles Bochet eaf9fe27b2 Improve Jotai work (#18205) 2026-02-24 20:38:30 +01:00
Charles Bochet 0f2af6a6cb Jotai 13 (#18178)
## Recoil to Jotai Migration — PR 13: Workflow, Page Layout, AI,
Activities, Settings, SSE & Remaining Modules

### Summary

This is the 13th PR in the [14-PR migration
series](packages/twenty-front/src/modules/ui/utilities/state/jotai/MIGRATION_PLAN.md)
to replace Recoil with Jotai as the state management library in
`twenty-front`. This PR migrates the remaining consumer code across all
modules — updating ~1,076 files with ~10k insertions/deletions.

### What changed

**New Jotai infrastructure (13 new files):**
- `createComponentSelectorV2` and `createComponentFamilySelectorV2` —
instance-scoped derived atoms, replacing Recoil's component selectors
- 6 new hooks: `useRecoilComponentSelectorValueV2`,
`useRecoilComponentFamilySelectorValueV2`,
`useRecoilComponentSelectorCallbackStateV2`,
`useRecoilComponentFamilySelectorCallbackStateV2`,
`useRecoilComponentStateCallbackStateV2`,
`useRecoilComponentFamilyStateCallbackStateV2`
- New types: `ComponentSelectorV2`, `ComponentFamilySelectorV2`,
`SelectorCallbacksV2`
- Extended `buildGetHelper` to support the new selector patterns

**State definition migrations:**
- `createState()` → `createStateV2()` (Jotai `atom()`)
- `createFamilyState()` → `createFamilyStateV2()` (Jotai `atom()` with
family cache)
- Recoil `selector`/`selectorFamily` → Jotai derived `atom()` via V2
utilities

**Hook migrations (~2,400 removed, ~1,545 added V2 equivalents):**
- `useRecoilValue` → `useRecoilValueV2`
- `useRecoilState` → `useRecoilStateV2`
- `useSetRecoilState` → `useSetRecoilStateV2`
- `useRecoilCallback` → `useCallback` + `jotaiStore.get/set`
- `useRecoilComponentValue` → `useRecoilComponentValueV2`
- `useSetRecoilComponentState` → `useSetRecoilComponentStateV2`
- `useRecoilComponentFamilyValue` → `useRecoilComponentFamilyValueV2` /
`useFamilySelectorValueV2`
- ~397 direct `import from 'recoil'` removed

**Deleted files (9 files):**
- `dateLocaleState.ts` — consolidated
- `currentAIChatThreadTitleStateV2.ts` — renamed to replace the original
- `isCommandMenuOpenedState.ts` — removed
- `filesFieldUploadState.ts` — replaced by V2
- `recordStoreFamilySelector.ts`, `recordStoreFieldValueSelector.ts`,
`recordStoreRecordsSelector.ts` — replaced by V2 equivalents
- `settingsAllRolesSelector.ts` — replaced by `useSettingsAllRoles` hook
- `settingsRoleIdsStateV2.ts` — consolidated

**Modules migrated:**
- Workflow (diagram, steps, variables, filters)
- Page Layout (widgets, fields, graph, tabs)
- AI (chat, agents, browsing context)
- Activities (rich text editor, targets, timeline)
- Action Menu (single/multiple record actions)
- Command Menu (navigation, history, pages, workflow)
- Context Store
- Record Board, Record Table, Record Calendar, Record Index
- Record Field, Record Filter, Record Sort, Record Group
- Record Drag, Record Picker, Record Store
- Views (view bar, view picker, filters, sorts)
- Settings (roles, permissions, SSO, security, data model, developers,
domains)
- SSE (event streams, subscriptions)
- Spreadsheet Import
- Auth, Favorites, Front Components, Information Banner
2026-02-24 17:37:01 +01:00
Charles Bochet b51eb6471f Jotai 12 (#18160)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 12:01:37 +01:00
Raphaël Bosi 7da8450075 [FRONT COMPONENTS] Headless components (#18096)
## Description

- Add `isHeadless` field to `FrontComponent` entity so front components
can run without rendering UI in the command menu
- Introduce headless front component mounting logic:
`HeadlessFrontComponentMountRoot` at the application root,
`useMountHeadlessFrontComponent`, and `useUnmountHeadlessFrontComponent`
hooks to mount/unmount headless components
- Expand the SDK with new action components (`Action`, `ActionLink`,
`ActionOpenSidePanelPage`) and host communication functions
(`openSidePanelPage`, `unmountFrontComponent`)
- Move `CommandMenuPages` type to twenty-shared so the SDK can reference
it for side panel navigation

## Video QA



https://github.com/user-attachments/assets/4f9e3bb1-fcd1-42be-b3f4-a97e80c2add2
2026-02-20 14:14:42 +00:00
Baptiste Devessier 00209f7e2c Wire fields widget to backend + basic edition (#17965)
Closes https://github.com/twentyhq/core-team-issues/issues/2215
Closes https://github.com/twentyhq/core-team-issues/issues/2216
Closes https://github.com/twentyhq/core-team-issues/issues/2218

## Fields widget edition demo


https://github.com/user-attachments/assets/08626d70-8fcb-4ae2-9222-10ef57e75f90

## Dashboards still work


https://github.com/user-attachments/assets/aa9a9c45-a0a2-481e-b132-bc52254778da
2026-02-20 13:18:00 +00:00
Charles Bochet 1a13258302 Keep migrating to jotai (#18064)
And we continue!
2026-02-19 12:10:02 +01:00
Paul Rastoin 88424611ec Refactor and standardize isSystem field and object (#17992)
# Introduction

## Centralize system field definitions
- Extract a single `PARTIAL_SYSTEM_FLAT_FIELD_METADATAS` constant as the
source of truth for all 8 system fields (`id`, `createdAt`, `updatedAt`,
`deletedAt`, `createdBy`, `updatedBy`, `position`, `searchVector`),
eliminating duplication across custom object and standard app field
builders
- Refactor `buildDefaultFlatFieldMetadatasForCustomObject` to use the
shared constant via a new `buildObjectSystemFlatFieldMetadatas` helper

## Mark system fields as `isSystem: true`
- Fields `id`, `createdAt`, `updatedAt`, `deletedAt`, `createdBy`,
`updatedBy`, `position`, `searchVector` are now properly flagged as
system fields across all standard objects and custom object creation
- Standard app field builders for all ~30 standard objects updated to
set `isSystem: true` on `createdAt`, `updatedAt`, `deletedAt`,
`createdBy`, `updatedBy`
- System-only standard objects (blocklist, calendar channels, message
threads, etc.) now also include `createdBy`, `updatedBy`, `position`,
`searchVector` field definitions that were previously missing

## Validate system fields on object creation
- New transversal validation (`crossEntityTransversalValidation`) runs
after all atomic entity validations in the build orchestrator, ensuring
all 8 system fields are present with correct `type` and `isSystem: true`
when an object is created
- New `buildUniversalFlatObjectFieldByNameAndJoinColumnMaps` utility to
resolve field names to universal identifiers for a given object
- New exception codes: `MISSING_SYSTEM_FIELD` and `INVALID_SYSTEM_FIELD`
on `ObjectMetadataExceptionCode`

## Protect system fields and objects from mutation
- Field validators now block update/delete of `isSystem` fields by
non-system callers (`FIELD_MUTATION_NOT_ALLOWED`)
- Object validators now block update/delete of `isSystem` objects by
non-system callers
- `POSITION` and `TS_VECTOR` field type validators replaced: instead of
rejecting creation outright, they now validate that the field is named
correctly (`position` / `searchVector`) and has `isSystem: true`

## Distinguish `isSystemBuild` from `isCallerTwentyStandardApp`
- New `isCallerTwentyStandardApp` utility checks whether the caller's
`applicationUniversalIdentifier` matches the twenty standard app
- Name-sync logic (`isFlatFieldMetadataNameSyncedWithLabel`,
`areFlatObjectMetadataNamesSyncedWithLabels`) refactored to use
`isCallerTwentyStandardApp` for custom suffix decisions, keeping
`isSystemBuild` for mutation permission checks
- `WorkspaceMigrationBuilderOptions` type updated to include
`applicationUniversalIdentifier`

## Adapt frontend filtering
- New `HIDDEN_SYSTEM_FIELD_NAMES` constant (`id`, `position`,
`searchVector`) and `isHiddenSystemField` utility to only hide truly
internal fields while keeping user-facing system fields (`createdAt`,
`updatedAt`, `deletedAt`, `createdBy`, `updatedBy`) visible in the UI
- ~20 frontend files updated to replace `!field.isSystem` checks with
`!isHiddenSystemField(field)` across record index, settings, data model,
charts, workflows, spreadsheet import, aggregations, and role
permissions

## Add 1.19 upgrade commands
- **`backfill-system-fields-is-system`**: Raw SQL command to set
`isSystem = true` on existing workspace fields matching system field
names, and fix `position` field type from `NUMBER` to `POSITION` for
`favorite`/`favoriteFolder` objects. Includes proper cache invalidation.
- **`add-missing-system-fields-to-standard-objects`**: Codegen'd
workspace migration to create missing `position`, `searchVector`,
`createdBy`, `updatedBy` fields on standard objects that didn't
previously have them. Runs via `WorkspaceMigrationRunnerService` in a
single transaction with idempotency check. **Known limitation**: assumes
all standard objects exist and are valid in the target workspace.

## Add `universalIdentifier` for system fields in standard object
constants
- `standard-object.constant.ts` updated to include `universalIdentifier`
for `createdBy`, `updatedBy`, `position`, and `searchVector` across all
standard objects
- `fieldManifestType.ts` updated to support the new field manifest shape

## System relation
Completely removed and backfilled all `isSystem` relation to be false
false
As we won't require an object to have any relation system fields

## Add integration tests
- New test suite `failing-sync-application-object-system-fields`
covering: missing system fields, wrong field types (`id` as TEXT,
`createdAt` as TEXT, `position` as TEXT), system field deletion
attempts, and system field update attempts
- New test utilities: `buildDefaultObjectManifest` (builds an object
manifest with all 8 system fields) and `setupApplicationForSync`
(centralizes application setup)
- Existing successful sync test updated to verify system fields are
created with correct properties

## Next step
Make the builder scope the compared entity to be the currently built app
+ nor twenty standard app
2026-02-19 10:13:50 +00:00
Charles Bochet 36c2b0e23b Migrate dropdown to jotai (#18063)
Here we go again
2026-02-19 00:58:26 +01:00
nitin 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
Abdul Rahman 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
Charles Bochet 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
Abdullah. 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
nitin cfc4e0e343 [DASHBOARDS] Add split multi-value fields setting for charts (#17907)
closes https://github.com/twentyhq/twenty/issues/17890



https://github.com/user-attachments/assets/dbf2ebe6-c2da-44d0-846e-d7fa9fac5f43
2026-02-17 09:29:17 +01:00
neo773 84afbb4d2c feat: add draft email workflow action (#17793)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-13 18:20:20 +01:00
acee3 e2b9bc935f Add mentions feature to objects in notes (#16373)
Issue #15755 

### Context
As shown in the issue, users should be able to @ objects and have it be
linked to their associated page.

### Changes Made
- Updated the BlockNote schema to include the newly created
MentionInlineContent that displays an object using a RecordChip
- Added the UI for the menu that appears to select the requested object
(similar to this example:
https://www.blocknotejs.org/examples/ui-components/suggestion-menus-slash-menu-component)
- Added a hook to retrieve the data for the UI
- Added the @ trigger to the block editor

### Result 

https://github.com/user-attachments/assets/87dae6a2-ad7a-4642-80b2-8b1751feae24

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-13 13:12:37 +00:00
Baptiste Devessier 83b800a077 Drag and drop fields of Fields widgets (#17910)
https://github.com/user-attachments/assets/97fad3f3-8654-4216-b58c-b7411119c8ce
2026-02-13 11:41:25 +00:00
Félix Malfait 21c51ec251 Improve AI agent chat, tool display, and workflow agent management (#17876)
## Summary

- **Fix token renewal endpoint**: Use `/metadata` instead of `/graphql`
for token renewal in agent chat, fixing auth issues
- **Improve tool display**: Add `load_skills` support, show formatted
tool names (underscores → spaces) with finish/loading states, display
tool icons during loading, and support custom loading messages from tool
input
- **Refactor workflow agent management**: Replace direct
`AgentRepository` access with `AgentService` for create/delete/find
operations in workflow steps, improving encapsulation and consistency
- **Simplify Apollo client usage**: Remove explicit Apollo client
override in `useGetToolIndex`, add `AgentChatProvider` to
`AppRouterProviders`
- **Fix load-skill tool**: Change parameter type from `string` to `json`
for proper schema parsing
- **Update agent-chat-streaming**: Use `AgentService` for agent
resolution and tool registration instead of direct repository queries

## Test plan

- [ ] Verify AI agent chat works end-to-end (send message, receive
response)
- [ ] Verify tool steps display correctly with icons and proper messages
during loading and after completion
- [ ] Verify workflow AI agent step creation and deletion works
correctly
- [ ] Verify workflow version cloning preserves agent configuration
- [ ] Verify token renewal works when tokens expire during agent chat


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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-13 09:27:38 +00:00
Charles Bochet 310d13fd17 Migrate twenty ui to jotai (#17900)
## Remove Recoil from twenty-ui

Completely removes the `recoil` dependency from `twenty-ui` by
converting all atoms, hooks, and providers to Jotai equivalents.

### twenty-ui
- `createState` now returns a Jotai `PrimitiveAtom` instead of a Recoil
atom
- `iconsState`, `IconsProvider`, `useIcons` converted to Jotai
(`useSetAtom`, `useAtomValue`)
- `RecoilRootDecorator` now uses Jotai `Provider` (name kept for compat)
- Deleted unused `invalidAvatarUrlsState` (Avatar already uses
`invalidAvatarUrlsAtomV2`)
- Removed `recoil` from `package.json`

### twenty-front
- Created local Recoil `createState` at
`@/ui/utilities/state/utils/createState` for ~112 state files still on
Recoil
- Updated all imports accordingly
- Removed `iconsState` from Recoil snapshot preservation in `useAuth`
(lives in Jotai store now)
2026-02-12 16:43:34 +01:00
Charles Bochet b456f79167 Reduce leak between gql schema (#17878)
## Reduce type leakage between GraphQL schemas

### Why

Twenty runs two separate GraphQL schemas: **core** and **metadata**.
NestJS's `@nestjs/graphql` uses a global `TypeMetadataStorage` that
accumulates all decorated types across all modules. When each schema is
built, every registered type leaks into both schemas regardless of which
module it belongs to.

This means the core schema's generated TypeScript
(`generated/graphql.ts`) contained ~2,700 lines of types that only
belong to the metadata schema (and vice versa). This creates confusion
about type ownership, inflates generated code, and makes it harder to
reason about which API surface each schema actually exposes.

### How

**1. Patch `@nestjs/graphql` to support schema-scoped type resolution**

- **(Already done)** Added a `resolverSchemaScope` option to
`GqlModuleOptions`, allowing each schema to declare a scope (e.g.
`'metadata'`)
- `ResolversExplorerService` now filters resolvers by a
`RESOLVER_SCHEMA_SCOPE` metadata key, so each schema only sees its own
resolvers
- `GraphQLSchemaFactory` now performs a **reachability walk**
(`computeReachableTypes`) starting from scoped resolver return types and
arguments, only including types that are transitively referenced —
handling unions, interfaces, and prototype chains
- Type definition storage and orphaned reference registry are cleared
between schema builds to prevent cross-contamination

**2. Register `ClientConfig` as orphaned type in metadata schema**

Since `ClientConfig` is needed in the metadata schema but not directly
returned by a resolver, it's explicitly declared via
`buildSchemaOptions.orphanedTypes`.

**3. Regenerate frontend types and fix imports**

- `generated/graphql.ts` shrank by ~2,700 lines (types moved to where
they belong)
- `generated-metadata/graphql.ts` gained types like `ClientConfig` that
were previously missing
- ~500 frontend files updated to import from the correct generated file
2026-02-12 10:58:52 +01:00
Abdul Rahman 3fb2352c78 Navbar customization followup (#17848)
Addresses review comments from the [first navbar customization
PR](https://github.com/twentyhq/twenty/pull/17728)

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
2026-02-12 02:35:43 +00:00
Abdul Rahman 0902579fbe Feat: Navbar customization (#17728)
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
2026-02-11 15:33:51 +00:00
Etienne d0c1841f0f File - Migrate avatarUrl > avatarFile on person (data migration + logic) + Attachment data migration (#17752)
- Migration command
    - Check IS_FILES_FIELD_MIGRATED:false
    - Check or create avatarFile field
    - Fetch all people with avatarUrl
           - Move (Copy/move) file in storage
           - Create core.file record
           - Update person record
           
    - bonus : attachment migration  : fullPath > file (same logic)
   
- BE logic
    - Add avatarFile field on person

- FE logic 
   - Adapt logic to upload on/display avatarFile data

The whole imageIdentifier logic will be done later
2026-02-11 15:07:05 +00:00
Rémi Delassus 859241d237 Fix merge records page accumulating duplicate morph items (#17705)
## Why
When opening **Merge records** repeatedly, morph items for the same
command-menu page were appended instead of replaced. This could produce
duplicated IDs (e.g. `[A,B,B,A]`) in the merge flow and extra duplicate
tabs in the UI.

## What
- Update `useCommandMenuUpdateNavigationMorphItemsByPage` to replace
page morph items instead of appending existing ones.
- Add regression tests covering:
  - replacing existing morph items for the same page
  - keeping only the latest payload when called twice for the same page

## Notes
I could not run the full workspace tests locally in this environment
because of existing test/build setup issues unrelated to this change
(missing `packages/twenty-front/tsconfig.spec.json` and
`temporal-polyfill` resolution in dependent tasks).

Co-authored-by: remi <remi@labox-apps.com>
2026-02-11 09:55:19 +00:00
Baptiste Devessier b250de216e Remove the code of old show pages (#17811)
Closes https://github.com/twentyhq/core-team-issues/issues/2213
2026-02-10 09:10:00 +00:00
Lakshay Manchanda 2d42b0a726 - Added accomodation of mobile navigation bar in command menu (#17419)
Fix for #16743 

Added styles to accommodate for mobile navigation bar for better
visibility and better access of the command menu buttons.

## CommandMenuAskAIPage.tsx (Not shown in the issue)
### Before
<img width="1100" height="1792" alt="screenshot-2026-01-24_17-22-45"
src="https://github.com/user-attachments/assets/8a337ffe-9dfc-4e52-b744-622cc6989ae4"
/>

### After 
Since the component here already had some padding on it the mobile
navigation bar offset was lesser than it is in other places.
<img width="1092" height="1778" alt="screenshot-2026-01-24_17-28-33"
src="https://github.com/user-attachments/assets/00a217f1-d98e-4303-bdc1-df112d71a553"
/>


## CommandMenuWorkflowEditStep.tsx
### Before
As mentioned in the issue

### After
<img width="755" height="1061" alt="image"
src="https://github.com/user-attachments/assets/487d0b20-f544-4e85-99d5-eb5add4b2cb4"
/>

## CommandMenuWorkflowRunViewStep.tsx
### Before
As shown in the issue

### After
<img width="1102" height="1784" alt="screenshot-2026-01-24_17-19-31"
src="https://github.com/user-attachments/assets/a95773e3-5f61-46d0-93cb-e678e087a42f"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-09 23:48:45 +01:00
Abdullah. 4cdb7d61b2 Redesign AI chat and add pre-existing prompts. (#17787)
Redesigned AI-chat based on the following provided design.

<p align="center">
<img
src="https://github.com/user-attachments/assets/f10ebbd2-9ee9-402f-b246-6e8f8cedbd53"
width="225" />
</p>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2026-02-09 15:29:32 +01:00
Copilot 43042d55b2 Scaffold Fields widget edition (#17548)
https://github.com/user-attachments/assets/960b8b0d-10e8-42a1-bf61-e875359ea302

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
2026-02-03 15:56:41 +00:00
nitin 19b56c5d3a [FRONT COMPONENTS] Frontend component widget creation (#17653)
closes https://github.com/twentyhq/core-team-issues/issues/2182



https://github.com/user-attachments/assets/babf154c-9cda-40ff-b2e8-5053e447c35f
2026-02-03 15:09:52 +00:00