Commit Graph

668 Commits

Author SHA1 Message Date
martmull 7b682bced9 feat(shared): require defaultValue on non-nullable field manifests (#22419)
## Context

Follow-up to #22362, which made `isNullable` manifest changes actually
apply (including a nullable → non-nullable backfill). This models the
`isNullable` / `defaultValue` relationship directly in the
`FieldManifest` type.

## Rule

- A **non-nullable** field (`isNullable: false`) must declare a
`defaultValue`, so the column always has a value to fall back on (e.g.
for the backfill on the nullable → non-nullable transition).
- A **nullable** or **unspecified** field may omit `defaultValue`.

## Changes

- Split `RegularFieldManifest` into a base shape plus a discriminated
nullability union. The union keeps `isNullable` free once a
`defaultValue` is supplied, so helpers that always provide one can still
pass a dynamic `boolean` `isNullable`.
- `defaultValue` keeps its rich per-type `FieldMetadataDefaultValue<T>`
(POSITION → number, ACTOR → composite) rather than a bare `string`.
- `RelationFieldManifest` is rebased on the shared base and keeps
`isNullable` / `defaultValue` optional, since relation join columns are
always nullable by design.
- Narrowed `buildEstimateFieldManifest` in the manifest-update
integration test to satisfy the stricter type.

## Verification

Environment couldn't install the monorepo deps (registry connections
aborting), so `nx typecheck` wasn't run here. Validated the union
structure with standalone `tsc` synthetic tests mirroring every
construction pattern in the codebase:

-  nullable/no-default, no-`isNullable`, non-nullable with
string/number/composite defaults, dynamic-boolean-with-default, and the
`DistributiveOmit` path into `ObjectFieldManifest`
-  non-nullable **without** a default is correctly rejected with a
clear "defaultValue is missing but required" error

Recommend a full `nx typecheck twenty-shared twenty-sdk twenty-server`
in CI to confirm against full project resolution.

https://claude.ai/code/session_01VnbrgBB3kNGP876qaKPYDL

---
_Generated by [Claude
Code](https://claude.ai/code/session_01VnbrgBB3kNGP876qaKPYDL)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22419?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-02 08:03:52 +00:00
Thomas des Francs d8cc81cb91 Improve billing settings UI (#22377)
## Summary

- Refresh the settings billing subscription and credits cards with
clearer status, usage, and action states.
- Add the credit-package picker flow and route past-due/cancellation
actions to billing management instead of credit modals.
- Clean up related billing UI helpers and formatting.

## Screens

### regular
<img width="1007" height="781" alt="image"
src="https://github.com/user-attachments/assets/dc9c0c59-8cda-422a-a0d3-56292421a744"
/>

### downgrading
<img width="1049" height="818" alt="image"
src="https://github.com/user-attachments/assets/0dc3dea8-5b55-4cf2-bc92-997cf6e9bebc"
/>
<img width="1048" height="901" alt="image"
src="https://github.com/user-attachments/assets/fba805ad-f523-444b-93a0-2011b6b43443"
/>

### Trialing

without card
<img width="1008" height="903" alt="image"
src="https://github.com/user-attachments/assets/d5dd11b6-4c92-4102-ac22-ad1ad4e9fbfb"
/>

with card
<img width="1008" height="806" alt="image"
src="https://github.com/user-attachments/assets/0dbeb00e-890e-4448-94fe-0cc0ef411e8d"
/>


### Past due & Unpaid

<img width="1052" height="860" alt="Past due"
src="https://github.com/user-attachments/assets/25ba53ef-6e74-4b4c-bfe1-d6c74e165917"
/>
<img width="1138" height="860" alt="Unpaid"
src="https://github.com/user-attachments/assets/bb16fe65-84e4-40a7-8951-90b01030aded"
/>

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2026-07-01 17:02:54 +00:00
Parship Chowdhury 6e319283c4 fix: Vite 8/Rolldown build warnings in library packages (#22205)
Clean up Vite 8/Rolldown build warnings that showed up during yarn
start:
- `twenty-client-sdk`: `relativeImportPath.ts` now imports `node:path`,
so the generate bundle treats it as a Node external instead of stubbing
it for the browser.
- Remove rollup’s `interop: 'auto'` from CJS output options - Rolldown
don’t support it and was showing `Invalid key: Expected never but
received "interop"`.
- Replaced deprecated `inlineDynamicImports: true` with `codeSplitting:
false` in the worker config.

References:
- https://v7.vite.dev/guide/rolldown#option-validation-warnings
-
https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22205?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Signed-off-by: Parship Chowdhury <parshipchowdhury@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-29 12:59:36 +02:00
Thomas des Francs 9870d1e6a9 Fix source icon SVG ID collisions (#22177)
## Summary

Fixes the Gmail and Google Calendar source icons by replacing
document-global generic SVG IDs (`a`, `b`, `c`, etc.) with icon-specific
IDs. This prevents inline SVG gradients, masks, and filters from
resolving against another icon instance when the icons render together
in the record table actor/source column.

## Root cause

The Gmail and Google Calendar SVG assets both used generic IDs. Browser
SVG fragment references are document-global for inline SVG, so whichever
icon appears first can hijack the other icon's `url(#...)` references.
That made the Calendar icon pick up Gmail gradients, and could also
affect Gmail depending on DOM order.

## Before

<img width="1280" height="720" alt="Before icon collision screenshot"
src="https://github.com/user-attachments/assets/82ce20a8-47c7-4b70-8af2-e134cf88c0b8"
/>

## After

<img width="1280" height="720" alt="After icon collision screenshot"
src="https://github.com/user-attachments/assets/240120a6-b84e-4682-a116-0ccb48192543"
/>

## Validation

- Rendered Gmail + Calendar in both DOM orders via a local browser
fixture.
- Verified the before fixture had 14 generic SVG IDs and the after
fixture had 0.
- Verified 4 SVGs rendered, no cross-icon URL reference problems, and no
browser console warnings/errors.
- Ran `xmllint --noout packages/twenty-ui/src/assets/icons/gmail.svg
packages/twenty-ui/src/assets/icons/google-calendar.svg`.
- Ran `rg -n
"id=\"[a-z]\"|url\(#[a-z]\)|mask=\"url\(#[a-z]\)\"|filter=\"url\(#[a-z]\)\""
packages/twenty-ui/src/assets/icons -S` and confirmed no matches.

`yarn nx build twenty-ui` could not run in this worktree because
`node_modules` is missing, and Yarn reports: `Couldn't find the
node_modules state file`.
2026-06-25 14:22:17 +00:00
Parship Chowdhury 6ee5413951 chore(vite): replace vite-tsconfig-paths with resolve.tsconfigPaths (#22100)
### Summary
Migrates main monorepo packages from the `vite-tsconfig-paths` plugin to
vite’s built-in path resolution.

Vite 8 showing this warning when the plugin is detected:
> The plugin "vite-tsconfig-paths" is detected. Vite now supports
tsconfig paths resolution natively via the resolve.tsconfigPaths option.
You can remove the plugin and set resolve.tsconfigPaths: true in your
Vite config instead.

### References
- https://vite.dev/config/shared-options#resolve-tsconfigpaths
- https://vite.dev/guide/features#paths
- https://github.com/vitejs/vite/pull/21781

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22100?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Signed-off-by: Parship Chowdhury <parshipchowdhury@gmail.com>
2026-06-24 19:03:18 +02:00
dependabot[bot] 8830ef89bd chore(deps-dev): bump @storybook/addon-docs from 10.3.4 to 10.4.6 (#22110)
Bumps
[@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs)
from 10.3.4 to 10.4.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/addon-docs's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.6</h2>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>v10.4.5</h2>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>v10.4.4</h2>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>v10.4.3</h2>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>v10.4.2</h2>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>v10.4.1</h2>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run `npx expo install --fix` after init for Expo projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support `peerDependencies` in framework detection for component
libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>v10.4.0</h2>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/addon-docs's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run <code>npx expo install --fix</code> after init for Expo
projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support <code>peerDependencies</code> in framework detection
for component libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<ul>
<li>🤖 Agentic Setup: New CLI workflow for AI-assisted Storybook setup
and onboarding</li>
<li>🔍 Change review: Sidebar filtering to highlight new, modified, and
related stories based on git changes</li>
<li>🧭 Sidebar review tools: Status filtering, URL-persisted filters, and
clearer review signals in the sidebar</li>
<li>⚛️ TanStack React: New <code>@storybook/tanstack-react</code>
framework with routing and server function support</li>
<li>🧩 React MCP: Faster, more accurate component docgen powered by the
TypeScript Language Server</li>
<li>📱 React Native: Zero config RN project initialization</li>
<li>🤝 Sharing: Easily publish and share your local Storybook with
teammates, powered by Chromatic</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/5496a4270da7f3a8e0203185792685cba671fdc5"><code>5496a42</code></a>
Bump version from &quot;10.4.5&quot; to &quot;10.4.6&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a>
Bump version from &quot;10.4.4&quot; to &quot;10.4.5&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a>
Bump version from &quot;10.4.3&quot; to &quot;10.4.4&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a>
Bump version from &quot;10.4.2&quot; to &quot;10.4.3&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c89882282295be3bc05b3a366916c53d7a499841"><code>c898822</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/34496">#34496</a>
from NYCU-Chung/fix/docs-blocks-custom-mdx</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c920fd08c79c57879fa2ddb4e8538e1684c71ec2"><code>c920fd0</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/35021">#35021</a>
from LongTangGithub/fix/docs-hmr-scroll-to-top</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/1750494e9f36748b2d89335e77f23f125fc5ec78"><code>1750494</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/35031">#35031</a>
from storybookjs/jeppe/fix-mdx-no-dev-tag</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a>
Bump version from &quot;10.4.1&quot; to &quot;10.4.2&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/cc19ae1a2145e8f7cda8dc869f1b90d5346dcedb"><code>cc19ae1</code></a>
Bump version from &quot;10.4.0&quot; to &quot;10.4.1&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f8c16d115cfcf0f79125b358266c37e5343bb70d"><code>f8c16d1</code></a>
Bump version from &quot;10.4.0-beta.0&quot; to &quot;10.4.0&quot; [skip
ci]</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/addons/docs">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@storybook/addon-docs&package-manager=npm_and_yarn&previous-version=10.3.4&new-version=10.4.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22110?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-24 18:37:04 +02:00
Thomas des Francs 9ed0d85954 Update workspace domain card layout (#22108)
## What changed
- Render the Workspace domain cards side by side instead of stacked.
- Keep both domain cards full width within the row.
- Rename the section title from `Workspace Domain` to `Workspace
domain`.
- Use the `www` globe icon for Subdomain while keeping the standard
globe for Custom Domain.
- Export `IconWorldWww` from `twenty-ui/icon` for front-end consumers.

<img width="1029" height="220" alt="image"
src="https://github.com/user-attachments/assets/83ad8a29-d63c-42bb-9233-7754d1e7adf7"
/>


## Why
This matches the updated settings design for the Workspace domain
section and makes the Subdomain and Custom Domain options scan as
sibling actions.

## Validation
- Ran focused `oxlint` and `oxfmt` checks on edited files.
- Built `twenty-ui` successfully.
- Ran `twenty-front` typecheck successfully.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22108?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-24 16:24:39 +00:00
Félix Malfait 7d3cd5ed00 feat(front): add search to the language picker (#22095)
## What

Adds a search bar to the **Settings → Experience → Language** picker,
and makes languages searchable across languages.

Each option is matched against:
- its displayed label (the name in the current UI language)
- its name **in English** — typing `chinese` finds "Chinois — Simplifié"
- its **native name** — typing `中文` finds the same option

Matching is also accent-insensitive (`francais` finds "Français").

## How

- The shared `Select` already supports search via `withSearchInput`
(used by the currency/country pickers) — the picker just opts in.
- Cross-language matching uses the platform `Intl.DisplayNames` API to
derive each language's English and native names — no hardcoded
translation tables, no extra requests.
- A generic optional `searchKeywords` field on `SelectOption` lets the
`Select` filter match synonyms on top of the label; the filter now runs
through the existing `normalizeSearchText`, hence the
accent-insensitivity. Behavior is unchanged for every existing `Select`
(strict superset for ASCII labels).

## Test

- `nx typecheck` / `nx lint` pass for `twenty-front` and `twenty-ui`.
- Open the Language dropdown and try `chinese`, `中文`, or `francais`.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22095?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-24 16:58:24 +02:00
Raphaël Bosi dd9ad876a4 Reduce published twenty-ui npm package size (#22087)
The published `twenty-ui@1.0.0-alpha.0` tarball was ~181 MB unpacked (27
MB compressed, 2,701 files). This was a build-config issue, so a clean
CI build would reproduce the same size.

Main fix: externalize `@tabler/icons-react` instead of bundling it. It
was forced into the bundle and aliased to the full icon barrel, inlining
the entire icon set into every entry point in both ESM and CJS (~81% of
the package). It stays a `dependency`, so consumers still get it; the
dynamic `<Icon name>` registry still resolves icons at runtime.

Also:
- Stop emitting/shipping declaration maps (`declarationMap: false`).
- Exclude the internal `dist/individual` build and `*.map` from the
tarball via `files` (it still builds locally for
`twenty-front-component-renderer`).
- Clean up the stale `files` / `project.json` build outputs at their
source, `scripts/generateBarrels.ts`.
- Add a `pack-size` CI guard (30 MB unpacked budget) and wire `size` +
`pack-size` into `ci-ui.yaml`.

Result: ~181 MB to ~2.3 MB unpacked (0.40 MB tarball, 400 files). All
export subpaths, types, and icon rendering verified intact in both
module formats.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22087?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-24 14:53:14 +00:00
Raphaël Bosi a575ef56c3 Add logo to twenty-ui README (#22077)
<img width="408" height="408" alt="Twenty_UI"
src="https://github.com/user-attachments/assets/f69fb630-97fb-4c21-ad44-d924e4bd72f5"
/>


Adds the Twenty UI logo to the top of the `twenty-ui` package README.

- New `packages/twenty-ui/logo.png` (rasterized at 3x for retina).
- README references it via an absolute raw GitHub URL so it renders on
both the GitHub repo page and the npmjs.com package page (npm strips SVG
images from READMEs, so PNG is used).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22077?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-24 13:19:03 +00:00
Vincent Vu 680e4a712b feat(ui): additional social providers to link components (#21716)
The current link component matches only to linkedin, twitter and
facebook.

It is currently missing the x handle. In addition to this, we should
also accomodate for instagram, bluesky and tiktok.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21716?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-24 12:21:17 +02:00
Raphaël Bosi f5f8865c4e Add a real README for the twenty-ui package (#22038)
Replaces the twenty-ui README, which was a long internal
design/migration document, with a real package README aimed at
consumers.

The new README covers installation, peer dependencies, a verified usage
example, the available subpath entry points, theming, and development
commands. It is what will be shown on the npm package page once
twenty-ui is published.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22038?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 18:24:04 +02:00
Raphaël Bosi b8e1004534 Bump twenty-ui to 1.0.0-alpha.0 for first npm pre-release (#22040)
Sets `twenty-ui` to `1.0.0-alpha.0` so it can be published as the first
pre-release on npm.

The package name was previously published once (`0.23.4`) and fully
unpublished in Sept 2024. Starting at `1.0.0-alpha.0` avoids the burned
version, stays above the old number, and publishes to the `alpha`
dist-tag (not `latest`) via the existing twenty-infra publish workflow,
so it can be dogfooded before a stable `1.0.0`.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22040?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 18:23:18 +02:00
Raphaël Bosi 766d90af7e Remove framer-motion from twenty-ui (#22021)
## What

Removes the `framer-motion` dependency from `twenty-ui` and replaces
every usage with pure CSS animations, reaching for Base UI primitives
where one fits:

- **Collapse/expand** (`AnimatedEaseInOut`,
`AnimatedExpandableContainer`): rebuilt on Base UI `Collapsible`
(CSS-animated `--collapsible-panel-height/width` + transition states).
Public props unchanged, so the ~28 call sites are untouched.
- **ProgressBar**: rebuilt on Base UI `Progress` (proper
`role`/`aria-valuenow`). The snackbar auto-dismiss countdown now uses a
CSS keyframe + `animation-play-state` (pause on hover), removing a
per-frame React re-render; `useProgressAnimation` is deleted.
- The remaining `Animated*` components, the circular spinner, checkmark,
and the placeholder pointer parallax move to plain CSS (SCSS modules +
the `duration()` helper + theme tokens).
- Deletes 3 unused components (`AnimatedTranslation`,
`AnimatedTextWord`, `AnimatedFadeOut`).

## Why

`twenty-ui` is a publicly published library with a size budget, so
dropping framer-motion shrinks what consumers ship. `twenty-front` keeps
its own framer-motion; that is out of scope here.

## Notes for reviewers

- A few `twenty-ui` components received framer props from `twenty-front`
call sites; those were migrated (e.g. `AnimatedLightIconButton` gained a
CSS `rotate` prop, and the `EMPTY_PLACEHOLDER_TRANSITION_PROPS` spreads
were removed).
- Behavior change: Base UI `Collapsible` animates only on open/close
transitions, so the old "animate in on first mount while already open"
case no longer plays (the `initial` prop is kept for API compatibility).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22021?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 17:43:08 +02:00
Johnny Martin d4e4e2612b feat(front): render Instagram URLs as @handles in link fields (#21642)
LinkedIn and X links already show a readable handle in Twenty's link
fields. Instagram doesn't — it just shows `instagram.com`, which isn't
much help when you're scanning a record.

This adds the same handling for Instagram. `instagram.com/ptcrash` now
shows as `@ptcrash`, in tables, on record pages, and in the edit menu.
Post and reel links (`/p/...`, `/reel/...`) have no handle, so they fall
back to `Instagram`.

How it works:
- `Instagram` added to the `LinkType` enum
- `checkUrlType` detects `instagram.com`
- `getDisplayValueByUrlType` pulls the handle and prefixes `@`
- a shared `isSocialLinkType` helper keeps the three display components
in sync

Tested with unit tests for both helpers, the updated story, and manually
against a record whose Instagram field is
`http://instagram.com/ptcrash`.

Closes #21644

Co-authored-by: Johnny Martin <ptcrash@users.noreply.github.com>
2026-06-23 17:25:50 +02:00
Raphaël Bosi 0f451897cf Make twenty-ui theming a consumer-facing API (#22007)
**What**
- Add `useTheme()` and `useThemeColorScheme()` as the public theme
accessors, and migrate the 88 internal `useContext(ThemeContext)` call
sites to them. `ThemeContext` stays exported.
- Make `ThemeProvider` overridable and scopeable: new `applyToRoot`
(default `true`), `overrides` (a `--t-*` map), and `className` props.
When scoping is requested it renders a `display: contents` wrapper that
also serves as the themed portal container, exposed via
`ThemeScopeContext` / `useThemeContainer()`. `AppTooltip` and `Modal`
portal into that container, falling back to `document.body`.
- Document the `--t-*` override contract in the README; barrels
regenerated.

**Why**
Consumers had no stable theme accessor (they reached into the raw
context) and no supported way to re-theme. This adds both without
behavior change.

**Reviewer notes**
- The default path is unchanged: `applyToRoot` defaults to `true`, so
the colorScheme class still lands on `<html>` and portaled overlays
(tooltips, dropdowns, modals) stay themed. The global class is
load-bearing for body portals; scoping is opt-in.
- `twenty-front` is untouched (migrating its consumers is a separate
follow-up).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22007?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-23 14:16:09 +02:00
Raphaël Bosi 5f22908588 Decouple twenty-ui Avatar from app server-URL config (#21968)
Makes `twenty-ui`'s `Avatar` render the `avatarUrl` it receives instead
of building it from `window._env_`/`window.location` at module load, so
the library no longer depends on the app environment. URL resolution
moves to `twenty-front` via a `getAbsoluteImageUrl` helper applied at
the call sites.

Part of making twenty-ui a standalone library.
2026-06-22 18:38:00 +02:00
Raphaël Bosi 8553c574db Improve twenty-ui packaging for standalone publishing (#21946)
Quick packaging wins to move twenty-ui closer to a standalone
publishable library.

- Move `react`/`react-dom` to `peerDependencies` (`^19.0.0`) so
consumers provide a single React and we avoid duplicate-React bugs. They
stay in `devDependencies` for the in-repo build, and `vite.config.ts`
now derives the Rollup `external` list from peer deps too so React stays
externalized instead of bundled.
- Declare `type-fest` in `dependencies`. It was a phantom dep (resolved
only via root hoisting) and its types are referenced by the emitted
json-visualizer `.d.ts`, so standalone consumers need it.
- Move build-only `glob` to `devDependencies` and add `typescript` (both
used only by `generateBarrels.ts`).
- Make `tsconfig.json` self-contained by inlining the base compiler
options, and point the Vite `cacheDir`/`optimizeDeps.exclude` at
package-local paths.

Verified: typecheck, build (React confirmed externalized in `dist`, not
inlined), dts emission, and unit tests all pass.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21946?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-22 15:09:25 +00:00
Raphaël Bosi e0fadfee7c Remove jotai from twenty-ui (#21937)
twenty-ui no longer depends on jotai, so its components work without a
consumer-provided jotai store (better practice for a shared UI library).
twenty-front keeps jotai; this is scoped to the library.

- **Avatar**: tracks image-load failure in local `useState` instead of a
global atom.
- **Icons**: the icon registry moved from a jotai atom to a React
Context. `IconsProvider` and `useIcons` keep identical signatures; the
context itself stays internal.
- Removed the unused `createState` helper, the `invalidAvatarUrlsAtomV2`
/ `iconsState` atoms, and `JotaiRootDecorator`; regenerated barrels and
dropped the `jotai` dependency.

No other package needs changes: nothing imports the removed symbols, and
`twenty-sdk` (which re-exports twenty-ui via `export *`) simply stops
surfacing the two leaked atoms on its next publish.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21937?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-22 13:33:32 +02:00
Raphaël Bosi 1f6c2b89fd Accessibility guardrails and component hardening for twenty-ui (#21848)
Builds on twenty-ui's existing runtime axe gate by adding a static
enforcement layer and fixing accessibility gaps in shared components.
Color contrast is intentionally out of scope (still deferred via
`A11Y_DEFER_COLOR_CONTRAST`).

## What changed
- **Static guardrails:** enabled oxlint's `jsx-a11y` plugin
(keyboard-operability rules at `error`), and added a custom
`twenty/no-storybook-a11y-disable` rule that blocks `a11y: { test: 'off'
| 'todo' }` so the axe gate can't be silently disabled again.
- **Focus visibility:** wired the existing `focus-ring` mixin into all
buttons for real `:focus-visible` rings (was `outline: none`).
- **Decorative icons:** `aria-hidden` on icons inside labeled buttons
(added to `IconComponentProps` + render sites).
- **Inputs:** accessible-name support on `SearchInput` and `Checkbox`.
- **Interactive components:** `Tag` renders a real `<button>` when
clickable; the non-semantic clickable `div`s (`Avatar`, `Status`,
`ColorSchemeCard`, `NavigationBarItem`, etc.) are now keyboard-operable
via a shared `handleClickableElementKeyDown` helper, role and accessible
name.

## Notes for reviewers
- Two `oxlint-disable` lines remain on genuine non-interactive capture
wrappers (`CodeEditor`, `OverflowingTextWithTooltip`).
- 8 lint warnings remain by design: conditional-interactivity
`no-static-element-interactions` and legitimate `autoFocus` on
`SearchInput`.
- `NavigationBarItem` gained a required `ariaLabel`; its only consumer
(`MobileNavigationBar`) is updated with translated labels.

## Follow-ups (separate PRs)
- Enforced accessible names on icon-only buttons
(`IconButton`/`LightIconButton`) — breaking, ~128 call sites.
- `aria-activedescendant` wiring for the dropdown/listbox keyboard
layer.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21848?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-19 15:57:23 +02:00
Raphaël Bosi 86a4066997 Accessibility fix pass for remaining twenty-ui domains (#21790)
Completes the twenty-ui accessibility fix pass for the remaining 32
`a11y: { test: 'todo' }` story files (navigation, feedback,
data-display, typography, surfaces, layout, json-visualizer), following
the input pilot (#21776, merged). The package now has **zero** `test:
'todo'` overrides left.

**What changed (gate-driven)**
- Bulk color-contrast deferred via the shared
`A11Y_DEFER_COLOR_CONTRAST` (greppable, tracked for the later
design-token pass).
- Real violations the axe gate surfaced and fixed: accessible names on
`ProgressBar` (progressbar), `Modal` (dialog), and the
MultiSelect/Toggle inner Checkbox/Switch; `role="listbox"` parents for
`MenuItemSelect`/`SelectAvatar`; `ariaLabel` on
`MenuItem`/`MenuItemDraggable` icon-buttons; a `version` for
`GithubVersionLink`; and `JsonTree`'s empty array/object now renders a
proper `<li>` (`list` rule).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21790?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 16:11:38 +02:00
Raphaël Bosi b4113de74a Accessibility fix pass for twenty-ui input components (#21776)
Re-enables the live Storybook axe gate across the twenty-ui `input`
domain (17 story files) by removing the inherited `a11y: { test: 'todo'
}` overrides. Pilot for the wider a11y fix pass; other domains follow
the same playbook.

**What changed**
- Accessible names added to icon-only buttons, `Toggle`, `Checkbox`, and
the button groups via small additive `aria-label`/`ariaLabel` props on 8
components. Where this fully fixes the story, the override is dropped so
the full gate applies.
- Color-contrast (design-token level) is deferred — not changed — via a
new shared `A11Y_DEFER_COLOR_CONTRAST` parameter (`@ui/testing`) that
disables only the `color-contrast` rule while every other axe rule stays
enforced. Grep the constant to find all deferrals when tokens are
darkened later.
- `CatalogDecorator`: unique cell ids (clears `duplicate-id-aria`) and
dimension titles switched from empty `h1/h2/h3` to `div` (clears
`empty-heading`). Both help every domain's catalogs.

**Reviewer notes**
- No visual change: edits are aria / id / story-args / axe-config only,
so Argos parity holds.
- Input axe gate goes from 12 failing to 60/60 passing; typecheck and
lint green.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21776?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 13:01:45 +00:00
Raphaël Bosi 8034c7725f Reorganize twenty-ui into best-practice component domains and per-component folders (#21745)
Reorganizes `twenty-ui`'s component organization to follow how the best
UI libraries (MUI, Mantine, Base UI, Polaris) structure their source,
now that the package has stabilized.

**Taxonomy** — dissolves the meaningless `components/` junk-drawer and
the 107-file `display/` mega-category. New domains/subpaths:
`data-display`, `typography`, `icon`, `surfaces`; `feedback` and
`layout` absorb the rest (banners/callout/info + placeholders →
feedback; modal/card → surfaces; motion + separators → layout).

**Per-component layout** — every component is now
`<domain>/<ComponentName>/<ComponentName>.tsx` with colocated
styles/stories/types, `internal/` for private helpers and `parts/` for
re-exported compound sub-parts. The redundant inner `/components/` is
gone. `icon` and `json-visualizer` are kept as cohesive subsystems.

**Also:** adds a tree-shakeable root barrel (`import { Button } from
'twenty-ui'`), the generator now owns `individual-entry.ts`, and a real
barrel-leak bug is fixed (private `internals/` parts were leaking into
the public API).

Consumer imports (~1.2k files) and the `twenty-sdk` UI aggregator were
updated by codemod. The change is **export-neutral** except 16
intentionally-removed private internals symbols (all verified
unconsumed). Gates green: typecheck, lint, build, size-limit, storybook.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21745?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-18 10:31:29 +02:00
martmull 102c530d0f Add limit on view widget (#21718)
<img width="1345" height="463" alt="image"
src="https://github.com/user-attachments/assets/a5d9ac2f-6375-4956-895d-3675aa9bebc1"
/>


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21718?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-06-17 14:43:31 +00:00
Raphaël Bosi 9c9c34fccf Remove twenty-ui-deprecated and migrate frontend to twenty-ui (#21596)
Migrates `twenty-front`, `twenty-sdk`, and
`twenty-front-component-renderer` from `twenty-ui-deprecated` to
`twenty-ui` (mechanical import swap — the packages have API parity) and
deletes the deprecated package along with its workspace/CI/config
wiring.

Also adds `@linaria/react`/`@linaria/core` as direct deps of
`twenty-front` (it used them transitively via the deprecated package).

Note: move the required status check from `ci-ui-status-check` to
`ci-new-ui-status-check`.

Argos: the Storybook box-model/button-reset baseline shift (the bulk of
the visual diffs) is isolated in #21665 — Storybook now loads
twenty-ui's global `reset.scss`, which the production app already ships.
Once #21665 merges and this branch is rebased, the remaining Argos diffs
are component-level visual-parity items only.
2026-06-17 09:41:11 +00:00
Thomas des Francs a67fdf2dac Clean up MCP Monaco editor (#21643)
Rebuild the MCP setup block on the shared Monaco editor with theme-driven colors, padding, and auto-height; add the settings description line-height token; revert the clipboard util to the shared navigator.clipboard implementation; and consolidate the code editor's auto-height to a single disposed, reactive effect.
2026-06-16 13:57:44 +02:00
Félix Malfait c3835a839f fix(ui): default Monaco CodeEditor to scrollBeyondLastLine: false (#21657)
## Problem

In the AI chat "Python Code Execution" panel (`CodeExecutionDisplay`),
scrolling the code goes far past the last line, leaving a large empty
area below the code.

The root cause is in the shared `CodeEditor`: Monaco's
`scrollBeyondLastLine` option **defaults to `true`**, which lets the
viewport scroll roughly a full editor height past the last line. The
shared component never set this option, so the Monaco default leaked
through to every consumer.

This affected every read-only viewer built on `CodeEditor` — the code
interpreter, `WorkflowReadonlyActionCode`,
`WorkflowStepExecutionResult`, and
`SettingsLogicFunctionTriggerPayloadFormat` — and each one had to
remember to disable it (only `WorkflowEditActionCode` did).

## Change

Set `scrollBeyondLastLine: false` in the shared `CodeEditor` defaults,
in both the active `twenty-ui-deprecated` copy and the `twenty-ui` copy
(kept in sync). Since `options` is spread last, any editor that
genuinely wants scroll-past-end can still opt back in with
`scrollBeyondLastLine: true`.

## Impact

- **Auto-fixed** the read-only viewers that showed dead scroll space
(code interpreter, workflow readonly action, step execution result,
trigger payload sample).
- The editable editors that previously inherited Monaco's default
(`SettingsLogicFunctionCodeEditor`, `RawJsonFieldInput`,
`SettingsLogicFunctionTestTab`, `ConfigVariableDatabaseInput`) now also
stop at the last line — consistent with `WorkflowEditActionCode`, which
already opted out. Any of these can re-enable scroll-past-end via
`options` if desired.

## Testing

Behavior verified by inspection against Monaco's option semantics and
existing usages. Note: dependencies were not installed in the authoring
environment, so `lint`/`typecheck` were not run locally —
`scrollBeyondLastLine: false` is a standard, type-safe Monaco option
already used with this component elsewhere. Worth a CI check.

https://claude.ai/code/session_01CWzyw1spKF8Dog9E5tcdj4

---
_Generated by [Claude
Code](https://claude.ai/code/session_01CWzyw1spKF8Dog9E5tcdj4)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21657?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-16 11:52:05 +02:00
Charles Bochet fb4608e437 chore(deps): upgrade Tier-1 deps (googleapis 173, gaxios 7, express 5, jsdom 29, date-fns 4, stripe 20) (#21570)
## What

Security-driven upgrade of the biggest-drift Tier-1 dependencies
(staying on latest = staying patched). Bundled because they share the
lockfile and the googleapis/gaxios pair must move together.

| Package | From | To | Gap |
|---|---|---|---|
| googleapis | 105.0.0 | **173.0.0** | 68 majors |
| gaxios | 5.1.3 | **7.1.5** | 2 majors |
| express | 4.22.2 | **5.2.1** | 1 major |
| jsdom | 26.1.0 | **29.1.1** | 3 majors |
| date-fns | 2.30.0 | **4.4.0** | 2 majors |
| date-fns-tz | 2.0.0 | **3.2.0** | 1 major |
| stripe | 19.3.1 | **20.4.1** | 1 major |

`yarn npm audit` reports **0 high/critical** advisories before and
after.

## Code changes

- **gaxios v7** — `GaxiosError.code` is now `string | number` (guard the
calendar network-error check by `typeof`); `GaxiosError` config/response
use `URL` + `Headers`; and crucially the v7 constructor drops
`response.data` unless `bodyUsed` is set — updated the synthetic gmail
error mocks accordingly (production gaxios sets it, so real error
parsing is unaffected).
- **google-auth-library / gaxios dedup** — `googleapis-common@8.0.2`
exact-pins `google-auth-library@10.5.0` + `gaxios@7.1.3` while
`googleapis` pulls `^10.2.0`; the two copies made
`OAuth2Client`/`GaxiosError` type-identities diverge across every
gmail/calendar service. Added two singleton `resolutions` (documented
inline in root `package.json`).
- **express 5** — no source changes. `@nestjs/platform-express@11.1.24`
already resolves `express@5.2.1` internally; the old `4.22.2` pin was
the override.
- **jsdom 29** — no source changes, but it now pulls ESM-only transitive
deps (`@csstools/*` `.mjs`, `parse5`, `entities`, `tough-cookie`,
`@exodus/bytes`). Extended the server jest `transformIgnorePatterns`
allowlist and added `.mjs` to the transform/extensions so jest can load
jsdom.
- **stripe 20** — `Subscription` gained a required `customer_account`
field; added to mocks. No runtime changes.
- **date-fns v4** — `Locale` is no longer ambient (import explicitly in
5 files); per-locale entrypoints dropped the typed `default` export (the
locale loader now reads the single named export); fixed the default
locale import in `formatTimeZoneLabel`.

## Tests

- Full suites green locally: **twenty-server 5709 passed**,
**twenty-front 4937 passed**, twenty-ui / twenty-ui-deprecated green;
typecheck + builds (swc + vite) + lint all pass.
- Added regression tests for the two runtime behaviors these upgrades
touch and that had no coverage:
  - `getDateFnsLocale` — named-export locale resolution (date-fns v4).
- `sanitizeFile` — jsdom 29 + DOMPurify still strips `<script>`/event
handlers from uploaded SVGs (security guard).

## Deliberately deferred (not in this PR)

- **stripe → 21/22**: stripe **21** bundles a runtime `Decimal` type for
money fields **and** jumps the pinned API version to `2026-03-25.dahlia`
(changes webhook/billing payload behavior) — too risky to fold into a
deps bump on billing code. stripe **22** additionally drops the
node10-resolvable `types` entry, which would force a repo-wide
`moduleResolution` change. Capped at the latest clean **20.x**.
- **openid-client → 6**: v6 is a full functional rewrite and its
passport strategy manages the OAuth `state` internally, but our SSO flow
uses `state` to carry `identityProviderId` across the shared
`/auth/oidc/callback`. That needs an auth-flow redesign (session-carried
provider id) on Enterprise SSO code with no integration harness — it
deserves its own focused PR rather than riding along here.

## Tier-1 source

Originated from a dependency-drift audit; remaining Tier-1 items
(date-fns done here) plus Tier-2/3 follow-ups tracked separately.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21570?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-15 10:23:42 +02:00
Charles Bochet fa80eb68b3 fix(deps): upgrade esbuild to 0.28.1 (GHSA-gv7w-rqvm-qjhr) (#21559)
## Context

Clears [Dependabot alert
#1469](https://github.com/twentyhq/twenty/security/dependabot/1469) —
esbuild Deno-module binary-integrity RCE (`GHSA-gv7w-rqvm-qjhr`,
vulnerable `>=0.17.0 <0.28.1`, fixed in `0.28.1`).

The advisory's range is much wider than the previous esbuild one
(`>=0.27.3`), so it re-exposed several older transitive esbuild copies
in the tree.

## Approach

Prefer upgrading the parent over adding a resolution; resolutions only
where the latest upstream release still pins a vulnerable esbuild
**outside** the `0.28.1` range (so an upgrade can't help).

**Upgraded parent (no resolution needed):**
- `tsx` → `^4.22.4` across all workspaces (its `~0.28.0` esbuild now
resolves to 0.28.1)
- `size-limit` / `@size-limit/preset-small-lib` → `^12.1.0` in
`twenty-ui` (v12 pins esbuild `^0.28.0`)

**Resolutions added** (verified against npm — latest still pins
vulnerable esbuild):
- `@opennextjs/aws` (exact-pins 0.25.4, still 0.25.4 in latest 4.0.3)
- `@lingui/cli` (`^0.25.1`, caps `<0.26`, unchanged in latest 6.3.0)
- `storybook` (range tops at `^0.27.0`, caps `<0.28`, unchanged in
latest 10.4.4)
- `zapier-platform-cli` (exact-pins 0.25.8, latest)

The three existing esbuild resolutions (`wrangler`, `@react-email/ui`,
`react-email`) remain. The `//resolutions` doc in `package.json` and the
`.yarnrc.yml` age-gate comment were updated to cover both advisories.

## Result

Every esbuild copy in `yarn.lock` now resolves to a single `0.28.1`
entry — no version `<0.28.1` remains. Lockfile change is a net reduction
(dropped duplicate esbuild trees + their `@esbuild/*` platform
binaries); no unrelated deps bumped. `yarn install` passes with
constraint checks enabled.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21559?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-14 22:29:11 +02:00
Charles Bochet 7c0136b97b feat(deps): migrate frontend to React 19 (#21531)
## What

Migrates the frontend stack from **React 18.3 → 19.2**. The website,
sdk, companion and emails packages were already on React 19; this brings
the remaining holdouts (`twenty-front`, `twenty-ui`,
`twenty-ui-deprecated`, `twenty-front-component-renderer`) and
`twenty-server`'s email rendering onto 19, and pins a single React
version repo-wide.

## Why

React 18.x is now the legacy line. Staying current keeps us on the
patched/maintained branch and unblocks downstream library majors
(react-router 7, mantine 9, etc.) that require React 19 peers.

## Dependency bumps (required by React 19 peers / removed APIs)

| Package | From | To | Reason |
|---|---|---|---|
| react / react-dom | 18.3.1 | 19.2.3 | core |
| @hello-pangea/dnd | 16 | 18 | peer `^18 \|\| ^19` |
| react-datepicker | 6 | 9 | v<7 used removed `findDOMNode`; drops
`@types/react-datepicker` |
| react-data-grid | beta.13 | beta.59 | peer `^19.2`; new render API |
| graphiql (+ @graphiql/react, plugin-explorer) | 3 / 0.23 / 1 | 5 /
0.37 / 5.1 | peer `^18 \|\| ^19` |
| react-helmet-async | 1.3 | **@dr.pogodin/react-helmet** 3.2 | upstream
caps peer at `^18`; drop-in React 19 fork |

A `resolutions` pin enforces a single React (19.2.3) + `@types/react`
(19.2.14) across the monorepo to avoid duplicate copies / type-identity
splits. Versions are the aged lockfile patches (clears the
`npmMinimalAgeGate`).

## Code changes

- **Global `JSX` shim** (`react-jsx-global.d.ts` per package): React 19
moved the `JSX` namespace under `React.JSX`; several deps' published
types (notably `@linaria/react`'s `styled.d.ts`, which types every
`styled.x` via `keyof JSX.IntrinsicElements`) still reference the global
namespace. Without the shim, every styled component degrades to `any`
props.
- **Ref nullability**: `useRef<T>(null)` now returns `RefObject<T |
null>`; widened consumer prop/hook ref types accordingly (incl. the
shared `useListenClickOutside`).
- **react-datepicker v9**: `onChange`/`onSelect` accept `Date | null`,
`calendarStartDay` typing, `ReactDatePickerProps`→`DatePickerProps`,
relaxed the dynamic `selectsMultiple` discriminated union.
- **react-data-grid beta.59**: `formatter`→`renderCell`,
`editor`→`renderEditCell`, `headerRenderer`→`renderHeaderCell`,
`components`→`renderers`, `onRowClick`→`onCellClick`, object-shaped
`useRowSelection`, Set-based selection.
- **dnd style cast**: `@radix-ui/react-popper` augments `CSSProperties`
with a `--radix-*` index signature that dnd's closed `DraggingStyle`
doesn't satisfy → cast at the spread.

## Status / testing

-  `typecheck` green: twenty-front, twenty-ui, twenty-ui-deprecated,
twenty-front-component-renderer, twenty-server
-  build / lint / unit tests / storybook+argos / runtime smoke-test in
progress

Draft until local + CI verification completes. Notable behavior to QA
manually: spreadsheet import (data-grid), date pickers, drag-and-drop
boards/lists, GraphQL playground, page titles/favicon.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21531?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-14 15:42:22 +02:00
Charles Bochet 869680a5a1 fix(deps): esbuild ^0.28.1 floors + vite 7→8 (rolldown) upgrade (#21517)
## What this does

Resolves the remaining esbuild security alerts on packages we own, and
upgrades the repo to **Vite 8** (which drops esbuild entirely in favour
of rolldown/oxc).

### 1. esbuild → `^0.28.1` (security)
- Raised the declared `esbuild` floor in `twenty-sdk` and the
logic-function common-layer (both were `^0.25.0`, which can only resolve
to a vulnerable version). These are our packages, so this is just
declaring the patched version — clears Dependabot **#1467** and
**#1468**.

### 2. Vite 7 → 8
- Bumped `vite` to `^8` in the 5 packages that declare it, and
`@vitejs/plugin-react-swc` to `^4.3.1` (the only plugin that needed a
bump for Vite 8; everything else already supports it).
- `twenty-front` keeps esbuild minification, so esbuild is now an
explicit (patched) devDependency there — Vite 8 no longer ships it.

### Two Vite-8 fallout fixes (bundler internals changed)
- **Storybook tests:** added React to `optimizeDeps.include` so Vite's
dep optimizer doesn't re-bundle React mid-run and break in-flight
imports in browser-mode tests.
- **`hex-rgb`:** it's ESM-only and broke rolldown's CJS interop (a
default import resolved to the wrong thing under jest). Replaced its one
use with a tiny inline hex→rgb parse and dropped the dependency.

## Verified
Vite resolves to a single `8.0.16` with no esbuild in its tree. Builds
pass on Vite 8/rolldown: `twenty-front` production build, the SDKs, and
Storybook; the previously-failing front and storybook test jobs now
pass; `yarn install --immutable` is clean.

## Note
This doesn't close root alert **#1469** — esbuild is still pulled by
other third-party tools (storybook, tsx, lingui, zapier, etc.) that
haven't shipped a patched release. The vulnerable code path (esbuild's
dev server) isn't used here, so that one is best dismissed as
not-affected.
2026-06-13 10:44:22 +00:00
Raphaël Bosi 7da6f25aaf Replace random remote images in stories to stop flaky Argos diffs (#21447)
### Problem
`TabButton` and `AvatarOrIcon` stories (in both `twenty-ui` and
`twenty-ui-deprecated`) used random remote image URLs —
`picsum.photos/192/192` and `i.pravatar.cc/300`. Each Argos run fetched
a different image, producing false-positive pixel diffs.

This is the image counterpart to #21412, which froze framer-motion
animations for the same reason.

### Fix
Replace all 6 random URLs with `AVATAR_URL_MOCK` — a fixed base64 data
URI already used across avatar stories. It's deterministic and
network-free, so screenshots are now stable across runs.

- `twenty-ui` / `twenty-ui-deprecated` → `TabButton.stories.tsx` (×2
each)
- `twenty-ui` / `twenty-ui-deprecated` → `AvatarOrIcon.stories.tsx` (×1
each)

Note: this changes the rendered image content, so it adds new baselines
(one-time Argos approval, not flakiness).
2026-06-11 11:41:01 +00:00
Raphaël Bosi d596c26f46 Migrate twenty UI (#21407)
## Migrate all `twenty-ui-deprecated` components into `twenty-ui`

Ports all **192 components** and **70 stories** into the new `twenty-ui`
package with full public-API parity (export diff: 0 missing / 0 extra
across all 13 modules; story titles byte-identical for the Argos
cross-package diff).

- **Styling:** Linaria → SCSS Modules, `var(--t-*)` tokens, `data-*`
state. Canonical pattern in `Button.module.scss`.
- **Behavior:** Base UI where mapped (Checkbox, Radio, Modal→Dialog,
Tooltip drops `react-tooltip`, JSON tree→Collapsible); framer kept only
where animation is the public contract.
- **Fixed an inert axe gate** in `.storybook/vitest.setup.ts` (a11y
addon annotations were never registered). Now live; 119 stories carry
`a11y: 'todo'` overrides pending a fix pass.
2026-06-11 11:02:28 +02:00
Charles Bochet e357116024 fix(ui): freeze framer-motion in Argos runs to stop flaky visual diffs (#21412)
## Problem

twenty-ui Argos visual tests are flaky — `Loader`,
`CircularProgressBar`, `ProgressBar` get flagged as changed with no
relevant code change.

## Cause

Argos screenshots use Playwright's `animations: "disabled"`, which only
freezes CSS animations. These components animate via framer-motion
(main-thread rAF), so each run captures a different frame.

## Fix

Set `MotionGlobalConfig.skipAnimations = true` in the Vitest setup of
both UI packages — freezes framer-motion to a deterministic state during
Argos runs only (interactive Storybook unaffected). Removes the
now-redundant per-story `disableSnapshot` opt-outs.

Note: removing `CircularProgressBar`'s opt-out adds new baselines
(one-time Argos approval, not flakiness).
2026-06-10 17:00:21 +02:00
Charles Bochet 0d8d463a44 security: clear all High minimatch Dependabot alerts via parent bumps (#21373)
## What

Clears **all 14 High `minimatch` ReDoS alerts** (GHSA-7r86-cg39-jmmj,
GHSA-23c5-xmqv-rm74, GHSA-3ppc-4f35-3m26) in the root tree — **by
bumping the actual parent dev tools, with no `resolutions`/overrides**.
Each parent that pinned a vulnerable minimatch is upgraded so the
patched version resolves naturally.

| Vulnerable minimatch | Pinned by | Fix |
|---|---|---|
| 10.0.3 | `@microsoft/api-extractor` 7.55.1 | → 7.58.7 (in-range
refresh) → minimatch 10.2.3 |
| 3.1.2 | `@stoplight/spectral-core` 1.20.0 | → 1.23.0 (in-range
refresh) → minimatch ^3.1.4 |
| 3.0.8 | `vite-plugin-dts` 3.8.1 → api-extractor 7.43.0 | bump to
`^4.5.4` (already used elsewhere here) → minimatch 10.2.3 |
| 4.2.3 | `graphql-config` 4.5.0 via `@graphql-codegen/cli` ^3.3.1 |
bump cli to `^5.0.7` → graphql-config 5.1.6 → minimatch ^10 |
| 9.0.3 | `zapier-platform-cli` ^15.4.1 | bump to `^19.0.0` |
| 7.4.6 | `verdaccio` 6.5.2 → `@verdaccio/core` 8.0.0-next | refresh to
6.7.2 → core 8.1.1 → minimatch 7.4.9 |

All six are **build/test tooling** — the ReDoS exposure is build-time,
never shipped to users.

## Verification

-  Every resolved `minimatch` in `yarn.lock` is now ≥ its patched floor
(3.1.5 / 7.4.9 / 9.0.9 / 10.2.3+). No `resolutions` added.
-  `nx build`: twenty-shared, twenty-ui, twenty-ui-deprecated,
twenty-emails (validates vite-plugin-dts v4)
-  twenty-zapier: typecheck + build + `zapier validate` (35/35 checks
pass; cli 19 + core 15.5.1)
-  twenty-front: typecheck; `graphql:generate` with codegen cli 5
produces **byte-identical** output (no generated-file changes in this
PR)
-  `yarn install --immutable` clean

## Notes

- The large `yarn.lock` diff is expected: major bumps to codegen (3→5),
zapier-cli (15→19), and vite-plugin-dts (3→4) cascade through dev-tree
transitives (net −1244 lines after dedup).
- `zapier-platform-core` (runtime) intentionally left at 15.5.1 — only
the CLI (dev tool) carried the vulnerable minimatch; `zapier validate`
flags only a non-blocking "consider upgrading core" suggestion.
- codegen plugins (`typescript`/`typescript-operations`) left at v3:
they run fine under cli 5 and produce identical output, so the minimal
change is just the cli bump.
2026-06-09 18:08:14 +02:00
Raphaël Bosi c596a5e342 Rename twenty-ui to twenty-ui-deprecated and twenty-new-ui to twenty-ui to prepare package release (#21315)
## Description

Promotes the next-gen UI library (formerly `twenty-new-ui`) to the name
**`twenty-ui`** (v0.1.0, publishable) and renames the old package to
**`twenty-ui-deprecated`**. Rewrites ~1,730 `twenty-ui` imports →
`twenty-ui-deprecated`, updates all configs/CI/Docker/deps, and migrates
twenty-front's `Toggle` to the new package (first consumer) as a
drop-in.

## Next steps
- Wire the `ui/v*` publish dispatch (`cd-deploy-tag.yaml` +
`.yarnrc.yml`), then tag `ui/v0.1.0` to publish.
- Continue migrating components from `twenty-ui-deprecated` →
`twenty-ui`.
2026-06-08 18:12:28 +02:00
Thomas des Francs 70066cdcf4 Update Google Workspace and integration logo assets (#21185)
## Summary
- Replace the Gmail and Google Calendar assets with their May 2026 icon
refreshes.
- Update the shared Google, Google Meet, Microsoft Outlook, Microsoft
Calendar-provider, Docusign, Stripe, Tally, and Zapier logo assets.
- Regenerate matching website/front raster assets at their existing
dimensions.

## Preview

GitHub's file diff can render some tiny transparent SVG/WebP logo diffs
as nearly empty. This grid uses the final raster assets from the PR
branch; Stripe and Zapier use their official favicon marks.

| Logo | Preview |
| --- | --- |
| Gmail | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/gmail.webp"
width="48" height="48" alt="Gmail logo" /> |
| Google Calendar | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/calendar.webp"
width="48" height="48" alt="Google Calendar logo" /> |
| Google | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/google.webp"
width="48" height="48" alt="Google logo" /> |
| Google Meet | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/meet.webp"
width="48" height="48" alt="Google Meet logo" /> |
| Microsoft Outlook / Calendar | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/outlook.webp"
width="48" height="48" alt="Microsoft Outlook / Calendar logo" /> |
| Docusign | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/docusign.webp"
width="48" height="48" alt="Docusign logo" /> |
| Stripe | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/stripe.webp"
width="48" height="48" alt="Stripe logo" /> |
| Tally | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/tally.webp"
width="48" height="48" alt="Tally logo" /> |
| Zapier | <img
src="https://raw.githubusercontent.com/twentyhq/twenty/bonapara/update-gmail-icon/packages/twenty-website/public/images/shared/companies/logos/zapier.webp"
width="48" height="48" alt="Zapier logo" /> |


## Notes
- Microsoft Calendar now uses the current Outlook/M365 icon, matching
the provider users connect for Microsoft calendar sync.
- Docusign keeps the compact Nexus mark for the small square logo slot,
regenerated from the current official Docusign lockup.
- Stripe now uses the official favicon mark from stripe.com.
- Zapier now uses the official square favicon mark from zapier.com.

## Sources
- Gmail 2026:
https://upload.wikimedia.org/wikipedia/commons/8/8f/Gmail_icon_%282026%29.svg
- Google Calendar 2026:
https://upload.wikimedia.org/wikipedia/commons/f/fa/Google_Calendar_icon_%282026%29.svg
- Google gradient G:
https://blog.google/company-news/inside-google/company-announcements/gradient-g-logo-design/
- Google Meet 2026:
https://commons.wikimedia.org/wiki/File:Google_Meet_icon_(2026).svg
- Microsoft 365 icon refresh:
https://techcommunity.microsoft.com/blog/microsoft365insiderblog/new-microsoft-365-icons-for-the-ai-era/4458674
- Docusign logo guidelines: https://brand.docusign.com/logo
- Stripe favicon:
https://images.stripeassets.com/fzn2n1nzq965/1hgcBNd12BfT9VLgbId7By/01d91920114b124fb4cf6d448f9f06eb/favicon.svg
- Tally press kit: https://tally.so/help/press-kit
- Zapier favicon: https://zapier.com/favicon.ico

## Validation
- Confirmed touched UI SVGs transform through SVGR successfully.
- Confirmed regenerated raster dimensions and alpha metadata with Sharp.
- Reviewed a generated contact sheet at 72px, 40px, and 16px.
- Ran `git diff --check`.
- Ran `packages/twenty-ui` Vite build with ARM Node v24.5.0:
`/Users/thomascolasdesfrancs/.nvm/versions/node/v24.5.0/bin/node
../../node_modules/vite/bin/vite.js build`.

Local note: `npx vite build` fails in `packages/twenty-ui` on this
machine because that directory resolves `/usr/local/bin/node` as x64
v23.5.0 while the Yarn install links Rollup's ARM optional package. The
direct ARM Node build above passed.
2026-06-04 14:19:49 +00:00
Charles Bochet a7fed47932 fix(twenty-ui): prevent local visual diffs from polluting CI baselines (#21225)
## Summary

- **Username-prefix branches**: Local visual-diff builds now use
`charles/main` instead of `main` as the branch name, preventing local
runs from creating auto-approved reference builds that could overwrite
CI baselines.
- **Local merge-base computation**: Computes `ARGOS_REFERENCE_COMMIT`
via `git merge-base HEAD main` locally, so the Argos SDK skips `git
fetch origin <branch>` — fixing the "fatal: couldn't find remote ref"
error when running from non-pushed branches.
- **Pass `referenceCommit` to vitest plugin**: Ensures the locally
computed merge-base is forwarded to the Argos upload.

## Test plan

- [x] Verified local visual-diff works from `main` branch (branch
becomes `charles/main`, not auto-approved)
- [x] Verified local visual-diff works from a non-pushed branch
(`test/local-only-visual-diff` → build uploaded successfully)
2026-06-04 15:42:32 +02:00
Charles Bochet 9042e8a542 feat(ci): Argos main baselines + local visual diff support (#21217)
## Summary

**CI: Main-branch Argos baselines**
- Run storybook build + screenshot capture on `push` to `main` in CI UI
workflow
- Add `dispatch-main` job in visual regression dispatch to forward
main-branch screenshots to ci-privileged
- Simplify `dispatch-pr` by inlining the artifact name and removing
unused `project` output

**Local visual diff support**
- Add `scripts/visual-diff.sh` for running Argos uploads locally via
tunnel
- Add `storybook:visual-diff` Nx target wrapping the script (depends on
`storybook:build`)
- Honor `STORYBOOK_URL` env in `vitest.config.ts` to reuse pre-served
static builds (mirrors twenty-front pattern)
- Support `ARGOS_BUILD_NAME`, `ARGOS_REFERENCE_BRANCH` env overrides in
vitest plugin config

## Context

Argos builds on PRs are all "Orphan" because there's no reference build
on `main` to compare against. The CI changes add the missing piece:
every merge to main now produces screenshots and uploads them to Argos
as reference builds.

The local visual diff script enables developers to run visual regression
checks from their machine against the self-hosted Argos instance via
`kubectl port-forward` (set up by the twenty-infra `argos-tunnel`
command).

## Related

- twentyhq/twenty-argos#1 (backend config for self-hosted HTTPS
redirect)
- twentyhq/twenty-infra#709 (argos-tunnel super CLI command +
self-hosted mode)

## Test plan

- [ ] Verify CI UI runs on next push to main and produces the
`argos-screenshots-twenty-ui` artifact
- [ ] Verify `dispatch-main` triggers and uploads screenshots to Argos
- [ ] Verify subsequent PR builds show diffs against the main baseline
instead of "Orphan"
- [ ] Run `ARGOS_TOKEN=<token> npx nx storybook:visual-diff twenty-ui`
locally with tunnel active
2026-06-04 14:55:08 +02:00
Charles Bochet e6614299c6 feat(ci): integrate Argos visual regression via vitest screenshots (#21210)
## Summary

- Adds `@argos-ci/storybook` vitest plugin to `twenty-ui` for automatic
screenshot capture during vitest storybook tests
- Uploads captured screenshots (PNG, ~5MB) as a CI artifact instead of
passing the full storybook build
- Updates the visual regression dispatch workflow to pass
`mode=argos-screenshots` to ci-privileged, which then uploads
screenshots to Argos via CLI

This replaces the 10-minute Storybook screenshot capture with a ~30s
vitest browser-mode approach. The heavy screenshot work happens on free
public runners, while ci-privileged only handles the Argos API upload
(keeping secrets private).

## Architecture

```
twenty (public, free runners)          ci-privileged (private)
─────────────────────────────          ────────────────────────
1. Build storybook-static              4. Download screenshots artifact
2. Vitest captures screenshots         5. `argos upload` → Argos API
3. Upload screenshots artifact         6. Poll for results
                                       7. Post PR comment
```

## Test plan

- [x] Verified locally: vitest captures 225 screenshots in ~28s
- [x] Verified `@argos-ci/cli upload` successfully creates Argos build
from captured screenshots
- [x] Argos diffs computed and results visible via API
- [ ] CI runs end-to-end on a PR
2026-06-04 08:46:37 +02:00
martmull 7ca9081efa Add application installation validation modale (#20907)
## After

<img width="1512" height="829" alt="image"
src="https://github.com/user-attachments/assets/231d4f0d-6052-4c4e-9a2a-0244d2b3832e"
/>
2026-05-26 09:48:31 +00:00
Thomas des Francs 015dca95fc Edit actor chip icon style & read-only behavior (#18552)
https://github.com/user-attachments/assets/925f4380-e3e2-430d-a8e3-7e1242298900

Removed background color from icons for consistency
Removed chip hover state as chips are not navigable
Updated read-only design (text/secondary on chip hover)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2026-05-26 09:38:39 +00:00
neo773 323e66433e lint: migrate prettier to oxfmt (#20783)
Most changes are `implements` being unwrapped this is not a oxfmt
regression
Prettier in 3.7 (we're on 3.1) changed this behaviour prettier blog
[post](https://prettier.io/blog/2025/11/27/3.7.0#change-18094)

This unifies our linting tooling

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-05-22 00:21:33 +02:00
martmull a9634b027e Stop bundling twenty-ui react cjs runtime code (#20703)
For this front component using Avatar from `twenty-sdk/ui`

```typescript
import { defineFrontComponent } from 'twenty-sdk/define';
import { Avatar } from 'twenty-sdk/ui';

// React component - implement your UI here
const Component = () => {
  return (
    <div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
      <Avatar avatarUrl={null} placeholder={'test'} />
      <h1>My new component!</h1>
      <p>This is your front component: fc-test</p>
    </div>
  );
};

export default defineFrontComponent({ ... });
```

## Before
<img width="3024" height="1964" alt="image"
src="https://github.com/user-attachments/assets/64479d9a-2316-4782-9552-c3982d85f97c"
/>

## After

<img width="1150" height="567" alt="image"
src="https://github.com/user-attachments/assets/67f34da2-a546-40e3-9f5d-62a5de6e4146"
/>
2026-05-19 09:26:41 +00:00
Félix Malfait d53f3e4ccc fix(kanban): give title full width when card is not hovered (#20455)
## Summary

On kanban cards, the title was being truncated even when the checkbox
wasn't displayed. The checkbox is hidden via `opacity: 0` on the card's
non-hovered state, which keeps it in flex flow and still reserves its
~24px of width — so the title's flex item was shrinking unnecessarily.

This change collapses the checkbox container's `max-width` to `0` (with
`overflow: hidden`) while it's hidden, and expands it back to the
checkbox's natural size (`spacing[6]` = 24px) on hover or when selected.
The existing `transition: all ease-in-out 160ms` animates the title
expanding into the freed space.

### Before
Title truncates with ellipsis even though the checkbox slot is empty:

<img width="350" alt="before"
src="https://i.imgur.com/placeholder-before.png" />

### After
Title uses the full row width when not hovered; the checkbox slides in
on hover (or when the card is selected) and the title reflows.

### Tooltip
The full title is already exposed on hover when truncated — `RecordChip`
→ `Chip` already wraps the label in `OverflowingTextWithTooltip`, which
detects overflow (`scrollWidth > clientWidth`) and renders an
`AppTooltip` with the full text. No additional wiring needed.

## Test plan

- [ ] On a kanban board, verify a long record title now uses the full
card width when the card is not hovered (no ellipsis if the title fits).
- [ ] Hover the card: the checkbox slides in smoothly (animated), and
the title reflows (may now truncate if it doesn't fit).
- [ ] Hover the (now-truncated) title: tooltip with the full title
appears.
- [ ] Select the card via the checkbox: checkbox stays visible (and
title stays in its hover-state width) without hovering.
- [ ] Compact view (eye icon) still renders correctly.

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:56:33 +02:00
Paul Rastoin 8a0225e974 Dispatch root package.json hoisted deps and devDeps (#20140)
# Introduction
Dispatching root package.json devDeps, prod deps
Taking care of keeping non imported module used at build/ci level in the
root package.json

## Motivation
Avoid redundant deps declaration, better scoping allow better workspace
deps granularity installation.

<img width="385" height="247" alt="image"
src="https://github.com/user-attachments/assets/9d7162ec-ba01-4f58-8563-38333733fdf0"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-30 16:50:22 +00:00
nitin e1828b6f41 [AI] Add thread actions, filters, and archive support (#20068)
## PR Description

### Summary
- Add AI chat thread actions: rename, archive (soft-delete via
`deletedAt`), and hard-delete with confirmation.
- Add chat thread filtering by status (active/archived/all), group-by
mode, and last activity.
- Rework drawer/side-panel thread lists to share thread sections, item
menus, archive icons, and empty-state behavior.
- Extend server chat thread model/API with `deletedAt`, mutations,
broadcasts, and archive-aware stream guards.

### Decisions
- Two-stage lifecycle: Archive sets `deletedAt` (soft); Delete is a
separate action on archived threads that hard-deletes the row. Aligns
with Twenty's soft-delete convention (Felix's suggestion).
- `lastMessageAt` is derived from `MAX(agentMessage.createdAt)` on read,
not stored. List query does inline aggregation for sort; `@ResolveField`
covers single-thread / mutation paths so the schema contract is honest
everywhere. Matches `timeline-messaging.service.ts` precedent and the
existing `totalInputCredits` / `totalOutputCredits` `@ResolveField`
pattern in the same resolver.
- Replaced auto-CRUD `chatThreads` (cursor-paginated Connection) with a
custom `[AgentChatThreadDTO!]` resolver. Frontend metadata-store treats
threads as a flat collection and filters/sorts client-side, so cursor
pagination was performative.
- Sending in an archived chat unarchives it optimistically on the client
and authoritatively on the server.
- Grouping and last-activity filtering use `lastMessageAt ?? updatedAt`
so archive/rename don't bump threads in the list.
- Kept metadata-store core API unchanged; AI chat uses the same local
cast pattern already used by other metadata-store partial updates.


https://github.com/user-attachments/assets/1b179b7b-1a2a-4a7a-aa0a-c88f6f051a87
2026-04-30 15:42:10 +00:00
martmull bddd23fd9c Fix application icons (#20142)
fixes application chip (icon Name) in all setting tables

## After
<img width="1200" height="896" alt="image"
src="https://github.com/user-attachments/assets/bd377f47-1d52-4142-b904-f2ce90c1db78"
/>
<img width="1200" height="917" alt="image"
src="https://github.com/user-attachments/assets/f49cc742-f11e-47e3-86ed-34beffe493c7"
/>
<img width="1234" height="878" alt="image"
src="https://github.com/user-attachments/assets/2ab459de-5f9d-4d39-9490-eec4ed9ee432"
/>
<img width="1239" height="845" alt="image"
src="https://github.com/user-attachments/assets/3c1bf258-285a-47b9-a60d-05ba1564334d"
/>
<img width="1183" height="907" alt="image"
src="https://github.com/user-attachments/assets/715b2470-2d88-48e3-88ac-d3daf3451717"
/>
<img width="1300" height="912" alt="image"
src="https://github.com/user-attachments/assets/d7c829fa-bf1d-4f19-82de-a8bf29e22bfa"
/>
2026-04-30 09:32:04 +00:00
neo773 11628d19a3 add recurring calendar events for google cal (#19748)
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-29 14:06:57 +00:00
Félix Malfait 8f362186ce Redesign application content tab + logic function settings; add Layout detail pages (#20056)
## Summary

Iterative redesign of two related areas in settings, plus a new
`pages/settings/layout/` folder for read-only entity detail pages.

### Application content tab

- **Grouped into three sections** — Data / Layout / Logic — each with
one H2 + multiple `TableSection`-wrapped sub-tables (mirrors the
role-permissions pattern). Replaces six per-category table/row
components with one uniform `<SettingsApplicationContentSubtable>` +
`ApplicationContentRow` shape (net **−~700 lines** across the refactor).
- **All 10 row categories now clickable** for installed apps:
- Objects / Fields / Logic functions / Front components → existing
detail pages
  - Agents → existing `AiAgentDetail`
- Skills → existing `AiSkillDetail` (looked up by `Skill.applicationId +
name`)
- Roles → existing `RoleDetail` (looked up by
`Role.universalIdentifier`)
- Views / Page layouts / Navigation menu items → **new** detail pages
(see below)
- **Lifecycle hooks visible** — `pre-install` / `post-install` logic
functions are surfaced in the Trigger column instead of appearing as
empty/misconfigured.

### Logic function settings (Triggers + Test tabs)

- Triggers tab is now editable (HTTP / Cron / Database event / AI tool)
with a `<SettingsLogicFunctionTriggerSection>` wrapper that owns the
toggle, header, and read-only short-circuit.
- HTTP section gets a Live URL field with copy-to-clipboard.
- Each section shows a **Sample input** preview (the JSON the function
will receive) using the same payload builders the Test tab uses.
- Test tab: **Simulate trigger** buttons that prefill the JSON input
from the configured trigger's schema. Replaces an unclickable `<Select>`
(which auto-disables when there's only one option — the typical case).
- Read-only behavior for installed-app functions: explicit `<Callout>`
notice when there's no trigger; trigger sections render as disabled
controls when there is one.
- Removed the empty Environment Variables section from the Settings tab
(it just told the user to go elsewhere).

### New `pages/settings/layout/` folder

Three new app-scoped detail pages so users can drill into entities the
GraphQL `Application` type doesn't expose by id (keyed by manifest
`universalIdentifier`):

- `ApplicationViewDetail` — type, object, visibility + Fields / Filters
/ Sorts subsections (field UIDs resolved to readable labels via
`useFieldLabelByUid`)
- `ApplicationPageLayoutDetail` — type, object + per-tab subsections
listing widgets
- `ApplicationNavigationMenuItemDetail` — type, destination (resolved),
icon, color, position

Each page reads from the marketplace manifest the parent app page
already loads (no extra queries). Folder set up so a future "Layout"
settings tab can grow here (analogous to the existing `data-model/`
folder under the Data tab).

### Other consistency fixes

- Breadcrumbs on every app-scoped entity detail page now include a
category crumb so users know what they're looking at: `Workspace /
Applications / Timely / Navigation menu items / Time entry`.
- Title fallback for nav menu items uses the resolved destination
(`"Time entry"`) instead of the raw enum (`"OBJECT"`).
- New shared utils: `getNavigationMenuItemDestination`,
`resolveManifestObjectLabel`, `getLogicFunctionTriggerLabel`,
`<MonoText>`.

## Backend changes

Only one minor schema-shape change (additive): added `applicationId` to
the `SkillFields` GraphQL fragment and `universalIdentifier` to the
`RoleFragment` so the new lookups have what they need. Generated
metadata schema patched in-tree to match — regenerate with `nx run
twenty-front:graphql:generate --configuration=metadata` if it drifts.

## Test plan

- [ ] Application content tab on an installed app shows the 3 grouped
sections; rows in each section are clickable
- [ ] Click an Object → existing object detail page
- [ ] Click a Field → existing field-edit page
- [ ] Click an Agent / Skill / Role → existing detail page
- [ ] Click a View / Page layout / Navigation menu item → new read-only
detail page; subsections (Fields/Filters/Sorts for views, per-tab
widgets for page layouts) populate correctly
- [ ] Breadcrumbs on every entity detail page have 5 crumbs ending in
`<Category> / <Entity name>`
- [ ] Logic function Triggers tab: toggle each trigger type on/off, see
the Sample input preview update; for installed apps, sections render as
read-only
- [ ] Test tab: each "Simulate trigger" button prefills the JSON editor
with the matching payload shape
- [ ] Functions list: a function configured as `post-install` shows
"Post-install" in the Trigger column

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: claude[bot] <claude[bot]@users.noreply.github.com>
2026-04-28 16:08:15 +02:00