Conversation
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
Closes [571](twentyhq/core-team-issues#571). Replicates the behavior of number field and allows specifying the number of decimals for currency field. <img width="931" height="858" alt="image" src="https://github.com/user-attachments/assets/f5100d58-b1b0-4a88-a090-e98b2feeebd0" /> Currencies around the world have a maximum of three decimal places - BHD, KWD etc. However, I have added a maximum of five decimal places in case someone wants to use the currency field type for displaying things like `per-second-billing` or `exchange rates`. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds configurable decimals (0–5) for currency fields, updating settings UI, types/schema, display/aggregate formatting, and input precision. > > - **Currency field settings**: > - Add `decimals` (0–5) to `FieldCurrencyMetadata.settings` and validate via `currencyFieldSettingsSchema`. > - Update `SettingsDataModelFieldCurrencyForm` to manage `format` (short/full) and `decimals` with counter when `full`; wire defaults via `useCurrencySettingsFormInitialValues`. > - **Display & aggregation**: > - `CurrencyDisplay` and `transformAggregateRawValueIntoAggregateDisplayValue` honor `decimals` when `format` is `full`; keep short format using `formatToShortNumber`. > - **Input**: > - Increase currency `IMaskInput` precision with `scale=5`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 959a8fc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
…tyhq#16816) ## Context After flushing the Redis cache (e.g., via `cache:flush` command), users get stuck in an infinite loop showing "Your workspace has been updated with a new data model. Please refresh the page." - refreshing the page doesn't help. ## Root Cause When the cache is flushed, `getMetadataVersion()` returns `undefined`. The version comparison in the error handler then becomes: ```typescript requestMetadataVersion !== `${currentMetadataVersion}` // Evaluates to: "5" !== "undefined" → always true ``` This triggers the schema mismatch error on every request, even after page refresh. ## History | Date | Commit | What Happened | |------|--------|---------------| | Aug 2024 | twentyhq#6691 (`17a1760afd`) | Introduced the `${currentMetadataVersion}` template literal that converts `undefined` to the string `"undefined"` | | Dec 2025 | twentyhq#16536 (`0035fc1145`) | Removed the safety check that would throw an early error when cache is empty, allowing `undefined` to propagate | ## Fix Add `isDefined(currentMetadataVersion)` check before comparing versions. If the server doesn't have a cached version, we shouldn't treat it as a mismatch - the schema factory already handles populating the cache when it actually needs the version. ```typescript if ( requestMetadataVersion && isDefined(currentMetadataVersion) && // ← Added this check requestMetadataVersion !== `${currentMetadataVersion}` ) { ``` ## Testing 1. Flush the cache: `npx nx run twenty-server:command cache:flush` 2. Refresh the page 3. Verify no infinite loop occurs and app loads normally
- when a view is deleted, it is removed from left menu + from list views in dropdown - deactivated fields are not suggested as options to group records by for a view (only in FE, not forbidden by BE)
…nother (twentyhq#16802) ## Summary This PR implements credit rollover functionality for billing, allowing unused credits from one billing period to carry over to the next (capped at the current period's subscription tier cap). ## Changes ### New Services - **StripeCreditGrantService**: Interacts with Stripe's Billing Credits API to create credit grants, retrieve customer credit balances, and void grants - **BillingCreditRolloverService**: Contains the rollover logic - calculates unused credits and creates new grants for the next period - **BillingWebhookCreditGrantService**: Handles `billing.credit_grant.created` and `billing.credit_grant.updated` webhooks to update billing alerts ### Modified Services - **StripeBillingAlertService**: Updated to include credit balance when calculating usage threshold alerts - **BillingUsageService**: Returns rollover credits to the frontend for display - **BillingSubscriptionService**: Queries credit balance when creating billing alerts - **BillingWebhookInvoiceService**: Triggers rollover processing on `invoice.finalized` webhook ### Frontend - Updated `SettingsBillingCreditsSection` to display base credits, rollover credits, and total available - Updated GraphQL query to fetch new `rolloverCredits` and `totalGrantedCredits` fields ### Stripe SDK Upgrade - Upgraded from v17.3.1 to v19.3.1 to get proper types for billing.credit_grant events - Fixed breaking changes: invoice.subscription path, subscription period fields location, removed properties ## How it works 1. When `invoice.finalized` webhook is received for `subscription_cycle`, the system: - Calculates usage from the previous period - Determines unused credits (tier cap - usage) - Caps rollover at current tier cap - Creates a Stripe credit grant with expiration at end of new period 2. When credit grants are created/updated/voided: - Billing alerts are recreated with the updated credit balance 3. The UI displays: - Base credits (from subscription tier) - Rollover credits (from previous periods) - Total available credits ## Edge Cases Handled - Credit grant voided: `billing.credit_grant.updated` webhook triggers alert update - Credit grant expired: Stripe's `creditBalanceSummary` API excludes expired grants - No unused credits: Rollover service skips grant creation - Customer ID as object: Controller extracts `.id` from expanded customer
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
…g without payment method (twentyhq#16827) ## Summary When users click 'Subscribe Now' during a trial period without a payment method configured, they previously saw an unhelpful error message: "No payment method found. Please update your billing details." This PR improves the UX by redirecting users directly to Stripe's billing portal payment method update flow, where they can add their payment information. After adding a payment method, users are redirected back to the billing settings page and can click 'Subscribe Now' again to successfully activate their subscription. ## Changes ### Backend - **stripe-billing-portal.service.ts**: Added `createBillingPortalSessionForPaymentMethodUpdate` method that creates a Stripe billing portal session with `flow_data.type: 'payment_method_update'` - **billing-portal.workspace-service.ts**: Added `computeBillingPortalSessionURLForPaymentMethodUpdate` method to build the portal URL - **billing-end-trial-period.output.ts**: Added optional `billingPortalUrl` field to the GraphQL output DTO - **billing-subscription.service.ts**: Modified `endTrialPeriod` to return `stripeCustomerId` when no payment method exists - **billing.resolver.ts**: Updated resolver to orchestrate billing portal URL generation when no payment method ### Frontend - **useEndSubscriptionTrialPeriod.ts**: Redirect to billing portal URL instead of showing error snackbar - **endSubscriptionTrialPeriod.ts**: Added `billingPortalUrl` to mutation response fields ## User Flow 1. User clicks "Subscribe Now" during trial 2. Backend checks for payment method 3. If no payment method → redirect to Stripe billing portal payment method update page 4. User adds payment method in Stripe 5. User is redirected back to `/settings/billing` 6. User clicks "Subscribe Now" again to activate subscription
….0 to 0.60.1 (twentyhq#16828) Bumps [@opentelemetry/auto-instrumentations-node](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/auto-instrumentations-node) from 0.60.0 to 0.60.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/releases"><code>@opentelemetry/auto-instrumentations-node</code>'s releases</a>.</em></p> <blockquote> <h2>instrumentation-aws-lambda: v0.60.1</h2> <h2><a href="https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-aws-lambda-v0.60.0...instrumentation-aws-lambda-v0.60.1">0.60.1</a> (2025-11-24)</h2> <h3>Dependencies</h3> <ul> <li>The following workspace dependencies were updated <ul> <li>devDependencies <ul> <li><code>@opentelemetry/propagator-aws-xray</code> bumped from ^2.1.3 to ^2.1.4</li> <li><code>@opentelemetry/propagator-aws-xray-lambda</code> bumped from ^0.55.3 to ^0.55.4</li> </ul> </li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/packages/auto-instrumentations-node/CHANGELOG.md"><code>@opentelemetry/auto-instrumentations-node</code>'s changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/open-telemetry/opentelemetry-js-contrib/compare/auto-instrumentations-node-v0.60.0...auto-instrumentations-node-v0.60.1">0.60.1</a> (2025-06-05)</h2> <h3>Dependencies</h3> <ul> <li>The following workspace dependencies were updated <ul> <li>dependencies <ul> <li><code>@opentelemetry/instrumentation-hapi</code> bumped from ^0.48.0 to ^0.49.0</li> <li><code>@opentelemetry/instrumentation-koa</code> bumped from ^0.50.0 to ^0.50.1</li> <li><code>@opentelemetry/instrumentation-mongodb</code> bumped from ^0.55.0 to ^0.55.1</li> <li><code>@opentelemetry/instrumentation-net</code> bumped from ^0.46.0 to ^0.46.1</li> <li><code>@opentelemetry/instrumentation-redis</code> bumped from ^0.49.0 to ^0.49.1</li> <li><code>@opentelemetry/instrumentation-restify</code> bumped from ^0.48.0 to ^0.48.1</li> <li><code>@opentelemetry/instrumentation-undici</code> bumped from ^0.13.0 to ^0.13.1</li> </ul> </li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/commits/auto-instrumentations-node-v0.60.1/packages/auto-instrumentations-node">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…hq#16830) Bumps [msw-storybook-addon](https://github.com/mswjs/msw-storybook-addon/tree/HEAD/packages/msw-addon) from 2.0.5 to 2.0.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/mswjs/msw-storybook-addon/releases">msw-storybook-addon's releases</a>.</em></p> <blockquote> <h2>v2.0.6</h2> <h4>🐛 Bug Fix</h4> <ul> <li>fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> <a href="https://redirect.github.com/mswjs/msw-storybook-addon/pull/178">#178</a> (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <h4>Authors: 1</h4> <ul> <li>Connor Shea (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/mswjs/msw-storybook-addon/blob/main/packages/msw-addon/CHANGELOG.md">msw-storybook-addon's changelog</a>.</em></p> <blockquote> <h1>v2.0.6 (Fri Oct 10 2025)</h1> <h4>🐛 Bug Fix</h4> <ul> <li>fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> <a href="https://redirect.github.com/mswjs/msw-storybook-addon/pull/178">#178</a> (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <h4>Authors: 1</h4> <ul> <li>Connor Shea (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <hr /> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/mswjs/msw-storybook-addon/commit/ae7ce4de01bf9665a03816f3ca4908feb5f90653"><code>ae7ce4d</code></a> Update CHANGELOG.md [skip ci]</li> <li><a href="https://github.com/mswjs/msw-storybook-addon/commit/0b9594003ce8226767d51b444bad505db401c387"><code>0b95940</code></a> fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> (<a href="https://github.com/mswjs/msw-storybook-addon/tree/HEAD/packages/msw-addon/issues/178">#178</a>)</li> <li>See full diff in <a href="https://github.com/mswjs/msw-storybook-addon/commits/v2.0.6/packages/msw-addon">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [eslint](https://github.com/eslint/eslint) from 9.32.0 to 9.39.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/eslint/eslint/releases">eslint's releases</a>.</em></p> <blockquote> <h2>v9.39.2</h2> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/57058331946568164449c5caabe2cf206e4fb5d9"><code>5705833</code></a> fix: warn when <code>eslint-env</code> configuration comments are found (<a href="https://redirect.github.com/eslint/eslint/issues/20381">#20381</a>) (sethamus)</li> </ul> <h2>Build Related</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/506f1549a64aa65bdddc75c71cb62f0ab94b5a23"><code>506f154</code></a> build: add .scss files entry to knip (<a href="https://redirect.github.com/eslint/eslint/issues/20391">#20391</a>) (Milos Djermanovic)</li> </ul> <h2>Chores</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/7ca0af7f9f89dd4a01736dae01931c45d528171b"><code>7ca0af7</code></a> chore: upgrade to <code>@eslint/js@9.39.2</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20394">#20394</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/c43ce24ff0ce073ec4ad691cd5a50171dfe6cf1e"><code>c43ce24</code></a> chore: package.json update for <code>@eslint/js</code> release (Jenkins)</li> <li><a href="https://github.com/eslint/eslint/commit/4c9858e47bb9146cf20f546a562bc58a9ee3dae1"><code>4c9858e</code></a> ci: add <code>v9.x-dev</code> branch (<a href="https://redirect.github.com/eslint/eslint/issues/20382">#20382</a>) (Milos Djermanovic)</li> </ul> <h2>v9.39.1</h2> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/650753ee3976784343ceb40170619dab1aa9fe0d"><code>650753e</code></a> fix: Only pass node to JS lang visitor methods (<a href="https://redirect.github.com/eslint/eslint/issues/20283">#20283</a>) (Nicholas C. Zakas)</li> </ul> <h2>Documentation</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/51b51f4f1ce82ef63264c4e45d9ef579bcd73f8e"><code>51b51f4</code></a> docs: add a section on when to use extends vs cascading (<a href="https://redirect.github.com/eslint/eslint/issues/20268">#20268</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/b44d42699dcd1729b7ecb50ca70e4c1c17f551f1"><code>b44d426</code></a> docs: Update README (GitHub Actions Bot)</li> </ul> <h2>Chores</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/92db329211c8da5ce8340a4d4c05ce9c12845381"><code>92db329</code></a> chore: update <code>@eslint/js</code> version to 9.39.1 (<a href="https://redirect.github.com/eslint/eslint/issues/20284">#20284</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/c7ebefc9eaf99b76b30b0d3cf9960807a47367c4"><code>c7ebefc</code></a> chore: package.json update for <code>@eslint/js</code> release (Jenkins)</li> <li><a href="https://github.com/eslint/eslint/commit/61778f6ca33c0f63962a91d6a75a4fa5db9f47d2"><code>61778f6</code></a> chore: update eslint-config-eslint dependency <code>@eslint/js</code> to ^9.39.0 (<a href="https://redirect.github.com/eslint/eslint/issues/20275">#20275</a>) (renovate[bot])</li> <li><a href="https://github.com/eslint/eslint/commit/d9ca2fcd9ad63331bfd329a69534e1ff04f231e8"><code>d9ca2fc</code></a> ci: Add rangeStrategy to eslint group in renovate config (<a href="https://redirect.github.com/eslint/eslint/issues/20266">#20266</a>) (唯然)</li> <li><a href="https://github.com/eslint/eslint/commit/009e5076ff5a4bd845f55e17676e3bb88f47c280"><code>009e507</code></a> test: fix version tests for ESLint v10 (<a href="https://redirect.github.com/eslint/eslint/issues/20274">#20274</a>) (Milos Djermanovic)</li> </ul> <h2>v9.39.0</h2> <h2>Features</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/cc57d87a3f119e9d39c55e044e526ae067fa31ce"><code>cc57d87</code></a> feat: update error loc to key in <code>no-dupe-class-members</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20259">#20259</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/126552fcf35da3ddcefa527db06dabc54c04041c"><code>126552f</code></a> feat: update error location in <code>for-direction</code> and <code>no-dupe-args</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20258">#20258</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/167d0970d3802a66910e9820f31dcd717fab0b2a"><code>167d097</code></a> feat: update <code>complexity</code> rule to highlight only static block header (<a href="https://redirect.github.com/eslint/eslint/issues/20245">#20245</a>) (jaymarvelz)</li> </ul> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/15f5c7c168d0698683943f51dd617f14a5e6815c"><code>15f5c7c</code></a> fix: forward traversal <code>step.args</code> to visitors (<a href="https://redirect.github.com/eslint/eslint/issues/20253">#20253</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/5a1a534e877f7c4c992885867f923df307c3929d"><code>5a1a534</code></a> fix: allow JSDoc comments in object-shorthand rule (<a href="https://redirect.github.com/eslint/eslint/issues/20167">#20167</a>) (Nitin Kumar)</li> <li><a href="https://github.com/eslint/eslint/commit/e86b813eb660f1a5adc8e143a70d9b683cd12362"><code>e86b813</code></a> fix: Use more types from <code>@eslint/core</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20257">#20257</a>) (Nicholas C. Zakas)</li> <li><a href="https://github.com/eslint/eslint/commit/927272d1f0d5683b029b729d368a96527f283323"><code>927272d</code></a> fix: correct <code>Scope</code> typings (<a href="https://redirect.github.com/eslint/eslint/issues/20198">#20198</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/37f76d9c539bb6fc816fedb7be4486b71a58620a"><code>37f76d9</code></a> fix: use <code>AST.Program</code> type for Program node (<a href="https://redirect.github.com/eslint/eslint/issues/20244">#20244</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/ae07f0b3334ebd22ae2e7b09bca5973b96aa9768"><code>ae07f0b</code></a> fix: unify timing report for concurrent linting (<a href="https://redirect.github.com/eslint/eslint/issues/20188">#20188</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/b165d471be6062f4475b972155b02654a974a0e9"><code>b165d47</code></a> fix: correct <code>Rule</code> typings (<a href="https://redirect.github.com/eslint/eslint/issues/20199">#20199</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/fb97cda70d87286a7dbd2457f578ef578d6905e8"><code>fb97cda</code></a> fix: improve error message for missing fix function in suggestions (<a href="https://redirect.github.com/eslint/eslint/issues/20218">#20218</a>) (jaymarvelz)</li> </ul> <h2>Documentation</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/d3e81e30ee6be5a21151b7a17ef10a714b6059c0"><code>d3e81e3</code></a> docs: Always recommend to include a files property (<a href="https://redirect.github.com/eslint/eslint/issues/20158">#20158</a>) (Percy Ma)</li> <li><a href="https://github.com/eslint/eslint/commit/0f0385f1404dcadaba4812120b1ad02334dbd66a"><code>0f0385f</code></a> docs: use consistent naming recommendation (<a href="https://redirect.github.com/eslint/eslint/issues/20250">#20250</a>) (Alex M. Spieslechner)</li> <li><a href="https://github.com/eslint/eslint/commit/a3b145609ac649fac837c8c0515cbb2a9321ca40"><code>a3b1456</code></a> docs: Update README (GitHub Actions Bot)</li> <li><a href="https://github.com/eslint/eslint/commit/cf5f2dd58dd98084a21da04fe7b9054b9478d552"><code>cf5f2dd</code></a> docs: fix correct tag of <code>no-useless-constructor</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20255">#20255</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/10b995c8e5473de8d66d3cd99d816e046f35e3ec"><code>10b995c</code></a> docs: add TS options and examples for <code>nofunc</code> in <code>no-use-before-define</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20249">#20249</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/2584187e4a305ea7a98e1a5bd4dca2a60ad132f8"><code>2584187</code></a> docs: remove repetitive word in comment (<a href="https://redirect.github.com/eslint/eslint/issues/20242">#20242</a>) (reddaisyy)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/eslint/eslint/commit/9278324aa0023d223874825b0d4b6ac75783096a"><code>9278324</code></a> 9.39.2</li> <li><a href="https://github.com/eslint/eslint/commit/542266ad3c58b47066d4b8ae61d419b423acee8f"><code>542266a</code></a> Build: changelog update for 9.39.2</li> <li><a href="https://github.com/eslint/eslint/commit/7ca0af7f9f89dd4a01736dae01931c45d528171b"><code>7ca0af7</code></a> chore: upgrade to <code>@eslint/js@9.39.2</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20394">#20394</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/c43ce24ff0ce073ec4ad691cd5a50171dfe6cf1e"><code>c43ce24</code></a> chore: package.json update for <code>@eslint/js</code> release</li> <li><a href="https://github.com/eslint/eslint/commit/57058331946568164449c5caabe2cf206e4fb5d9"><code>5705833</code></a> fix: warn when <code>eslint-env</code> configuration comments are found (<a href="https://redirect.github.com/eslint/eslint/issues/20381">#20381</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/506f1549a64aa65bdddc75c71cb62f0ab94b5a23"><code>506f154</code></a> build: add .scss files entry to knip (<a href="https://redirect.github.com/eslint/eslint/issues/20391">#20391</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/4c9858e47bb9146cf20f546a562bc58a9ee3dae1"><code>4c9858e</code></a> ci: add <code>v9.x-dev</code> branch (<a href="https://redirect.github.com/eslint/eslint/issues/20382">#20382</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/e2772811a8595d161870835ff04822b25a2cdf45"><code>e277281</code></a> 9.39.1</li> <li><a href="https://github.com/eslint/eslint/commit/4cdf397b30b2b749865ea0fcf4d30eb8ba458896"><code>4cdf397</code></a> Build: changelog update for 9.39.1</li> <li><a href="https://github.com/eslint/eslint/commit/92db329211c8da5ce8340a4d4c05ce9c12845381"><code>92db329</code></a> chore: update <code>@eslint/js</code> version to 9.39.1 (<a href="https://redirect.github.com/eslint/eslint/issues/20284">#20284</a>)</li> <li>Additional commits viewable in <a href="https://github.com/eslint/eslint/compare/v9.32.0...v9.39.2">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com>
<!-- CURSOR_SUMMARY --> > [!NOTE] > Implements last-modifier tracking and unified actor injection. > > - New `ActorFromAuthContextService` replaces createdBy-only logic; pre-query hooks now inject both `createdBy` and `updatedBy` on create and `updatedBy` on update > - Add `updatedBy` standard field to core/custom objects (e.g., `person`, `company`, `task`, `note`, `attachment`, `dashboard`, `workflow`, `workflowRun`) with IDs, metadata builders, and ORM entity fields > - Record CRUD: `create` now sets both `createdBy` and `updatedBy`; `update` sets `updatedBy`; workflow actions use a shared workflow actor builder; REST base handler uses the new actor service > - Seeder data and snapshots updated to include `updatedBy`; GraphQL result formatting adds defaults/handling for empty composite fields (incl. actor) > - Frontend `useUpdateOneRecord` upserts returned record into the local store after mutation > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1f28377. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Félix Malfait <felix@twenty.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
Created by Github action --------- Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: github-actions <github-actions@twenty.com>
… notes (twentyhq#16818) Following [discord thread](https://discord.com/channels/1130383047699738754/1453910755387899996/1453910755387899996), reproductible on twenty-eng https://github.com/user-attachments/assets/ae7f363d-87e1-44fa-8fe2-ee78412d62a7 Records positions are computed at record creation, depending on the position arg from the request, being equal to `last`, `first`, or not present. When being equal to last, as it is done when creating a note from the product, the position is calculated using `.maximum()` function which uses postgres' MAX function. If there is a `NaN` value among the list, the MAX will return `NaN` too. So if for some reason there is a NaN somewhere in the position column, all subsequent records being created with last position argument will be created with NaN value. Until [this PR](twentyhq#16630), where we introduced a validation on position at record creation which throws when NaN is trying to be introduced as a position, this was going silent. (fyi @etiennejouan , not on you at all but for info) Looking into twenty-eng workspace, I found note records with NaN position dating back to august 2025, making it hard to understand and debug why they were introduced with NaN position. So I did not find the real root cause, but I suggest to - update record-position.service to fix the issue for subsequent records that go through this service (which is what is currently broken) - run a command to fix the existing records with NaN position for Notes, as it is where the issue happened for both the user reporting the issue on discord, and us on twenty-eng. So hopefully the problem was limited to Notes
twentyhq#16822) Closes [1957](twentyhq/core-team-issues#1957). `getWidgetCardVariant` now returns `side-panel` for mobile and right drawer instead of returning `record-page`. Added stories to WidgetRenderer.stories.tsx because WidgetRenderer is where getWidgetCardVariant is called and the variant is applied. These stories test the actual behavior (mobile/side panel triggering side-column variant) rather than just visual appearance, following the existing pattern of individual behavior-testing stories in this file.
Had to close the other PR since I messed up re-basing somehow: https://github.com/twentyhq/twenty/pull/16668/files. Moved changes to this new PR in order to resolve comments from the previous PR and also match the field-design to that on Figma. --------- Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
…or page layout widget configuration type (twentyhq#16671) # Introduction In this pull-request we're refactoring the page layout widget configuration entity to be containing its discriminated key simplifying underlying code and maintainability - Made the configuration and title non nullable - Introduced a generic predicate for the `widgetConfigurationType` - Upgraded command to remove `graphType` and insert new `configurationType` to existing entries - Migrated frontend to new type system --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com> Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
To avoid breaking workflows during release
…tyhq#16039) closes twentyhq#15854 - Add `isValid()` check in `formatDateISOStringToDateTime` before calling `formatInTimeZone` - Add `isDefined()` guard in `getFieldLinkDefinedLinks` (mirrors `phonesUtils` pattern) before: https://github.com/user-attachments/assets/1eb89fa4-70b6-4794-8860-0a42522598b5 https://github.com/user-attachments/assets/781c7d37-c435-4832-98d4-8e6925b51e10 after: https://github.com/user-attachments/assets/b1c22d25-4e8e-45c3-af98-be1684a5962e https://github.com/user-attachments/assets/ce084a9d-03b8-4f88-8522-a32cb1b7cf2f --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Prepare for release, will re-enable them
…16829) Bumps [@monaco-editor/react](https://github.com/suren-atoyan/monaco-react) from 4.6.0 to 4.7.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/releases"><code>@monaco-editor/react</code>'s releases</a>.</em></p> <blockquote> <h2>v4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (<code>v1.5.0</code>) version (this uses <code>monaco-editor</code> <code>v0.52.2</code>)</li> <li>package: inherit all changes from <code>v4.7.0-rc.0</code></li> </ul> <h2>v4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom <code>v19</code> as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/blob/master/CHANGELOG.md"><code>@monaco-editor/react</code>'s changelog</a>.</em></p> <blockquote> <h2>4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version (this uses monaco-editor v0.52.2)</li> <li>package: inherit all changes from v4.7.0-rc.0</li> </ul> <h2>4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom v19 as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/eb120e66378471315620fe5339b73ba003f199ad"><code>eb120e6</code></a> update package to 4.7.0 version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/cdd070c9f080caf4a9a7b13c2c34fa4e10edc9bf"><code>cdd070c</code></a> update snapshots</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/55a063e45d2f2672884b77059ac97850758764ae"><code>55a063e</code></a> update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/52e8c75616e09730b7b1a0b5822385212a082ce8"><code>52e8c75</code></a> update package to 4.7.0-rc.o version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/e72be4edc1b4492eae9f7d85671ee61a43a6aee8"><code>e72be4e</code></a> add react 19 to peerDependencies</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/642be903a9dd21d6fe639ab5c92c234dad77c813"><code>642be90</code></a> update playground's react version to 19</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ceee344fbe26285dabb0fe90985fe18ec867211c"><code>ceee344</code></a> Add Monaco-React AI Bot in Readme (<a href="https://redirect.github.com/suren-atoyan/monaco-react/issues/655">#655</a>)</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/f7cac39fbad0f062dc66458831aaf57a7126dd40"><code>f7cac39</code></a> add electron blog post link</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ea601cf9f6fe9f2cc0c6271d6a9cde9a332b6dc0"><code>ea601cf</code></a> add tea constitution file</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/3327f3c368cb6d56c02f2df8a9d45177ce6f52e9"><code>3327f3c</code></a> add GitHub sponsor button</li> <li>See full diff in <a href="https://github.com/suren-atoyan/monaco-react/compare/v4.6.0...v4.7.0">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com>
Fixes [twentyhq#16805](twentyhq#16805) User was not able to update his own profile picture it showed permisson error while doing so. Updated permission so that user is able to edit profile picture <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Ensures profile picture uploads succeed only with appropriate permissions and clearer errors. > > - Tightens `UploadProfilePicturePermissionGuard` to handle missing `workspace`, allow during workspace creation, and permit uploads when user has `WORKSPACE_MEMBERS` or `PROFILE_INFORMATION` settings; otherwise throws a `PermissionsException` with a user-friendly message > - In `user-workspace.resolver.ts`, validates the upload result and throws an error if no files were returned > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3766bac. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix@twenty.com>
Redesign the data model pages for more clarity / better distinction between fields and relations
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
Two challenges with error messages - always provide a useful/meaningful error message for the end user instead of the generic one. eg: show "Wrong password" and not "An error occured" - avoid technical details unless error regards a technical feature. eg: show "An error occured" and not "Invalid post-hook payload."; but do show "Invalid issuer URL." as it occurs while configuring SSO What this PR does - Make userFriendlyMessage mandatory for widely used GraphqlQueryRunnerException and CommonQueryRunnerException, so that developers are forced to ask themselves what the error message should be, and as it contains very wide error codes (eg: "Bad request") which should not be mapped to just one default message - Keep userFriendlyMessage optional for service-specific exceptions (eg: workflowStepExecutorException), but convert the error code to userFriendlyMessage mapper to a switch case function with a typecheck ensuring that all codes are mapped to a message. These default messages are still overridable where they are thrown.
## Summary This PR introduces row-level security (RLS) permissions for roles in the frontend, allowing fine-grained access control at the record level. Users can now define permission rules that determine which specific records a role can access based on dynamic conditions and filters. ## What's Changed Implemented UI for configuring record-level permissions on object permissions screens Added support for defining permission predicates using filter conditions (similar to advanced filters) Introduced variable picker for dynamic permission rules (e.g., "me" context for user-specific access) Built predicate conversion layer to sync UI state with backend permission structure Extended GraphQL schema with mutations for upserting row-level permission predicates Fixed handling of orphaned RLS groups to prevent data inconsistencies Added enterprise key validation for RLS features The implementation enables scenarios like "users can only see their own records" or "users can access records associated with their team." <img width="687" height="702" alt="Screenshot 2026-01-09 at 23 07 02" src="https://github.com/user-attachments/assets/33fe736e-6cbf-40bd-b2eb-c8a90c8d21bc" /> --------- Co-authored-by: Charles Bochet <charles@twenty.com>
twentyhq#17103) ## Summary - Fixed the billing credits progress bar background color in dark mode - The background was hardcoded to `BACKGROUND_LIGHT.tertiary`, causing it to always display a light color regardless of the current theme - Changed to use `theme.background.tertiary` to properly respect dark/light mode ## Test plan - [x] Navigate to Settings > Billing in dark mode - [x] Verify the credits progress bar background matches the tertiary background color (dark in dark mode) - [x] Verify it still looks correct in light mode Figma reference: https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=64812-242606&m=dev
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
## Before <img width="2616" height="2012" alt="image" src="https://github.com/user-attachments/assets/40c8c12d-aa06-42d1-9cc8-4644dbf64318" /> ## After <img width="640" height="702" alt="image" src="https://github.com/user-attachments/assets/25d924fb-82d1-4c95-9285-2b0bac68e250" />
…wentyhq#17104) ## Summary - Updated Relations and Fields tables in the object detail settings page to use flexible width (`1fr`) for the Name column instead of fixed pixels - Aligned column widths between both tables (`1fr 148px 148px 36px`) so the App and Type/Data type columns line up ## Test plan - [ ] Navigate to Settings > Data model > select any object (e.g., Companies) - [ ] Verify the Relations table rows take the full available width - [ ] Verify the Fields table rows take the full available width - [ ] Verify the App and Type/Data type columns are aligned between both tables
This PR is a follow-up of twentyhq#16966 and implements a new mechanism to handle SSE events. It creates only one event stream per browser tab, then use mutations to tell the backend which query to listen to, without re-mounting the event stream connexion. Then each event that comes from this unique subscription is then dispatched in a new JavaScript CustomEvent, per queryId, on which specific hooks add an event listener. This PR introduces the generic tooling as well as the handling of update events on table.
# Introduction Followup twentyhq#16981 1/ Migration, applicationId and universalIdentifier are required on entity ( save point migration + upgrade command fallback pattern ) 2/ Backfill using previous standard ids
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
…wentyhq#17107) ## Summary - Update all illustration icons to use `theme.accent.accent3` for fill and `theme.accent.accent8` for border - Replaces hardcoded `IllustrationIcon.blue` values with theme-responsive accent colors - Icons will now adapt correctly to theme changes ## Test plan - [ ] Navigate to Settings > Data model > select any object - [ ] Verify the Relations "Type" column icons use the accent colors - [ ] Verify the Fields "Data type" column icons use the accent colors - [ ] Switch themes (if available) and verify icons adapt accordingly
Upgraded to Storybook 10. We still use `@storybook/test-runner` for testing since it appears it'd require more work to move from Jest to Vitest than I initially anticipated, but I completed this PR to fix `storybook:serve:dev` - it takes time to load, but it works the way it used to with Storybook 8. https://github.com/user-attachments/assets/7afc32c6-4bcf-4b37-b83b-8d00d28dda15
The current Japanese translations are severely lacking. My company (based in Tokyo) uses Japanese as its main language. I've gone through and corrected/standardized everything. This is good enough to merge as a starting point. Includes `lingui compile` for the changes. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Major localization refresh focused on Japanese. > > - Rewrites and standardizes `ja-JP` message strings (clearer phrasing, consistent terminology, corrected placeholders/punctuation) > - Regenerates compiled Lingui locale bundles; updates `ja-JP.ts` and `ko-KR.ts` outputs > - No runtime logic changes; scope limited to generated i18n resources > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3365dcd. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix@twenty.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
# Introduction As we've just [identified](twentyhq#16981) the standard field metadata in production we can not enable the is unique comparison even for standard entities
- exports `extendObject` utils from `twenty-sdk` - define `*.object-extension.ts` filename pattern to extend and object - handle object-extension configs in manifest
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
# Introduction Some legacy caches are based on the flat ones So we need to seq invalidate before invalidating others as it could result in inter dep cache invalidation race condition
… drawer (twentyhq#17123) Closes twentyhq/core-team-issues#2058 We settled on a simpler solution by just hardcoding the objects order for now. We will change this once it's possible to reorder the workspace favorites with drag and drop.
Followups after @Weiko review on twentyhq#17042
Refactors to be consistent with Microsoft service Handles scenarios like temporary error which was not handled before Moved `IsGmailNetworkError` from root orchestrator to driver level
…tyhq#17128) - added article to detail how to attach a pdf to a given record - added link in another article - updated the english section of the docs.json to have the file appear in the left menu - updated the 2 navigation files --------- Co-authored-by: github-actions <github-actions@twenty.com>
Fixes twentyhq#17006 ## Changes Added `lastAuthenticateWorkspaceSsoMethodState` Recoil atom to track the last used SSO method, persisted in localStorage Updated `SignInUpWithGoogle` component to display a "Last" pill badge when Google was the last auth method Updated `SignInUpWithMicrosoft` component to display a "Last" pill badge when Microsoft was the last auth method Updated `SignInUpWithSSO` component to display a "Last" pill badge when SSO was the last auth method. The state is saved after successful authentication redirect, ensuring it persists across sessions ## Implementation Details Uses existing `localStorageEffect` for persistence across browser sessions Leverages the existing Pill component from twenty-ui with blue accent color The label is positioned on the right border of the button using absolute positioning State is saved in the `useAuth` hook during Google/Microsoft sign-in and in the SSO login component <img width="684" height="608" alt="image" src="https://github.com/user-attachments/assets/629a1599-aab0-44e4-b684-ae91a8e725fd" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Highlights the most recently used authentication method and preserves it across sessions. > > - Introduces `AuthenticatedMethod` enum and `lastAuthenticatedMethodState` (persisted via `localStorageEffect`) and preserves it through `useAuth.clearSession` > - Displays a "Last" pill via `LastUsedPill` on `SignInUpWithGoogle`, `SignInUpWithMicrosoft`, `SignInUpWithSSO`, and `SignInUpWithCredentials` when appropriate; adds `StyledSSOButtonContainer` for badge positioning > - Adds `useHasMultipleAuthMethods` to detect when to show the badge; threads `isGlobalScope` to relevant components > - Sets last-used method on click/submit in SSO and credentials flows (`useSignInUp`, SSO button handlers) > - Refactors `SignInUpGlobalScopeForm` to use `SignInUpWithCredentials` and updates `SignInUp` title logic for global scope (e.g., "Welcome to Twenty") > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 70d5527. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix@twenty.com>
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com>
|
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:13643 This environment will automatically shut down when the PR is closed or after 5 hours. |
This skill instructs AI agents how to: - Find customers by phone number using find_people tool - Send customer information to external webhooks using http_request tool
📊 API Changes ReportGraphQL Schema ChangesGraphQL Schema Changes[log] [log] ✖ Field graphType was removed from object type AggregateChartConfiguration GraphQL Metadata Schema ChangesGraphQL Metadata Schema Changes[log] [log] ✖ Field graphType was removed from object type AggregateChartConfiguration
|
- Add min(1) validation to prevent empty strings in toolNames array - Add min(1) validation to prevent empty strings in skillNames array - Add array min(1) validation to require at least one tool/skill name This helps prevent AI models from generating invalid tool calls with empty names.
No description provided.